diff --git a/BAN/include/BAN/Errors.h b/BAN/include/BAN/Errors.h index 63674add..52ec5f27 100644 --- a/BAN/include/BAN/Errors.h +++ b/BAN/include/BAN/Errors.h @@ -85,6 +85,33 @@ namespace BAN Variant m_data; }; + template + class [[nodiscard]] ErrorOr + { + public: + ErrorOr(T value) + { + m_data.template set(value); + } + ErrorOr(Error&& error) + : m_data(move(error)) + { } + ErrorOr(const Error& error) + : m_data(error) + { } + + bool is_error() const { return m_data.template has(); } + Error& error() { return m_data.template get(); } + const Error& error() const { return m_data.template get(); } + T value() { return m_data.template get(); } + + Error release_error() { return move(error()); m_data.clear(); } + T release_value() { return value(); m_data.clear(); } + + private: + Variant m_data; + }; + template<> class [[nodiscard]] ErrorOr { diff --git a/BAN/include/BAN/Traits.h b/BAN/include/BAN/Traits.h index de723388..0a9ca4f3 100644 --- a/BAN/include/BAN/Traits.h +++ b/BAN/include/BAN/Traits.h @@ -40,6 +40,7 @@ namespace BAN template struct is_lvalue_reference : false_type {}; template struct is_lvalue_reference : true_type {}; template inline constexpr bool is_lvalue_reference_v = is_lvalue_reference::value; + template concept lvalue_reference = is_lvalue_reference_v; template struct is_integral { static constexpr bool value = requires (T t, T* p, void (*f)(T)) { reinterpret_cast(t); f(0); p + t; }; }; template inline constexpr bool is_integral_v = is_integral::value;