mirror of
https://github.com/boostorg/msm.git
synced 2026-07-21 13:23:45 +00:00
refactor(backmp11): various topics
This commit is contained in:
committed by
Christian Granzin
parent
428cbad053
commit
79067cf6e0
@@ -15,7 +15,7 @@ It offers a significant improvement in runtime and memory usage, as can be seen
|
||||
| back | 14 | 815 | 68 | 2.8
|
||||
| back_favor_compile_time | 17 | 775 | 226 | 3.5
|
||||
| back11 | 37 | 2682 | 84 | 2.8
|
||||
| backmp11 | 3 | 211 | 29 | 0.7
|
||||
| backmp11 | 3 | 209 | 29 | 0.7
|
||||
| backmp11_favor_compile_time | 3 | 195 | 43 | 6.0
|
||||
| sml | 5 | 234 | 57 | 0.3
|
||||
|=======================================================================================================
|
||||
@@ -28,9 +28,9 @@ It offers a significant improvement in runtime and memory usage, as can be seen
|
||||
| | Compile time / sec | Compile RAM / MB | Binary size / kB | Runtime / sec
|
||||
| back | 49 | 2165 | 230 | 13.2
|
||||
| back_favor_compile_time | 55 | 1704 | 911 | > 300
|
||||
| backmp11 | 8 | 354 | 85 | 3.4
|
||||
| backmp11_favor_compile_time | 5 | 262 | 100 | 20.4
|
||||
| backmp11_favor_compile_time_multi_cu | 5 | ~863 | 100 | 20.8
|
||||
| backmp11 | 8 | 348 | 83 | 3.4
|
||||
| backmp11_favor_compile_time | 5 | 261 | 97 | 20.6
|
||||
| backmp11_favor_compile_time_multi_cu | 4 | ~863 | 97 | 21.4
|
||||
| sml | 18 | 543 | 422 | 5.4
|
||||
|================================================================================================================
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_COMMON_TYPES_H
|
||||
#define BOOST_MSM_BACKMP11_COMMON_TYPES_H
|
||||
#ifndef BOOST_MSM_BACKMP11_COMMON_TYPES_HPP
|
||||
#define BOOST_MSM_BACKMP11_COMMON_TYPES_HPP
|
||||
|
||||
#include <any>
|
||||
#include <cstdint>
|
||||
@@ -111,11 +111,11 @@ static constexpr process_result handled_true_or_deferred =
|
||||
// Event occurrences are placed in an event pool for later processing.
|
||||
class event_occurrence
|
||||
{
|
||||
using process_fnc_t = std::optional<process_result> (*)(
|
||||
using process_fn_t = std::optional<process_result> (*)(
|
||||
event_occurrence&, void* /*sm*/, uint16_t /*seq_cnt*/);
|
||||
|
||||
public:
|
||||
event_occurrence(process_fnc_t process_fnc) : m_process_fnc(process_fnc)
|
||||
event_occurrence(process_fn_t process_fn) : m_process_fn(process_fn)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ class event_occurrence
|
||||
template <typename StateMachine>
|
||||
std::optional<process_result> try_process(StateMachine& sm, uint16_t seq_cnt)
|
||||
{
|
||||
return m_process_fnc(*this, static_cast<void*>(&sm), seq_cnt);
|
||||
return m_process_fn(*this, static_cast<void*>(&sm), seq_cnt);
|
||||
}
|
||||
|
||||
void mark_for_deletion()
|
||||
@@ -139,7 +139,7 @@ class event_occurrence
|
||||
}
|
||||
|
||||
private:
|
||||
process_fnc_t m_process_fnc{};
|
||||
process_fn_t m_process_fn{};
|
||||
// Flag set when this event has been processed and can be erased.
|
||||
// Deletion is deferred to allow the use of std::deque,
|
||||
// which provides better cache locality and lower per-element overhead.
|
||||
@@ -188,4 +188,4 @@ struct compile_policy_impl;
|
||||
} // namespace detail
|
||||
} // namespace boost::msm::backmp11
|
||||
|
||||
#endif // BOOST_MSM_BACKMP11_COMMON_TYPES_H
|
||||
#endif // BOOST_MSM_BACKMP11_COMMON_TYPES_HPP
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright 2025 Christian Granzin
|
||||
// Copyright 2008 Christophe Henry
|
||||
// henry UNDERSCORE christophe AT hotmail DOT com
|
||||
// This is an extended version of the state machine available in the boost::mpl library
|
||||
// Distributed under the same license as the original.
|
||||
// Copyright for the original version:
|
||||
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_DISPATCH_TABLE_H
|
||||
#define BOOST_MSM_BACKMP11_DISPATCH_TABLE_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
#include <boost/msm/backmp11/common_types.hpp>
|
||||
|
||||
namespace boost { namespace msm { namespace backmp11
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Value used to initialize a cell of the dispatch table
|
||||
template<typename Cell>
|
||||
struct init_cell_value
|
||||
{
|
||||
size_t index;
|
||||
Cell cell;
|
||||
};
|
||||
template<size_t index, typename Cell, Cell cell>
|
||||
struct init_cell_constant
|
||||
{
|
||||
using value_type = init_cell_value<Cell>;
|
||||
static constexpr value_type value = {index, cell};
|
||||
};
|
||||
|
||||
// Type-punned init cell value to suppress redundant template instantiations.
|
||||
using generic_cell = void(*)();
|
||||
using generic_init_cell_value = init_cell_value<generic_cell>;
|
||||
|
||||
// Class that handles the initialization of dispatch table entries.
|
||||
struct dispatch_table_initializer
|
||||
{
|
||||
static void execute(generic_cell* cells, const generic_init_cell_value* values, size_t values_size)
|
||||
{
|
||||
for (size_t i = 0; i < values_size; i++)
|
||||
{
|
||||
const auto& item = values[i];
|
||||
cells[item.index] = item.cell;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
}}} // boost::msm::backmp11
|
||||
|
||||
#endif //BOOST_MSM_BACKMP11_DISPATCH_TABLE_H
|
||||
@@ -9,16 +9,15 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_H
|
||||
#define BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_H
|
||||
#ifndef BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_HPP
|
||||
#define BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_HPP
|
||||
|
||||
#include <boost/msm/backmp11/detail/metafunctions.hpp>
|
||||
#include <boost/msm/backmp11/detail/dispatch_table.hpp>
|
||||
#include <boost/msm/backmp11/detail/state_visitor.hpp>
|
||||
#include <boost/msm/backmp11/detail/transition_table.hpp>
|
||||
#include <boost/msm/backmp11/event_traits.hpp>
|
||||
|
||||
namespace boost { namespace msm { namespace backmp11
|
||||
namespace boost::msm::backmp11
|
||||
{
|
||||
|
||||
struct favor_runtime_speed
|
||||
@@ -172,8 +171,6 @@ struct compile_policy_impl<
|
||||
}
|
||||
|
||||
private:
|
||||
using cell_t = process_result (*)(StateMachine&, int /*region_id*/, Event const&);
|
||||
|
||||
// All dispatch tables are friend with each other to check recursively
|
||||
// whether forward transitions are required.
|
||||
template <class, typename>
|
||||
@@ -360,78 +357,39 @@ struct compile_policy_impl<
|
||||
{
|
||||
using base = dispatch_base;
|
||||
public:
|
||||
template <typename... Ts>
|
||||
struct mp_indexed_dispatch_impl
|
||||
{
|
||||
using list = mp11::mp_list<Ts...>;
|
||||
static constexpr std::size_t size = sizeof...(Ts);
|
||||
|
||||
template <typename F>
|
||||
static constexpr process_result invoke(int state_id, F&& func)
|
||||
{
|
||||
return dispatch(state_id, func,
|
||||
std::make_index_sequence<size>{});
|
||||
}
|
||||
|
||||
private:
|
||||
// For position I in the list, get the corresponding state_id
|
||||
// at compile time.
|
||||
template <std::size_t I>
|
||||
static constexpr int state_id_at =
|
||||
StateMachine::template get_state_id<
|
||||
typename mp11::mp_at_c<list, I>::current_state_type>();
|
||||
|
||||
// Single case handler: invoke func with the I-th transition
|
||||
template <std::size_t I, typename F>
|
||||
static constexpr process_result handle_case(F& func)
|
||||
{
|
||||
return func(mp11::mp_at_c<list, I>{});
|
||||
}
|
||||
|
||||
// Generate branches comparing state_id against compile-time
|
||||
// state_id_at<I> for each position I in the list.
|
||||
template <typename F, std::size_t... Is>
|
||||
static constexpr process_result dispatch(int state_id, F& func,
|
||||
std::index_sequence<Is...>)
|
||||
{
|
||||
process_result result = process_result::HANDLED_FALSE;
|
||||
// Each branch compares the runtime state_id against the
|
||||
// compile-time state_id of the I-th transition.
|
||||
// State IDs may be non-contiguous (e.g., 0, 2, 5).
|
||||
(void)((state_id == state_id_at<Is> &&
|
||||
(result = handle_case<Is>(func), true)) || ...);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename L, typename F>
|
||||
static constexpr process_result mp_indexed_dispatch(int state_id, F&& func)
|
||||
{
|
||||
return mp11::mp_apply<mp_indexed_dispatch_impl, L>::invoke(
|
||||
state_id, std::forward<F>(func));
|
||||
}
|
||||
|
||||
static inline process_result dispatch(StateMachine& sm, int region_id,
|
||||
const Event& event)
|
||||
{
|
||||
const int state_id = sm.m_active_state_ids[region_id];
|
||||
return mp_indexed_dispatch<typename base::merged_transitions>(state_id,
|
||||
[&sm, region_id, &event](auto transition) -> process_result
|
||||
process_result result = process_result::HANDLED_FALSE;
|
||||
mp11::mp_for_each<typename base::merged_transitions>(
|
||||
[&sm, region_id, &event, state_id, &result](auto transition)
|
||||
{
|
||||
using Transition = decltype(transition);
|
||||
using TransitionEvent =
|
||||
typename Transition::transition_event;
|
||||
if constexpr (!is_kleene_event<TransitionEvent>::value)
|
||||
using SourceState =
|
||||
typename Transition::current_state_type;
|
||||
constexpr int source_state_id =
|
||||
StateMachine::template get_state_id<SourceState>();
|
||||
if (state_id == source_state_id)
|
||||
{
|
||||
return Transition::execute(sm, region_id, event);
|
||||
if constexpr (!is_kleene_event<
|
||||
TransitionEvent>::value)
|
||||
{
|
||||
result =
|
||||
Transition::execute(sm, region_id, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
result =
|
||||
base::template convert_event_and_execute<
|
||||
Transition>(sm, region_id, event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return base::template
|
||||
convert_event_and_execute<Transition>(
|
||||
sm, region_id, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -440,6 +398,9 @@ struct compile_policy_impl<
|
||||
: public dispatch_base
|
||||
{
|
||||
using base = dispatch_base;
|
||||
using cell_t = process_result (*)(StateMachine&, int /*region_id*/,
|
||||
Event const&);
|
||||
|
||||
public:
|
||||
static process_result dispatch(
|
||||
StateMachine& sm, int region_id, const Event& event)
|
||||
@@ -557,7 +518,7 @@ struct compile_policy_impl<
|
||||
};
|
||||
|
||||
} // detail
|
||||
}}} // boost::msm::backmp11
|
||||
} // boost::msm::backmp11
|
||||
|
||||
|
||||
#endif // BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_H
|
||||
#endif // BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_HPP
|
||||
|
||||
@@ -9,18 +9,14 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_HISTORY_IMPL_H
|
||||
#define BOOST_MSM_BACKMP11_HISTORY_IMPL_H
|
||||
#ifndef BOOST_MSM_BACKMP11_DETAIL_HISTORY_IMPL_HPP
|
||||
#define BOOST_MSM_BACKMP11_DETAIL_HISTORY_IMPL_HPP
|
||||
|
||||
#include <boost/msm/front/history_policies.hpp>
|
||||
#include <boost/mp11.hpp>
|
||||
|
||||
namespace boost::msm::backmp11
|
||||
namespace boost::msm::backmp11::detail
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Implementations for history policies.
|
||||
|
||||
template<typename History, int NumberOfRegions>
|
||||
class history_impl;
|
||||
@@ -138,8 +134,6 @@ public:
|
||||
std::array<int, NumberOfRegions> m_last_active_state_ids;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
} // boost::msm::backmp11
|
||||
|
||||
#endif // BOOST_MSM_BACKMP11_HISTORY_IMPL_H
|
||||
#endif // BOOST_MSM_BACKMP11_DETAIL_HISTORY_IMPL_HPP
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_METAFUNCTIONS_H
|
||||
#define BOOST_MSM_BACKMP11_METAFUNCTIONS_H
|
||||
#ifndef BOOST_MSM_BACKMP11_DETAIL_METAFUNCTIONS_HPP
|
||||
#define BOOST_MSM_BACKMP11_DETAIL_METAFUNCTIONS_HPP
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
#include <boost/mp11/mpl_list.hpp>
|
||||
@@ -36,10 +36,7 @@ namespace boost::mpl
|
||||
struct is_sequence;
|
||||
}
|
||||
|
||||
namespace boost { namespace msm { namespace backmp11
|
||||
{
|
||||
|
||||
namespace detail
|
||||
namespace boost::msm::backmp11::detail
|
||||
{
|
||||
|
||||
// Call a functor on all elements of List, until the functor returns true.
|
||||
@@ -336,8 +333,6 @@ struct is_state_blocking_impl
|
||||
template<typename T>
|
||||
using is_state_blocking = typename is_state_blocking_impl<T>::type;
|
||||
|
||||
} // detail
|
||||
} // boost::msm::backmp11::detail
|
||||
|
||||
}}} // boost::msm::backmp11
|
||||
|
||||
#endif // BOOST_MSM_BACKMP11_METAFUNCTIONS_H
|
||||
#endif // BOOST_MSM_BACKMP11_DETAIL_METAFUNCTIONS_HPP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,6 @@
|
||||
#ifndef BOOST_MSM_BACKMP11_DETAIL_STATE_VISITOR_HPP
|
||||
#define BOOST_MSM_BACKMP11_DETAIL_STATE_VISITOR_HPP
|
||||
|
||||
#include <boost/msm/backmp11/detail/dispatch_table.hpp>
|
||||
#include <boost/msm/backmp11/detail/metafunctions.hpp>
|
||||
#include <boost/msm/backmp11/state_machine_config.hpp>
|
||||
|
||||
@@ -197,61 +196,27 @@ class state_visitor_impl<
|
||||
{
|
||||
if (sm.m_running)
|
||||
{
|
||||
const state_visitor_impl& self = instance();
|
||||
for (const int state_id : sm.m_active_state_ids)
|
||||
using state_identities = mp11::mp_transform<
|
||||
mp11::mp_identity,
|
||||
typename base::states_to_traverse>;
|
||||
for (const int active_state_id : sm.m_active_state_ids)
|
||||
{
|
||||
self.dispatch(sm, state_id, visitor);
|
||||
mp11::mp_for_each<state_identities>(
|
||||
[&sm, &visitor, active_state_id](auto state_identity)
|
||||
{
|
||||
using State =
|
||||
typename decltype(state_identity)::type;
|
||||
constexpr int state_id =
|
||||
StateMachine::template get_state_id<State>();
|
||||
if (active_state_id == state_id)
|
||||
{
|
||||
base::template accept<Mode, State>(sm, visitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bug: Clang 17 complains about private member if this method is private.
|
||||
template <typename State>
|
||||
static void accept(StateMachine& sm, Visitor& visitor)
|
||||
{
|
||||
base::template accept<Mode, State>(sm, visitor);
|
||||
}
|
||||
|
||||
private:
|
||||
using state_set = typename StateMachine::internal::state_set;
|
||||
using cell_t = void (*)(StateMachine&, Visitor&);
|
||||
template <size_t index, cell_t cell>
|
||||
using init_cell_constant = init_cell_constant<index, cell_t, cell>;
|
||||
|
||||
template <typename State>
|
||||
using get_init_cell_constant = init_cell_constant<
|
||||
StateMachine::template get_state_id<State>(),
|
||||
&accept<State>>;
|
||||
|
||||
state_visitor_impl()
|
||||
{
|
||||
using init_cell_constants = mp11::mp_transform<
|
||||
get_init_cell_constant,
|
||||
typename base::states_to_traverse>;
|
||||
dispatch_table_initializer::execute(
|
||||
reinterpret_cast<generic_cell*>(m_cells),
|
||||
reinterpret_cast<const generic_init_cell_value*>(
|
||||
value_array<init_cell_constants>),
|
||||
mp11::mp_size<init_cell_constants>::value);
|
||||
}
|
||||
|
||||
void dispatch(StateMachine& sm, int state_id, Visitor& visitor) const
|
||||
{
|
||||
const cell_t& cell = m_cells[state_id];
|
||||
if (cell)
|
||||
{
|
||||
(*cell)(sm, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
static const state_visitor_impl& instance()
|
||||
{
|
||||
static const state_visitor_impl instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
cell_t m_cells[mp11::mp_size<state_set>::value]{};
|
||||
};
|
||||
|
||||
template <
|
||||
@@ -325,15 +290,27 @@ class event_deferral_visitor
|
||||
"The visitor must have at least one state to visit");
|
||||
if (sm.m_running)
|
||||
{
|
||||
const event_deferral_visitor& self = instance();
|
||||
for (const int state_id : sm.m_active_state_ids)
|
||||
using state_identities = mp11::mp_transform<
|
||||
mp11::mp_identity,
|
||||
typename visit_set::states_to_traverse>;
|
||||
for (const int active_state_id : sm.m_active_state_ids)
|
||||
{
|
||||
self.dispatch(sm, state_id, visitor);
|
||||
mp11::mp_for_each<state_identities>(
|
||||
[&sm, &visitor, active_state_id](auto state_identity)
|
||||
{
|
||||
using State = typename decltype(state_identity)::type;
|
||||
constexpr int state_id =
|
||||
StateMachine::template get_state_id<State>();
|
||||
if (active_state_id == state_id)
|
||||
{
|
||||
accept<State>(sm, visitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bug: Clang 17 complains about private member if this method is private.
|
||||
private:
|
||||
template <typename State>
|
||||
static void accept(StateMachine& sm, Visitor& visitor)
|
||||
{
|
||||
@@ -353,46 +330,6 @@ class event_deferral_visitor
|
||||
submachine_visitor::visit(state, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
using state_set = typename StateMachine::internal::state_set;
|
||||
using cell_t = void (*)(StateMachine&, Visitor&);
|
||||
template <size_t index, cell_t cell>
|
||||
using init_cell_constant = init_cell_constant<index, cell_t, cell>;
|
||||
|
||||
template <typename State>
|
||||
using get_init_cell_constant = init_cell_constant<
|
||||
StateMachine::template get_state_id<State>(),
|
||||
&accept<State>>;
|
||||
|
||||
event_deferral_visitor()
|
||||
{
|
||||
using init_cell_constants = mp11::mp_transform<
|
||||
get_init_cell_constant,
|
||||
typename visit_set::states_to_traverse>;
|
||||
dispatch_table_initializer::execute(
|
||||
reinterpret_cast<generic_cell*>(m_cells),
|
||||
reinterpret_cast<const generic_init_cell_value*>(
|
||||
value_array<init_cell_constants>),
|
||||
mp11::mp_size<init_cell_constants>::value);
|
||||
}
|
||||
|
||||
void dispatch(StateMachine& sm, int state_id, Visitor& visitor) const
|
||||
{
|
||||
const cell_t& cell = m_cells[state_id];
|
||||
if (cell)
|
||||
{
|
||||
(*cell)(sm, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
static const event_deferral_visitor& instance()
|
||||
{
|
||||
static const event_deferral_visitor instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
cell_t m_cells[mp11::mp_size<state_set>::value]{};
|
||||
};
|
||||
|
||||
// Predefined visitor functors used in backmp11.
|
||||
@@ -499,12 +436,7 @@ class init_state_visitor
|
||||
{
|
||||
if constexpr (has_exit_pseudostate_be_tag<State>::value)
|
||||
{
|
||||
state.set_forward_fct(
|
||||
[&root_sm = m_root_sm](typename State::event const& event)
|
||||
{
|
||||
return root_sm.enqueue_event(event);
|
||||
}
|
||||
);
|
||||
state.template init<RootSm>();
|
||||
}
|
||||
|
||||
if constexpr (has_state_machine_tag<State>::value)
|
||||
|
||||
@@ -213,7 +213,7 @@ struct transition_table_impl
|
||||
if constexpr (has_exit_pseudostate_be_tag<Target>::value)
|
||||
{
|
||||
// Execute the second part of the compound transition.
|
||||
target.forward_event(event);
|
||||
target.forward_event(sm.m_root_sm, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_EVENT_TRAITS_H
|
||||
#define BOOST_MSM_BACKMP11_EVENT_TRAITS_H
|
||||
#ifndef BOOST_MSM_BACKMP11_EVENT_TRAITS_HPP
|
||||
#define BOOST_MSM_BACKMP11_EVENT_TRAITS_HPP
|
||||
|
||||
#include <boost/msm/kleene_event.hpp>
|
||||
#include <any>
|
||||
@@ -35,4 +35,4 @@ using std::any_cast;
|
||||
|
||||
} // boost::msm::backmp11
|
||||
|
||||
#endif //BOOST_MSM_EVENT_TRAITS_H
|
||||
#endif //BOOST_MSM_EVENT_TRAITS_HPP
|
||||
|
||||
@@ -9,17 +9,15 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_FAVOR_COMPILE_TIME_H
|
||||
#define BOOST_MSM_BACKMP11_FAVOR_COMPILE_TIME_H
|
||||
#ifndef BOOST_MSM_BACKMP11_FAVOR_COMPILE_TIME_HPP
|
||||
#define BOOST_MSM_BACKMP11_FAVOR_COMPILE_TIME_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <typeindex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/msm/front/completion_event.hpp>
|
||||
#include <boost/msm/backmp11/detail/metafunctions.hpp>
|
||||
#include <boost/msm/backmp11/detail/dispatch_table.hpp>
|
||||
#include <boost/msm/backmp11/detail/state_visitor.hpp>
|
||||
#include <boost/msm/backmp11/detail/transition_table.hpp>
|
||||
#include <boost/msm/backmp11/event_traits.hpp>
|
||||
@@ -39,7 +37,7 @@
|
||||
} \
|
||||
} // boost::msm::backmp11::detail
|
||||
|
||||
namespace boost { namespace msm { namespace backmp11
|
||||
namespace boost:: msm::backmp11
|
||||
{
|
||||
|
||||
struct favor_compile_time
|
||||
@@ -54,6 +52,9 @@ namespace detail
|
||||
template <>
|
||||
struct compile_policy_impl<favor_compile_time>
|
||||
{
|
||||
// Type-punned init cell value to suppress redundant template instantiations.
|
||||
using generic_cell = void(*)();
|
||||
|
||||
// GCC cannot recognize the parameter pack in the array's initializer.
|
||||
#if !defined(__GNUC__) || defined(__clang__)
|
||||
// Convert a list with integral constants of the same value_type to a value array
|
||||
@@ -80,11 +81,23 @@ struct compile_policy_impl<favor_compile_time>
|
||||
return event;
|
||||
}
|
||||
|
||||
template<typename Statemachine>
|
||||
static bool is_end_interrupt_event(Statemachine& sm, const any_event& event)
|
||||
template<typename StateMachine>
|
||||
static bool is_end_interrupt_event(const StateMachine& sm, const any_event& event)
|
||||
{
|
||||
static end_interrupt_event_helper helper{sm};
|
||||
return helper.is_end_interrupt_event(event);
|
||||
using event_set = generate_event_set<
|
||||
typename StateMachine::front_end_t::transition_table>;
|
||||
bool result{false};
|
||||
mp11::mp_for_each<mp11::mp_transform<mp11::mp_identity, event_set>>(
|
||||
[&sm, &event, &result](auto event_identity)
|
||||
{
|
||||
using Event = typename decltype(event_identity)::type;
|
||||
using Flag = EndInterruptFlag<Event>;
|
||||
if (event.type() == typeid(Event))
|
||||
{
|
||||
result = sm.template is_flag_active<Flag>();
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// Dispatch table for event deferral checks.
|
||||
@@ -185,39 +198,6 @@ struct compile_policy_impl<favor_compile_time>
|
||||
return std::type_index{typeid(Event)};
|
||||
}
|
||||
|
||||
// Helper class to manage end interrupt events.
|
||||
class end_interrupt_event_helper
|
||||
{
|
||||
public:
|
||||
template<class StateMachine>
|
||||
end_interrupt_event_helper(const StateMachine& sm)
|
||||
{
|
||||
using event_set = generate_event_set<
|
||||
typename StateMachine::front_end_t::transition_table>;
|
||||
mp11::mp_for_each<mp11::mp_transform<mp11::mp_identity, event_set>>(
|
||||
[this, &sm](auto event_identity)
|
||||
{
|
||||
using Event = typename decltype(event_identity)::type;
|
||||
using Flag = EndInterruptFlag<Event>;
|
||||
m_is_flag_active_functions[to_type_index<Event>()] =
|
||||
[&sm](){return sm.template is_flag_active<Flag>();};
|
||||
});
|
||||
}
|
||||
|
||||
bool is_end_interrupt_event(const any_event& event) const
|
||||
{
|
||||
auto it = m_is_flag_active_functions.find(event.type());
|
||||
if (it != m_is_flag_active_functions.end())
|
||||
{
|
||||
return (it->second)();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
using map = std::unordered_map<std::type_index, std::function<bool()>>;
|
||||
map m_is_flag_active_functions;
|
||||
};
|
||||
|
||||
// Class used to build a chain of transitions for a given event and state.
|
||||
// Allows transition conflicts.
|
||||
@@ -553,6 +533,6 @@ compile_policy_impl<favor_compile_time>::dispatch_table<StateMachine, any_event>
|
||||
#endif
|
||||
|
||||
} // detail
|
||||
}}} // boost::msm::backmp11
|
||||
} // boost::msm::backmp11
|
||||
|
||||
#endif //BOOST_MSM_BACKMP11_FAVOR_COMPILE_TIME_H
|
||||
#endif //BOOST_MSM_BACKMP11_FAVOR_COMPILE_TIME_HPP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,8 +9,8 @@
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MSM_BACKMP11_STATE_MACHINE_CONFIG_H
|
||||
#define BOOST_MSM_BACKMP11_STATE_MACHINE_CONFIG_H
|
||||
#ifndef BOOST_MSM_BACKMP11_STATE_MACHINE_CONFIG_HPP
|
||||
#define BOOST_MSM_BACKMP11_STATE_MACHINE_CONFIG_HPP
|
||||
|
||||
#include <deque>
|
||||
|
||||
@@ -102,4 +102,4 @@ struct function_pointer_array {};
|
||||
|
||||
} // namespace boost::msm::backmp11
|
||||
|
||||
#endif // BOOST_MSM_BACKMP11_STATE_MACHINE_CONFIG_H
|
||||
#endif // BOOST_MSM_BACKMP11_STATE_MACHINE_CONFIG_HPP
|
||||
|
||||
+2
-1
@@ -9,7 +9,8 @@
|
||||
"State"
|
||||
],
|
||||
"maintainers": [
|
||||
"Christophe Henry <christophe.j.henry -at- googlemail.com>"
|
||||
"Christophe Henry <christophe.j.henry -at- googlemail.com>",
|
||||
"Christian Granzin"
|
||||
],
|
||||
"cxxstd": "03"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user