20 template <
typename...>
22 :
public std::bool_constant<false>
26 template <
typename... Args>
27 inline constexpr bool always_false_v = always_false<Args...>::value;
29 template <std::
size_t priority>
32 :
public priority_tag<priority - 1u>
38 struct priority_tag<0u>
42 template <
typename T,
typename U>
45 using type = std::conditional_t<
46 std::is_const_v<std::remove_reference_t<T>>,
47 std::remove_reference_t<U>
const&&,
48 std::remove_reference_t<U>&&>;
51 template <
typename T,
typename U>
52 struct const_ref_like<T&, U>
54 using type = std::conditional_t<
55 std::is_const_v<std::remove_reference_t<T>>,
56 std::remove_reference_t<U>
const&,
57 std::remove_reference_t<U>&>;
60 template <
typename T,
typename U>
61 using const_ref_like_t = const_ref_like<T, U>::type;
63 template <
typename T,
typename U>
65 constexpr auto&& forward_like(U&& x)
noexcept
67 return static_cast<const_ref_like_t<T, U>
>(x);
71 concept unqualified = std::same_as<T, std::remove_cvref_t<T>>;
74 concept transferable = !std::is_void_v<std::remove_cvref_t<T>>;
77 concept boolean_testable =
78 std::convertible_to<B, bool>
80 { !std::forward<B>(b) } -> std::convertible_to<bool>;
83 template <
typename T,
typename U>
84 concept weakly_equality_comparable_with =
85 requires(T
const& t, U
const& u) {
86 { t == u } -> boolean_testable;
87 { t != u } -> boolean_testable;
88 { u == t } -> boolean_testable;
89 { u != t } -> boolean_testable;
101 template <
typename Nullable>
106 template <
typename T,
typename U,
typename C = std::common_reference_t<T const&, U const&>>
107 concept regular_relationship_impl =
109 std::common_reference_t<T const&, U const&>,
110 std::common_reference_t<U const&, T const&>>
111 && (std::convertible_to<T const&, C const&>
112 || std::convertible_to<T, C const&>)
113 && (std::convertible_to<U const&, C const&>
114 || std::convertible_to<U, C const&>);
116 template <
typename T,
typename U>
117 concept regular_relationship =
118 regular_relationship_impl<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
120 template <
typename Lhs,
typename Rhs>
121 concept weakly_assignable_from =
122 std::is_lvalue_reference_v<Lhs>
123 &&
requires(Lhs lhs, Rhs&& rhs) {
124 { lhs = std::forward<Rhs>(rhs) } -> std::same_as<Lhs>;
135 template <
typename Null,
typename Nullable>
136 concept null_for = detail::regular_relationship<Nullable, Null>
137 && detail::weakly_equality_comparable_with<Null, Nullable>
138 && std::constructible_from<Nullable, Null const&>
139 && detail::weakly_assignable_from<Nullable&, Null const&>;
143 template <
typename T>
144 concept trait_readable_value =
requires(T&& closure) {
148 template <trait_readable_value T>
149 constexpr decltype(
auto) value_impl([[maybe_unused]] priority_tag<2u>
const tag, T&& closure)
154 template <
typename T>
155 concept indirectly_readable_value =
requires(T&& closure) {
156 { *std::forward<T>(closure) } -> transferable;
159 template <indirectly_readable_value T>
160 constexpr decltype(
auto) value_impl([[maybe_unused]] priority_tag<1u>
const tag, T&& closure)
162 return *std::forward<T>(closure);
165 template <
typename T>
166 concept adl_readable_value =
requires(T&& closure) {
167 { value(std::forward<T>(closure)) } -> transferable;
170 template <adl_readable_value T>
171 constexpr decltype(
auto) value_impl([[maybe_unused]] priority_tag<0u>
const tag, T&& closure)
173 return value(std::forward<T>(closure));
176 inline constexpr priority_tag<2u> max_value_tag{};
178 template <
typename T>
179 concept readable_value =
requires(T&& closure) {
180 { detail::value_impl(max_value_tag, std::forward<T>(closure)) } -> transferable;
183 template <readable_value T>
184 constexpr decltype(
auto) value(T&& closure)
186 return detail::value_impl(max_value_tag, std::forward<T>(closure));
199 template <
typename T>
202 requires detail::readable_value<T>;
207 template <
typename Nullable,
typename Value>
208 concept trait_value_constructible =
requires(Value&& value) {
212 template <
typename Nullable,
typename Arg>
213 requires trait_value_constructible<Nullable, Arg>
214 constexpr Nullable construct_from_value_impl([[maybe_unused]] priority_tag<1u>
const tag, Arg&& arg)
215 noexcept(
noexcept(traits<Nullable>::from_value(std::forward<Arg>(arg))))
217 return traits<Nullable>::from_value(std::forward<Arg>(arg));
220 template <
typename Nullable,
typename Arg>
221 requires std::constructible_from<Nullable, Arg&&>
222 constexpr Nullable construct_from_value_impl([[maybe_unused]] priority_tag<0u>
const tag, Arg&& arg)
223 noexcept(std::is_nothrow_constructible_v<Nullable, Arg&&>)
225 return Nullable{std::forward<Arg>(arg)};
228 inline constexpr priority_tag<1u> max_value_constructible_tag{};
230 template <
typename Nullable,
typename Value>
231 concept constructible_from_value =
requires(Value&& value) {
232 { detail::construct_from_value_impl<Nullable>(max_value_tag, std::forward<Value>(value)) } -> std::same_as<Nullable>;
235 template <
typename Nullable,
typename Value>
236 concept nothrow_constructible_from_value =
requires(Value&& value) {
237 { detail::construct_from_value_impl<Nullable>(max_value_tag, std::forward<Value>(value)) }
noexcept;
250 template <
typename T,
typename Arg>
252 && detail::unqualified<T>
253 && detail::constructible_from_value<T, Arg&&>;
267 template <nullable Nullable,
typename Arg>
269 constexpr Nullable
construct_from_value(Arg&& arg)
noexcept(detail::nothrow_constructible_from_value<Nullable, Arg&&>)
271 return detail::construct_from_value_impl<Nullable>(detail::max_value_tag, std::forward<Arg>(arg));
279 template <nullable Nullable,
typename Value>
287 template <
typename Nullable,
typename Value>
299 template <nullable Nullable>
304 template <nullable Nullable>
305 using value_result_t =
decltype(value(std::declval<Nullable&&>()));
307 template <
typename Nullable>
309 constexpr bool has_value(Nullable
const& target)
314 template <nullable T>
315 constexpr decltype(
auto) forward_value(std::remove_reference_t<T>& nullable)
317 GIMO_ASSERT(detail::has_value(nullable),
"Nullable must contain a value.", nullable);
319 return detail::value(std::forward<T>(nullable));
322 template <nullable Nullable>
324 constexpr auto construct_empty()
329 template <nullable Nullable, nullable Source>
331 constexpr Nullable rebind_value(std::remove_reference_t<Source>& source)
339 template <
typename T>
340 concept trait_readable_error =
requires(T&& closure) {
341 { traits<std::remove_cvref_t<T>>::error(std::forward<T>(closure)) } -> transferable;
344 template <trait_readable_error T>
345 constexpr decltype(
auto) error_impl([[maybe_unused]] priority_tag<2u>
const tag, T&& closure)
347 return traits<std::remove_cvref_t<T>>::error(std::forward<T>(closure));
350 template <
typename T>
351 concept member_readable_error =
requires(T&& closure) {
352 { std::forward<T>(closure).error() } -> transferable;
355 template <member_readable_error T>
356 constexpr decltype(
auto) error_impl([[maybe_unused]] priority_tag<1u>
const tag, T&& closure)
358 return std::forward<T>(closure).error();
361 template <
typename T>
362 concept adl_readable_error =
requires(T&& closure) {
363 { error(std::forward<T>(closure)) } -> transferable;
366 template <adl_readable_error T>
367 constexpr decltype(
auto) error_impl([[maybe_unused]] priority_tag<0u>
const tag, T&& closure)
369 return error(std::forward<T>(closure));
372 inline constexpr priority_tag<2u> max_error_tag{};
374 template <
typename T>
375 concept readable_error =
requires(T&& closure) {
376 { detail::error_impl(max_error_tag, std::forward<T>(closure)) } -> transferable;
379 template <readable_error T>
380 constexpr decltype(
auto) error(T&& closure)
382 return detail::error_impl(max_error_tag, std::forward<T>(closure));
393 template <
typename T>
395 && detail::readable_error<T>;
402 template <
typename T,
typename Error>
405 && detail::unqualified<T>
406 &&
requires(Error&& e) {
415 template <expected_like Expected,
typename Error>
423 template <
typename Expected,
typename Error>
433 template <expected_like Expected>
434 using error_result_t =
decltype(error(std::declval<Expected&&>()));
436 template <expected_like T>
437 constexpr decltype(
auto) forward_error(std::remove_reference_t<T>& expected)
439 GIMO_ASSERT(!detail::has_value(expected),
"Expected must hold an error.", expected);
441 return detail::error(std::forward<T>(expected));
444 template <expected_like Expected,
typename Error>
445 constexpr Expected construct_from_error(Error&& error)
447 return traits<Expected>::from_error(std::forward<Error>(error));
450 template <expected_like Expected, expected_like Source>
452 constexpr Expected rebind_error(std::remove_reference_t<Source>& source)
454 return detail::construct_from_error<Expected>(forward_error<Source>(source));
#define GIMO_ASSERT(condition, msg,...)
Definition Config.hpp:11
Concept determining whether the Expected type supports rebinding its error-type.
Definition Common.hpp:403
Concept determining whether the Nullable is constructible with the specified argument.
Definition Common.hpp:251
Concept describing a type that acts like std::expected (has both a value and an error channel).
Definition Common.hpp:394
Concept describing the relationship between a Nullable type and its null state.
Definition Common.hpp:136
Concept describing a type that can be used as a monad in the pipeline.
Definition Common.hpp:200
Concept determining whether the Expected type supports rebinding its error-type.
Definition Common.hpp:424
Concept determining whether the Nullable type supports rebinding its value-type.
Definition Common.hpp:288
Definition AndThen.hpp:21
typename traits< std::remove_cvref_t< Expected > >::template rebind_error< std::remove_cvref_t< Error > > rebind_error_t
Helper alias to obtain the Expected type with the rebound Error type.
Definition Common.hpp:416
constexpr auto null_v
Helper to obtain the null value for a specific Nullable type.
Definition Common.hpp:300
constexpr Nullable construct_from_value(Arg &&arg) noexcept(detail::nothrow_constructible_from_value< Nullable, Arg && >)
Constructs the specified Nullable with the provided value.
Definition Common.hpp:269
typename traits< std::remove_cvref_t< Nullable > >::template rebind_value< Value > rebind_value_t
Helper alias to obtain the Nullable type with the rebound Value type.
Definition Common.hpp:280
The central customization point for the library.
Definition Common.hpp:102