13 #include <system_error>
14 #include <type_traits>
24 template <
typename T,
typename E = std::error_code>
29 Result(std::variant<T, E>&& var) : m_var(std::
move(var)) {}
65 typename T2,
typename _E =
E,
typename _T =
T,
66 typename = std::enable_if_t<
67 (!std::is_same_v<_T, _E> && !std::is_constructible_v<_T, _E> &&
68 !std::is_convertible_v<_T, _E> && !std::is_constructible_v<_E, _T> &&
69 !std::is_convertible_v<_E, _T> &&
70 !(std::is_convertible_v<T2, _T> && std::is_convertible_v<T2, _E>))>>
72 : m_var(std::conditional_t<std::is_convertible_v<T2, _T>,
T,
E>{
83 typename T2,
typename _E =
E,
typename _T =
T,
84 typename = std::enable_if_t<
85 (!std::is_same_v<_T, _E> && !std::is_constructible_v<_T, _E> &&
86 !std::is_convertible_v<_T, _E> && !std::is_constructible_v<_E, _T> &&
87 !std::is_convertible_v<_E, _T> &&
88 !(std::is_convertible_v<T2, _T> && std::is_convertible_v<T2, _E>))>>
90 m_var =
std::move(std::conditional_t<std::is_convertible_v<T2, _T>,
T,
E>{
98 static Result<T, E> success(
T value) {
100 std::variant<T, E>{std::in_place_index<0>,
std::move(value)});
106 static Result<T, E> failure(
E error) {
108 std::variant<T, E>{std::in_place_index<1>,
std::move(error)});
113 bool ok() const noexcept {
return m_var.index() == 0; }
118 T&
operator*() noexcept {
return std::get<T>(m_var); }
123 const T&
operator*() const noexcept {
return std::get<T>(m_var); }
129 T* operator->() noexcept {
return &std::get<T>(m_var); }
135 const T* operator->() const noexcept {
return &std::get<T>(m_var); }
140 E&
error() & noexcept {
return std::get<E>(m_var); }
145 const E&
error() const& noexcept {
return std::get<E>(m_var); }
157 return std::get<T>(m_var);
165 return std::get<T>(m_var);
178 std::variant<T, E> m_var;
181 if (m_var.index() != 0) {
182 if constexpr (std::is_same_v<E, std::error_code>) {
183 std::stringstream ss;
184 const auto&
e = std::get<E>(m_var);
185 ss <<
"Value called on error value: " <<
e.category().name() <<
": "
186 <<
e.message() <<
" [" <<
e.value() <<
"]";
187 throw std::runtime_error(ss.str());
189 throw std::runtime_error(
"Value called on error value");
207 template <
typename E>
234 template <
typename E2>
241 template <
typename E2>
260 bool ok() const noexcept {
return !m_opt; }
265 E&
error() & noexcept {
return m_opt.value(); }
270 const E&
error() const& noexcept {
return m_opt.value(); }