44#include < any>
55#include < functional>
66#include < optional>
7+ #include < ranges>
78#include < tuple>
89#include < unordered_map>
910#include < vector>
10- # include < ranges >
11+
1112
1213// / @brief Values injected into actions and guards.
1314using Injection = std::vector<std::any>;
1415
1516// / @brief Optional transition action callback.
1617// / @see std::function<void()>
17- using Action = std::optional<std::function<void ()>>;
18+ using Action = std::optional<std::function<void ()>>;
1819
1920// / @brief Optional guard predicate for transitions.
2021// / @return true if transition is allowed.
21- using Guard = std::optional<std::function<bool ()>>;
22+ using Guard = std::optional<std::function<bool ()>>;
2223
2324// / @brief Forward declaration of the state machine engine.
2425template <typename Parent>
2526class SM ;
2627
2728// / @brief Container for states, transitions, and injections of the state machine.
2829// / @tparam Parent Type defining State and Event.
29- template <typename Parent>
30+ template <typename Parent>
3031struct StateMachineContainer {
31- using State = typename Parent::State;
32- using Event = typename Parent::Event;
33- using Entry = std::tuple< State, Guard, Action, Injection >;
34- using Transition = std::tuple< State, Event, State, Guard, Action, Injection >;
35- using Anonymous = std::tuple< State, State, Guard, Action, Injection >;
32+ using State = typename Parent::State;
33+ using Event = typename Parent::Event;
34+ using Entry = std::tuple<State, Guard, Action, Injection>;
35+ using Transition = std::tuple<State, Event, State, Guard, Action, Injection>;
36+ using Anonymous = std::tuple<State, State, Guard, Action, Injection>;
3637
3738 // / @brief Current active state of the state machine.
38- State currentState;
39+ State currentState;
3940
4041 // / @brief Registered state entries with guards and entry actions.
41- std::vector<Entry> entries;
42+ std::vector<Entry> entries;
4243
4344 // / @brief Event-driven transitions.
4445 std::vector<Transition> transitions;
4546
4647 // / @brief Automatic transitions executed without an explicit event.
47- std::vector<Anonymous> anonymous;
48+ std::vector<Anonymous> anonymous;
4849
4950 // / @brief Values injected into callbacks during state changes.
50- Injection injections;
51+ Injection injections;
5152
5253 // Member convenience methods
5354 // / @brief Trigger a state machine event.
5455 // / @tparam ExternalInjection Types of additional data to inject.
5556 // / @param event Event to trigger.
5657 // / @param args Optional injection values.
57- template <typename ... ExternalInjection>
58- void triggerEvent (typename Parent::Event event, ExternalInjection&&... args) {
58+ template <typename ... ExternalInjection>
59+ void triggerEvent (typename Parent::Event event, ExternalInjection &&...args) {
5960 SM<Parent>::triggerEvent (event, *this , std::forward<ExternalInjection>(args)...);
6061 }
6162
6263 // / @brief Set a new state directly, bypassing events.
6364 // / @tparam ExternalInjection Types of additional data to inject.
6465 // / @param state Target state to set.
6566 // / @param args Optional injection values.
66- template <typename ... ExternalInjection>
67- void setState (typename Parent::State state, ExternalInjection&&... args) {
67+ template <typename ... ExternalInjection>
68+ void setState (typename Parent::State state, ExternalInjection &&...args) {
6869 SM<Parent>::setState (state, *this , std::forward<ExternalInjection>(args)...);
6970 }
70-
71- // / @brief Run anonymous transitions until none remain.
72- // / @tparam ExternalInjection Types of additional data to inject.
73- // / @param args Optional injection values.
74- // / @return true if any anonymous transition executed.
75- template <typename ... ExternalInjection>
76- bool runAnonymous (ExternalInjection&&... args) {
77- return SM<Parent>::runAnonymous (*this , std::forward<ExternalInjection>(args)...);
78- }
7971};
8072
81- template <typename Parent>
73+ template <typename Parent>
8274using StateMachine = StateMachineContainer<Parent>;
8375
8476// / @brief State machine engine implementing transitions and state changes.
@@ -106,7 +98,8 @@ class SM {
10698 updateInjection (sm, injection, std::forward<ExternalInjection>(args)...);
10799 handleStateChange (sm, nextState, guard, action);
108100 }
109- while (runAnonymous (sm, std::forward<ExternalInjection>(args)...)) {}
101+ while (runAnonymous (sm, std::forward<ExternalInjection>(args)...)) {
102+ }
110103 }
111104
112105 // / @brief Force set the state with injection values.
@@ -124,9 +117,16 @@ class SM {
124117 updateInjection (sm, injection, std::forward<ExternalInjection>(args)...);
125118 handleStateChange (sm, state, guard, action);
126119 }
127- while (runAnonymous (sm, std::forward<ExternalInjection>(args)...)) {}
120+ while (runAnonymous (sm, std::forward<ExternalInjection>(args)...)) {
121+ }
128122 }
129123
124+ // / @brief Retrieve the current state from the state machine.
125+ // / @param sm StateMachine instance.
126+ // / @return Current active state.
127+ static Parent::State getState (StateMachine &sm) { return sm.currentState ; }
128+
129+ private:
130130 // / @brief Execute an anonymous transition if the current state matches.
131131 // / @tparam ExternalInjection Types of optional injection values.
132132 // / @param sm StateMachine instance to operate on.
@@ -146,12 +146,6 @@ class SM {
146146 return false ;
147147 }
148148
149- // / @brief Retrieve the current state from the state machine.
150- // / @param sm StateMachine instance.
151- // / @return Current active state.
152- static Parent::State getState (StateMachine &sm) { return sm.currentState ; }
153-
154- private:
155149 // / @brief Evaluate guard and perform state change and action.
156150 // / @param sm Instance to update.
157151 // / @param nextState State to transition to.
0 commit comments