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
10 changes: 5 additions & 5 deletions doc/modules/ROOT/pages/tutorial/backmp11-back-end.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ It offers a significant reduction in compilation time and RAM usage, as can be s
| back | 18 | 953 | 7
| back_favor_compile_time | 21 | 1000 | 8
| back11 | 43 | 2794 | 7
| backmp11 | 3 | 239 | 3
| backmp11_favor_compile_time | 3 | 220 | 13
| backmp11 | 3 | 229 | 3
| backmp11_favor_compile_time | 3 | 220 | 8
| sml | 12 | 363 | 3
|=======================================================================

Expand All @@ -34,9 +34,9 @@ It offers a significant reduction in compilation time and RAM usage, as can be s
| | Compile / sec | RAM / MB | Runtime / sec
| back | 68 | 2849 | 23
| back_favor_compile_time | 80 | 2551 | 261
| backmp11 | 11 | 472 | 10
| backmp11_favor_compile_time | 7 | 288 | 40
| backmp11_favor_compile_time_multi_cu | 5 | ~919 | 40
| backmp11 | 10 | 438 | 11
| backmp11_favor_compile_time | 7 | 288 | 26
| backmp11_favor_compile_time_multi_cu | 5 | ~919 | 26
| sml | 48 | 1128 | 11
|================================================================================

Expand Down
89 changes: 86 additions & 3 deletions include/boost/msm/backmp11/common_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <any>
#include <boost/msm/back/common_types.hpp>
#include <cstddef>

namespace boost { namespace msm { namespace backmp11
{
Expand All @@ -23,8 +24,7 @@ using process_result = back::HandledEnum;
using any_event = std::any;

// Selector for the visit mode.
// Can be active_states or all_states in recursive
// or non-recursive mode.
// Can be active_states or all_states in recursive or non-recursive mode.
enum class visit_mode
{
// State selection (mutually exclusive).
Expand All @@ -51,6 +51,39 @@ constexpr visit_mode operator|(visit_mode lhs, visit_mode rhs)
namespace detail
{

class enqueued_event
{
public:
virtual ~enqueued_event() = default;

// Process the event.
virtual process_result process() = 0;
};

class deferred_event
{
public:
virtual ~deferred_event() = default;

// Process the event.
virtual process_result process() = 0;

// Report whether the event is currently deferred.
virtual bool is_deferred() const = 0;

// Get the sequence counter of the event.
size_t get_seq_cnt() const
{
return m_seq_cnt;
}

protected:
deferred_event(size_t seq_cnt) : m_seq_cnt(seq_cnt) {}

private:
size_t m_seq_cnt;
};

using EventSource = back::EventSourceEnum;
using back::HandledEnum;

Expand All @@ -62,7 +95,57 @@ constexpr EventSource operator|(EventSource lhs, EventSource rhs)
);
}

}
// Minimal implementation of a unique_ptr.
// Used to keep header dependencies to a minimum
// (from C++20 the memory header includes ostream).
template <typename T>
class basic_unique_ptr
{
public:
explicit basic_unique_ptr(T* ptr) : m_ptr(ptr)
{
}

~basic_unique_ptr()
{
delete m_ptr;
}

basic_unique_ptr(const basic_unique_ptr&) = delete;
basic_unique_ptr& operator=(const basic_unique_ptr&) = delete;

basic_unique_ptr(basic_unique_ptr&& other) : m_ptr(other.m_ptr)
{
other.m_ptr = nullptr;
}

basic_unique_ptr& operator=(basic_unique_ptr&& other)
{
delete m_ptr;
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
}

T* get() const
{
return m_ptr;
}

T& operator*() const
{
return *m_ptr;
}

T* operator->() const
{
return m_ptr;
}

private:
T* m_ptr;
};

} // namespace detail

}}} // namespace boost::msm::backmp11

