Maki
Loading...
Searching...
No Matches
state_builder.hpp
1//Copyright Florian Goujeon 2021 - 2025.
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_builder_fwd.hpp"
19#include "detail/type.hpp"
20#include "detail/event_action.hpp"
21#include "detail/signature_macros.hpp"
22#include "detail/tuple.hpp"
23#include "detail/impl.hpp"
24#include "detail/tlu.hpp"
25#include <string_view>
26#include <type_traits>
27
28namespace maki
29{
30
31#ifdef MAKI_DETAIL_DOXYGEN
32#define MAKI_DETAIL_STATE_CONF_RETURN_TYPE state_builder<IMPLEMENTATION_DETAIL>
33#else
34#define MAKI_DETAIL_STATE_CONF_RETURN_TYPE auto
35#endif
36
40template<class Impl>
41class state_builder
42{
43public:
44 using context_type = typename Impl::context_type;
45
46 constexpr state_builder() = default;
47
48 state_builder(const state_builder&) = delete;
49
50 state_builder(state_builder&&) = delete;
51
52 ~state_builder() = default;
53
54 state_builder& operator=(const state_builder&) = delete;
55
56 state_builder& operator=(state_builder&&) = delete;
57
58#define MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN /*NOLINT(cppcoreguidelines-macro-usage)*/ \
59 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_type = detail::type<typename Impl::context_type>; \
60 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_sig = impl_.context_sig; \
61 [[maybe_unused]] const auto MAKI_DETAIL_ARG_entry_actions = impl_.entry_actions; \
62 [[maybe_unused]] const auto MAKI_DETAIL_ARG_internal_actions = impl_.internal_actions; \
63 [[maybe_unused]] const auto MAKI_DETAIL_ARG_exit_actions = impl_.exit_actions; \
64 [[maybe_unused]] const auto MAKI_DETAIL_ARG_pretty_name_view = impl_.pretty_name; \
65 [[maybe_unused]] const auto MAKI_DETAIL_ARG_transition_tables = impl_.transition_tables;
66
67#define MAKI_DETAIL_MAKE_STATE_CONF_COPY_END /*NOLINT(cppcoreguidelines-macro-usage)*/ \
68 return state_builder \
69 < \
70 detail::state_builder_option_set \
71 < \
72 typename std::decay_t<decltype(MAKI_DETAIL_ARG_context_type)>::type, \
73 std::decay_t<decltype(MAKI_DETAIL_ARG_entry_actions)>, \
74 std::decay_t<decltype(MAKI_DETAIL_ARG_internal_actions)>, \
75 std::decay_t<decltype(MAKI_DETAIL_ARG_exit_actions)>, \
76 std::decay_t<decltype(MAKI_DETAIL_ARG_transition_tables)> \
77 > \
78 > \
79 { \
80 MAKI_DETAIL_ARG_context_sig, \
81 MAKI_DETAIL_ARG_entry_actions, \
82 MAKI_DETAIL_ARG_internal_actions, \
83 MAKI_DETAIL_ARG_exit_actions, \
84 MAKI_DETAIL_ARG_pretty_name_view, \
85 MAKI_DETAIL_ARG_transition_tables \
86 };
87
88#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
89 \
92 template<class Context> \
93 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE context_##signature() const \
94 { \
95 return context<Context, state_context_signature::signature>(); \
96 }
97 MAKI_DETAIL_STATE_CONTEXT_CONSTRUCTOR_SIGNATURES
98#undef MAKI_DETAIL_X
99
100#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
101 \
105 template<class EventSetPredicate, class Action> \
106 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE entry_action_##signature(const event_set<EventSetPredicate>& evt_set, const Action& action) const \
107 { \
108 return entry_action<action_signature::signature>(evt_set, action); \
109 } \
110 \
111 \
115 template<class Event, class Action> \
116 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE entry_action_##signature(const Action& action) const \
117 { \
118 return entry_action_##signature(event_set{event<Event>}, action); \
119 } \
120 \
121 \
125 template<class Action> \
126 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE entry_action_##signature(const Action& action) const \
127 { \
128 return entry_action_##signature(all_events, action); \
129 }
130 MAKI_DETAIL_ACTION_SIGNATURES
131#undef MAKI_DETAIL_X
132
133#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
134 MAKI_DETAIL_ACTION_SIGNATURES
135#undef MAKI_DETAIL_X
136
137#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
138 \
142 template<class EventSetPredicate, class Action> \
143 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE internal_action_##signature(const event_set<EventSetPredicate>& evt_set, const Action& action) const \
144 { \
145 return internal_action<action_signature::signature>(evt_set, action); \
146 } \
147 \
148 \
152 template<class Event, class Action> \
153 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE internal_action_##signature(const Action& action) const \
154 { \
155 return internal_action_##signature(event_set{event<Event>}, action); \
156 }
157 MAKI_DETAIL_ACTION_SIGNATURES
158#undef MAKI_DETAIL_X
159
160#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
161 \
165 template<class EventSetPredicate, class Action> \
166 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE exit_action_##signature(const event_set<EventSetPredicate>& evt_set, const Action& action) const \
167 { \
168 return exit_action<action_signature::signature>(evt_set, action); \
169 } \
171 \
175 template<class Event, class Action> \
176 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE exit_action_##signature(const Action& action) const \
177 { \
178 return exit_action_##signature(event_set{event<Event>}, action); \
179 } \
180 \
181
183 to be called whatever the event type. \
184 */ \
185 template<class Action> \
186 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE exit_action_##signature(const Action& action) const \
187 { \
188 return exit_action_##signature(all_events, action); \
189 }
190 MAKI_DETAIL_ACTION_SIGNATURES
191#undef MAKI_DETAIL_X
192
196 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE pretty_name(const std::string_view value) const
197 {
198 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
199#define MAKI_DETAIL_ARG_pretty_name_view value
200 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
201#undef MAKI_DETAIL_ARG_pretty_name_view
202 }
203
208 template<class... TransitionTables>
209 [[nodiscard]] constexpr MAKI_DETAIL_STATE_CONF_RETURN_TYPE transition_tables(const TransitionTables&... tables) const
210 {
211 const auto tpl = detail::tuple<TransitionTables...>{detail::distributed_construct, tables...};
212 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
213#define MAKI_DETAIL_ARG_transition_tables tpl
214 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
215#undef MAKI_DETAIL_ARG_transition_tables
216 }
217
218private:
219 using impl_type = Impl;
220
221 template<class Impl2>
222 friend class state_builder;
223
224 template<class... Args>
225 constexpr state_builder(Args&&... args):
226 impl_{std::forward<Args>(args)...}
227 {
228 }
229
230 template<class Context, auto ContextSig>
231 [[nodiscard]] constexpr auto context() const
232 {
233 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
234#define MAKI_DETAIL_ARG_context_type detail::type<Context>
235#define MAKI_DETAIL_ARG_context_sig ContextSig
236 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
237#undef MAKI_DETAIL_ARG_context_type
238#undef MAKI_DETAIL_ARG_context_sig
239 }
240
241 template<action_signature Sig, class EventSetPredicate, class Action>
242 [[nodiscard]] constexpr auto entry_action(const event_set<EventSetPredicate>& evt_set, const Action& action) const
243 {
244 const auto new_entry_actions = tuple_append
245 (
246 impl_.entry_actions,
247 detail::make_event_action<Sig>(evt_set, action)
248 );
249
250 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
251#define MAKI_DETAIL_ARG_entry_actions new_entry_actions
252 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
253#undef MAKI_DETAIL_ARG_entry_actions
254 }
255
256 template<action_signature Sig, class EventSetPredicate, class Action>
257 [[nodiscard]] constexpr auto internal_action(const event_set<EventSetPredicate>& evt_set, const Action& action) const
258 {
259 const auto new_internal_actions = tuple_append
260 (
261 impl_.internal_actions,
262 detail::make_event_action<Sig>(evt_set, action)
263 );
264
265 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
266#define MAKI_DETAIL_ARG_internal_actions new_internal_actions
267 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
268#undef MAKI_DETAIL_ARG_internal_actions
269 }
270
271 template<action_signature Sig, class EventSetPredicate, class Action>
272 [[nodiscard]] constexpr auto exit_action(const event_set<EventSetPredicate>& evt_set, const Action& action) const
273 {
274 const auto new_exit_actions = tuple_append
275 (
276 impl_.exit_actions,
277 detail::make_event_action<Sig>(evt_set, action)
278 );
279
280 MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
281#define MAKI_DETAIL_ARG_exit_actions new_exit_actions
282 MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
283#undef MAKI_DETAIL_ARG_exit_actions
284 }
285
286#undef MAKI_DETAIL_MAKE_STATE_CONF_COPY_END
287#undef MAKI_DETAIL_MAKE_STATE_CONF_COPY_BEGIN
288
289 MAKI_DETAIL_FRIENDLY_IMPL
290};
291
292#undef MAKI_DETAIL_STATE_CONF_RETURN_TYPE
293
294} //namespace
295
296#endif
event_set(event_t< Event >) -> event_set< IMPLEMENTATION_DETAIL >
Class template argument deduction guide for maki::event_set.
constexpr state_builder< IMPLEMENTATION_DETAIL > pretty_name(const std::string_view value) const
Forces the value returned by maki::state::pretty_name().
Definition state_builder.hpp:170
constexpr state_builder< IMPLEMENTATION_DETAIL > transition_tables(const TransitionTables &... tables) const
Specifies the list of transition tables. One region per transition table is created.
Definition state_builder.hpp:183
The Maki library.