5 #ifndef VCCC_EXPECTED_MONADIC_HPP_
6 #define VCCC_EXPECTED_MONADIC_HPP_
24 template<
bool Void ,
typename T,
template<
typename...>
class Test,
typename... U>
25 struct void_or_impl : std::true_type {};
27 template<
typename T,
template<
typename...>
class Test,
typename... U>
28 struct void_or_impl<false, T, Test, U...> : Test<U...> {};
30 template<
typename T,
template<
typename...>
class Test,
typename... U>
33 template<
typename T,
typename =
void>
34 struct has_typename_error_type : std::false_type {};
37 struct has_typename_error_type<T,
void_t<typename T::error_type>> : std::true_type {};
40 struct expected_valid_value_type
42 negation<std::is_reference<T>>,
43 negation<std::is_array<T>>,
44 negation<std::is_function<T>>,
45 negation<is_specialization<T, unexpected>>,
46 negation<std::is_same<std::remove_cv_t<T>, in_place_t>>,
47 negation<std::is_same<std::remove_cv_t<T>, unexpect_t>>
51 struct expected_valid_error_type
54 negation<std::is_array<E>>,
55 negation<is_specialization<E, unexpected>>,
56 negation<std::is_const<E>>,
57 negation<std::is_volatile<E>>
61 struct expected_is_void : std::is_void<typename remove_cvref_t<E>::value_type> {};
64 struct expected_value_invocable
67 template<
typename F,
typename Expected>
68 struct expected_value_invocable<F, Expected, false>
69 : is_invocable<F, decltype(*std::declval<Expected>())> {};
71 template<
typename F,
typename Expected>
72 struct expected_error_invocable
73 : is_invocable<F, decltype(std::declval<Expected>().error())>{};
76 struct expected_value_invoke_result {
77 using type = invoke_result_t<F>;
80 template<
typename F,
typename Expected>
81 struct expected_value_invoke_result<F, Expected, false> {
82 using type = invoke_result_t<F, decltype(*std::declval<Expected>())>;
85 template<
typename F,
typename Expected>
86 using expected_value_invoke_result_t =
typename expected_value_invoke_result<F, Expected>::type;
88 template<
typename F,
typename Expected>
89 using expected_error_invoke_result_t = invoke_result_t<F, decltype(std::declval<Expected>().error())>;
91 template<
typename F,
typename Expected, std::enable_if_t<
93 constexpr decltype(
auto) expected_value_invoke(F&& f, Expected&&) {
97 template<
typename F,
typename Expected, std::enable_if_t<
99 constexpr decltype(
auto) expected_value_invoke(F&& f, Expected&&
e) {
100 return vccc::invoke(std::forward<F>(f), *std::forward<Expected>(
e));
103 template<
typename Expected>
104 class expected_and_then_t;
106 template<
template<
typename,
typename>
class Expected,
typename T,
typename E>
107 class expected_and_then_t<Expected<T, E>> {
108 template<
typename F,
typename Self>
109 using U = remove_cvref_t<expected_value_invoke_result_t<F, Self>>;
112 template<
typename F,
typename Self, std::enable_if_t<conjunction<
113 expected_value_invocable<F, Self>,
114 is_specialization<U<F, Self>, Expected>,
115 has_typename_error_type<U<F, Self>>,
116 std::is_same<typename U<F, Self>::error_type, E>
118 constexpr
auto operator()(F&& f, Self&&
self)
const {
119 if (
self.has_value()) {
120 return expected_value_invoke(std::forward<F>(f), std::forward<Self>(
self));
122 return U<F, Self>(
unexpect, std::forward<Self>(
self).error());
127 template<
typename Expected>
128 class expected_transform_t;
130 template<
template<
typename,
typename>
class Expected,
typename T,
typename E>
131 class expected_transform_t<Expected<T, E>> {
132 template<
typename F,
typename Self>
133 using U = std::remove_cv_t<expected_value_invoke_result_t<F, Self>>;
135 template<
typename F,
typename Self>
136 constexpr
auto valued(F&& f, Self&&
self, std::true_type )
const {
137 expected_value_invoke(std::forward<F>(f), std::forward<Self>(
self));
138 return Expected<U<F, Self>, E>();
141 template<
typename F,
typename Self>
142 constexpr
auto valued(F&& f, Self&&
self, std::false_type )
const {
143 return Expected<U<F, Self>, E>(expected_value_invoke(std::forward<F>(f), std::forward<Self>(
self)));
147 template<
typename F,
typename Self, std::enable_if_t<conjunction<
148 expected_value_invocable<F, Self>,
149 expected_valid_value_type<U<F, Self>>,
150 void_or<T, std::is_constructible, U<F, Self>, expected_value_invoke_result_t<F, Self>>
152 constexpr
auto operator()(F&& f, Self&&
self)
const {
153 if (
self.has_value()) {
154 return valued(std::forward<F>(f), std::forward<Self>(
self), std::is_void<T>{});
156 return Expected<U<F, Self>, E>(
unexpect, std::forward<Self>(
self).error());
161 template<
typename Expected>
162 class expected_or_else_t;
164 template<
template<
typename,
typename>
class Expected,
typename T,
typename E>
165 class expected_or_else_t<Expected<T, E>> {
166 template<
typename F,
typename Self>
167 using G = remove_cvref_t<expected_error_invoke_result_t<F, Self>>;
169 template<
typename F,
typename Self>
170 constexpr
auto valued(F&&, Self&&, std::true_type )
const {
174 template<
typename F,
typename Self>
175 constexpr
auto valued(F&&, Self&&
self, std::false_type )
const {
176 return G<F, Self>(
in_place, *std::forward<Self>(
self));
180 template<
typename F,
typename Self, std::enable_if_t<conjunction<
181 expected_error_invocable<F, Self>,
182 is_specialization<G<F, Self>, Expected>,
183 std::is_same<typename G<F, Self>::value_type, T>
185 constexpr
auto operator()(F&& f, Self&&
self)
const {
186 if (
self.has_value()) {
187 return valued(std::forward<F>(f), std::forward<Self>(
self), std::is_void<T>{});
189 return vccc::invoke(std::forward<F>(f), std::forward<Self>(
self).error());
194 template<
typename Expected>
195 class expected_transform_error_t;
197 template<
template<
typename,
typename>
class Expected,
typename T,
typename E>
198 class expected_transform_error_t<Expected<T, E>> {
199 template<
typename F,
typename Self>
200 using G = std::remove_cv_t<expected_error_invoke_result_t<F, Self>>;
202 template<
typename F,
typename Self>
203 constexpr
auto valued(F&&, Self&&, std::true_type)
const {
204 return Expected<T, G<F, Self>>();
207 template<
typename F,
typename Self>
208 constexpr
auto valued(F&&, Self&&
e, std::false_type)
const {
209 return Expected<T, G<F, Self>>(
in_place, *std::forward<Self>(
e));
213 template<
typename F,
typename Self, std::enable_if_t<conjunction<
214 expected_error_invocable<F, Self>,
215 expected_valid_error_type<G<F, Self>>,
216 std::is_constructible<G<F, Self>, expected_error_invoke_result_t<F, Self>>
218 constexpr
auto operator()(F&& f, Self&&
self)
const {
219 if (
self.has_value()) {
220 return valued(std::forward<F>(f), std::forward<Self>(
self), std::is_void<T>{});
222 return Expected<T, G<F, Self>>(
unexpect,
vccc::invoke(std::forward<F>(f), std::forward<Self>(
self).error()));
constexpr VCCC_INLINE_OR_STATIC unexpect_t unexpect
Definition: unexpect.hpp:34
constexpr invoke_result_t< F, Args... > invoke(F &&f, Args &&... args) noexcept(is_nothrow_invocable< F, Args... >::value)
Definition: invoke.hpp:38
constexpr T e
the mathematical constant
Definition: constants.hpp:37
constexpr VCCC_INLINE_OR_STATIC in_place_t in_place
Definition: in_place.hpp:47
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35