#pragma once #include #include namespace meta { // a struct stolen from rust // lets us define a result, or return an error otherwise template class result : protected std::variant { protected: using Base = std::variant; private: static constexpr auto Success = 0; static constexpr auto Failure = 1; static_assert(std::is_default_constructible_v, "Error must be default constructible"); public: using value_type = Result; using Base::Base; using Base::operator=; // accessors Result& value(); template>> Result value_or(U&& result) const; Error& error(); const Result& value() const; const Error& error() const; // monadic operators template auto map(Fn&& visitor) const; template auto and_then(Fn&& visitor) const; template auto and_then(Fn&& visitor, ErrFn&& err_visitor) const; template auto or_else(ErrFunc&& err_visitor) const; // operator overloads explicit operator bool() const; Result& operator*(); Result* operator->(); const Result& operator*() const; const Result* operator->() const; }; }