Iros
 
Loading...
Searching...
No Matches
expected_void_value.h
Go to the documentation of this file.
1#pragma once
2
6#include "di/meta/compare.h"
8#include "di/meta/util.h"
9#include "di/meta/vocab.h"
10#include "di/util/forward.h"
12#include "di/util/move.h"
13#include "di/util/swap.h"
20
21namespace di::vocab {
22template<typename E>
23class [[nodiscard]] Expected<void, E> : public function::monad::MonadInterface<Expected<void, E>> {
24private:
25 using ErrorStorage = Optional<E>;
26
27public:
28 using Value = void;
29 using Error = E;
31
32 constexpr Expected() = default;
33
34 constexpr Expected(Expected const&)
36 = default;
37 constexpr Expected(Expected const&)
39 = delete;
40
41 constexpr Expected(Expected&&)
43 = default;
44
45 template<typename F>
49 : m_error(other.m_error) {}
50
51 template<typename F>
54 : m_error(util::move(other).m_error) {}
55
56 template<typename G>
59 : m_error(error.error()) {}
60
61 template<typename G>
64 : m_error(util::move(error).error()) {}
65
66 constexpr explicit Expected(types::InPlace) {}
67
68 template<typename... Args>
69 requires(concepts::ConstructibleFrom<E, Args...>)
70 constexpr explicit Expected(types::Unexpect, Args&&... args)
71 : m_error(types::in_place, util::forward<Args>(args)...) {}
72
73 template<typename U, typename... Args>
75 constexpr explicit Expected(types::Unexpect, std::initializer_list<U> list, Args&&... args)
76 : m_error(types::in_place, list, util::forward<Args>(args)...) {}
77
78 constexpr ~Expected() = default;
79
80 constexpr auto operator=(Expected const&) -> Expected& requires(!concepts::CopyConstructible<E>) = delete;
81 constexpr auto operator=(Expected const&) -> Expected& requires(concepts::CopyConstructible<E>) = default;
82
83 constexpr auto operator=(Expected&&) -> Expected& requires(concepts::MoveConstructible<E>) = default;
84
85 template<typename G>
87 constexpr auto operator=(Unexpected<G> const& error) -> Expected& {
88 m_error = error.error();
89 return *this;
90 }
91
92 template<typename G>
94 constexpr auto operator=(Unexpected<G>&& error) -> Expected& {
95 m_error = util::move(error).error();
96 return *this;
97 }
98
99 constexpr explicit operator bool() const { return has_value(); }
100 constexpr auto has_value() const -> bool { return !m_error.has_value(); }
101
102 constexpr void emplace() { m_error.reset(); }
103
104 constexpr void operator*() const { DI_ASSERT(has_value()); }
105
106 constexpr void value() const& { DI_ASSERT(has_value()); }
107
108 constexpr void value() && { DI_ASSERT(has_value()); }
109
110 constexpr auto error() & -> E& { return *m_error; }
111 constexpr auto error() const& -> E const& { return *m_error; }
112 constexpr auto error() && -> E&& { return *util::move(m_error); }
113 constexpr auto error() const&& -> E const&& { return *util::move(m_error); }
114
115 constexpr auto __try_did_fail() && -> Unexpected<E> {
116 return Unexpected<E> { in_place, util::move(*this).error() };
117 }
118 constexpr auto __try_did_succeed() && -> Expected { return Expected {}; }
119 constexpr void __try_move_out() && { return util::move(*this).value(); }
120
121private:
122 template<typename U, typename G>
123 friend class Expected;
124
125 constexpr friend void tag_invoke(types::Tag<util::swap>, Expected& a, Expected& b)
126 requires(concepts::Swappable<E>)
127 {
128 util::swap(a.m_value, b.m_value);
129 }
130
131 template<concepts::EqualityComparableWith<E> G>
132 constexpr friend auto operator==(Expected const& a, Expected<void, G> const& b) -> bool {
133 if (a.has_value() != b.has_value()) {
134 return false;
135 }
136 return a.has_value() || a.error() == b.error();
137 }
138
139 template<concepts::EqualityComparableWith<E> G>
140 constexpr friend auto operator==(Expected const& a, Unexpected<G> const& b) -> bool {
141 return !a && a.error() == b.error();
142 }
143
144 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F,
145 typename U = meta::UnwrapRefDecay<meta::InvokeResult<F>>>
147 constexpr friend auto tag_invoke(types::Tag<function::monad::fmap>, Self&& self, F&& function) -> Expected<U, E> {
148 if (!self) {
149 return Expected<U, E> { types::unexpect, util::forward<Self>(self).error() };
150 }
151 if constexpr (concepts::LanguageVoid<U>) {
152 function::invoke(util::forward<F>(function));
153 return {};
154 } else {
155 return function::invoke(util::forward<F>(function));
156 }
157 }
158
159 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F, typename R = meta::InvokeResult<F>>
161 constexpr friend auto tag_invoke(types::Tag<function::monad::bind>, Self&& self, F&& function) -> R {
162 if (!self) {
163 return R { types::unexpect, util::forward<Self>(self).error() };
164 }
165 return function::invoke(util::forward<F>(function));
166 }
167
168 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F,
169 typename R = meta::InvokeResult<F, meta::Like<Self, E>>>
171 constexpr friend auto tag_invoke(types::Tag<function::monad::fail>, Self&& self, F&& function) -> R {
172 if (self) {
173 return {};
174 }
175 return function::invoke(util::forward<F>(function), util::forward<Self>(self).error());
176 }
177
178 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F,
179 typename G = meta::UnwrapRefDecay<meta::InvokeResult<F, meta::Like<Self, E>>>>
180 constexpr friend auto tag_invoke(types::Tag<function::monad::fmap_right>, Self&& self, F&& function)
182 if (self) {
183 return {};
184 }
185 if constexpr (concepts::LanguageVoid<G>) {
186 function::invoke(util::forward<F>(function), util::forward<Self>(self).error());
187 return {};
188 } else {
190 util::forward<Self>(self).error()) };
191 }
192 }
193
194 Optional<E> m_error;
195};
196}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition monad_interface.h:15
constexpr Expected(types::InPlace)
Definition expected_void_value.h:66
constexpr friend auto tag_invoke(types::Tag< function::monad::fmap >, Self &&self, F &&function) -> Expected< U, E >
Definition expected_void_value.h:147
constexpr void operator*() const
Definition expected_void_value.h:104
constexpr friend auto operator==(Expected const &a, Expected< void, G > const &b) -> bool
Definition expected_void_value.h:132
friend class Expected
Definition expected_void_value.h:123
constexpr auto operator=(Expected const &) -> Expected &requires(!concepts::CopyConstructible< E >)=delete
E Error
Definition expected_void_value.h:29
constexpr auto error() const &-> E const &
Definition expected_void_value.h:111
constexpr friend void tag_invoke(types::Tag< util::swap >, Expected &a, Expected &b)
Definition expected_void_value.h:125
void Value
Definition expected_void_value.h:28
Unexpected< E > UnexpectedType
Definition expected_void_value.h:30
constexpr void value() const &
Definition expected_void_value.h:106
constexpr friend auto operator==(Expected const &a, Unexpected< G > const &b) -> bool
Definition expected_void_value.h:140
constexpr auto error() &-> E &
Definition expected_void_value.h:110
constexpr auto has_value() const -> bool
Definition expected_void_value.h:100
constexpr Expected(Expected &&)=default
constexpr Expected(types::Unexpect, std::initializer_list< U > list, Args &&... args)
Definition expected_void_value.h:75
constexpr Expected(Expected const &)=delete
constexpr auto operator=(Expected const &) -> Expected &requires(concepts::CopyConstructible< E >)=default
constexpr auto operator=(Expected &&) -> Expected &requires(concepts::MoveConstructible< E >)=default
constexpr friend auto tag_invoke(types::Tag< function::monad::fail >, Self &&self, F &&function) -> R
Definition expected_void_value.h:171
constexpr void emplace()
Definition expected_void_value.h:102
constexpr F const & other
Definition expected_void_value.h:52
constexpr Expected(Expected const &)=default
constexpr ~Expected()=default
constexpr void value() &&
Definition expected_void_value.h:108
constexpr Expected()=default
constexpr void __try_move_out() &&
Definition expected_void_value.h:119
constexpr Expected(types::Unexpect, Args &&... args)
Definition expected_void_value.h:70
constexpr auto __try_did_succeed() &&-> Expected
Definition expected_void_value.h:118
constexpr auto __try_did_fail() &&-> Unexpected< E >
Definition expected_void_value.h:115
constexpr friend auto tag_invoke(types::Tag< function::monad::fmap_right >, Self &&self, F &&function) -> Expected< void, G >
Definition expected_void_value.h:180
constexpr auto error() &&-> E &&
Definition expected_void_value.h:112
constexpr auto error() const &&-> E const &&
Definition expected_void_value.h:113
constexpr friend auto tag_invoke(types::Tag< function::monad::bind >, Self &&self, F &&function) -> R
Definition expected_void_value.h:161
Definition optional_forward_declaration.h:5
Definition unexpected.h:14
Definition operations.h:11
Definition operations.h:99
Definition operations.h:34
Definition vocab.h:30
Definition core.h:128
Definition operations.h:43
Definition swap.h:31
Definition expected_can_convert_constructor.h:9
Definition as_bool.h:8
constexpr auto invoke
Definition invoke.h:100
meta::RemoveCVRef< T >::Error ExpectedError
Definition vocab.h:38
constexpr auto in_place
Definition in_place.h:8
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
constexpr auto unexpect
Definition unexpect.h:8
Definition vocab.h:96
constexpr struct di::util::SwapFunction swap
Definition lazy.h:165
constexpr auto in_place
Definition in_place.h:8
Definition in_place.h:4
Definition unexpect.h:4