mirror of
https://github.com/boostorg/msm.git
synced 2026-01-19 04:22:11 +00:00
fixed incorrect fusion::map usage
This commit is contained in:
@@ -21,7 +21,11 @@
|
||||
#include <boost/mpl/pop_front.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/mpl/advance.hpp>
|
||||
|
||||
#include <boost/fusion/container/vector.hpp>
|
||||
#include <boost/fusion/container/map.hpp>
|
||||
#include <boost/fusion/include/push_back.hpp>
|
||||
#include <boost/fusion/include/make_vector.hpp>
|
||||
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
@@ -199,20 +203,18 @@ struct dispatch_table
|
||||
{
|
||||
typedef typename
|
||||
boost::fusion::result_of::as_map<
|
||||
typename boost::fusion::result_of::insert<
|
||||
Map,
|
||||
typename ::boost::fusion::result_of::end<Map>::type,
|
||||
typename ::boost::fusion::result_of::make_pair<
|
||||
typename transition_source_type<T>::type,
|
||||
typename ::boost::mpl::push_back<
|
||||
typename ::boost::fusion::result_of::value_at_key<
|
||||
Map,
|
||||
typename transition_source_type<T>::type
|
||||
>::type,
|
||||
typename change_frow_event<T>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
typename boost::fusion::result_of::make_vector<
|
||||
typename ::boost::fusion::result_of::make_pair<
|
||||
typename transition_source_type<T>::type,
|
||||
typename ::boost::mpl::push_back<
|
||||
typename ::boost::fusion::result_of::value_at_key<
|
||||
Map,
|
||||
typename transition_source_type<T>::type
|
||||
>::type,
|
||||
typename change_frow_event<T>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
@@ -440,25 +442,15 @@ struct dispatch_table
|
||||
::boost::fusion::map<>,
|
||||
::boost::mpl::if_<
|
||||
// if we already have a row on this source state
|
||||
::boost::mpl::has_key< ::boost::mpl::placeholders::_1,
|
||||
::boost::fusion::result_of::has_key< ::boost::mpl::placeholders::_1,
|
||||
transition_source_type< ::boost::mpl::placeholders::_2> >,
|
||||
// insert a new element in the value type
|
||||
// push_to_map_of_vec<::boost::mpl::placeholders::_2, ::boost::mpl::placeholders::_1>,
|
||||
boost::fusion::result_of::as_map<boost::fusion::result_of::insert<
|
||||
::boost::mpl::placeholders::_1,
|
||||
::boost::fusion::result_of::end<mpl::placeholders::_1 >,
|
||||
::boost::fusion::result_of::make_pair<transition_source_type< ::boost::mpl::placeholders::_2>,
|
||||
::boost::mpl::push_back<
|
||||
::boost::fusion::result_of::value_at_key< ::boost::mpl::placeholders::_1,
|
||||
transition_source_type< ::boost::mpl::placeholders::_2> >,
|
||||
change_frow_event< ::boost::mpl::placeholders::_2 > >
|
||||
> > >,
|
||||
push_to_map_of_vec<::boost::mpl::placeholders::_2, ::boost::mpl::placeholders::_1>,
|
||||
// first row on this source state, make a vector with 1 element
|
||||
boost::fusion::result_of::as_map<boost::fusion::result_of::insert<
|
||||
boost::fusion::result_of::as_map<boost::fusion::result_of::push_back<
|
||||
::boost::mpl::placeholders::_1,
|
||||
::boost::fusion::result_of::end<mpl::placeholders::_1 >,
|
||||
::boost::fusion::result_of::make_pair<transition_source_type< ::boost::mpl::placeholders::_2>,
|
||||
make_vector< change_frow_event< ::boost::mpl::placeholders::_2> > > > >
|
||||
boost::msm::back11::make_vector< change_frow_event< ::boost::mpl::placeholders::_2> > > > >
|
||||
>
|
||||
>::type map_of_row_seq;
|
||||
|
||||
|
||||
160
test/Back11TransitionSkipping.cpp
Normal file
160
test/Back11TransitionSkipping.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
// 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)
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifndef BOOST_MSM_NONSTANDALONE_TEST
|
||||
#define BOOST_TEST_MODULE back11_transition_skipping
|
||||
#endif
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
//#define USE_PRE11_MSM_BACKEND // <- toggle this to switch between back vs back11
|
||||
|
||||
// back-end
|
||||
#if defined(USE_PRE11_MSM_BACKEND)
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
namespace msm_back = boost::msm::back;
|
||||
#else
|
||||
#include <boost/msm/back11/state_machine.hpp>
|
||||
namespace msm_back = boost::msm::back11;
|
||||
#endif
|
||||
|
||||
// front-end
|
||||
#include <boost/fusion/include/insert_range.hpp>
|
||||
#include <boost/msm/front/euml/operator.hpp>
|
||||
#include <boost/msm/front/functor_row.hpp>
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
|
||||
|
||||
template <typename ...T>
|
||||
using msm_flags = boost::mpl::vector<T...>;
|
||||
template <typename ...T>
|
||||
using msm_transition_table = boost::mpl::vector<T...>;
|
||||
|
||||
|
||||
|
||||
namespace msmf = boost::msm::front;
|
||||
namespace euml = boost::msm::front::euml;
|
||||
|
||||
struct evt1 {};
|
||||
struct evt2 {};
|
||||
struct evt3 {};
|
||||
|
||||
struct top_ : public msmf::state_machine_def<top_> {
|
||||
int count_guard_false = 0;
|
||||
int count_guard_true = 0;
|
||||
|
||||
|
||||
struct nested : public msmf::state<> {
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const&, FSM&) { ++entry_counter; }
|
||||
template <class Event, class FSM>
|
||||
void on_exit(Event const&, FSM&) { ++exit_counter; }
|
||||
int entry_counter=0;
|
||||
int exit_counter=0;
|
||||
};
|
||||
|
||||
struct other1 : public msmf::state<> {
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const&, FSM&) { ++entry_counter; }
|
||||
template <class Event, class FSM>
|
||||
void on_exit(Event const&, FSM&) { ++exit_counter; }
|
||||
int entry_counter = 0;
|
||||
int exit_counter = 0;
|
||||
};
|
||||
|
||||
struct other2 : public msmf::state<> {
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const&, FSM&) { ++entry_counter; }
|
||||
template <class Event, class FSM>
|
||||
void on_exit(Event const&, FSM&) { ++exit_counter; }
|
||||
int entry_counter = 0;
|
||||
int exit_counter = 0;
|
||||
};
|
||||
|
||||
struct other3 : public msmf::state<> {
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const&, FSM&) { ++entry_counter; }
|
||||
template <class Event, class FSM>
|
||||
void on_exit(Event const&, FSM&) { ++exit_counter; }
|
||||
int entry_counter = 0;
|
||||
int exit_counter = 0;
|
||||
};
|
||||
|
||||
struct other4 : public msmf::state<> {
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const&, FSM&) { ++entry_counter; }
|
||||
template <class Event, class FSM>
|
||||
void on_exit(Event const&, FSM&) { ++exit_counter; }
|
||||
int entry_counter = 0;
|
||||
int exit_counter = 0;
|
||||
};
|
||||
struct other5 : public msmf::state<> {
|
||||
template <class Event, class FSM>
|
||||
void on_entry(Event const&, FSM&) { ++entry_counter; }
|
||||
template <class Event, class FSM>
|
||||
void on_exit(Event const&, FSM&) { ++exit_counter; }
|
||||
int entry_counter = 0;
|
||||
int exit_counter = 0;
|
||||
};
|
||||
|
||||
struct guard_true {
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
bool operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) const {
|
||||
++fsm.count_guard_true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct guard_false {
|
||||
template <class EVT, class FSM, class SourceState, class TargetState>
|
||||
bool operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) const {
|
||||
++fsm.count_guard_false;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef nested initial_state;
|
||||
|
||||
using transition_table = msm_transition_table<
|
||||
// Start Event Next Action Guard
|
||||
//--------+------------+---------+------------+-----------+--------------
|
||||
msmf::Row < nested, msmf::none, other1, msmf::none, guard_false>,
|
||||
msmf::Row < nested, msmf::none, other2, msmf::none, guard_true >, // <- this transition is not executed with back11
|
||||
msmf::Row < nested, msmf::none, other3, msmf::none, guard_false>,
|
||||
msmf::Row < nested, msmf::none, other4, msmf::none, guard_false>,
|
||||
msmf::Row < other1, evt3, nested, msmf::none, msmf::none >
|
||||
>;
|
||||
};
|
||||
|
||||
using top = msm_back::state_machine<top_>;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(back11_transition_skipping)
|
||||
{
|
||||
top msm;
|
||||
msm.start();
|
||||
BOOST_CHECK_MESSAGE(msm.count_guard_true == 1, "guard_true should be called once");
|
||||
BOOST_CHECK_MESSAGE(msm.count_guard_false == 2, "guard_false should be called once");
|
||||
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::nested&>().exit_counter == 1, "nested exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::nested&>().entry_counter == 1, "nested entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other2&>().exit_counter == 0, "other2 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other2&>().entry_counter == 1, "other2 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other1&>().exit_counter == 0, "other1 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other1&>().entry_counter == 0, "other1 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other3&>().exit_counter == 0, "other3 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other3&>().entry_counter == 0, "other3 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other4&>().exit_counter == 0, "other4 exit not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.get_state<top_::other4&>().entry_counter == 0, "other4 entry not called correctly");
|
||||
BOOST_CHECK_MESSAGE(msm.current_state()[0] == 2, "other2 should be active"); //Open
|
||||
|
||||
}
|
||||
@@ -81,6 +81,8 @@ test-suite msm-unit-tests
|
||||
: [ requires cxx11_variadic_templates ] ]
|
||||
[ run Back11ManyDeferTransitions.cpp : :
|
||||
: [ requires cxx11_variadic_templates ] ]
|
||||
[ run Back11TransitionSkipping.cpp : :
|
||||
: [ requires cxx11_variadic_templates ] ]
|
||||
[ run Back11SimpleWithPuml.cpp : :
|
||||
: [ requires cxx20_hdr_version cxx20_hdr_barrier cxx20_hdr_compare cxx20_hdr_format cxx20_hdr_ranges cxx20_hdr_numbers ] ]
|
||||
[ run Back11OnlyStringPuml.cpp : :
|
||||
|
||||
Reference in New Issue
Block a user