remove eUML support in backmp11

This commit is contained in:
Christian Granzin
2025-09-28 10:55:33 -04:00
parent 819eb44a3f
commit be1295e4b9
14 changed files with 348 additions and 92 deletions
+24
View File
@@ -20,6 +20,30 @@ It is named after the metaprogramming library Boost Mp11, the main contributor t
- If the SM was stopped, the last active state(s) were visited
## New features
## Resolved limitations
## Breaking changes
### The targeted minimum C++ version is C++17
C++11 brings the strongly needed variadic template support for MSM, but later C++ versions provide other important features - for example C++17's `if constexpr`.
### The eUML frontend is not supported
The support of EUML induces longer compilation times by the need to include the Boost proto headers and applying C++03 variadic template emulation. If you want to use a UML-like syntax, please try out the new PUML frontend.
### The backend's constructor does not allow initialization of states and `set_states` is not available
There were some caveats with one constructor that was used for different use cases: On the one hand some arguments were immediately forwarded to the frontend's constructor, on the other hand the stream operator was used to identify other arguments in the constructor as states, to copy them into the state machine. Besides the syntax of the later being rather unusual, when doing both at once the syntax becomes too difficult to understand; even more so if states within hierarchical sub state machines were initialized in this fashion.
In order to keep API of the constructor simpler and less ambiguous, it only supports forwarding arguments to the frontend and no more.
Also the `set_states` API is removed. If setting a state is required, this can still be done (in a little more verbose, but also more direct & explicit fashion) by getting a reference to the desired state via `get_state` and then assigning the desired new state to it.
## How to use it
The backend and both its policies `favor_runtime_speed` and `favor_compile_time` should be compatible with existing code. Required replacements to try it out:
+6 -64
View File
@@ -57,9 +57,7 @@
#include <boost/msm/active_state_switching_policies.hpp>
#include <boost/msm/row_tags.hpp>
#include <boost/msm/msm_grammar.hpp>
#include <boost/msm/back/traits.hpp>
#include <boost/msm/back/fold_to_list.hpp>
#include <boost/msm/backmp11/favor_compile_time.hpp>
#include <boost/msm/backmp11/metafunctions.hpp>
#include <boost/msm/backmp11/history_policies.hpp>
@@ -73,7 +71,6 @@ namespace boost { namespace msm { namespace backmp11
using back::no_fsm_check;
using back::queue_container_deque;
using back::FoldToList;
// event used internally for wrapping a direct entry
@@ -111,17 +108,6 @@ typedef ::boost::parameter::parameters<
>
> state_machine_signature;
// just here to disable use of proto when not needed
template <class T, class F,class Enable=void>
struct make_euml_terminal;
template <class T,class F>
struct make_euml_terminal<T,F,typename ::boost::disable_if<has_using_declared_table<F> >::type>
{};
template <class T,class F>
struct make_euml_terminal<T,F,typename ::boost::enable_if<has_using_declared_table<F> >::type>
: public proto::extends<typename proto::terminal< boost::msm::state_tag>::type, T, boost::msm::state_domain>
{};
// library-containing class for state machines. Pass the actual FSM class as
// the Concrete parameter.
// A0=Derived,A1=NoHistory,A2=CompilePolicy,A3=FsmCheckPolicy >
@@ -136,11 +122,6 @@ class state_machine : //public Derived
public ::boost::parameter::binding<
typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, tag::front_end
>::type
, public make_euml_terminal<state_machine<A0,A1,A2,A3,A4>,
typename ::boost::parameter::binding<
typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, tag::front_end
>::type
>
{
public:
// Create ArgumentPack
@@ -1577,27 +1558,13 @@ public:
int* const m_initial_states;
int m_index;
};
public:
struct update_state
{
update_state(substate_list& to_overwrite_):to_overwrite(&to_overwrite_){}
template<typename StateType>
void operator()(StateType const& astate) const
{
std::get<get_state_id<stt, StateType>::value>(*to_overwrite)=astate;
}
substate_list* to_overwrite;
};
template <class Expr>
void set_states(Expr const& expr)
{
::boost::fusion::for_each(
::boost::fusion::as_vector(FoldToList()(expr, boost::fusion::nil_())),update_state(this->m_substate_list));
}
// Construct with the default initial states
state_machine()
: Derived()
public:
// Construct with the default initial states and forward constructor arguments to the frontend.
template <typename... Args>
state_machine(Args&&... args)
: Derived(std::forward<Args>(args)...)
{
// initialize our list of states with the ones defined in Derived::initial_state
::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
@@ -1607,31 +1574,6 @@ public:
fill_states(this);
}
// Construct with the default initial states and some default argument(s)
template <class ARG0,class... ARG,class=typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type>
state_machine(ARG0&& t0,ARG&&... t)
: Derived(std::forward<ARG0>(t0), std::forward<ARG>(t)...)
{
::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
(init_states(m_states));
m_history.set_initial_states(m_states);
fill_states(this);
}
template <class Expr,class... ARG,class=typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type>
state_machine(Expr const& expr,ARG&&... t)
: Derived(std::forward<ARG>(t)...)
{
BOOST_MPL_ASSERT_MSG(
( ::boost::proto::matches<Expr, FoldToList>::value),
THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
(FoldToList));
::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
(init_states(m_states));
m_history.set_initial_states(m_states);
set_states(expr);
fill_states(this);
}
// assignment operator using the copy policy to decide if non_copyable, shallow or deep copying is necessary
library_sm& operator= (library_sm const& rhs)
{
+2 -3
View File
@@ -9,6 +9,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
// back-end
// EUML is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
#include <boost/msm/front/euml/euml.hpp>
@@ -163,6 +165,3 @@ namespace
}
}
using backmp11_fsm = boost::msm::backmp11::state_machine<my_machine_, boost::msm::backmp11::favor_compile_time>;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_fsm);
+4
View File
@@ -19,8 +19,10 @@ template<typename Front>
using get_test_machines = boost::mpl::vector<
boost::msm::back::state_machine<Front>,
boost::msm::back::state_machine<Front, boost::msm::back::favor_compile_time>,
#if !defined(BOOST_MSM_TEST_SKIP_BACKMP11)
boost::msm::backmp11::state_machine<Front>,
boost::msm::backmp11::state_machine<Front, boost::msm::backmp11::favor_compile_time>,
#endif // BOOST_MSM_TEST_SKIP_BACKMP11
boost::msm::back11::state_machine<Front>
>;
@@ -28,8 +30,10 @@ template <template <template <typename...> class, typename = void> class hierarc
using get_hierarchical_test_machines = boost::mpl::vector<
hierarchical<boost::msm::back::state_machine>,
hierarchical<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
#if !defined(BOOST_MSM_TEST_SKIP_BACKMP11)
hierarchical<boost::msm::backmp11::state_machine>,
hierarchical<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>,
#endif // BOOST_MSM_TEST_SKIP_BACKMP11
hierarchical<boost::msm::back11::state_machine>
>;
+296
View File
@@ -0,0 +1,296 @@
// Copyright 2025 Christian Granzin
// Copyright 2010 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)
// back-end
#include "BackCommon.hpp"
//front-end
#include <boost/msm/front/state_machine_def.hpp>
#ifndef BOOST_MSM_NONSTANDALONE_TEST
#define BOOST_TEST_MODULE test_constructor
#endif
#include <boost/test/unit_test.hpp>
#include <boost/config.hpp>
namespace msm = boost::msm;
namespace mpl = boost::mpl;
namespace
{
struct SomeExternalContext
{
SomeExternalContext(int b):bla(b){}
int bla;
};
// events
struct play {};
struct end_pause {};
struct stop {};
struct pause {};
struct open_close {};
struct NextSong {};
struct PreviousSong {};
// A "complicated" event type that carries some data.
enum DiskTypeEnum
{
DISK_CD=0,
DISK_DVD=1
};
struct cd_detected
{
cd_detected(std::string name, DiskTypeEnum diskType)
: name(name),
disc_type(diskType)
{}
std::string name;
DiskTypeEnum disc_type;
};
template<template <typename...> class Back, typename Policy = void>
struct hierarchical_state_machine
{
// front-end: define the FSM structure
struct player_ : public msm::front::state_machine_def<player_>
{
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(player_)
player_(SomeExternalContext& context,int someint)
:context_(context)
{
BOOST_CHECK_MESSAGE(context_.bla == 3,"Wrong context value");
BOOST_CHECK_MESSAGE(someint == 5,"Wrong int value");
context.bla = 10;
}
SomeExternalContext& context_;
// The list of FSM states
struct Empty : public msm::front::state<>
{
int data_;
Empty():data_(0){}
Empty(int i):data_(i){}
// every (optional) entry/exit methods get the event passed.
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) {std::cout << "entering: Empty" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Empty" << std::endl;}
};
struct Open : public msm::front::state<>
{
int data_;
Open():data_(0){}
Open(int i):data_(i){}
template <class Event,class FSM>
void on_entry(Event const& ,FSM&) {std::cout << "entering: Open" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Open" << std::endl;}
};
// sm_ptr still supported but deprecated as functors are a much better way to do the same thing
struct Stopped : public msm::front::state<msm::front::default_base_state,msm::front::sm_ptr>
{
template <class Event,class FSM>
void on_entry(Event const& ,FSM&) {std::cout << "entering: Stopped" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Stopped" << std::endl;}
void set_sm_ptr(player_* pl)
{
m_player=pl;
}
player_* m_player;
};
struct Playing_ : public msm::front::state_machine_def<Playing_>
{
BOOST_MSM_TEST_DEFINE_DEPENDENT_TEMPLATES(Playing_)
// when playing, the CD is loaded and we are in either pause or playing (duh)
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) {std::cout << "entering: Playing" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Playing" << std::endl;}
// The list of FSM states
struct Song1 : public msm::front::state<>
{
int data_;
Song1():data_(0){}
Song1(int i):data_(i){}
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) {std::cout << "starting: First song" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "finishing: First Song" << std::endl;}
};
struct Song2 : public msm::front::state<>
{
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) {std::cout << "starting: Second song" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "finishing: Second Song" << std::endl;}
};
struct Song3 : public msm::front::state<>
{
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) {std::cout << "starting: Third song" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "finishing: Third Song" << std::endl;}
};
// the initial state. Must be defined
typedef Song1 initial_state;
// transition actions
void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
// guard conditions
typedef Playing_ pl; // makes transition table cleaner
// Transition table for Playing
struct transition_table : mpl::vector4<
// Start Event Next Action Guard
// +---------+-------------+---------+---------------------+----------------------+
a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
// +---------+-------------+---------+---------------------+----------------------+
> {};
// Replaces the default no-transition response.
template <class FSM,class Event>
void no_transition(Event const& e, FSM&,int state)
{
std::cout << "no transition from state " << state
<< " on event " << typeid(e).name() << std::endl;
}
};
// back-end
typedef Back<Playing_, Policy> Playing;
// state not defining any entry or exit
struct Paused : public msm::front::state<>
{
};
// the initial state of the player SM. Must be defined
typedef Empty initial_state;
// transition actions
void start_playback(play const&) { std::cout << "player::start_playback\n"; }
void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
void store_cd_info(cd_detected const&) { std::cout << "player::store_cd_info\n"; }
void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
// guard conditions
bool good_disk_format(cd_detected const& evt)
{
// to test a guard condition, let's say we understand only CDs, not DVD
if (evt.disc_type != DISK_CD)
{
std::cout << "wrong disk, sorry" << std::endl;
return false;
}
return true;
}
// used to show a transition conflict. This guard will simply deactivate one transition and thus
// solve the conflict
bool auto_start(cd_detected const&)
{
return false;
}
typedef player_ p; // makes transition table cleaner
// Transition table for player
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +---------+-------------+---------+---------------------+----------------------+
a_row < Stopped , play , Playing , &p::start_playback >,
a_row < Stopped , open_close , Open , &p::open_drawer >,
_row < Stopped , stop , Stopped >,
// +---------+-------------+---------+---------------------+----------------------+
a_row < Open , open_close , Empty , &p::close_drawer >,
// +---------+-------------+---------+---------------------+----------------------+
a_row < Empty , open_close , Open , &p::open_drawer >,
row < Empty , cd_detected , Stopped , &p::store_cd_info ,&p::good_disk_format >,
row < Empty , cd_detected , Playing , &p::store_cd_info ,&p::auto_start >,
// +---------+-------------+---------+---------------------+----------------------+
a_row < Playing , stop , Stopped , &p::stop_playback >,
a_row < Playing , pause , Paused , &p::pause_playback >,
a_row < Playing , open_close , Open , &p::stop_and_open >,
// +---------+-------------+---------+---------------------+----------------------+
a_row < Paused , end_pause , Playing , &p::resume_playback >,
a_row < Paused , stop , Stopped , &p::stop_playback >,
a_row < Paused , open_close , Open , &p::stop_and_open >
// +---------+-------------+---------+---------------------+----------------------+
> {};
// Replaces the default no-transition response.
template <class FSM,class Event>
void no_transition(Event const& , FSM&,int)
{
BOOST_FAIL("no_transition called!");
}
};
typedef Back<player_, Policy> player;
};
// Pick a back-end
typedef boost::mpl::vector<
hierarchical_state_machine<boost::msm::backmp11::state_machine>,
hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>
> test_machines;
BOOST_AUTO_TEST_CASE_TEMPLATE( test_constructor, test_machine, test_machines )
{
typedef typename test_machine::player player;
typedef typename test_machine::player_ player_;
SomeExternalContext ctx(3);
player p1(ctx, 5);
BOOST_CHECK_MESSAGE(p1.context_.bla == 10,"Wrong returned context value");
p1.template get_state<typename player_::Empty&>() = typename player_::Empty(1);
BOOST_CHECK_MESSAGE(p1.template get_state<typename player_::Empty&>().data_ == 1,"Wrong Empty value");
p1.template get_state<typename player_::Empty&>() = typename player_::Empty(5);
BOOST_CHECK_MESSAGE(p1.template get_state<typename player_::Empty&>().data_ == 5,"Wrong Empty value");
p1.template get_state<typename player_::Empty&>() = typename player_::Empty(7);
p1.template get_state<typename player_::Open&>() = typename player_::Open(2);
BOOST_CHECK_MESSAGE(p1.template get_state<typename player_::Empty&>().data_ == 7,"Wrong Empty value");
BOOST_CHECK_MESSAGE(p1.template get_state<typename player_::Open&>().data_ == 2,"Wrong Open value");
#if defined(BOOST_MSVC) && BOOST_MSVC >= 1910 && BOOST_MSVC < 1930
// error C2440: '<function-style-cast>': cannot convert from 'const boost::msm::msm_terminal<Expr>' to '`anonymous-namespace'::player_::Playing'
#elif defined(BOOST_CLANG_VERSION) && BOOST_CLANG_VERSION >= 160000 && BOOST_CLANG_VERSION < 170000
// error: ambiguous conversion for functional-style cast from 'const typename boost::proto::detail::enable_binary<deduce_domain, deduce_domain::proto_grammar, boost::mpl::or_<is_extension<const define_states_creation<is_proto_expr> &>, is_extension<Song1>>, boost::proto::tag::shift_left, const define_states_creation<> &, const Song1 &>::type'
#else
ctx.bla = 3;
player p(ctx, 5);
p.template get_state<typename player_::Empty&>() = typename player_::Empty(1);
p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing_::Song1&>() = typename player_::Playing_::Song1(8);
BOOST_CHECK_MESSAGE(p.template get_state<typename player_::Playing&>().template get_state<typename player_::Playing_::Song1&>().data_ == 8,"Wrong Open value");
#endif
}
}
+2 -5
View File
@@ -8,6 +8,8 @@
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// EUML is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
#include <boost/msm/front/euml/euml.hpp>
@@ -289,8 +291,3 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Playing_type;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_0);
using backmp11_1 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::Playing_type;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_1);
+1
View File
@@ -35,6 +35,7 @@ test-suite msm-unit-tests
[ run AnonymousAndGuard.cpp ]
[ run AnonymousEuml.cpp ]
[ run Back11CompositeMachine.cpp ]
[ run Backmp11Constructor.cpp ]
[ run Backmp11Visitor.cpp ]
[ run BigWithFunctors.cpp ]
# MSVC 32-bit runs out of memory when compiling this test
+1 -8
View File
@@ -155,9 +155,7 @@ namespace
// Pick a back-end
typedef boost::mpl::vector<
hierarchical_state_machine<boost::msm::back::state_machine>,
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>,
hierarchical_state_machine<boost::msm::backmp11::state_machine>,
hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>
hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>
// TODO:
// Investigate reason for test failure in back11.
// hierarchical_state_machine<boost::msm::back11::state_machine>
@@ -375,8 +373,3 @@ namespace
using back0 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::player;
using back1 = hierarchical_state_machine<boost::msm::back::state_machine, boost::msm::back::favor_compile_time>::Playing_type;
BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(back1);
using backmp11_0 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::player;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_0);
using backmp11_1 = hierarchical_state_machine<boost::msm::backmp11::state_machine, boost::msm::backmp11::favor_compile_time>::Playing_type;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_1);
+2 -3
View File
@@ -8,6 +8,8 @@
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// EUML is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
#include <boost/msm/front/euml/euml.hpp>
@@ -213,6 +215,3 @@ namespace
// at the risk of a programming error creating duplicate objects.
// this is to get rid of warning because p is not const
// BOOST_CLASS_TRACKING(player, boost::serialization::track_never)
using backmp11_fsm = boost::msm::backmp11::state_machine<player_, boost::msm::backmp11::favor_compile_time>;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_fsm);
+2
View File
@@ -9,6 +9,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
// back-end
// set_states API is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
//front-end
#include <boost/msm/front/state_machine_def.hpp>
+2 -3
View File
@@ -8,6 +8,8 @@
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// EUML is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
#include <boost/msm/front/euml/euml.hpp>
@@ -193,6 +195,3 @@ namespace
"Stopped entry not called correctly");
}
}
using backmp11_fsm = boost::msm::backmp11::state_machine<player_, boost::msm::backmp11::favor_compile_time>;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_fsm);
+2 -3
View File
@@ -8,6 +8,8 @@
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// EUML is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
#include <boost/msm/front/euml/euml.hpp>
@@ -193,6 +195,3 @@ namespace
"Stopped entry not called correctly");
}
}
using backmp11_fsm = boost::msm::backmp11::state_machine<player_, boost::msm::backmp11::favor_compile_time>;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_fsm);
+2 -3
View File
@@ -8,6 +8,8 @@
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// EUML is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
#include <boost/msm/front/euml/euml.hpp>
#ifndef BOOST_MSM_NONSTANDALONE_TEST
@@ -251,6 +253,3 @@ namespace
"Stopped entry not called correctly");
}
}
using backmp11_fsm = boost::msm::backmp11::state_machine<player_, boost::msm::backmp11::favor_compile_time>;
BOOST_MSM_BACKMP11_GENERATE_DISPATCH_TABLE(backmp11_fsm);
+2
View File
@@ -9,6 +9,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
// back-end
// set_states API is not supported by backmp11
#define BOOST_MSM_TEST_SKIP_BACKMP11
#include "BackCommon.hpp"
//front-end
#include <boost/msm/front/state_machine_def.hpp>