18 #include <type_traits>
31 inline constexpr std::uint16_t
npos = 0xFFFFU;
49 template<std::
size_t Capacity>
51 std::array<std::uint16_t, Capacity>
values{};
55 if (
size < Capacity) {
60 [[nodiscard]] constexpr std::uint16_t
operator[](std::size_t index)
const {
64 [[nodiscard]] constexpr
bool contains(std::uint16_t value)
const {
65 for (std::size_t i = 0; i <
size; ++i) {
75 for (std::size_t i = 0; i <
size; ++i) {
85 for (std::size_t i = 0; i <
size; ++i) {
119 template<
typename T,
typename...
Ts>
121 constexpr std::array<bool,
sizeof...(Ts)> matches{
122 std::is_same_v<T, Ts>...
124 for (std::size_t i = 0; i < matches.size(); ++i) {
129 return static_cast<std::size_t
>(-1);
136 template<
typename T,
typename...
Ts>
138 return (std::is_same_v<T, Ts> || ...);
152 template<
typename List>
155 template<
typename...
Ts>
157 static constexpr std::size_t size =
sizeof...(Ts);
160 static consteval std::uint16_t index() {
162 static_assert(value !=
static_cast<std::size_t
>(-1),
163 "tsm: type is not in this type_set");
164 return static_cast<std::uint16_t
>(value);
168 static consteval
bool contains() {
173 template<
typename TransitionList>
175 tsm::detail::type_list_like<TransitionList> &&
176 tsm::detail::type_list_traits::all_satisfy<
177 tsm::detail::is_transition,
178 TransitionList>::value;
180 template<transition_list_like TransitionList>
200 template<
typename Transition>
203 tsm::detail::type_list<typename Transition::from, typename Transition::to>;
206 template<
typename TransitionList>
210 struct get_states<
tsm::detail::type_list<TransitionEntries...>> {
211 using type =
typename tsm::detail::unique_tuple<
214 tsm::detail::type_list<>>::type;
217 template<
typename TransitionList>
220 template<
typename TransitionList>
224 struct get_events<
tsm::detail::type_list<TransitionEntries...>> {
225 using type =
typename tsm::detail::unique_tuple<
226 tsm::detail::type_list<
typename TransitionEntries::event...>,
227 tsm::detail::type_list<>>::type;
230 template<
typename TransitionList>
233 template<
typename From,
typename Event,
typename Transition>
235 std::is_same_v<typename Transition::from, From> &&
236 std::is_same_v<typename Transition::event, Event>;
238 template<
typename From,
typename Event,
typename... TransitionEntries>
240 return (std::size_t{ 0 } + ... +
241 (same_trigger_v<From, Event, TransitionEntries>
243 : std::size_t{ 0 }));
246 template<
typename From,
typename Event,
typename... TransitionEntries>
248 return ((same_trigger_v<From, Event, TransitionEntries>
249 ? tsm::detail::transition_has_guard<TransitionEntries>
254 template<
typename From,
typename Event,
typename... TransitionEntries>
256 return (std::size_t{ 0 } + ... +
257 (same_trigger_v<From, Event, TransitionEntries> &&
258 !tsm::detail::transition_has_guard<TransitionEntries>
260 : std::size_t{ 0 }));
263 template<
typename From,
typename Event,
typename... TransitionEntries>
265 constexpr
auto count =
trigger_count<From, Event, TransitionEntries...>();
266 if constexpr (count <= 1U) {
268 }
else if constexpr (tsm::detail::decision_pseudostate_like<From> &&
269 std::is_same_v<Event, tsm::detail::automatic_event>) {
272 TransitionEntries...>() <= 1U;
288 template<
typename... TransitionEntries>
291 typename TransitionEntries::event,
292 TransitionEntries...>() &&
325 using list = tsm::detail::type_list<TransitionEntries...>;
326 using states = get_states_t<list>;
327 using events = get_events_t<list>;
328 using state_set = type_set<states>;
329 using event_set = type_set<events>;
331 static constexpr std::size_t transition_count =
sizeof...(TransitionEntries);
332 static constexpr std::size_t state_count = state_set::size;
333 static constexpr
bool valid_triggers =
336 template<
typename State>
337 static consteval std::uint16_t state_index() {
338 return state_set::template index<State>();
341 template<
typename Event>
342 static consteval std::uint16_t event_index() {
343 if constexpr (event_set::template contains<Event>()) {
344 return event_set::template index<Event>();
350 template<
typename Transition>
351 static consteval std::uint16_t transition_type_index() {
352 constexpr std::array<bool,
sizeof...(TransitionEntries)> matches{
353 std::is_same_v<Transition, TransitionEntries>...
355 for (std::size_t i = 0; i < matches.size(); ++i) {
357 return static_cast<std::uint16_t
>(i);
363 template<
typename From,
typename Event>
364 static consteval
bool has_transition() {
365 return ((std::is_same_v<typename TransitionEntries::from, From> &&
366 std::is_same_v<typename TransitionEntries::event, Event>) ||
370 template<
typename From,
typename Event>
371 static consteval std::uint16_t transition_index() {
372 constexpr std::array<bool,
sizeof...(TransitionEntries)> matches{
373 (std::is_same_v<typename TransitionEntries::from, From> &&
374 std::is_same_v<typename TransitionEntries::event, Event>)...
376 for (std::size_t i = 0; i < matches.size(); ++i) {
378 return static_cast<std::uint16_t
>(i);
388 template<
typename Child,
typename Parent>
400 template<
typename Composite,
typename Initial>
406 template<
typename ParentList>
409 template<
typename... Parents>
411 using type = tsm::detail::type_map<
412 tsm::detail::type_map_entry<
typename Parents::child,
413 typename Parents::parent_state>...>;
416 template<
typename ParentList>
419 template<
typename InitialChildList>
422 template<
typename... InitialChildren>
424 using type = tsm::detail::type_map<
425 tsm::detail::type_map_entry<
typename InitialChildren::composite,
426 typename InitialChildren::initial>...>;
429 template<
typename InitialChildList>
433 template<
typename Root,
typename States,
typename Parents,
typename InitialChildren>
436 template<
typename Context,
typename Root = Context>
441 template<
typename Context>
446 template<
typename Context,
typename Root = detail::inferred_root<Context>>
471 template<
typename Root,
474 typename... InitialChildren>
476 tsm::detail::type_list<States...>,
477 tsm::detail::type_list<Parents...>,
478 tsm::detail::type_list<InitialChildren...>> {
479 using states = tsm::detail::type_list<States...>;
480 using state_set =
type_set<tsm::detail::type_list<States...>>;
481 static constexpr std::size_t state_count =
sizeof...(States);
482 static constexpr std::size_t max_depth = state_count;
490 template<
typename State>
491 static consteval std::uint16_t state_index() {
492 return state_set::template index<State>();
503 template<
typename State>
504 static consteval std::uint16_t parent_index() {
505 constexpr std::array<bool,
sizeof...(Parents)> matches{
506 std::is_same_v<State, typename Parents::child>...
508 constexpr std::array<std::uint16_t,
sizeof...(Parents)> parent_ids{
509 state_index<typename Parents::parent_state>()...
511 for (std::size_t i = 0; i < matches.size(); ++i) {
513 return parent_ids[i];
528 template<
typename State>
529 static consteval std::uint16_t initial_child_index() {
530 constexpr std::array<bool,
sizeof...(InitialChildren)> matches{
531 std::is_same_v<State, typename InitialChildren::composite>...
533 constexpr std::array<std::uint16_t,
sizeof...(InitialChildren)> child_ids{
534 state_index<typename InitialChildren::initial>()...
536 for (std::size_t i = 0; i < matches.size(); ++i) {
547 [[nodiscard]]
static constexpr std::uint16_t parent_index(
548 std::uint16_t state) {
549 constexpr std::array<std::uint16_t, state_count> parents{
550 parent_index<States>()...
552 return state < parents.size() ? parents[state] :
npos;
558 [[nodiscard]]
static constexpr std::uint16_t initial_child_index(
559 std::uint16_t state) {
560 constexpr std::array<std::uint16_t, state_count> initial_children{
561 initial_child_index<States>()...
563 return state < initial_children.size() ? initial_children[state] :
npos;
579 std::uint16_t state) {
581 auto current = parent_index(state);
582 while (current !=
npos) {
583 result.push_back(current);
584 current = parent_index(current);
602 std::uint16_t state) {
605 auto parent = parent_index(state);
607 leaf_to_root.push_back(
parent);
610 return leaf_to_root.reversed();
630 [[nodiscard]]
static constexpr std::uint16_t least_common_ancestor(
635 auto parent = parent_index(a);
642 while (current !=
npos) {
643 if (a_path.contains(current)) {
646 current = parent_index(current);
662 std::uint16_t source,
663 std::uint16_t stop) {
665 auto current = source;
666 while (current !=
npos && current != stop) {
668 current = parent_index(current);
684 std::uint16_t destination) {
685 return states_from_leaf_up_to(destination, lca).
reversed();
701 std::uint16_t state) {
703 auto current = initial_child_index(state);
704 while (current !=
npos) {
705 result.push_back(current);
706 current = initial_child_index(current);
743 template<std::
size_t Capacity>
768 template<
typename Hierarchy>
770 std::uint16_t source,
771 std::uint16_t destination) {
774 sequence.lca = Hierarchy::least_common_ancestor(source, destination);
775 if (sequence.lca ==
npos) {
779 sequence.exits = Hierarchy::states_from_leaf_up_to(source, sequence.lca);
780 auto direct_entries =
781 Hierarchy::states_from_lca_down_to(sequence.lca, destination);
782 for (std::size_t i = 0; i < direct_entries.size; ++i) {
783 sequence.entries.push_back(direct_entries[i]);
786 auto initial_entries = Hierarchy::enter_initial_children(destination);
787 for (std::size_t i = 0; i < initial_entries.size; ++i) {
788 sequence.entries.push_back(initial_entries[i]);
791 auto prefix = Hierarchy::path_from_root(sequence.lca);
792 for (std::size_t i = 0; i < prefix.size; ++i) {
793 sequence.final_path.push_back(prefix[i]);
795 for (std::size_t i = 0; i < sequence.entries.size; ++i) {
796 sequence.final_path.push_back(sequence.entries[i]);
801 template<
typename Hierarchy>
803 std::uint16_t active_leaf,
804 std::uint16_t selected_source,
805 std::uint16_t destination) {
808 sequence.lca = selected_source;
810 if (Hierarchy::least_common_ancestor(active_leaf, selected_source) !=
815 if (Hierarchy::least_common_ancestor(selected_source, destination) !=
822 Hierarchy::states_from_leaf_up_to(active_leaf, selected_source);
824 auto direct_entries =
825 Hierarchy::states_from_lca_down_to(selected_source, destination);
826 for (std::size_t i = 0; i < direct_entries.size; ++i) {
827 sequence.entries.push_back(direct_entries[i]);
830 auto initial_entries = Hierarchy::enter_initial_children(destination);
831 for (std::size_t i = 0; i < initial_entries.size; ++i) {
832 sequence.entries.push_back(initial_entries[i]);
835 auto prefix = Hierarchy::path_from_root(selected_source);
836 for (std::size_t i = 0; i < prefix.size; ++i) {
837 sequence.final_path.push_back(prefix[i]);
839 for (std::size_t i = 0; i < sequence.entries.size; ++i) {
840 sequence.final_path.push_back(sequence.entries[i]);
858 template<
typename Hierarchy>
860 std::uint16_t active_leaf,
861 std::uint16_t selected_source,
862 std::uint16_t destination) {
866 if (Hierarchy::least_common_ancestor(active_leaf, selected_source) !=
871 const auto parent = Hierarchy::parent_index(selected_source);
874 if (Hierarchy::least_common_ancestor(sequence.lca, destination) !=
880 sequence.exits = Hierarchy::states_from_leaf_up_to(active_leaf, sequence.lca);
882 auto direct_entries =
883 Hierarchy::states_from_lca_down_to(sequence.lca, destination);
884 for (std::size_t i = 0; i < direct_entries.size; ++i) {
885 sequence.entries.push_back(direct_entries[i]);
888 auto initial_entries = Hierarchy::enter_initial_children(destination);
889 for (std::size_t i = 0; i < initial_entries.size; ++i) {
890 sequence.entries.push_back(initial_entries[i]);
893 auto prefix = Hierarchy::path_from_root(sequence.lca);
894 for (std::size_t i = 0; i < prefix.size; ++i) {
895 sequence.final_path.push_back(prefix[i]);
897 for (std::size_t i = 0; i < sequence.entries.size; ++i) {
898 sequence.final_path.push_back(sequence.entries[i]);
918 template<
typename Context>
924 template<
typename Context>
928 template<
typename Context>
931 template<
typename Context>
934 template<
typename State,
typename Parent,
bool IsComposite>
936 using type = tsm::detail::type_list<>;
939 template<
typename State,
typename Parent>
944 template<
typename DirectStates,
typename Parent>
947 template<
typename Parent,
typename... States>
952 tsm::detail::has_transitions_c<States>>::type...>;
955 template<
typename State,
bool IsComposite>
957 using type = tsm::detail::type_list<>;
960 template<
typename State>
965 template<
typename DirectStates>
968 template<
typename... States>
972 tsm::detail::has_transitions_c<States>>::type...>;
975 template<
typename State,
typename Parent,
bool IsFinal,
bool IsHistory>
980 template<
typename State,
typename Parent>
982 using type =
typename State::final_parent;
985 template<
typename State,
typename Parent>
987 using type =
typename State::history_parent;
990 template<
typename State,
typename Parent,
bool IsComposite>
996 tsm::detail::final_state_like<State>,
997 tsm::detail::history_state_like<State>>
::type;
998 using type = tsm::detail::type_list<parent<State, inferred_parent>>;
1001 template<
typename State,
typename Parent>
1009 template<
typename DirectStates,
typename Parent>
1012 template<
typename Parent,
typename... States>
1017 tsm::detail::has_transitions_c<States>>::type...>;
1020 template<
typename State,
bool IsComposite>
1022 using type = tsm::detail::type_list<>;
1025 template<
typename State>
1035 template<
typename DirectStates>
1038 template<
typename... States>
1042 tsm::detail::has_transitions_c<States>>::type...>;
1045 template<
typename State,
bool IsComposite>
1047 using type = tsm::detail::type_list<State>;
1050 template<
typename State>
1055 template<
typename DirectStates>
1058 template<
typename... States>
1062 tsm::detail::has_transitions_c<States>>::type...>;
1067 template<
typename Context,
typename Root>
1081 typename tsm::detail::unique_tuple<
1085 tsm::detail::type_list<>>
::type;
get_states_t< context_transition_list_t< Context > > direct_states_t
Definition: core_algorithms.h:929
typename context_transition_list< Context >::type context_transition_list_t
Definition: core_algorithms.h:926
tsm::detail::type_set< direct_states_t< Context > > direct_state_set_t
Definition: core_algorithms.h:932
Definition: core_algorithms.h:23
consteval bool trigger_group_is_valid()
Definition: core_algorithms.h:264
consteval std::size_t trigger_count()
Definition: core_algorithms.h:239
consteval bool transition_triggers_are_valid()
Definition: core_algorithms.h:289
typename initial_child_map_from_list< InitialChildList >::type initial_child_map_from_list_t
Definition: core_algorithms.h:431
typename parent_map_from_list< ParentList >::type parent_map_from_list_t
Definition: core_algorithms.h:417
consteval std::size_t index_in_pack()
Definition: core_algorithms.h:120
concept transition_list_like
Definition: core_algorithms.h:174
constexpr bool same_trigger_v
Definition: core_algorithms.h:234
typename get_states< TransitionList >::type get_states_t
Definition: core_algorithms.h:218
typename get_events< TransitionList >::type get_events_t
Definition: core_algorithms.h:231
constexpr auto compute_reentering_transition_sequence(std::uint16_t active_leaf, std::uint16_t selected_source, std::uint16_t destination)
Definition: core_algorithms.h:859
constexpr auto compute_local_transition_sequence(std::uint16_t active_leaf, std::uint16_t selected_source, std::uint16_t destination)
Definition: core_algorithms.h:802
constexpr auto compute_transition_sequence(std::uint16_t source, std::uint16_t destination)
Definition: core_algorithms.h:769
consteval bool contains_type()
Definition: core_algorithms.h:137
typename infer_hierarchy< Context, Root >::type infer_hierarchy_t
Definition: core_algorithms.h:447
consteval bool duplicate_group_is_guarded()
Definition: core_algorithms.h:247
consteval std::size_t duplicate_group_unguarded_count()
Definition: core_algorithms.h:255
constexpr std::uint16_t npos
Definition: core_algorithms.h:31
concept transition_edge_like
Definition: transition.h:411
typename concat_type_lists< Lists... >::type concat_type_lists_t
Definition: type_list.h:202
typename as_type_list< T >::type as_type_list_t
Definition: type_list.h:175
typename front_type< T >::type front_type_t
Definition: type_list.h:72
concept transition_like
Definition: transition.h:417
typename transitions_of< T >::type transitions_of_t
Definition: transition.h:486
Definition: bare_metal.h:20
detail::type_list< TransitionEntries... > transition_table
Definition: tsm.h:2442
transition_table< TransitionEntries... > Ts
Definition: tsm.h:2445
Definition: core_algorithms.h:919
tsm::detail::as_type_list_t< tsm::detail::transitions_of_t< Context > > type
Definition: core_algorithms.h:921
typename State::history_parent type
Definition: core_algorithms.h:987
typename State::final_parent type
Definition: core_algorithms.h:982
Definition: core_algorithms.h:976
Parent type
Definition: core_algorithms.h:977
Definition: core_algorithms.h:442
Definition: core_algorithms.h:1036
tsm::detail::concat_type_lists_t< tsm::detail::type_list< initial_child< State, typename nested::initial > >, typename nested::initial_children > type
Definition: core_algorithms.h:1032
Definition: core_algorithms.h:1021
tsm::detail::type_list<> type
Definition: core_algorithms.h:1022
Definition: core_algorithms.h:1056
typename infer_hierarchy< State, State >::leaf_states type
Definition: core_algorithms.h:1052
Definition: core_algorithms.h:1046
tsm::detail::type_list< State > type
Definition: core_algorithms.h:1047
Definition: core_algorithms.h:945
typename infer_hierarchy< State, State >::states type
Definition: core_algorithms.h:941
Definition: core_algorithms.h:935
tsm::detail::type_list<> type
Definition: core_algorithms.h:936
Definition: core_algorithms.h:966
typename infer_hierarchy< State, State >::transitions type
Definition: core_algorithms.h:962
Definition: core_algorithms.h:956
tsm::detail::type_list<> type
Definition: core_algorithms.h:957
Definition: core_algorithms.h:1010
typename infer_hierarchy< State, State >::parents nested
Definition: core_algorithms.h:1003
tsm::detail::concat_type_lists_t< tsm::detail::type_list< parent< State, Parent > >, nested > type
Definition: core_algorithms.h:1006
Definition: core_algorithms.h:991
tsm::detail::type_list< parent< State, inferred_parent > > type
Definition: core_algorithms.h:998
typename inferred_parent_for_state< State, Parent, tsm::detail::final_state_like< State >, tsm::detail::history_state_like< State > >::type inferred_parent
Definition: core_algorithms.h:997
Definition: core_algorithms.h:221
Definition: core_algorithms.h:207
Definition: core_algorithms.h:434
Definition: core_algorithms.h:1107
infer_hierarchy::transitions transitions
Definition: core_algorithms.h:1108
Definition: core_algorithms.h:1068
local_leaf_states leaf_states
Definition: core_algorithms.h:1097
tsm::detail::concat_type_lists_t< direct_transitions, typename detail::nested_transitions_for_list< direct_states >::type > transitions
Definition: core_algorithms.h:1106
tsm::detail::front_type_t< direct_states > initial
Definition: core_algorithms.h:1098
typename detail::initial_edges_for_list< direct_states >::type initial_children
Definition: core_algorithms.h:1091
typename detail::local_leaf_states_for_list< direct_states >::type local_leaf_states
Definition: core_algorithms.h:1096
detail::direct_states_t< Context > direct_states
Definition: core_algorithms.h:1071
detail::context_transition_list_t< Context > direct_transitions
Direct machine surface authored by Context.
Definition: core_algorithms.h:1070
typename detail::nested_states_for_list< direct_states, Root >::type nested_states
Recursively imported structure from nested composite states.
Definition: core_algorithms.h:1076
typename tsm::detail::unique_tuple< tsm::detail::concat_type_lists_t< tsm::detail::type_list< Root >, direct_states, nested_states >, tsm::detail::type_list<> >::type states
Definition: core_algorithms.h:1085
detail::direct_state_set_t< Context > direct_state_set
Definition: core_algorithms.h:1072
typename detail::parent_edges_for_list< direct_states, Root >::type parents
Parent and initial-child maps inferred from nesting.
Definition: core_algorithms.h:1089
Definition: core_algorithms.h:420
Definition: core_algorithms.h:401
Composite composite
Definition: core_algorithms.h:402
Initial initial
Definition: core_algorithms.h:403
Definition: core_algorithms.h:407
Definition: core_algorithms.h:389
Child child
Definition: core_algorithms.h:390
Parent parent_state
Definition: core_algorithms.h:391
Definition: core_algorithms.h:50
std::size_t size
Definition: core_algorithms.h:52
std::array< std::uint16_t, Capacity > values
Definition: core_algorithms.h:51
constexpr static_path reversed() const
Definition: core_algorithms.h:73
constexpr bool contains(std::uint16_t value) const
Definition: core_algorithms.h:64
constexpr bool operator==(static_path const &other) const
Definition: core_algorithms.h:81
constexpr std::uint16_t operator[](std::size_t index) const
Definition: core_algorithms.h:60
constexpr void push_back(std::uint16_t value)
Definition: core_algorithms.h:54
Definition: core_algorithms.h:744
static_path< Capacity > entries
Definition: core_algorithms.h:748
static_path< Capacity > exits
Definition: core_algorithms.h:747
std::uint16_t destination
Definition: core_algorithms.h:745
std::uint16_t lca
Definition: core_algorithms.h:746
static_path< Capacity > final_path
Definition: core_algorithms.h:749
Definition: core_algorithms.h:201
tsm::detail::type_list< typename Transition::from, typename Transition::to > type
Definition: core_algorithms.h:203
Definition: core_algorithms.h:181
Definition: core_algorithms.h:153
Authoring vocabulary for transitions, pseudostates, and synchronization.
Small compile-time list and set utilities for C++ type tokens.