Expand Down
99 changes: 61 additions & 38 deletions include/boost/msm/backmp11/detail/favor_runtime_speed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_MSM_BACKMP11_FAVOR_RUNTIME_SPEED_H
#define BOOST_MSM_BACKMP11_FAVOR_RUNTIME_SPEED_H
#ifndef BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_H
#define BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_H

#include <boost/msm/backmp11/detail/metafunctions.hpp>
#include <boost/msm/backmp11/detail/dispatch_table.hpp>
Expand Down Expand Up @@ -62,22 +62,65 @@ struct compile_policy_impl<favor_runtime_speed>
return sm.process_event_internal_impl(event, source);
}

template <typename Event, typename StateMachine>
static bool is_event_deferred(StateMachine& sm)
template <typename StateMachine, typename Event>
class deferred_event_impl : public deferred_event
{
bool result = false;
auto visitor = [&result](auto& state)
public:
deferred_event_impl(StateMachine& sm, const Event& event, size_t seq_cnt)
: deferred_event(seq_cnt), m_sm(sm), m_event(event)
{
using State = std::decay_t<decltype(state)>;
result |= has_state_deferred_event<State, Event>::value;
};
sm.template visit<visit_mode::active_non_recursive>(visitor);
return result;
}
}

process_result process() override
{
return process_event_internal(
m_sm,
m_event,
EventSource::EVENT_SOURCE_DEFERRED);
}

bool is_deferred() const override
{
return is_event_deferred(m_sm, m_event);
}

private:
StateMachine& m_sm;
Event m_event;
};

template <class State, class Event>
using has_deferred_event = mp11::mp_contains<
to_mp_list_t<typename State::deferred_events>,
Event
>;

template <typename StateMachine, typename Event>
static bool is_event_deferred(StateMachine& sm, const Event&)
class is_event_deferred_helper
{
return is_event_deferred<Event>(sm);
public:
static bool execute(const StateMachine& sm)
{
bool result = false;
auto visitor = [&result](const auto& /*state*/)
{
result = true;
};
sm.template visit_if<defers_event,
visit_mode::active_non_recursive>(visitor);
return result;
}

private:
template <typename State>
using defers_event = has_deferred_event<State, Event>;
};

template <typename StateMachine, typename Event>
static bool is_event_deferred(const StateMachine& sm, const Event&)
{
using helper = is_event_deferred_helper<StateMachine, Event>;
return helper::execute(sm);
}

template <typename StateMachine, typename Event>
Expand Down Expand Up @@ -117,22 +160,9 @@ struct compile_policy_impl<favor_runtime_speed>
static void do_defer_event(StateMachine& sm, const Event& event)
{
auto& deferred_events = sm.get_deferred_events();
deferred_events.queue.push_back(
{
[&sm, event]()
{
return process_event_internal(
sm,
event,
EventSource::EVENT_SOURCE_DEFERRED);
},
[&sm]()
{
return is_event_deferred<Event>(sm);
},
deferred_events.cur_seq_cnt
}
);
deferred_events.queue.push_back(basic_unique_ptr<deferred_event>{
new deferred_event_impl<StateMachine, Event>(
sm, event, deferred_events.cur_seq_cnt)});
}

struct cell_initializer
Expand All @@ -147,13 +177,6 @@ struct compile_policy_impl<favor_runtime_speed>
}
};

// returns a mp11::mp_bool<true> if State has Event as deferred event
template <class State, class Event>
using has_state_deferred_event = mp11::mp_contains<
to_mp_list_t<typename State::deferred_events>,
Event
>;

template<typename Fsm, typename State>
struct table_index
{
Expand Down Expand Up @@ -483,4 +506,4 @@ struct compile_policy_impl<favor_runtime_speed>
}}} // boost::msm::backmp11


#endif //BOOST_MSM_BACKMP11_FAVOR_RUNTIME_SPEED_H
#endif // BOOST_MSM_BACKMP11_DETAIL_FAVOR_RUNTIME_SPEED_H
8 changes: 7 additions & 1 deletion include/boost/msm/backmp11/detail/metafunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,16 @@ struct get_event_id
};

