mirror of
https://github.com/boostorg/msm.git
synced 2026-07-21 13:23:45 +00:00
feat(backmp11): simplified functor signatures
This commit is contained in:
committed by
Christian Granzin
parent
d0cf98bd39
commit
428cbad053
@@ -15,8 +15,8 @@ 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 | 209 | 29 | 0.7
|
||||
| backmp11_favor_compile_time | 3 | 193 | 43 | 6.0
|
||||
| backmp11 | 3 | 211 | 29 | 0.7
|
||||
| backmp11_favor_compile_time | 3 | 195 | 43 | 6.0
|
||||
| sml | 5 | 234 | 57 | 0.3
|
||||
|=======================================================================================================
|
||||
|
||||
@@ -28,8 +28,8 @@ 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 | 351 | 85 | 3.3
|
||||
| backmp11_favor_compile_time | 5 | 256 | 100 | 20.4
|
||||
| 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
|
||||
| sml | 18 | 543 | 422 | 5.4
|
||||
|================================================================================================================
|
||||
@@ -170,6 +170,10 @@ If the type of the state appears multiple times in a hierarchical state machine,
|
||||
// - if `start()` is called for a running state machine, the call is ignored
|
||||
// - if `stop()` is called on a stopped (not running) state machine, the call is ignored
|
||||
|
||||
=== Support for simplified functor signatures
|
||||
|
||||
Further described in xref:./functor-front-end.adoc#simplified_functor_signatures[the functor front-end documentation].
|
||||
|
||||
|
||||
=== Simplified state machine signature
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ Row < Paused , stop , Stopped , stop_playback , none
|
||||
Row < Paused , open_close , Open , stop_and_open , none >
|
||||
// +---------+------------+-----------+---------------------------+----------------------------+
|
||||
> {};
|
||||
|
||||
----
|
||||
|
||||
Transitions are now of type "Row" with exactly 5 template arguments:
|
||||
@@ -66,12 +65,12 @@ detected event, the state machine, source and target state:
|
||||
----
|
||||
struct store_cd_info
|
||||
{
|
||||
template <class Fsm,class Evt,class SourceState,class TargetState>
|
||||
void operator()(Evt const&, Fsm& fsm, SourceState&,TargetState& )
|
||||
template <class Event, class Fsm, class SourceState, class TargetState>
|
||||
void operator()(Event const&, Fsm& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
cout << "player::store_cd_info" << endl;
|
||||
fsm.process_event(play());
|
||||
}
|
||||
}
|
||||
};
|
||||
----
|
||||
|
||||
@@ -119,6 +118,88 @@ It even starts looking like functional programming. MSM ships with
|
||||
functors for operators, state machine usage, STL algorithms or container
|
||||
methods.
|
||||
|
||||
|
||||
== Using lambdas as functors ({cpp}20)
|
||||
|
||||
If {cpp}20 is available you can shorten the functor syntax by using lambdas as functors.
|
||||
The `store_cd_info` functor can be rewritten with a lambda as follows:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
using store_cd_info = msm::front::Lambda<
|
||||
[](auto const& /*event*/, auto& fsm, auto& /*source*/, auto& /*target*/)
|
||||
{
|
||||
cout << "player::store_cd_info" << endl;
|
||||
fsm.process_event(play());
|
||||
}>;
|
||||
----
|
||||
|
||||
[[simplified_functor_signatures]]
|
||||
== Simplified functor signatures (`backmp11` only)
|
||||
|
||||
The `backmp11` back-end allows you to use shorter functor signatures, reducing the boilerplate of action and guard functor definitions. It automatically detects how many parameters your functors have and invokes them with the appropriate arguments.
|
||||
|
||||
The following three signatures are supported:
|
||||
|
||||
**Full signature**
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
struct store_cd_info
|
||||
{
|
||||
template <class Event, class Fsm, class SourceState, class TargetState>
|
||||
void operator()(Event const&, Fsm& fsm, SourceState&, TargetState&)
|
||||
{
|
||||
cout << "player::store_cd_info" << endl;
|
||||
fsm.process_event(play());
|
||||
}
|
||||
};
|
||||
----
|
||||
|
||||
**Event and FSM only**
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
struct store_cd_info
|
||||
{
|
||||
template <class Event, class Fsm>
|
||||
void operator()(Event const&, Fsm& fsm)
|
||||
{
|
||||
cout << "player::store_cd_info" << endl;
|
||||
fsm.process_event(play());
|
||||
}
|
||||
};
|
||||
----
|
||||
|
||||
**FSM only**
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
struct store_cd_info
|
||||
{
|
||||
template <class Fsm>
|
||||
void operator()(Fsm& fsm)
|
||||
{
|
||||
cout << "player::store_cd_info" << endl;
|
||||
fsm.process_event(play());
|
||||
}
|
||||
};
|
||||
----
|
||||
|
||||
Simplified signatures are also supported with lambdas, providing a way to define
|
||||
functors with minimal boilerplate:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
using store_cd_info = msm::front::Lambda<
|
||||
[](auto& fsm)
|
||||
{
|
||||
cout << "player::store_cd_info" << endl;
|
||||
fsm.process_event(play());
|
||||
}>;
|
||||
----
|
||||
|
||||
|
||||
[[defining-states-with-entryexit-actions]]
|
||||
|
||||
== Defining states with entry/exit actions
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
* feat(backmp11): Small Object Optimization for events in the event pool (https://github.com/boostorg/msm/issues/172[#172])
|
||||
* feat(backmp11): Improve support for the `deferred_events` property in hierarchical state machines (https://github.com/boostorg/msm/issues/173[#173])
|
||||
* feat(backmp11): Improve runtime performance with a `flat_fold` dispatch strategy (https://github.com/boostorg/msm/issues/180[#180])
|
||||
* feat(backmp11): Simplified functor signatures (https://github.com/boostorg/msm/issues/175[#175])
|
||||
|
||||
== Boost 1.90
|
||||
|
||||
|
||||
@@ -18,9 +18,111 @@
|
||||
#include <boost/msm/backmp11/detail/metafunctions.hpp>
|
||||
#include "boost/msm/backmp11/state_machine_config.hpp"
|
||||
|
||||
namespace boost::msm::front
|
||||
{
|
||||
struct Defer;
|
||||
};
|
||||
|
||||
namespace boost::msm::backmp11::detail
|
||||
{
|
||||
|
||||
// Chain of priority tags for SFINAE handling:
|
||||
// priority_tag_0
|
||||
// ↓ (SFINAE fails?)
|
||||
// priority_tag_1 (base of priority_tag_0)
|
||||
// ↓ (SFINAE fails?)
|
||||
// priority_tag_2 (base of priority_tag_1)
|
||||
struct priority_tag_2 {};
|
||||
struct priority_tag_1 : priority_tag_2 {};
|
||||
struct priority_tag_0 : priority_tag_1 {};
|
||||
|
||||
template <typename Functor, typename Event, typename Fsm, typename Source,
|
||||
typename Target>
|
||||
auto invoke_functor(priority_tag_0, Functor&&, const Event& event, Fsm& fsm,
|
||||
Source& source, Target& target)
|
||||
-> decltype(Functor{}(event, fsm, source, target))
|
||||
{
|
||||
return Functor{}(event, fsm, source, target);
|
||||
}
|
||||
template <typename Functor, typename Event, typename Fsm, typename Source,
|
||||
typename Target>
|
||||
auto invoke_functor(priority_tag_1, Functor&&, const Event& event, Fsm& fsm, Source&,
|
||||
Target&) -> decltype(Functor{}(event, fsm))
|
||||
{
|
||||
return Functor{}(event, fsm);
|
||||
}
|
||||
template <typename Functor, typename Event, typename Fsm, typename Source,
|
||||
typename Target>
|
||||
auto invoke_functor(priority_tag_2, Functor&&, const Event&, Fsm& fsm, Source&,
|
||||
Target&) -> decltype(Functor{}(fsm))
|
||||
{
|
||||
return Functor{}(fsm);
|
||||
}
|
||||
|
||||
template <typename Row>
|
||||
using get_Guard = typename Row::Guard;
|
||||
template <typename Row>
|
||||
struct has_Guard : mp11::mp_valid<get_Guard, Row> {};
|
||||
|
||||
template <typename Functor>
|
||||
struct invoke_guard_functor
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
static bool execute(const Event& event, Fsm& fsm, Source& source,
|
||||
Target& target)
|
||||
{
|
||||
return invoke_functor<Functor>(priority_tag_0{}, Functor{}, event, fsm,
|
||||
source, target);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct invoke_guard_functor<front::none>
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
static bool execute(const Event&, Fsm&, Source&, Target&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Row>
|
||||
using get_Action = typename Row::Action;
|
||||
template <typename Row>
|
||||
struct has_Action : mp11::mp_valid<get_Action, Row> {};
|
||||
|
||||
template <typename Functor>
|
||||
struct invoke_action_functor
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
static process_result execute(const Event& event, Fsm& fsm, Source& source,
|
||||
Target& target)
|
||||
{
|
||||
invoke_functor<Functor>(priority_tag_0{}, Functor{}, event, fsm, source,
|
||||
target);
|
||||
return process_result::HANDLED_TRUE;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct invoke_action_functor<front::none>
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
static process_result execute(const Event&, Fsm&, Source&, Target&)
|
||||
{
|
||||
return process_result::HANDLED_TRUE;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct invoke_action_functor<front::Defer>
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
static process_result execute(const Event& event, Fsm& fsm, Source&,
|
||||
Target&)
|
||||
{
|
||||
fsm.defer_event(event);
|
||||
return process_result::HANDLED_DEFERRED;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename StateMachine>
|
||||
struct transition_table_impl
|
||||
{
|
||||
@@ -39,7 +141,12 @@ struct transition_table_impl
|
||||
static bool call_guard_or_true(StateMachine& sm, const Event& event,
|
||||
Source& source, Target& target)
|
||||
{
|
||||
if constexpr (HasGuard)
|
||||
if constexpr (has_Guard<Row>::value)
|
||||
{
|
||||
return invoke_guard_functor<typename Row::Guard>::execute(
|
||||
event, sm.get_fsm_argument(), source, target);
|
||||
}
|
||||
else if constexpr (HasGuard)
|
||||
{
|
||||
return Row::guard_call(
|
||||
sm.get_fsm_argument(), event, source, target, sm.m_states);
|
||||
@@ -49,13 +156,19 @@ struct transition_table_impl
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Row, bool HasAction, typename Event, typename Source,
|
||||
typename Target>
|
||||
static process_result call_action_or_true(StateMachine& sm,
|
||||
const Event& event,
|
||||
Source& source, Target& target)
|
||||
{
|
||||
if constexpr (HasAction)
|
||||
if constexpr (has_Action<Row>::value)
|
||||
{
|
||||
return invoke_action_functor<typename Row::Action>::execute(
|
||||
event, sm.get_fsm_argument(), source, target);
|
||||
}
|
||||
else if constexpr (HasAction)
|
||||
{
|
||||
return Row::action_call(
|
||||
sm.get_fsm_argument(), event, source, target, sm.m_states);
|
||||
|
||||
@@ -361,5 +361,12 @@ namespace boost { namespace msm { namespace front
|
||||
fsm.defer_event(evt);
|
||||
}
|
||||
};
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
// Wrapper to make a functor from a lambda.
|
||||
template <auto T>
|
||||
struct Lambda : decltype(T) {};
|
||||
#endif
|
||||
|
||||
}}}
|
||||
#endif //BOOST_MSM_FRONT_FUNCTOR_ROW_H
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
// Copyright 2026 Christian Granzin
|
||||
// Copyright 2024 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_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE backmp11_completion
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
// back-end
|
||||
#include "Backmp11.hpp"
|
||||
// #include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include "FrontCommon.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
using namespace boost::msm::front;
|
||||
using namespace boost::msm::backmp11;
|
||||
namespace mp11 = boost::mp11;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Events
|
||||
struct TriggerOnlyFsmActionLambda {};
|
||||
struct TriggerDefaultAction {};
|
||||
struct TriggerOnlyEventAndFsmAction {};
|
||||
struct TriggerOnlyFsmAction {};
|
||||
struct TriggerActionWithMultipleOverloads {};
|
||||
struct TriggerSpecificAction {};
|
||||
|
||||
// States
|
||||
struct State1 : test::StateBase
|
||||
{
|
||||
};
|
||||
struct State2 : test::StateBase
|
||||
{
|
||||
};
|
||||
|
||||
struct Machine_;
|
||||
|
||||
// Actions
|
||||
struct DefaultAction
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
void operator()(const Event&, Fsm&, Source&, Target&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerDefaultAction>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
calls += 1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t calls{};
|
||||
};
|
||||
struct OnlyEventAndFsmAction
|
||||
{
|
||||
template <typename Event, typename Fsm>
|
||||
void operator()(const Event&, Fsm&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerOnlyEventAndFsmAction>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
calls += 1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t calls{};
|
||||
};
|
||||
struct OnlyFsmAction
|
||||
{
|
||||
template <typename Fsm>
|
||||
void operator()(Fsm&)
|
||||
{
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
calls += 1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t calls{};
|
||||
};
|
||||
struct ActionWithMultipleOverloads : DefaultAction
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
void operator()(const Event&, Fsm&, Source&, Target&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerActionWithMultipleOverloads>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
default_calls += 1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t default_calls{};
|
||||
|
||||
// Overload constraint because caused by priority tags in this edge case:
|
||||
// A specific overload must use the highest used arity of the generic overloads.
|
||||
template <typename Fsm, typename Source, typename Target>
|
||||
void operator()(const TriggerSpecificAction&, Fsm&, Source&, Target&)
|
||||
{
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
specific_calls += 1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t specific_calls{};
|
||||
|
||||
template <typename Event, typename Fsm>
|
||||
void operator()(const Event&, Fsm&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerActionWithMultipleOverloads>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
only_event_and_fsm_calls += 1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t only_event_and_fsm_calls{};
|
||||
|
||||
template <typename Fsm>
|
||||
void operator()(Fsm&)
|
||||
{
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
only_fsm_calls += 1;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t only_fsm_calls{};
|
||||
};
|
||||
|
||||
// Lambda support for shorter syntax (requires C++20).
|
||||
#if __cplusplus >= 202002L
|
||||
using OnlyFsmActionLambda = Lambda<[](auto& fsm) {
|
||||
using Fsm = std::decay_t<decltype(fsm)>;
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
}>;
|
||||
#endif
|
||||
|
||||
// Guards
|
||||
struct DefaultGuard
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
bool operator()(const Event&, Fsm&, Source&, Target&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerDefaultAction>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
calls += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t calls{};
|
||||
};
|
||||
struct OnlyEventAndFsmGuard
|
||||
{
|
||||
template <typename Event, typename Fsm>
|
||||
bool operator()(const Event&, Fsm&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerOnlyEventAndFsmAction>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
calls += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t calls{};
|
||||
};
|
||||
struct OnlyFsmGuard
|
||||
{
|
||||
template <typename Fsm>
|
||||
bool operator()(Fsm&)
|
||||
{
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
calls += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t calls{};
|
||||
};
|
||||
struct GuardWithMultipleOverloads
|
||||
{
|
||||
template <typename Event, typename Fsm, typename Source, typename Target>
|
||||
bool operator()(const Event&, Fsm&, Source&, Target&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerActionWithMultipleOverloads>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
default_calls += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t default_calls{};
|
||||
|
||||
// Overload constraint because caused by priority tags in this edge case:
|
||||
// A specific overload must use the highest used arity of the generic overloads.
|
||||
template <typename Fsm, typename Source, typename Target>
|
||||
bool operator()(const TriggerSpecificAction&, Fsm&, Source&, Target&)
|
||||
{
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
specific_calls += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t specific_calls{};
|
||||
|
||||
template <typename Event, typename Fsm>
|
||||
bool operator()(const Event&, Fsm&)
|
||||
{
|
||||
static_assert(std::is_same_v<Event, TriggerActionWithMultipleOverloads>);
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
only_event_and_fsm_calls += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t only_event_and_fsm_calls{};
|
||||
|
||||
template <typename Fsm>
|
||||
bool operator()(Fsm&)
|
||||
{
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
only_fsm_calls += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static inline size_t only_fsm_calls{};
|
||||
};
|
||||
// Lambda support for shorter syntax (requires C++20).
|
||||
#if __cplusplus >= 202002L
|
||||
using OnlyFsmGuardLambda = Lambda<[](auto& fsm) {
|
||||
using Fsm = std::decay_t<decltype(fsm)>;
|
||||
static_assert(std::is_base_of_v<Machine_, Fsm>);
|
||||
return true;
|
||||
}>;
|
||||
#endif
|
||||
|
||||
struct Machine_ : test::StateMachineBase_<Machine_>
|
||||
{
|
||||
using initial_state = State1;
|
||||
|
||||
using transition_table = mp11::mp_list<
|
||||
// Start Event Next Action Guard
|
||||
#if __cplusplus >= 202002L
|
||||
Row < State1, TriggerOnlyFsmActionLambda , none, OnlyFsmActionLambda , OnlyFsmGuardLambda >,
|
||||
#endif
|
||||
Row < State1, TriggerDefaultAction , none, DefaultAction , DefaultGuard >,
|
||||
Row < State1, TriggerOnlyEventAndFsmAction , none, OnlyEventAndFsmAction , OnlyEventAndFsmGuard >,
|
||||
Row < State1, TriggerOnlyFsmAction , none, OnlyFsmAction , OnlyFsmGuard >,
|
||||
Row < State1, TriggerActionWithMultipleOverloads, none, ActionWithMultipleOverloads, GuardWithMultipleOverloads >,
|
||||
Row < State1, TriggerSpecificAction , none, ActionWithMultipleOverloads, GuardWithMultipleOverloads >
|
||||
>;
|
||||
};
|
||||
|
||||
// Pick a back-end
|
||||
using TestMachines = mp11::mp_list<
|
||||
#ifndef BOOST_MSM_TEST_SKIP_BACKMP11
|
||||
state_machine<Machine_>,
|
||||
state_machine<Machine_, favor_compile_time_config>
|
||||
#endif // BOOST_MSM_TEST_SKIP_BACKMP11
|
||||
>;
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test, TestMachine, TestMachines)
|
||||
{
|
||||
TestMachine state_machine;
|
||||
|
||||
state_machine.start();
|
||||
|
||||
state_machine.process_event(TriggerDefaultAction());
|
||||
ASSERT_ONE_AND_RESET(DefaultAction::calls);
|
||||
ASSERT_ONE_AND_RESET(DefaultGuard::calls);
|
||||
|
||||
state_machine.process_event(TriggerOnlyEventAndFsmAction());
|
||||
ASSERT_ONE_AND_RESET(OnlyEventAndFsmAction::calls);
|
||||
ASSERT_ONE_AND_RESET(OnlyEventAndFsmGuard::calls);
|
||||
|
||||
state_machine.process_event(TriggerOnlyFsmAction());
|
||||
ASSERT_ONE_AND_RESET(OnlyFsmAction::calls);
|
||||
ASSERT_ONE_AND_RESET(OnlyFsmGuard::calls);
|
||||
|
||||
state_machine.process_event(TriggerActionWithMultipleOverloads());
|
||||
ASSERT_ONE_AND_RESET(ActionWithMultipleOverloads::default_calls);
|
||||
ASSERT_ONE_AND_RESET(GuardWithMultipleOverloads::default_calls);
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
state_machine.process_event(TriggerOnlyFsmActionLambda());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -78,6 +78,7 @@ add_executable(boost_msm_cxx17_tests
|
||||
Backmp11Context.cpp
|
||||
Backmp11Deferred.cpp
|
||||
Backmp11EntryExit.cpp
|
||||
Backmp11FunctorApi.cpp
|
||||
Backmp11ManyDeferTransitions.cpp
|
||||
Backmp11RootSm.cpp
|
||||
Backmp11Transitions.cpp
|
||||
|
||||
@@ -81,6 +81,7 @@ test-suite msm-unit-tests-cxxstd17
|
||||
[ run Backmp11Constructor.cpp ]
|
||||
[ run Backmp11Context.cpp ]
|
||||
[ run Backmp11Deferred.cpp ]
|
||||
[ run Backmp11FunctorApi.cpp ]
|
||||
[ run Backmp11EntryExit.cpp ]
|
||||
[ run Backmp11ManyDeferTransitions.cpp ]
|
||||
[ run Backmp11RootSm.cpp ]
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// back-end
|
||||
// Backmp11 does not support custom Defer actions.
|
||||
#define BOOST_MSM_TEST_SKIP_BACKMP11
|
||||
#include "BackCommon.hpp"
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
|
||||
Reference in New Issue
Block a user