diff options
Diffstat (limited to 'src/libutil/or-suggestions.hh')
-rw-r--r-- | src/libutil/or-suggestions.hh | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/libutil/or-suggestions.hh b/src/libutil/or-suggestions.hh new file mode 100644 index 000000000..cb152a1e4 --- /dev/null +++ b/src/libutil/or-suggestions.hh @@ -0,0 +1,64 @@ +#include "suggestions.hh" +#include "error.hh" + +namespace nix { + +// Either a value of type `T`, or some suggestions +template<typename T> +class OrSuggestions { +public: + using Raw = std::variant<T, Suggestions>; + + Raw raw; + + T* operator ->() + { + return &**this; + } + + T& operator *() + { + if (auto elt = std::get_if<T>(&raw)) + return *elt; + throw Error("Invalid access to a failed value"); + } + + operator bool() const noexcept + { + return std::holds_alternative<T>(raw); + } + + OrSuggestions(T t) + : raw(t) + { + } + + OrSuggestions() + : raw(Suggestions{}) + { + } + + static OrSuggestions<T> failed(const Suggestions & s) + { + auto res = OrSuggestions<T>(); + res.raw = s; + return res; + } + + static OrSuggestions<T> failed() + { + return OrSuggestions<T>::failed(Suggestions{}); + } + + const Suggestions & getSuggestions() + { + static Suggestions noSuggestions; + if (const auto & suggestions = std::get_if<Suggestions>(&raw)) + return *suggestions; + else + return noSuggestions; + } + +}; + +} |