@@ -763,6 +763,10 @@ template <class R, class T, int N>
763763constexpr R get_id (type_id_type<N, T> *) {
764764 return static_cast <R>(N);
765765}
766+ template <class T , int N>
767+ constexpr true_type has_type_id (type_id_type<N, T> *);
768+ template <class T >
769+ constexpr false_type has_type_id (...);
766770template <template <class ...> class , class T >
767771struct is : false_type {};
768772template <template <class ...> class T , class ... Ts>
@@ -1303,6 +1307,15 @@ struct transitions<aux::false_type> {
13031307 return false ;
13041308 }
13051309};
1310+ template <class TEvent , class ...>
1311+ struct has_terminate_parent_transition : aux::false_type {};
1312+ template <class TEvent , class TTransition , class ... TRest>
1313+ struct has_terminate_parent_transition <TEvent, TTransition, TRest...>
1314+ : aux::conditional<
1315+ aux::is_same<terminate_state, typename TTransition::dst_state>::value &&
1316+ aux::is_same<TEvent, typename TTransition::event>::value,
1317+ aux::true_type,
1318+ has_terminate_parent_transition<TEvent, TRest...>>::type {};
13061319template <class Tsm , class T , class ... Ts>
13071320struct transitions_sub <sm<Tsm>, T, Ts...> {
13081321 template <class TEvent , class SM , class TDeps , class TSubs >
@@ -1318,7 +1331,14 @@ struct transitions_sub<sm<Tsm>, T, Ts...> {
13181331 }
13191332 template <class TEvent , class SM , class TDeps , class TSubs >
13201333 constexpr static bool execute_impl (const TEvent &event, SM &sm, TDeps &deps, TSubs &subs, typename SM::state_t ¤t_state) {
1321- const auto handled = sub_sm<sm_impl<Tsm>>::get (&subs).process_event (event, deps, subs);
1334+ auto &sub = sub_sm<sm_impl<Tsm>>::get (&subs);
1335+ const auto handled = sub.process_event (event, deps, subs);
1336+
1337+ if (handled && sub.is_terminated () && has_terminate_parent_transition<TEvent, T, Ts...>::value) {
1338+ const auto propagated = transitions<T, Ts...>::execute (event, sm, deps, subs, current_state);
1339+ return propagated ? propagated : handled;
1340+ }
1341+
13221342 return handled ? handled : transitions<T, Ts...>::execute (event, sm, deps, subs, current_state);
13231343 }
13241344 template <class _ , class TEvent , class SM , class TDeps , class TSubs >
@@ -2114,12 +2134,17 @@ struct sm_impl : aux::conditional_t<aux::should_not_subclass_statemachine_class<
21142134 constexpr static void visit_state (const TVisitor &visitor) {
21152135 visitor (aux::string<TState>{});
21162136 }
2117- constexpr bool is_terminated () const { return is_terminated_impl (aux::make_index_sequence<regions>{}); }
2118- constexpr bool is_terminated_impl (aux::index_sequence<0 >) const {
2119- return current_state_[0 ] == aux::get_id<state_t , terminate_state>((states_ids_t *)0 );
2137+ constexpr bool is_terminated () const {
2138+ return is_terminated_impl (aux::make_index_sequence<regions>{},
2139+ decltype (aux::has_type_id<terminate_state>((states_ids_t *)0 )){});
2140+ }
2141+ template <int ... Ns>
2142+ constexpr bool is_terminated_impl (aux::index_sequence<Ns...>, aux::false_type) const {
2143+ (void )sizeof ...(Ns);
2144+ return false ;
21202145 }
21212146 template <int ... Ns>
2122- constexpr bool is_terminated_impl (aux::index_sequence<Ns...>) const {
2147+ constexpr bool is_terminated_impl (aux::index_sequence<Ns...>, aux::true_type ) const {
21232148#if defined(__cpp_fold_expressions)
21242149 return ((current_state_[Ns] == aux::get_id<state_t , terminate_state>((states_ids_t *)0 )) && ...);
21252150#else
0 commit comments