import an implementation of c++17 std::optional
There was a recent master-branch bug introduced by mismatches between iterator types and pointers (see, I think, https://gerrit.gromacs.org/#/c/8933/24/src/gromacs/topology/residuetypes.cpp) which has provoked unrelated changes to how we implement ArrayRef::iterator.
The logic leading to the bug was that the return value of std::find_if being returned from a helper function and then immediately compared for whether the value was the end() of the range. However, this is a classic use case for the c++17 std feature optional<T>, where the return type of such a method consumes at least one more byte (for a boolean that represents whether a valid T is found, but has a clear semantic for "do you have a value for me to use?"
I suggest we import a c++14 implementation of such a type (e.g. part of https://github.com/TartanLlama/optional/blob/master/tl/optional.hpp, or https://github.com/akrzemi1/Optional, or https://github.com/martinmoene/optional-lite), and document in the dev guide intended use cases (e.g. like https://www.bfilipek.com/2018/06/optional-examples-wall.html, but notably not including error handling). This will probably find several applications in parsing user input where a thing may or may not be present. We should choose an implementation that works on all our compilers, and e.g. does not require heap access. Any other requirements?
It might also provide a path to a better implementation of optional command-line parameters, such that we do not have to get involved with choosing a number within a domain that encodes that the user didn't ask for a specific behaviour, because that is confusing to use and difficult to test and implement.
We could implement that as gmx::compat::optional<T>, following the same pattern as we had when we imported an implementation of c++14 std::make_unique<T>
#2 Updated by Roland Schulz 13 days ago
We should consider having not just optional but also expected. In many cases when you don't have a value something went wrong in which case you should add an error and not just return an empty optional (and we can't always use exceptions in case of error). Just adding optional might encourage us to skip on the error because there is no convenient way to express it.