Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions include/boost/sml.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,10 @@ template <class R, class T, int N>
constexpr R get_id(type_id_type<N, T> *) {
return static_cast<R>(N);
}
template <class T, int N>
constexpr true_type has_type_id(type_id_type<N, T> *);
template <class T>
constexpr false_type has_type_id(...);
template <template <class...> class, class T>
struct is : false_type {};
template <template <class...> class T, class... Ts>
Expand Down Expand Up @@ -1299,6 +1303,15 @@ struct transitions<aux::false_type> {
return false;
}
};
template <class TEvent, class...>
struct has_terminate_parent_transition : aux::false_type {};
template <class TEvent, class TTransition, class... TRest>
struct has_terminate_parent_transition<TEvent, TTransition, TRest...>
: aux::conditional<
aux::is_same<terminate_state, typename TTransition::dst_state>::value &&
aux::is_same<TEvent, typename TTransition::event>::value,
aux::true_type,
has_terminate_parent_transition<TEvent, TRest...>>::type {};
template <class Tsm, class T, class... Ts>
struct transitions_sub<sm<Tsm>, T, Ts...> {
template <class TEvent, class SM, class TDeps, class TSubs>
Expand All @@ -1314,7 +1327,14 @@ struct transitions_sub<sm<Tsm>, T, Ts...> {
}
template <class TEvent, class SM, class TDeps, class TSubs>
constexpr static bool execute_impl(const TEvent &event, SM &sm, TDeps &deps, TSubs &subs, typename SM::state_t &current_state) {
const auto handled = sub_sm<sm_impl<Tsm>>::get(&subs).process_event(event, deps, subs);
auto &sub = sub_sm<sm_impl<Tsm>>::get(&subs);
const auto handled = sub.process_event(event, deps, subs);

if (handled && sub.is_terminated() && has_terminate_parent_transition<TEvent, T, Ts...>::value) {
const auto propagated = transitions<T, Ts...>::execute(event, sm, deps, subs, current_state);
return propagated ? propagated : handled;
}

return handled ? handled : transitions<T, Ts...>::execute(event, sm, deps, subs, current_state);
}
template <class _, class TEvent, class SM, class TDeps, class TSubs>
Expand Down Expand Up @@ -2088,12 +2108,17 @@ struct sm_impl : aux::conditional_t<aux::should_not_subclass_statemachine_class<
constexpr static void visit_state(const TVisitor &visitor) {
visitor(aux::string<TState>{});
}
constexpr bool is_terminated() const { return is_terminated_impl(aux::make_index_sequence<regions>{}); }
constexpr bool is_terminated_impl(aux::index_sequence<0>) const {
return current_state_[0] == aux::get_id<state_t, terminate_state>((states_ids_t *)0);
constexpr bool is_terminated() const {
return is_terminated_impl(aux::make_index_sequence<regions>{},
decltype(aux::has_type_id<terminate_state>((states_ids_t *)0)){});
}
template <int... Ns>
constexpr bool is_terminated_impl(aux::index_sequence<Ns...>, aux::false_type) const {
(void)sizeof...(Ns);
return false;
}
template <int... Ns>
constexpr bool is_terminated_impl(aux::index_sequence<Ns...>) const {
constexpr bool is_terminated_impl(aux::index_sequence<Ns...>, aux::true_type) const {
#if defined(__cpp_fold_expressions)
return ((current_state_[Ns] == aux::get_id<state_t, terminate_state>((states_ids_t *)0)) && ...);
#else
Expand Down
9 changes: 8 additions & 1 deletion include/boost/sml/utility/dispatch_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,14 @@ auto make_dispatch_table(SM &fsm, const aux::index_sequence<Ns...> &) {
using dispatch_table_t = bool (*)(SM &, const TEvent &);
const static dispatch_table_t dispatch_table[sizeof...(Ns) ? sizeof...(Ns) : 1] = {
&get_event_t<Ns + EventRangeBegin, events_ids_t>::template execute<SM, TEvent>...};
return dispatch_table[id - EventRangeBegin](fsm, e);
const auto id64 = static_cast<long long>(id);
const auto begin64 = static_cast<long long>(EventRangeBegin);
const auto count64 = static_cast<long long>(sizeof...(Ns));
if (id64 < begin64 || id64 >= begin64 + count64) {
return false;
}
const auto dispatch_id = static_cast<int>(id64 - begin64);
return dispatch_table[dispatch_id](fsm, e);
};
}
} // namespace detail
Expand Down
3 changes: 3 additions & 0 deletions scripts/quality_gates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@ fi
if [[ -n "${EXTRA_CXX_FLAGS}" ]]; then
BASE_CXX_FLAGS="${BASE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}"
fi
if [[ "${COMPILER_FAMILY}" == "clang" ]]; then
BASE_CXX_FLAGS="${BASE_CXX_FLAGS} -Wno-unknown-warning-option -Wno-error=mismatched-tags -Wno-error=stack-exhausted -Wno-stack-exhausted"
fi

require_defaults

Expand Down
4 changes: 4 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@ elseif(IS_COMPILER_OPTION_GCC_LIKE)
add_compile_options(-include common/test.hpp)
endif()

if(MINGW AND IS_COMPILER_OPTION_GCC_LIKE)
add_compile_options(-Wa,-mbig-obj)
endif()

add_subdirectory(ft)
add_subdirectory(ut)
15 changes: 14 additions & 1 deletion test/ft/extended_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@

namespace sml = boost::sml;

inline std::string canonical_state_name(std::string state) {
if (0 == state.find("class ")) {
state.erase(0, 6);
} else if (0 == state.find("struct ")) {
state.erase(0, 7);
}
const auto scope_pos = state.rfind("::");
if (scope_pos != std::string::npos) {
state.erase(0, scope_pos + 2);
}
return state;
}

template <class TSM>
std::vector<std::string> sorted_current_states(const TSM& sm) {
std::vector<std::string> states;
sm.visit_current_states([&](auto state) { states.push_back(state.c_str()); });
sm.visit_current_states([&](auto state) { states.push_back(canonical_state_name(state.c_str())); });
std::sort(states.begin(), states.end());
return states;
}
Expand Down
Loading
Loading