13 #include <system_error>
14 #include <type_traits>
25 template <
typename T,
typename E = std::error_code>
32 Result(std::variant<T, E>&& var) : m_var(std::move(var)) {}
61 m_var = std::move(other.m_var);
80 typename T2,
typename _E = E,
typename _T =
T,
82 (!std::is_same_v<_T, _E> && !std::is_constructible_v<_T, _E> &&
83 !std::is_convertible_v<_T, _E> && !std::is_constructible_v<_E, _T> &&
84 !std::is_convertible_v<_E, _T> &&
85 !(std::is_convertible_v<T2, _T> && std::is_convertible_v<T2, _E>))>>
87 : m_var(std::conditional_t<std::is_convertible_v<T2, _T>,
T, E>{
100 typename T2,
typename _E = E,
typename _T =
T,
102 (!std::is_same_v<_T, _E> && !std::is_constructible_v<_T, _E> &&
103 !std::is_convertible_v<_T, _E> && !std::is_constructible_v<_E, _T> &&
104 !std::is_convertible_v<_E, _T> &&
105 !(std::is_convertible_v<T2, _T> && std::is_convertible_v<T2, _E>))>>
107 m_var = std::move(std::conditional_t<std::is_convertible_v<T2, _T>,
T, E>{
117 static Result<T, E> success(
T value) {
119 std::variant<T, E>{std::in_place_index<0>, std::move(value)});
127 static Result<T, E> failure(E error) {
129 std::variant<T, E>{std::in_place_index<1>, std::move(error)});
136 bool ok() const noexcept {
return m_var.index() == 0; }
143 T&
operator*() noexcept {
return std::get<T>(m_var); }
150 E& error() & noexcept {
return std::get<E>(m_var); }
157 E error() && noexcept {
return std::move(std::get<E>(m_var)); }
165 if (m_var.index() != 0) {
166 if constexpr (std::is_same_v<E, std::error_code>) {
167 std::stringstream ss;
168 const auto&
e = std::get<E>(m_var);
169 ss <<
"Value called on error value: " <<
e.category().name() <<
": "
170 <<
e.message() <<
" [" <<
e.value() <<
"]";
171 throw std::runtime_error(ss.str());
173 throw std::runtime_error(
"Value called on error value");
177 return std::get<T>(m_var);
187 if (m_var.index() != 0) {
188 if constexpr (std::is_same_v<E, std::error_code>) {
189 std::stringstream ss;
190 const auto&
e = std::get<E>(m_var);
191 ss <<
"Value called on error value: " <<
e.category().name() <<
": "
192 <<
e.message() <<
" [" <<
e.value() <<
"]";
193 throw std::runtime_error(ss.str());
195 throw std::runtime_error(
"Value called on error value");
199 return std::move(std::get<T>(m_var));
203 std::variant<T, E> m_var;
219 template <
typename E>
248 m_opt = std::move(other.
m_opt);
257 template <
typename E2>
258 Result(E2 error) noexcept : m_opt(std::move(error)) {}
266 template <
typename E2>
268 m_opt = std::move(error);
291 bool ok() const noexcept {
return !m_opt; }
298 E&
error() & noexcept {
return *m_opt; }
305 E
error() && noexcept {
return std::move(*m_opt); }