7#include <libassert/assert.hpp>
11#include <system_error>
24template <
typename T =
void,
typename E = std::error_code>
42 template <
typename... Args>
43 explicit constexpr Expected(std::in_place_t , Args&&... args)
44 requires(!std::is_void_v<T> && std::constructible_from<
ExpectedT, Args...>)
45 : data_{std::in_place_type<
ExpectedT>, std::forward<Args>(args)...} {}
47 template <
typename Tu>
49 requires(!std::is_void_v<T> && std::convertible_to<Tu, T>)
50 : data_{std::forward<Tu>(value)} {}
52 template <
typename Eu>
54 requires(std::convertible_to<Eu, E> && !std::is_convertible_v<T, E> && !std::is_convertible_v<T, E>)
55 : data_{std::forward<Eu>(error)} {}
57 template <
typename Eu>
59 requires(std::convertible_to<Eu, E>)
60 : data_{std::forward<Eu>(error)} {}
65 if constexpr (std::is_void_v<T>) {
66 return std::holds_alternative<std::monostate>(data_.data);
68 return std::holds_alternative<T>(data_.data);
72 constexpr bool has_error()
const {
return !has_value(); }
74 constexpr explicit operator bool()
const {
return has_value(); }
77 template <
typename U = T>
79 requires(!std::is_void_v<U>)
81 return const_cast<U&
>(
const_cast<const Expected*
>(
this)->
value());
84 template <
typename U = T>
85 constexpr const U&
value() const
86 requires(!std::is_void_v<U>)
88 static_assert(std::same_as<U, T>,
89 "Do not attempt to instantiate Expected<T,E>::value() for any type other than T");
90 DEBUG_ASSERT(has_value());
91 return std::get<U>(data_.data);
94 template <
typename U = T>
96 requires(std::is_void_v<U>)
98 static_assert(std::same_as<U, T>,
99 "Do not attempt to instantiate Expected<T,E>::value() for any type other than T");
100 DEBUG_ASSERT(has_value());
103 template <
typename U = T>
105 requires(!std::is_void_v<U>)
107 static_assert(std::same_as<U, T>,
108 "Do not attempt to instantiate Expected<T,E>::operator*() for any type other than T");
112 template <
typename U = T>
114 requires(!std::is_void_v<U>)
116 static_assert(std::same_as<U, T>,
117 "Do not attempt to instantiate Expected<T,E>::operator*() for any type other than T");
121 template <
typename U = T>
123 requires(!std::is_void_v<U>)
125 static_assert(std::same_as<U, T>,
126 "Do not attempt to instantiate Expected<T,E>::operator->() for any type other than T");
130 template <
typename U = T>
132 requires(!std::is_void_v<U>)
134 static_assert(std::same_as<U, T>,
135 "Do not attempt to instantiate Expected<T,E>::operator->() for any type other than T");
139 template <
typename Tu>
141 requires(std::convertible_to<Tu, T>)
144 return static_cast<T
>(std::forward<Tu>(default_value));
146 return std::get<T>(data_.data);
150 DEBUG_ASSERT(!has_value());
151 return std::get<E>(data_.data);
154 template <
typename Eu>
157 return static_cast<E
>(std::forward<Eu>(default_value));
159 return std::get<E>(data_.data);
162 template <
typename Func>
168 return func(value());
172 template <
typename Td,
typename Ed>
175 std::variant<Td, Ed> data;
176 constexpr auto operator<=>(
const ExpectedData& rhs)
const =
default;
179 template <
typename Ed>
180 struct ExpectedData<void, Ed>
182 std::variant<std::monostate, Ed> data;
183 constexpr auto operator<=>(
const ExpectedData& rhs)
const =
default;
191 requires(std::equality_comparable<E> && (std::is_void_v<T> || std::equality_comparable<T>))
193 return data_ == rhs.data_;
196 template <
typename Tu>
198 requires(!std::is_void_v<T> && !std::same_as<Tu, Expected> && std::equality_comparable_with<Tu, T>)
204 return value() == rhs;
207 template <
typename Eu>
209 requires(!std::same_as<Eu, Expected> && std::equality_comparable_with<Eu, E>)
215 return error() == rhs;
219 ExpectedData<T, E> data_;
224template <
typename T,
typename E>
228 auto format(const ::asmgrader::Expected<T, E>& from, fmt::format_context& ctx)
const {
230 return format_to(ctx.out(),
"{}", format_impl(from));
234 std::string format_impl(const ::asmgrader::Expected<T, E>& from)
const {
236 if constexpr (formattable<E>) {
237 return fmt::format(
"Error({})", from.error());
239 return "Error(<unformattable>)";
243 if constexpr (std::same_as<T, void>) {
244 return "Expected(void)";
245 }
else if constexpr (formattable<T>) {
246 return fmt::format(
"Expected({})", from.value());
248 return "Expected(<unformattable>)";
std::variant wrapper for a partial implementation of C++23's expected type
Definition expected.hpp:34
E ErrT
Definition expected.hpp:37
constexpr const U * operator->() const
Definition expected.hpp:131
constexpr void assert_val()
Definition expected.hpp:62
constexpr bool operator==(const Expected &rhs) const
Definition expected.hpp:190
constexpr Expected(std::in_place_t, Args &&... args)
Definition expected.hpp:43
T ExpectedT
Definition expected.hpp:36
constexpr Expected(Tu &&value)
Definition expected.hpp:48
constexpr Expected< std::invoke_result_t< Func, T >, E > transform(const Func &func)
Definition expected.hpp:163
constexpr U & value()
Definition expected.hpp:78
constexpr T value_or(Tu &&default_value) const
Definition expected.hpp:140
constexpr U * operator->()
Definition expected.hpp:122
constexpr bool operator==(const Tu &rhs) const
Definition expected.hpp:197
constexpr E error() const
Definition expected.hpp:149
constexpr Expected(Eu &&error)
Definition expected.hpp:53
constexpr bool operator==(const Eu &rhs) const
Definition expected.hpp:208
constexpr void value() const
Definition expected.hpp:95
constexpr Expected(UnexpectedT, Eu &&error)
Definition expected.hpp:58
constexpr const U & operator*() const
Definition expected.hpp:113
constexpr E error_or(Eu &&default_value) const
Definition expected.hpp:155
constexpr const U & value() const
Definition expected.hpp:85
constexpr bool has_value() const
Definition expected.hpp:64
constexpr Expected()
Definition expected.hpp:39
constexpr U & operator*()
Definition expected.hpp:104
constexpr bool has_error() const
Definition expected.hpp:72
constexpr auto operator<=>(const Expected &rhs) const =default
Definition asm_buffer.hpp:19
Definition expected.hpp:21