6#ifndef GIMO_ALGORITHM_COMMON_HPP
7#define GIMO_ALGORITHM_COMMON_HPP
27 template <
typename Traits,
typename Action,
typename Nullable,
typename... Steps>
29 static constexpr auto test_and_execute(Action&& action, Nullable&& opt, Steps&&... steps)
31 if (detail::has_value(opt))
33 return Traits::on_value(
34 std::forward<Action>(action),
35 std::forward<Nullable>(opt),
36 std::forward<Steps>(steps)...);
39 return Traits::on_null(
40 std::forward<Action>(action),
41 std::forward<Nullable>(opt),
42 std::forward<Steps>(steps)...);
45 template <
typename Nullable,
typename Traits,
typename Action>
46 concept applicable_to_impl = Traits::template is_applicable_on<Nullable, Action>;
55 template <
typename Nullable,
typename Algorithm>
57 requires detail::applicable_to_impl<
59 typename std::remove_cvref_t<Algorithm>::traits_type,
60 detail::const_ref_like_t<Algorithm, typename std::remove_cvref_t<Algorithm>::action_type>>;
72 template <detail::unqualified Traits, detail::unqualified Action>
79 template <
typename... Args>
80 requires std::constructible_from<Action, Args&&...>
82 explicit constexpr BasicAlgorithm(Args&&... args)
noexcept(std::is_nothrow_constructible_v<Action, Args&&...>)
83 : m_Action{std::forward<Args>(args)...}
87 template <
typename Nullable,
typename... Steps>
89 constexpr auto operator()(Nullable&& opt, Steps&&... steps) &
91 return detail::test_and_execute<Traits>(
93 std::forward<Nullable>(opt),
94 std::forward<Steps>(steps)...);
97 template <
typename Nullable,
typename... Steps>
99 constexpr auto operator()(Nullable&& opt, Steps&&... steps)
const&
101 return detail::test_and_execute<Traits>(
103 std::forward<Nullable>(opt),
104 std::forward<Steps>(steps)...);
107 template <
typename Nullable,
typename... Steps>
109 constexpr auto operator()(Nullable&& opt, Steps&&... steps) &&
111 return detail::test_and_execute<Traits>(
113 std::forward<Nullable>(opt),
114 std::forward<Steps>(steps)...);
117 template <
typename Nullable,
typename... Steps>
119 constexpr auto operator()(Nullable&& opt, Steps&&... steps)
const&&
121 return detail::test_and_execute<Traits>(
123 std::forward<Nullable>(opt),
124 std::forward<Steps>(steps)...);
127 template <
typename Nullable,
typename... Steps>
129 constexpr auto on_value(Nullable&& opt, Steps&&... steps) &
131 GIMO_ASSERT(detail::has_value(opt),
"Nullable must contain a value.", opt);
133 return Traits::on_value(
135 std::forward<Nullable>(opt),
136 std::forward<Steps>(steps)...);
139 template <
typename Nullable,
typename... Steps>
141 constexpr auto on_value(Nullable&& opt, Steps&&... steps)
const&
143 GIMO_ASSERT(detail::has_value(opt),
"Nullable must contain a value.", opt);
145 return Traits::on_value(
147 std::forward<Nullable>(opt),
148 std::forward<Steps>(steps)...);
151 template <
typename Nullable,
typename... Steps>
153 constexpr auto on_value(Nullable&& opt, Steps&&... steps) &&
155 GIMO_ASSERT(detail::has_value(opt),
"Nullable must contain a value.", opt);
157 return Traits::on_value(
159 std::forward<Nullable>(opt),
160 std::forward<Steps>(steps)...);
163 template <
typename Nullable,
typename... Steps>
165 constexpr auto on_value(Nullable&& opt, Steps&&... steps)
const&&
167 GIMO_ASSERT(detail::has_value(opt),
"Nullable must contain a value.", opt);
169 return Traits::on_value(
171 std::forward<Nullable>(opt),
172 std::forward<Steps>(steps)...);
175 template <
typename Nullable,
typename... Steps>
177 constexpr auto on_null(Nullable&& opt, Steps&&... steps) &
179 GIMO_ASSERT(!detail::has_value(opt),
"Nullable must not contain a value.", opt);
181 return Traits::on_null(
183 std::forward<Nullable>(opt),
184 std::forward<Steps>(steps)...);
187 template <
typename Nullable,
typename... Steps>
189 constexpr auto on_null(Nullable&& opt, Steps&&... steps)
const&
191 GIMO_ASSERT(!detail::has_value(opt),
"Nullable must not contain a value.", opt);
193 return Traits::on_null(
195 std::forward<Nullable>(opt),
196 std::forward<Steps>(steps)...);
199 template <
typename Nullable,
typename... Steps>
201 constexpr auto on_null(Nullable&& opt, Steps&&... steps) &&
203 GIMO_ASSERT(!detail::has_value(opt),
"Nullable must not contain a value.", opt);
205 return Traits::on_null(
207 std::forward<Nullable>(opt),
208 std::forward<Steps>(steps)...);
211 template <
typename Nullable,
typename... Steps>
213 constexpr auto on_null(Nullable&& opt, Steps&&... steps)
const&&
215 GIMO_ASSERT(!detail::has_value(opt),
"Nullable must not contain a value.", opt);
217 return Traits::on_null(
219 std::forward<Nullable>(opt),
220 std::forward<Steps>(steps)...);
224 [[no_unique_address]] Action m_Action;
#define GIMO_ASSERT(condition, msg,...)
Definition Config.hpp:11
constexpr auto on_value(Nullable &&opt, Steps &&... steps) const &
Definition BasicAlgorithm.hpp:141
constexpr BasicAlgorithm(Args &&... args) noexcept(std::is_nothrow_constructible_v< Action, Args &&... >)
Definition BasicAlgorithm.hpp:82
Traits traits_type
Definition BasicAlgorithm.hpp:76
Action action_type
Definition BasicAlgorithm.hpp:77
constexpr auto operator()(Nullable &&opt, Steps &&... steps) const &
Definition BasicAlgorithm.hpp:99
constexpr auto on_null(Nullable &&opt, Steps &&... steps) &
Definition BasicAlgorithm.hpp:177
constexpr auto on_null(Nullable &&opt, Steps &&... steps) const &
Definition BasicAlgorithm.hpp:189
constexpr auto on_value(Nullable &&opt, Steps &&... steps) &&
Definition BasicAlgorithm.hpp:153
constexpr auto operator()(Nullable &&opt, Steps &&... steps) &&
Definition BasicAlgorithm.hpp:109
constexpr auto operator()(Nullable &&opt, Steps &&... steps) &
Definition BasicAlgorithm.hpp:89
constexpr auto on_value(Nullable &&opt, Steps &&... steps) const &&
Definition BasicAlgorithm.hpp:165
constexpr auto operator()(Nullable &&opt, Steps &&... steps) const &&
Definition BasicAlgorithm.hpp:119
constexpr auto on_value(Nullable &&opt, Steps &&... steps) &
Definition BasicAlgorithm.hpp:129
constexpr auto on_null(Nullable &&opt, Steps &&... steps) const &&
Definition BasicAlgorithm.hpp:213
constexpr auto on_null(Nullable &&opt, Steps &&... steps) &&
Definition BasicAlgorithm.hpp:201
Evaluates whether a Nullable type is compatible with the specific Algorithm.
Definition BasicAlgorithm.hpp:56
Definition AndThen.hpp:21