Merge or-suggestions.hh into suggestions.hh

No real need for keeping a separate header for such a simple class.

This requires changing a bit `OrSuggestions<T>::operator*` to not throw
an `Error` to prevent a cyclic dependency. But since this error is only
thrown on programmer error, we can replace the whole method by a direct
call to `std::get` which will raise its own assertion if needs be.
This commit is contained in:
regnat 2022-03-07 17:45:35 +01:00
parent 313bbc07a8
commit dcf4f77fac
3 changed files with 57 additions and 65 deletions

View file

@ -3,7 +3,6 @@
#include "sync.hh" #include "sync.hh"
#include "hash.hh" #include "hash.hh"
#include "eval.hh" #include "eval.hh"
#include "or-suggestions.hh"
#include <functional> #include <functional>
#include <variant> #include <variant>

View file

@ -1,64 +0,0 @@
#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;
}
};
}

View file

@ -42,4 +42,61 @@ public:
std::ostream & operator<<(std::ostream & str, const Suggestion &); std::ostream & operator<<(std::ostream & str, const Suggestion &);
std::ostream & operator<<(std::ostream & str, const Suggestions &); std::ostream & operator<<(std::ostream & str, const Suggestions &);
// 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 *()
{
return std::get<T>(raw);
}
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;
}
};
} }