tin  1.5.9
transition.h
Go to the documentation of this file.
1 // Copyright (c) 2026 Tinverse LLC. All rights reserved.
2 // SPDX-License-Identifier: LicenseRef-Tinverse-Commercial
3 
12 
13 #pragma once
14 
15 #include <concepts>
16 #include <type_traits>
17 #include <utility>
18 
19 #include "tsm/type_list.h"
20 
21 namespace tsm::detail {
22 
33 struct Event {};
34 
35 template<typename T>
36 struct wrapped_event : Event {
37  using type = T;
38 };
39 
40 template<typename Parent>
41 struct final_state {
42  using final_parent = Parent;
43 };
44 
45 template<typename T>
47  typename T::final_parent;
48 };
49 
50 template<typename Parent>
51 struct history_state {
52  using history_parent = Parent;
53 };
54 
55 template<typename T>
57  typename T::history_parent;
58 };
59 
60 template<typename Parent>
61 struct deep_history_state {
62  using history_parent = Parent;
63 };
64 
65 template<typename T>
67  typename T::history_parent;
68 } && std::same_as<T, deep_history_state<typename T::history_parent>>;
69 
70 struct automatic_event {};
71 struct completion_event {};
72 
79 struct choice {};
80 struct junction {};
81 struct region {};
82 struct fork {};
83 struct join {};
84 
85 template<typename State, typename Event>
86 struct defer {
87  using state = State;
88  using event = Event;
89 };
90 
91 template<typename T>
92 concept choice_like = std::derived_from<T, choice>;
93 
94 template<typename T>
95 concept junction_like = std::derived_from<T, junction>;
96 
97 template<typename T>
98 concept decision_pseudostate_like = choice_like<T> || junction_like<T>;
99 
100 template<typename T>
101 concept region_like = std::derived_from<T, region>;
102 
103 template<typename T>
104 concept fork_like = std::derived_from<T, fork>;
105 
106 template<typename T>
107 concept join_like = std::derived_from<T, join>;
108 
109 template<typename T>
110 concept defer_like = requires {
111  typename T::state;
112  typename T::event;
113 };
114 
115 template<typename Fork, typename... Targets>
116 struct fork_to {
117  using fork = Fork;
118  using targets = type_list<Targets...>;
119 };
120 
121 template<typename ForkMarker, typename... Targets>
122 using Fork = fork_to<ForkMarker, Targets...>;
123 
124 template<typename Join, typename... Sources>
125 struct join_from {
126  using join = Join;
127  using sources = type_list<Sources...>;
128 };
129 
130 template<typename Join, typename Target>
131 struct join_to {
132  using join = Join;
133  using target = Target;
134 };
135 
136 template<typename JoinMarker, typename... Sources>
137 using Join = join_from<JoinMarker, Sources...>;
138 
139 template<typename JoinMarker, typename Target>
140 using JoinTo = join_to<JoinMarker, Target>;
141 
142 template<typename T>
144  typename T::fork;
145  typename T::targets;
146 } && fork_like<typename T::fork> && type_list_like<typename T::targets>;
147 
148 template<typename T>
150  typename T::join;
151  typename T::sources;
152 } && join_like<typename T::join> && type_list_like<typename T::sources>;
153 
154 template<typename T>
156  typename T::join;
157  typename T::target;
158 } && join_like<typename T::join>;
159 
160 template<typename T>
162  fork_rule_like<T> || join_from_rule_like<T> || join_to_rule_like<T>;
163 
164 template<typename T>
165 struct is_synchronization_rule
166  : std::bool_constant<synchronization_rule_like<T>> {};
167 
174 template<typename T>
176  typename T::synchronization;
177 };
178 
179 template<typename T>
180 struct synchronization_of {
181  using type = type_list<>;
182 };
183 
184 template<typename T>
185  requires has_synchronization_type_c<T>
186 struct synchronization_of<T> {
187  using type = typename T::synchronization;
188  static_assert(type_list_like<type>,
189  "tsm: synchronization must be tsm::synchronization<...>");
190  static_assert(type_list_traits::all_satisfy<is_synchronization_rule, type>::value,
191  "tsm: synchronization entries must be fork_to, join_from, "
192  "or join_to rules");
193 };
194 
195 enum class transition_kind {
196  external,
197  local,
198  internal,
200 };
201 
216 template<typename From, typename Event, typename To>
217 struct on {
218  using from = From;
219  using event = Event;
220  using to = To;
221  static constexpr transition_kind kind = transition_kind::external;
222 };
223 
224 template<transition_kind Kind, typename From, typename Event, typename To>
225 struct basic_transition {
226  using from = From;
227  using event = Event;
228  using to = To;
229  static constexpr transition_kind kind = Kind;
230 };
231 
232 template<transition_kind Kind, typename From, typename Event, typename To, auto Action>
233 struct transition_with_action : basic_transition<Kind, From, Event, To> {
234  using action_t = decltype(Action);
235  static constexpr action_t action = Action;
236 };
237 
238 template<transition_kind Kind, typename From, typename Event, typename To, auto Guard>
239 struct transition_with_guard : basic_transition<Kind, From, Event, To> {
240  using guard_t = decltype(Guard);
241  static constexpr guard_t guard = Guard;
242 };
243 
244 template<transition_kind Kind,
245  typename From,
246  typename Event,
247  typename To,
248  auto Guard,
249  auto Action>
250 struct transition_with_guard_action : basic_transition<Kind, From, Event, To> {
251  using guard_t = decltype(Guard);
252  using action_t = decltype(Action);
253  static constexpr guard_t guard = Guard;
254  static constexpr action_t action = Action;
255 };
256 
257 template<typename From, typename Event, typename To, auto Action>
258 using with_action =
259  transition_with_action<transition_kind::external, From, Event, To, Action>;
260 
261 template<typename From, typename Event, typename To, auto Guard>
262 using with_guard =
263  transition_with_guard<transition_kind::external, From, Event, To, Guard>;
264 
265 template<typename From, typename Event, typename To, auto Guard, auto Action>
267  transition_with_guard_action<transition_kind::external,
268  From,
269  Event,
270  To,
271  Guard,
272  Action>;
273 
274 template<transition_kind Kind, typename From, typename Event, typename To, auto... Behavior>
275 struct transition;
276 
277 template<auto Guard>
278 struct guard
279 {
280  static constexpr auto value = Guard;
281 };
282 
283 template<auto Action>
284 struct action
285 {
286  static constexpr auto value = Action;
287 };
288 
289 template<typename From, typename Event, typename To, typename... Behavior>
290 struct edge;
291 
292 template<typename From, typename Event, typename To>
293 struct edge<From, Event, To>
294  : transition<transition_kind::external, From, Event, To>
295 {
296 };
297 
298 template<typename From, typename Event, typename To, auto Guard>
299 struct edge<From, Event, To, guard<Guard>>
300  : transition_with_guard<transition_kind::external, From, Event, To, Guard>
301 {
302 };
303 
304 template<typename From, typename Event, typename To, auto Action>
305 struct edge<From, Event, To, action<Action>>
306  : transition_with_action<transition_kind::external, From, Event, To, Action>
307 {
308 };
309 
310 template<typename From, typename Event, typename To, auto Guard, auto Action>
311 struct edge<From, Event, To, guard<Guard>, action<Action>>
312  : transition_with_guard_action<transition_kind::external,
313  From,
314  Event,
315  To,
316  Guard,
317  Action>
318 {
319 };
320 
321 template<typename From, typename Event, typename To, auto Action, auto Guard>
322 struct edge<From, Event, To, action<Action>, guard<Guard>>
323  : transition_with_guard_action<transition_kind::external,
324  From,
325  Event,
326  To,
327  Guard,
328  Action>
329 {
330 };
331 
332 template<transition_kind Kind, typename From, typename Event, typename To>
333 struct transition<Kind, From, Event, To> : basic_transition<Kind, From, Event, To> {};
334 
335 template<transition_kind Kind, typename From, typename Event, typename To, auto Action>
336 struct transition<Kind, From, Event, To, Action>
337  : transition_with_action<Kind, From, Event, To, Action> {};
338 
339 template<transition_kind Kind,
340  typename From,
341  typename Event,
342  typename To,
343  auto Action,
344  auto Guard>
345 struct transition<Kind, From, Event, To, Action, Guard>
346  : transition_with_guard_action<Kind, From, Event, To, Guard, Action> {};
347 
348 template<typename From, typename Event, typename To, auto... Behavior>
349 struct T;
350 
356 template<typename From, typename Event, typename To>
357 struct T<From, Event, To>
358  : transition<transition_kind::external, From, Event, To> {};
359 
360 template<typename From, typename Event, typename To, auto Action>
361 struct T<From, Event, To, Action>
362  : transition<transition_kind::external, From, Event, To, Action> {};
363 
364 template<typename From, typename Event, typename To, auto Action, auto Guard>
365 struct T<From, Event, To, Action, Guard>
366  : transition<transition_kind::external, From, Event, To, Action, Guard> {};
367 
368 template<typename From, typename Event, typename To, auto... Behavior>
369 struct local : transition<transition_kind::local, From, Event, To, Behavior...> {};
370 
371 template<typename From, typename Event, auto... Behavior>
372 struct internal : transition<transition_kind::internal, From, Event, From, Behavior...> {};
373 
384 template<typename From, typename Event, typename To, auto... Behavior>
385 struct Internal : transition<transition_kind::local, From, Event, To, Behavior...> {};
386 
387 template<typename From, typename Event, typename To, auto... Behavior>
388 struct External
389  : transition<transition_kind::reentering_external,
390  From,
391  Event,
392  To,
393  Behavior...> {};
394 
395 struct ClockTickEvent {
396  int ticks_{0};
397 };
398 
402 template<typename From, typename To, auto... Behavior>
403 struct ClockedTransition : T<From, ClockTickEvent, To, Behavior...> {};
404 
410 template<typename Transition>
412  typename Transition::from;
413  typename Transition::to;
414 };
415 
416 template<typename Transition>
417 concept transition_like = transition_edge_like<Transition> && requires {
418  typename Transition::event;
419 };
420 
421 template<typename Transition>
422 struct is_transition : std::bool_constant<transition_like<Transition>> {};
423 
424 template<typename Transition>
425 concept transition_has_guard = transition_like<Transition> && requires {
426  Transition::guard;
427 };
428 
429 template<typename Transition>
430 concept transition_has_action = transition_like<Transition> && requires {
431  Transition::action;
432 };
433 
434 template<typename Transition>
436  if constexpr (requires { Transition::kind; }) {
437  return Transition::kind;
438  } else {
440  }
441 }
442 
443 template<typename Transition>
445  get_transition_kind<Transition>();
446 
447 template<typename Transition, typename From, typename Event>
449  transition_like<Transition> &&
450  std::same_as<typename Transition::from, From> &&
451  std::same_as<typename Transition::event, Event>;
452 
453 template<typename T>
455  typename T::transitions;
456 };
457 
458 template<typename T>
459 concept has_transition_member_c = requires(T& context) {
460  context.transitions();
461 };
462 
469 template<typename T, typename = void>
470 struct transitions_of;
471 
472 template<typename T>
473  requires has_transition_type_c<T>
474 struct transitions_of<T> {
475  using type = typename T::transitions;
476 };
477 
478 template<typename T>
479  requires(!has_transition_type_c<T> && has_transition_member_c<T>)
480 struct transitions_of<T> {
481  using type =
482  std::remove_cvref_t<decltype(std::declval<T&>().transitions())>;
483 };
484 
485 template<typename T>
486 using transitions_of_t = typename transitions_of<T>::type;
487 
488 template<typename T>
490  has_transition_type_c<T> || has_transition_member_c<T>;
491 
498 template<transition_like Transition>
499 struct transition_traits {
500  using from = typename Transition::from;
501  using event = typename Transition::event;
502  using to = typename Transition::to;
503 
504  static constexpr bool has_guard = transition_has_guard<Transition>;
505  static constexpr bool has_action = transition_has_action<Transition>;
506  static constexpr auto kind = transition_kind_v<Transition>;
507 
508  template<typename From, typename Event, typename To>
509  static consteval auto with_endpoints_type() {
510  if constexpr (has_guard && has_action) {
511  return std::type_identity<
512  transition_with_guard_action<kind,
513  From,
514  Event,
515  To,
516  Transition::guard,
517  Transition::action>>{};
518  } else if constexpr (has_guard) {
519  return std::type_identity<
520  transition_with_guard<kind, From, Event, To, Transition::guard>>{};
521  } else if constexpr (has_action) {
522  return std::type_identity<
523  transition_with_action<kind, From, Event, To, Transition::action>>{};
524  } else {
525  return std::type_identity<transition<kind, From, Event, To>>{};
526  }
527  }
528 
529  template<typename From, typename Event, typename To>
530  using with_endpoints =
531  typename decltype(with_endpoints_type<From, Event, To>())::type;
532 };
533 
534 } // namespace tsm::detail
Definition: linux.h:32
concept transition_matches
Definition: transition.h:448
concept defer_like
Definition: transition.h:110
concept has_transition_member_c
Definition: transition.h:459
constexpr transition_kind transition_kind_v
Definition: transition.h:444
concept synchronization_rule_like
Definition: transition.h:161
fork_to< ForkMarker, Targets... > Fork
Definition: transition.h:122
concept history_state_like
Definition: transition.h:56
concept transition_edge_like
Definition: transition.h:411
transition_kind
Definition: transition.h:195
concept choice_like
Definition: transition.h:92
requires(!has_transition_type_c< T > &&has_transition_member_c< T >) struct transitions_of< T >
Definition: transition.h:479
concept join_to_rule_like
Definition: transition.h:155
concept transition_has_guard
Definition: transition.h:425
concept final_state_like
Definition: transition.h:46
concept fork_rule_like
Definition: transition.h:143
concept deep_history_state_like
Definition: transition.h:66
concept decision_pseudostate_like
Definition: transition.h:98
transition_with_guard< transition_kind::external, From, Event, To, Guard > with_guard
Definition: transition.h:263
concept join_from_rule_like
Definition: transition.h:149
concept join_like
Definition: transition.h:107
concept has_transition_type_c
Definition: transition.h:454
join_to< JoinMarker, Target > JoinTo
Definition: transition.h:140
concept transition_like
Definition: transition.h:417
concept junction_like
Definition: transition.h:95
transition_with_action< transition_kind::external, From, Event, To, Action > with_action
Definition: transition.h:259
concept region_like
Definition: transition.h:101
concept has_transitions_c
Definition: transition.h:489
concept transition_has_action
Definition: transition.h:430
typename transitions_of< T >::type transitions_of_t
Definition: transition.h:486
consteval transition_kind get_transition_kind()
Definition: transition.h:435
join_from< JoinMarker, Sources... > Join
Definition: transition.h:137
concept has_synchronization_type_c
Definition: transition.h:175
concept fork_like
Definition: transition.h:104
transition_with_guard_action< transition_kind::external, From, Event, To, Guard, Action > with_guard_action
Definition: transition.h:272
Kind
Definition: logging.h:25
consteval auto transitions(TransitionEntries...)
Definition: tsm.h:2448
detail::type_list< Rules... > synchronization
Definition: tsm.h:2439
Small compile-time list and set utilities for C++ type tokens.