6#ifndef GIMO_ALGORITHM_TRANSFORM_HPP
7#define GIMO_ALGORITHM_TRANSFORM_HPP
20namespace gimo::detail::transform
22 template <
typename Nullable,
typename Action>
23 consteval Nullable* print_diagnostics()
25 if constexpr (!std::is_invocable_v<Action, value_result_t<Nullable>>)
27 static_assert(always_false_v<Nullable>,
"The transform algorithm requires an action invocable with the nullable's value.");
29 else if constexpr (!rebindable_value_to<Nullable, std::invoke_result_t<Action, value_result_t<Nullable>>>)
31 static_assert(always_false_v<Nullable>,
"The transform algorithm requires a nullable whose value-type can be rebound.");
37 template <
typename Nullable,
typename Action>
40 std::invoke_result_t<Action, value_result_t<Nullable>>>;
42 template <
typename Action, nullable Nullable>
44 constexpr result_t<Nullable, Action> on_value([[maybe_unused]] Action&& action, Nullable&& opt)
48 std::forward<Action>(action),
49 detail::forward_value<Nullable>(opt)));
52 template <
typename Action, nullable Nullable,
typename Next,
typename... Steps>
54 constexpr auto on_value(
55 [[maybe_unused]] Action&& action,
60 return std::forward<Next>(next).on_value(
61 transform::on_value(std::forward<Action>(action), std::forward<Nullable>(opt)),
62 std::forward<Steps>(steps)...);
65 template <
typename Action, nullable Nullable>
67 constexpr result_t<Nullable, Action> on_null([[maybe_unused]] Action&& action, [[maybe_unused]] Nullable&& opt)
69 return detail::construct_empty<result_t<Nullable, Action>>();
72 template <
typename Action, expected_like Expected>
74 constexpr result_t<Expected, Action> on_null([[maybe_unused]] Action&& action, Expected&& expected)
76 return detail::rebind_error<result_t<Expected, Action>, Expected>(expected);
79 template <nullable Nullable,
typename Action,
typename Next,
typename... Steps>
81 constexpr auto on_null(Action&& action, Nullable&& opt, Next&& next, Steps&&... steps)
83 return std::forward<Next>(next).on_null(
84 transform::on_null(std::forward<Action>(action), std::forward<Nullable>(opt)),
85 std::forward<Steps>(steps)...);
90 template <nullable Nullable,
typename Action>
91 static constexpr bool is_applicable_on =
requires {
92 requires rebindable_value_to<
94 std::invoke_result_t<Action, value_result_t<Nullable>>>;
97 template <
typename Action, nullable Nullable,
typename... Steps>
99 static constexpr auto on_value(Action&& action, Nullable&& opt, Steps&&... steps)
101 if constexpr (is_applicable_on<Nullable, Action>)
103 return transform::on_value(
104 std::forward<Action>(action),
105 std::forward<Nullable>(opt),
106 std::forward<Steps>(steps)...);
110 return *transform::print_diagnostics<Nullable, Action>();
114 template <
typename Action, nullable Nullable,
typename... Steps>
116 static constexpr auto on_null(Action&& action, Nullable&& opt, Steps&&... steps)
118 if constexpr (is_applicable_on<Nullable, Action>)
120 return transform::on_null(
121 std::forward<Action>(action),
122 std::forward<Nullable>(opt),
123 std::forward<Steps>(steps)...);
127 return *transform::print_diagnostics<Nullable, Action>();
137 template <
typename Action>
138 using transform_t = BasicAlgorithm<transform::traits, std::remove_cvref_t<Action>>;
160 template <
typename Action>
164 using Algorithm = detail::transform_t<Action>;
166 return Pipeline{std::tuple<Algorithm>{std::forward<Action>(action)}};
A composite object representing a sequence of monadic operations.
Definition Pipeline.hpp:30
constexpr auto transform(Action &&action)
Creates a pipeline step that transforms the underlying value.
Definition Transform.hpp:162
Definition AndThen.hpp:21
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