Maki
Loading...
Searching...
No Matches
state_mold.hpp
1//Copyright Florian Goujeon 2021 - 2026.
2//Distributed under the Boost Software License, Version 1.0.
3//(See accompanying file LICENSE or copy at
4//https://www.boost.org/LICENSE_1_0.txt)
5//Official repository: https://github.com/fgoujeon/maki
6
11
12#ifndef MAKI_STATE_BUILDER_HPP
13#define MAKI_STATE_BUILDER_HPP
14
15#include "action.hpp"
16#include "context.hpp"
17#include "event_set.hpp"
18#include "detail/state_mold_impl.hpp"
19#include "detail/type_set.hpp"
20#include "detail/type.hpp"
21#include "detail/event_action.hpp"
22#include "detail/signature_macros.hpp"
23#include "detail/tuple.hpp"
24#include "detail/friendly_impl.hpp"
25#include "detail/tlu.hpp"
26#include <string_view>
27#include <type_traits>
28
29namespace maki
30{
31
32#ifdef MAKI_DETAIL_DOXYGEN
33#define MAKI_DETAIL_STATE_CONF_RETURN_TYPE state_mold<IMPLEMENTATION_DETAIL>
34#else
35#define MAKI_DETAIL_STATE_CONF_RETURN_TYPE auto
36#endif
37
41template<class Impl>
42class state_mold
43{
44public:
45 using context_type = typename Impl::context_type;
46
47 constexpr state_mold() = default;
48
49 state_mold(const state_mold&) = delete;
50
51 state_mold(state_mold&&) = delete;
52
53 ~state_mold() = default;
54
55 state_mold& operator=(const state_mold&) = delete;
56
57 state_mold& operator=(state_mold&&) = delete;
58
59#define MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN /*NOLINT(cppcoreguidelines-macro-usage)*/ \
60 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_type = detail::type<typename Impl::context_type>; \
61 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_sig = impl_.context_sig; \
62 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_lifetime = impl_.context_lifetime; \
63 [[maybe_unused]] const auto MAKI_DETAIL_ARG_entry_actions = impl_.entry_actions; \
64 [[maybe_unused]] const auto MAKI_DETAIL_ARG_internal_actions = impl_.internal_actions; \
65 [[maybe_unused]] const auto MAKI_DETAIL_ARG_exit_actions = impl_.exit_actions; \
66 [[maybe_unused]] const auto MAKI_DETAIL_ARG_pretty_name_view = impl_.pretty_name; \
67 [[maybe_unused]] const auto MAKI_DETAIL_ARG_transition_tables = impl_.transition_tables;
68
69#define MAKI_DETAIL_MAKE_STATE_CONF_COPY_END /*NOLINT(cppcoreguidelines-macro-usage)*/ \
70 return state_mold \
71 < \
72 detail::state_mold_impl \
73 < \
74 typename std::decay_t<decltype(MAKI_DETAIL_ARG_context_type)>::type, \
75 std::decay_t<decltype(MAKI_DETAIL_ARG_entry_actions)>, \
76 std::decay_t<decltype(MAKI_DETAIL_ARG_internal_actions)>, \
77 std::decay_t<decltype(MAKI_DETAIL_ARG_exit_actions)>, \
78 std::decay_t<decltype(MAKI_DETAIL_ARG_transition_tables)> \
79 > \
80 > \
81 { \
82 MAKI_DETAIL_ARG_context_sig, \
83 MAKI_DETAIL_ARG_context_lifetime, \
84 MAKI_DETAIL_ARG_entry_actions, \
85 MAKI_DETAIL_ARG_internal_actions, \
86 MAKI_DETAIL_ARG_exit_actions, \
87 MAKI_DETAIL_ARG_pretty_name_view, \
88 MAKI_DETAIL_ARG_transition_tables \
89 };
90
91#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
92 \
95 template<class Context> \
96 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE context_##signature() const \
97 { \
98 return context<Context, state_context_signature::signature>(); \
99 }
100 MAKI_DETAIL_STATE_CONTEXT_CONSTRUCTOR_SIGNATURES
101#undef MAKI_DETAIL_X
102
105 @note Available from Maki 1.1.0.
106 */
107 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE context_lifetime(const state_context_lifetime value) const
108 {
109 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
110#define MAKI_DETAIL_ARG_context_lifetime value
111 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
112#undef MAKI_DETAIL_ARG_context_lifetime
113 }
114
115#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
116 \
120 template<class EventSetImpl, class Action> \
121 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE entry_action_##signature(const event_set<EventSetImpl>& /*event_types*/, const Action& action) const \
122 { \
123 return entry_action<action_signature::signature, EventSetImpl>(action); \
124 } \
125 \
126 \
130 template<class Event, class Action> \
131 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE entry_action_##signature(const Action& action) const \
132 { \
133 return entry_action<action_signature::signature, detail::type_set_item<Event>>(action); \
134 } \
135 \
136 \
140 template<class Action> \
141 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE entry_action_##signature(const Action& action) const \
142 { \
143 return entry_action<action_signature::signature, detail::universal_type_set_t>(action); \
144 }
145 MAKI_DETAIL_ACTION_SIGNATURES
146#undef MAKI_DETAIL_X
147
148#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
149 MAKI_DETAIL_ACTION_SIGNATURES
150#undef MAKI_DETAIL_X
151
152#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
153 \
157 template<class EventSetImpl, class Action> \
158 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE internal_action_##signature(const event_set<EventSetImpl>& /*event_types*/, const Action& action) const \
159 { \
160 return internal_action<action_signature::signature, EventSetImpl>(action); \
161 } \
162 \
163 \
167 template<class Event, class Action> \
168 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE internal_action_##signature(const Action& action) const \
169 { \
170 return internal_action<action_signature::signature, detail::type_set_item<Event>>(action); \
171 }
172 MAKI_DETAIL_ACTION_SIGNATURES
173#undef MAKI_DETAIL_X
174
175#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
176 \
180 template<class EventSetImpl, class Action> \
181 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE exit_action_##signature(const event_set<EventSetImpl>& /*event_types*/, const Action& action) const \
182 { \
183 return exit_action<action_signature::signature, EventSetImpl>(action); \
184 } \
186 \
190 template<class Event, class Action> \
191 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE exit_action_##signature(const Action& action) const \
192 { \
193 return exit_action<action_signature::signature, detail::type_set_item<Event>>(action); \
194 } \
195 \
196
198 to be called whatever the event type. \
199 */ \
200 template<class Action> \
201 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE exit_action_##signature(const Action& action) const \
202 { \
203 return exit_action<action_signature::signature, detail::universal_type_set_t>(action); \
204 }
205 MAKI_DETAIL_ACTION_SIGNATURES
206#undef MAKI_DETAIL_X
207
211 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE pretty_name(const std::string_view value) const
212 {
213 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
214#define MAKI_DETAIL_ARG_pretty_name_view value
215 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
216#undef MAKI_DETAIL_ARG_pretty_name_view
217 }
218
223 template<class... TransitionTables>
224 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE transition_tables(const TransitionTables&... tables) const
225 {
226 const auto tpl = detail::tuple<TransitionTables...>{tables...};
227 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
228#define MAKI_DETAIL_ARG_transition_tables tpl
229 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
230#undef MAKI_DETAIL_ARG_transition_tables
231 }
232
233private:
234 MAKI_DETAIL_FRIENDLY_IMPL
235
236 using impl_type = Impl;
237
238 template<class Impl2>
239 friend class state_mold;
240
241 template<class... Args>
242 constexpr state_mold(Args&&... args):
243 impl_{std::forward<Args>(args)...}
244 {
245 }
246
247 template<class Context, auto ContextSig>
248 [[nodiscard]] constexpr auto context() const
249 {
250 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
251#define MAKI_DETAIL_ARG_context_type detail::type<Context>
252#define MAKI_DETAIL_ARG_context_sig ContextSig
253 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
254#undef MAKI_DETAIL_ARG_context_type
255#undef MAKI_DETAIL_ARG_context_sig
256 }
257
258 template<action_signature Sig, class EventTypeSet, class Action>
259 [[nodiscard]] constexpr auto entry_action(const Action& action) const
260 {
261 const auto new_entry_actions = append
262 (
263 impl_.entry_actions,
264 detail::make_event_action<Sig, EventTypeSet>(action)
265 );
266
267 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
268#define MAKI_DETAIL_ARG_entry_actions new_entry_actions
269 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
270#undef MAKI_DETAIL_ARG_entry_actions
271 }
272
273 template<action_signature Sig, class EventTypeSet, class Action>
274 [[nodiscard]] constexpr auto internal_action(const Action& action) const
275 {
276 const auto new_internal_actions = append
277 (
278 impl_.internal_actions,
279 detail::make_event_action<Sig, EventTypeSet>(action)
280 );
281
282 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
283#define MAKI_DETAIL_ARG_internal_actions new_internal_actions
284 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
285#undef MAKI_DETAIL_ARG_internal_actions
286 }
287
288 template<action_signature Sig, class EventTypeSet, class Action>
289 [[nodiscard]] constexpr auto exit_action(const Action& action) const
290 {
291 const auto new_exit_actions = append
292 (
293 impl_.exit_actions,
294 detail::make_event_action<Sig, EventTypeSet>(action)
295 );
296
297 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
298#define MAKI_DETAIL_ARG_exit_actions new_exit_actions
299 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
300#undef MAKI_DETAIL_ARG_exit_actions
301 }
302
303#undef MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
304#undef MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
305
306 impl_type impl_;
307};
308
309#undef MAKI_DETAIL_STATE_CONF_RETURN_TYPE
310
311#ifdef MAKI_DETAIL_DOXYGEN
313#else
315#endif
316
317namespace detail
318{
319 template<class T>
320 struct is_state_mold
321 {
322 static constexpr auto value = false;
323 };
324
325 template<class OptionSet>
326 struct is_state_mold<state_mold<OptionSet>>
327 {
328 static constexpr auto value = true;
329 };
330
331 template<class T>
332 constexpr bool is_state_mold_v = is_state_mold<T>::value;
333}
334
335} //namespace
336
337#endif
State mold.
Definition state_mold.hpp:43
constexpr state_mold< IMPLEMENTATION_DETAIL > transition_tables(const TransitionTables &... tables) const
Specifies the list of transition tables. One region per transition table is created.
Definition state_mold.hpp:198
constexpr state_mold< IMPLEMENTATION_DETAIL > context_lifetime(const state_context_lifetime value) const
Sets the lifetime of the context.
Definition state_mold.hpp:105
constexpr state_mold< IMPLEMENTATION_DETAIL > pretty_name(const std::string_view value) const
Forces the value returned by maki::state::pretty_name().
Definition state_mold.hpp:185
The Maki library.
state_context_lifetime
The lifetime of a context instance.
Definition context.hpp:49