gimo v0.1.0
Loading...
Searching...
No Matches
BasicAlgorithm.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2025.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef GIMO_ALGORITHM_COMMON_HPP
7#define GIMO_ALGORITHM_COMMON_HPP
8
9#pragma once
10
11#include "gimo/Common.hpp"
12#include "gimo/Config.hpp"
13
14#include <concepts>
15#include <type_traits>
16#include <utility>
17
18namespace gimo
19{
24
25 namespace detail
26 {
27 template <typename Traits, typename Action, typename Nullable, typename... Steps>
28 [[nodiscard]]
29 static constexpr auto test_and_execute(Action&& action, Nullable&& opt, Steps&&... steps)
30 {
31 if (detail::has_value(opt))
32 {
33 return Traits::on_value(
34 std::forward<Action>(action),
35 std::forward<Nullable>(opt),
36 std::forward<Steps>(steps)...);
37 }
38
39 return Traits::on_null(
40 std::forward<Action>(action),
41 std::forward<Nullable>(opt),
42 std::forward<Steps>(steps)...);
43 }
44
45 template <typename Nullable, typename Traits, typename Action>
46 concept applicable_to_impl = Traits::template is_applicable_on<Nullable, Action>;
47 }
48
55 template <typename Nullable, typename Algorithm>
56 concept applicable_to = requires {
57 requires detail::applicable_to_impl<
58 Nullable,
59 typename std::remove_cvref_t<Algorithm>::traits_type,
60 detail::const_ref_like_t<Algorithm, typename std::remove_cvref_t<Algorithm>::action_type>>;
61 };
62
72 template <detail::unqualified Traits, detail::unqualified Action>
74 {
75 public:
76 using traits_type = Traits;
77 using action_type = Action;
78
79 template <typename... Args>
80 requires std::constructible_from<Action, Args&&...>
81 [[nodiscard]] //
82 explicit constexpr BasicAlgorithm(Args&&... args) noexcept(std::is_nothrow_constructible_v<Action, Args&&...>)
83 : m_Action{std::forward<Args>(args)...}
84 {
85 }
86
87 template <typename Nullable, typename... Steps>
88 [[nodiscard]]
89 constexpr auto operator()(Nullable&& opt, Steps&&... steps) &
90 {
91 return detail::test_and_execute<Traits>(
92 m_Action,
93 std::forward<Nullable>(opt),
94 std::forward<Steps>(steps)...);
95 }
96
97 template <typename Nullable, typename... Steps>
98 [[nodiscard]]
99 constexpr auto operator()(Nullable&& opt, Steps&&... steps) const&
100 {
101 return detail::test_and_execute<Traits>(
102 m_Action,
103 std::forward<Nullable>(opt),
104 std::forward<Steps>(steps)...);
105 }
106
107 template <typename Nullable, typename... Steps>
108 [[nodiscard]]
109 constexpr auto operator()(Nullable&& opt, Steps&&... steps) &&
110 {
111 return detail::test_and_execute<Traits>(
112 std::move(m_Action),
113 std::forward<Nullable>(opt),
114 std::forward<Steps>(steps)...);
115 }
116
117 template <typename Nullable, typename... Steps>
118 [[nodiscard]]
119 constexpr auto operator()(Nullable&& opt, Steps&&... steps) const&&
120 {
121 return detail::test_and_execute<Traits>(
122 std::move(m_Action),
123 std::forward<Nullable>(opt),
124 std::forward<Steps>(steps)...);
125 }
126
127 template <typename Nullable, typename... Steps>
128 [[nodiscard]]
129 constexpr auto on_value(Nullable&& opt, Steps&&... steps) &
130 {
131 GIMO_ASSERT(detail::has_value(opt), "Nullable must contain a value.", opt);
132
133 return Traits::on_value(
134 m_Action,
135 std::forward<Nullable>(opt),
136 std::forward<Steps>(steps)...);
137 }
138
139 template <typename Nullable, typename... Steps>
140 [[nodiscard]]
141 constexpr auto on_value(Nullable&& opt, Steps&&... steps) const&
142 {
143 GIMO_ASSERT(detail::has_value(opt), "Nullable must contain a value.", opt);
144
145 return Traits::on_value(
146 m_Action,
147 std::forward<Nullable>(opt),
148 std::forward<Steps>(steps)...);
149 }
150
151 template <typename Nullable, typename... Steps>
152 [[nodiscard]]
153 constexpr auto on_value(Nullable&& opt, Steps&&... steps) &&
154 {
155 GIMO_ASSERT(detail::has_value(opt), "Nullable must contain a value.", opt);
156
157 return Traits::on_value(
158 std::move(m_Action),
159 std::forward<Nullable>(opt),
160 std::forward<Steps>(steps)...);
161 }
162
163 template <typename Nullable, typename... Steps>
164 [[nodiscard]]
165 constexpr auto on_value(Nullable&& opt, Steps&&... steps) const&&
166 {
167 GIMO_ASSERT(detail::has_value(opt), "Nullable must contain a value.", opt);
168
169 return Traits::on_value(
170 std::move(m_Action),
171 std::forward<Nullable>(opt),
172 std::forward<Steps>(steps)...);
173 }
174
175 template <typename Nullable, typename... Steps>
176 [[nodiscard]]
177 constexpr auto on_null(Nullable&& opt, Steps&&... steps) &
178 {
179 GIMO_ASSERT(!detail::has_value(opt), "Nullable must not contain a value.", opt);
180
181 return Traits::on_null(
182 m_Action,
183 std::forward<Nullable>(opt),
184 std::forward<Steps>(steps)...);
185 }
186
187 template <typename Nullable, typename... Steps>
188 [[nodiscard]]
189 constexpr auto on_null(Nullable&& opt, Steps&&... steps) const&
190 {
191 GIMO_ASSERT(!detail::has_value(opt), "Nullable must not contain a value.", opt);
192
193 return Traits::on_null(
194 m_Action,
195 std::forward<Nullable>(opt),
196 std::forward<Steps>(steps)...);
197 }
198
199 template <typename Nullable, typename... Steps>
200 [[nodiscard]]
201 constexpr auto on_null(Nullable&& opt, Steps&&... steps) &&
202 {
203 GIMO_ASSERT(!detail::has_value(opt), "Nullable must not contain a value.", opt);
204
205 return Traits::on_null(
206 std::move(m_Action),
207 std::forward<Nullable>(opt),
208 std::forward<Steps>(steps)...);
209 }
210
211 template <typename Nullable, typename... Steps>
212 [[nodiscard]]
213 constexpr auto on_null(Nullable&& opt, Steps&&... steps) const&&
214 {
215 GIMO_ASSERT(!detail::has_value(opt), "Nullable must not contain a value.", opt);
216
217 return Traits::on_null(
218 std::move(m_Action),
219 std::forward<Nullable>(opt),
220 std::forward<Steps>(steps)...);
221 }
222
223 private:
224 [[no_unique_address]] Action m_Action;
225 };
226}
227
228#endif
#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
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