12 #include <system_error>
13 #include <type_traits>
24 template <
typename T,
typename E = std::error_code>
31 Result(std::variant<T, E>&& var) : m_var(var) {}
60 m_var = std::move(other.m_var);
79 typename T2,
typename _E =
E,
typename _T =
T,
81 (!std::is_same_v<_T, _E> && !std::is_constructible_v<_T, _E> &&
82 !std::is_convertible_v<_T, _E> && !std::is_constructible_v<_E, _T> &&
83 !std::is_convertible_v<_E, _T> &&
84 !(std::is_convertible_v<T2, _T> && std::is_convertible_v<T2, _E>))>>
86 : m_var(std::conditional_t<std::is_convertible_v<T2, _T>,
T,
E>{
99 typename T2,
typename _E =
E,
typename _T =
T,
101 (!std::is_same_v<_T, _E> && !std::is_constructible_v<_T, _E> &&
102 !std::is_convertible_v<_T, _E> && !std::is_constructible_v<_E, _T> &&
103 !std::is_convertible_v<_E, _T> &&
104 !(std::is_convertible_v<T2, _T> && std::is_convertible_v<T2, _E>))>>
106 m_var = std::move(std::conditional_t<std::is_convertible_v<T2, _T>,
T,
E>{
116 static Result<T, E> success(
T value) {
118 std::variant<T, E>{std::in_place_index<0>, std::move(value)});
126 static Result<T, E> failure(
E error) {
128 std::variant<T, E>{std::in_place_index<1>, std::move(error)});
135 bool ok() const noexcept {
return m_var.index() == 0; }
142 T&
operator*() noexcept {
return std::get<T>(m_var); }
149 E&
error() & noexcept {
return std::get<E>(m_var); }
156 E error() && noexcept {
return std::move(std::get<E>(m_var)); }
164 if (m_var.index() != 0) {
165 if constexpr (std::is_same_v<E, std::error_code>) {
166 std::stringstream ss;
167 const auto&
e = std::get<E>(m_var);
168 ss <<
"Value called on error value: " <<
e.category().name() <<
": "
169 <<
e.message() <<
" [" <<
e.value() <<
"]";
170 throw std::runtime_error(ss.str());
172 throw std::runtime_error(
"Value called on error value");
176 return std::get<T>(m_var);
186 if (m_var.index() != 0) {
187 if constexpr (std::is_same_v<E, std::error_code>) {
188 std::stringstream ss;
189 const auto&
e = std::get<E>(m_var);
190 ss <<
"Value called on error value: " <<
e.category().name() <<
": "
191 <<
e.message() <<
" [" <<
e.value() <<
"]";
192 throw std::runtime_error(ss.str());
194 throw std::runtime_error(
"Value called on error value");
198 return std::move(std::get<T>(m_var));
202 std::variant<T, E> m_var;
218 template <
typename E>
247 m_opt = std::move(other.
m_opt);
256 template <
typename E2>
265 template <
typename E2>
267 m_opt = std::move(error);
290 bool ok() const noexcept {
return !m_opt; }
304 E error() && noexcept {
return std::move(*m_opt); }