diff --git a/include/boost/sml.hpp b/include/boost/sml.hpp index fb57d81f..9c9b4135 100644 --- a/include/boost/sml.hpp +++ b/include/boost/sml.hpp @@ -1087,7 +1087,9 @@ template transitions get_state_mapping_impl(state_mappings> *); template struct get_state_mapping { - using type = decltype(get_state_mapping_impl((TMappings *)0)); + using type = aux::conditional_t((TMappings *)0)), transitions>::value, + decltype(get_state_mapping_impl<_, TUnexpected>((TMappings *)0)), + decltype(get_state_mapping_impl((TMappings *)0))>; }; template transitions_sub get_sub_state_mapping_impl(...); diff --git a/test/ft/states.cpp b/test/ft/states.cpp index 0047d793..48cd4c8c 100644 --- a/test/ft/states.cpp +++ b/test/ft/states.cpp @@ -28,6 +28,7 @@ struct e7 { const auto idle = sml::state; const auto s1 = sml::state; const auto s2 = sml::state; +const auto any = sml::state; test terminate_state = [] { struct c { @@ -215,6 +216,51 @@ test states_initial_entry_actions_with_events = [] { std::type_index(typeid(sml::anonymous))} == c_.entries); }; +test any_state = [] { + struct c { + auto operator()() { + using namespace sml; + auto action1 = [this]{ calls += "a1|"; }; + auto action2 = [this]{ calls += "a2|"; }; + auto action3 = [this]{ calls += "a3|"; }; + + // clang-format off + return make_transition_table( + any + event / action1, + any + event / action2, + any + event / action3 = idle, + + *idle + event = s1, + s1 + event = s2, + s2 + event = s1 + ); + // clang-format on + } + + std::string calls{}; + }; + + sml::sm sm{}; + const c& c_ = sm; + + sm.process_event(e1()); + expect(sm.is(s1)); + sm.process_event(e1()); + expect(sm.is(s1)); + sm.process_event(e2()); + expect(sm.is(s2)); + sm.process_event(e1()); + expect(sm.is(s2)); + sm.process_event(e2()); + expect(sm.is(s2)); + sm.process_event(e3()); + expect(sm.is(s1)); + sm.process_event(e3()); + expect(sm.is(idle)); + + expect("a1|a1|a2|a3|" == c_.calls); +}; + #if !defined(_MSC_VER) test state_names = [] { struct c {