di 0.1.0
Loading...
Searching...
No Matches
expected_void_error.h
Go to the documentation of this file.
1#pragma once
2
4#include "di/meta/compare.h"
5#include "di/meta/language.h"
7#include "di/meta/util.h"
8#include "di/meta/vocab.h"
9#include "di/util/addressof.h"
10#include "di/util/forward.h"
11#include "di/util/move.h"
13#include "di/util/unreachable.h"
17
18namespace di::vocab {
19// Expected<T, void> is used to denote an expected value
20// which is known at compile to not contain an error, and
21// is thus not equivalent to Optional<T>. This is especially
22// for code which can be generic over the fallibility of certain
23// operations, while still accounting for potential errors, but
24// not wrapping its return value in expected unless necessary.
25template<typename T>
26class [[nodiscard]] Expected<T, void> : public function::monad::MonadInterface<Expected<T, void>> {
27public:
28 using Value = T;
29 using Error = void;
30
31 constexpr Expected()
33 = default;
34
35 constexpr Expected(Expected const&)
37 = delete;
38 constexpr Expected(Expected const&) = default;
39
40 constexpr Expected(Expected&&)
42 = default;
43
44 template<typename U>
46 concepts::detail::ExpectedCanConvertConstructor<T, void, U, void>)
48 : m_value(other.value()) {}
49
50 template<typename U>
51 requires(concepts::ConstructibleFrom<T, U> && concepts::detail::ExpectedCanConvertConstructor<T, void, U, void>)
53 : m_value(util::move(other).value()) {}
54
55 template<typename U = T>
58 constexpr explicit(!concepts::ConvertibleTo<U, T>) Expected(U&& value) : m_value(util::forward<U>(value)) {}
59
60 template<typename... Args>
61 requires(concepts::ConstructibleFrom<T, Args...>)
62 constexpr explicit Expected(types::InPlace, Args&&... args) : m_value(util::forward<Args>(args)...) {}
63
64 template<typename U, typename... Args>
66 constexpr explicit Expected(types::InPlace, std::initializer_list<U> list, Args&&... args)
67 : m_value(list, util::forward<Args>(args)...) {}
68
69 constexpr ~Expected() = default;
70
71 constexpr auto operator=(Expected const&) -> Expected&
73 = delete;
74 constexpr auto operator=(Expected const&) -> Expected&
76 = default;
77
78 constexpr auto operator=(Expected&&) -> Expected&
80 = default;
81
82 template<typename U = T>
84 constexpr auto operator=(U&& value) -> Expected& {
85 m_value = util::forward<U>(value);
86 return *this;
87 }
88
89 constexpr auto operator->() { return util::addressof(m_value.value()); }
90 constexpr auto operator->() const { return util::addressof(m_value.value()); }
91
92 constexpr auto operator*() & -> T& { return m_value.value(); }
93 constexpr auto operator*() const& -> T const& { return m_value.value(); }
94 constexpr auto operator*() && -> T&& { return util::move(m_value).value(); }
95 constexpr auto operator*() const&& -> T const&& { return util::move(m_value).value(); }
96
97 constexpr explicit operator bool() const { return true; }
98 constexpr auto has_value() const -> bool { return true; }
99
100 constexpr auto value() & -> T& { return m_value.value(); }
101 constexpr auto value() const& -> T const& { return m_value.value(); }
102 constexpr auto value() && -> T&& { return util::move(m_value).value(); }
103 constexpr auto value() const&& -> T const&& { return util::move(m_value).value(); }
104
105 constexpr void error() const& {}
106 constexpr void error() && {}
107
108 template<concepts::ConvertibleTo<T> U>
110 constexpr auto value_or(U&&) const& -> T {
111 return **this;
112 }
113
114 template<concepts::ConvertibleTo<T> U>
116 constexpr auto value_or(U&&) && -> T {
117 return *util::move(*this);
118 }
119
120 constexpr auto optional_value() const { return Optional<void>(has_value()); }
121
122 template<typename... Args>
123 requires(concepts::ConstructibleFrom<T, Args...>)
124 constexpr auto emplace(Args&&... args) -> T& {
125 return m_value.emplace(util::forward<Args>(args)...);
126 }
127
128 template<typename U, typename... Args>
130 constexpr auto emplace(std::initializer_list<U> list, Args&&... args) -> T& {
131 return m_value.emplace(list, util::forward<Args>(args)...);
132 }
133
135 constexpr auto __try_did_succeed() && -> Expected { return Expected { in_place, util::move(*this).value() }; }
136 constexpr auto __try_move_out() && -> T&& { return util::move(*this).value(); }
137
138private:
139 template<typename U, typename G>
140 friend class Expected;
141
142 constexpr friend void tag_invoke(types::Tag<util::swap>, Expected& a, Expected& b)
143 requires(concepts::Swappable<T>)
144 {
145 util::swap(a.m_value, b.m_value);
146 }
147
148 template<concepts::EqualityComparableWith<T> U, typename G>
149 constexpr friend auto operator==(Expected const& a, Expected<U, G> const& b) -> bool {
150 return b.has_value() && *a == *b;
151 }
152
153 template<typename U>
155 constexpr friend auto operator==(Expected const& a, U const& b) -> bool {
156 return a.value() == b;
157 }
158
159 template<typename G>
160 constexpr friend auto operator==(Expected const&, Unexpected<G> const&) -> bool {
161 return false;
162 }
163
164 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F,
165 typename U = meta::UnwrapRefDecay<meta::InvokeResult<F, meta::Like<Self, T>>>>
166 constexpr friend auto tag_invoke(types::Tag<function::monad::fmap>, Self&& self, F&& function)
168 if constexpr (concepts::LanguageVoid<U>) {
169 function::invoke(util::forward<F>(function), util::forward<Self>(self).value());
170 return {};
171 } else {
173 function::invoke(util::forward<F>(function), util::forward<Self>(self).value()));
174 }
175 }
176
177 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F,
178 typename R = meta::InvokeResult<F, meta::Like<Self, T>>>
179 requires(concepts::Expected<R>)
180 constexpr friend auto tag_invoke(types::Tag<function::monad::bind>, Self&& self, F&& function) -> R {
181 return function::invoke(util::forward<F>(function), util::forward<Self>(self).value());
182 }
183
184 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F>
186 constexpr friend auto tag_invoke(types::Tag<function::monad::fail>, Self&& self, F&&) -> Expected {
187 return util::forward<Self>(self);
188 }
189
190 template<concepts::RemoveCVRefSameAs<Expected> Self, typename F>
192 constexpr friend auto tag_invoke(types::Tag<function::monad::fmap_right>, Self&& self, F&&) -> Expected {
193 return util::forward<Self>(self);
194 }
195
196 util::RebindableBox<T> m_value {};
197};
198
199template<typename T>
201}
Definition monad_interface.h:15
Definition rebindable_box.h:42
constexpr auto operator=(Expected &&) -> Expected &requires(concepts::MoveConstructible< T >)=default
constexpr friend auto tag_invoke(types::Tag< function::monad::fmap_right >, Self &&self, F &&) -> Expected
Definition expected_void_error.h:192
constexpr auto emplace(Args &&... args) -> T &
Definition expected_void_error.h:124
constexpr auto value() const &&-> T const &&
Definition expected_void_error.h:103
constexpr friend void tag_invoke(types::Tag< util::swap >, Expected &a, Expected &b)
Definition expected_void_error.h:142
friend class Expected
Definition expected_void_error.h:140
constexpr void error() &&
Definition expected_void_error.h:106
constexpr auto operator*() const &&-> T const &&
Definition expected_void_error.h:95
constexpr auto emplace(std::initializer_list< U > list, Args &&... args) -> T &
Definition expected_void_error.h:130
constexpr auto value() &&-> T &&
Definition expected_void_error.h:102
constexpr auto has_value() const -> bool
Definition expected_void_error.h:98
constexpr friend auto operator==(Expected const &, Unexpected< G > const &) -> bool
Definition expected_void_error.h:160
constexpr auto operator=(Expected const &) -> Expected &requires(concepts::CopyConstructible< T >)=default
constexpr auto operator*() const &-> T const &
Definition expected_void_error.h:93
constexpr friend auto operator==(Expected const &a, Expected< U, G > const &b) -> bool
Definition expected_void_error.h:149
constexpr auto operator*() &&-> T &&
Definition expected_void_error.h:94
constexpr Expected(Expected const &)=delete
constexpr auto value() &-> T &
Definition expected_void_error.h:100
constexpr Expected(types::InPlace, std::initializer_list< U > list, Args &&... args)
Definition expected_void_error.h:66
constexpr friend auto tag_invoke(types::Tag< function::monad::bind >, Self &&self, F &&function) -> R
Definition expected_void_error.h:180
constexpr auto optional_value() const
Definition expected_void_error.h:120
constexpr Expected()=default
void Error
Definition expected_void_error.h:29
constexpr void const & other
Definition expected_void_error.h:51
constexpr auto operator->() const
Definition expected_void_error.h:90
constexpr ~Expected()=default
constexpr auto operator->()
Definition expected_void_error.h:89
constexpr auto value_or(U &&) const &-> T
Definition expected_void_error.h:110
constexpr auto operator=(Expected const &) -> Expected &requires(!concepts::CopyConstructible< T >)=delete
constexpr void error() const &
Definition expected_void_error.h:105
constexpr Expected(Expected &&)=default
constexpr friend auto tag_invoke(types::Tag< function::monad::fmap >, Self &&self, F &&function) -> Expected< U, void >
Definition expected_void_error.h:166
constexpr auto operator*() &-> T &
Definition expected_void_error.h:92
constexpr auto __try_did_succeed() &&-> Expected
Definition expected_void_error.h:135
constexpr Expected(Expected const &)=default
T Value
Definition expected_void_error.h:28
constexpr Expected(types::InPlace, Args &&... args)
Definition expected_void_error.h:62
constexpr auto __try_move_out() &&-> T &&
Definition expected_void_error.h:136
constexpr auto value() const &-> T const &
Definition expected_void_error.h:101
constexpr friend auto tag_invoke(types::Tag< function::monad::fail >, Self &&self, F &&) -> Expected
Definition expected_void_error.h:186
auto __try_did_fail() &&-> Expected
Definition expected_void_error.h:134
constexpr auto value_or(U &&) &&-> T
Definition expected_void_error.h:116
Definition expected_forward_declaration.h:8
Definition optional_forward_declaration.h:5
Definition unexpected.h:14
Definition operations.h:11
Definition operations.h:99
Definition operations.h:34
Definition operations.h:24
Definition vocab.h:30
Definition core.h:128
Definition operations.h:43
Definition swap.h:37
Definition vocab.h:152
Definition as_bool.h:8
constexpr auto invoke
Definition invoke.h:100
constexpr auto ExpectedRank
Definition vocab.h:41
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr struct di::util::SwapFunction swap
void unreachable()
Definition unreachable.h:4
Definition lazy.h:165
Expected(T &&) -> Expected< meta::UnwrapRefDecay< T >, void >
constexpr auto in_place
Definition in_place.h:8
Definition in_place.h:4