45 lines
1.3 KiB
C++
45 lines
1.3 KiB
C++
#pragma once
|
|
#include <utility>
|
|
#include <variant>
|
|
|
|
namespace meta
|
|
{
|
|
// a struct stolen from rust
|
|
// lets us define a result, or return an error otherwise
|
|
template<typename Result, typename Error>
|
|
class result
|
|
: protected std::variant<Result, Error>
|
|
{
|
|
protected:
|
|
using Base = std::variant<Result, Error>;
|
|
private:
|
|
static constexpr auto Success = 0;
|
|
static constexpr auto Failure = 1;
|
|
static_assert(std::is_default_constructible_v<Error>, "Error must be default constructible");
|
|
public:
|
|
using value_type = Result;
|
|
using Base::Base;
|
|
using Base::operator=;
|
|
|
|
// accessors
|
|
Result& value();
|
|
template<typename U, typename = std::enable_if_t<std::is_constructible_v<Result, U>>>
|
|
Result value_or(U&& result) const;
|
|
Error& error();
|
|
const Result& value() const;
|
|
const Error& error() const;
|
|
|
|
// monadic operators
|
|
template<class Fn> auto map(Fn&& visitor) const;
|
|
template<class Fn> auto and_then(Fn&& visitor) const;
|
|
template<class Fn, class ErrFn> auto and_then(Fn&& visitor, ErrFn&& err_visitor) const;
|
|
template<class ErrFunc> 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;
|
|
};
|
|
} |