template <class State>
using has_state_deferred_events = mp11::mp_not<
using has_deferred_events = mp11::mp_not<
mp11::mp_empty<to_mp_list_t<typename State::deferred_events>>
>;

template <class State, class Event>
using has_deferred_event = mp11::mp_contains<
to_mp_list_t<typename State::deferred_events>,
Event
>;

// Template used to create dummy entries for initial states not found in the stt.
template< typename T1 >
struct not_a_row
Expand Down
51 changes: 40 additions & 11 deletions include/boost/msm/backmp11/detail/state_visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ struct copy_if_impl<List, always_true>
template<typename List, template <typename> typename Predicate>
using copy_if = typename copy_if_impl<List, Predicate>::type;

template<typename StateMachine, template <typename> typename Predicate>
using state_subset = copy_if<typename StateMachine::internal::state_set, Predicate>;

// State visitor implementation.
// States to visit can be selected with VisitMode
// and additionally be compile-time filtered with a predicate.
// and additionally compile-time filtered with Predicate.
template <
typename StateMachine,
typename Visitor,
Expand All @@ -49,16 +52,19 @@ template <
template <typename> typename Predicate>
class state_visitor<
StateMachine,
Visitor, Mode,
Visitor,
Mode,
Predicate,
std::enable_if_t<has_flag(Mode, visit_mode::active_states)>>
std::enable_if_t<
has_flag(Mode, visit_mode::active_states) &&
mp11::mp_not<mp11::mp_empty<state_subset<StateMachine, Predicate>>>::value>>
{
using state_set = typename StateMachine::internal::state_set;
using state_subset = copy_if<state_set, Predicate>;
using state_identities = mp11::mp_transform<mp11::mp_identity, state_subset>;
public:
state_visitor()
{
using state_identities =
mp11::mp_transform<mp11::mp_identity,
state_subset<StateMachine, Predicate>>;
mp11::mp_for_each<state_identities>(
[this](auto state_identity)
{
Expand All @@ -81,6 +87,7 @@ class state_visitor<
}

private:
using state_set = typename StateMachine::internal::state_set;
using cell_t = void (*)(StateMachine&, Visitor);

template<typename State>
Expand Down Expand Up @@ -121,16 +128,19 @@ template <
template <typename> typename Predicate>
class state_visitor<
StateMachine,
Visitor, Mode,
Visitor,
Mode,
Predicate,
std::enable_if_t<has_flag(Mode, visit_mode::all_states)>>
std::enable_if_t<
has_flag(Mode, visit_mode::all_states) &&
mp11::mp_not<mp11::mp_empty<state_subset<StateMachine, Predicate>>>::value>>
{
using state_set = typename StateMachine::internal::state_set;
using state_subset = copy_if<state_set, Predicate>;
using state_identities = mp11::mp_transform<mp11::mp_identity, state_subset>;
public:
static void visit(StateMachine& sm, Visitor visitor)
{
using state_identities =
mp11::mp_transform<mp11::mp_identity,
state_subset<StateMachine, Predicate>>;
mp11::mp_for_each<state_identities>(
[&sm, &visitor](auto state_identity)
{
Expand All @@ -148,6 +158,25 @@ class state_visitor<
}
};

template <
typename StateMachine,
typename Visitor,
visit_mode Mode,
template <typename> typename Predicate>
class state_visitor<
StateMachine,
Visitor,
Mode,
Predicate,
std::enable_if_t<
mp11::mp_empty<state_subset<StateMachine, Predicate>>::value>>
{
public:
static constexpr void visit(StateMachine&, Visitor)
{
}
};

} // boost::msm::backmp11::detail

#endif // BOOST_MSM_BACKMP11_DETAIL_STATE_VISITOR_HPP
Loading