I am trying to set up my own state machine with several states, guards and actions but when the number of states in the transition table exceeds 10 states, extensive error messages pops out but I still cannot infer the source of the error from them. I have simplified my codes as bellow:
/* Boost MSM */
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/back/mpl_graph_fsm_check.hpp>
/* STL */
#include <memory>
namespace msm = boost::msm ;
namespace msmf = boost::msm::front ;
namespace msmb = boost::msm::back ;
namespace mpl = boost::mpl ;
#define None \
msmf::none
namespace {
class Shelf_Hooking ;
// typedef msmb::state_machine<Shelf_Hooking> SM_ ;
typedef msmb::state_machine<Shelf_Hooking, msmb::mpl_graph_fsm_check> SM_ ;
struct Event {} ;
class Shelf_Hooking : public msmf::state_machine_def<Shelf_Hooking> {
/* States */
struct A ;
struct B ;
struct C ;
struct D ;
struct E ;
struct F ;
struct G ;
struct H ;
struct I ;
struct J ;
struct K ;
struct L ;
struct M ;
struct End ;
public:
Shelf_Hooking() {} ;
~Shelf_Hooking() {} ;
typedef A initial_state ;
struct transition_table : mpl::vector<
msmf::Row < A, Event, B, None, None >
, msmf::Row < B, None, C, None, None >
, msmf::Row < C, None, D, None, None >
, msmf::Row < D, None, E, None, None >
, msmf::Row < E, None, F, None, None >
, msmf::Row < F, None, G, None, None >
, msmf::Row < G, None, H, None, None >
, msmf::Row < H, None, I, None, None >
, msmf::Row < I, None, J, None, None >
, msmf::Row < J, None, K, None, None >
, msmf::Row < K, None, L, None, None >
, msmf::Row < L, None, M, None, None >
, msmf::Row < M, None, End, None, None >
>{} ;
private:
struct A : public msmf::state<> {} ;
struct B : public msmf::state<> {} ;
struct C : public msmf::state<> {} ;
struct D : public msmf::state<> {} ;
struct E : public msmf::state<> {} ;
struct F : public msmf::state<> {} ;
struct G : public msmf::state<> {} ;
struct H : public msmf::state<> {} ;
struct I : public msmf::state<> {} ;
struct J : public msmf::state<> {} ;
struct K : public msmf::state<> {} ;
struct L : public msmf::state<> {} ;
struct M : public msmf::state<> {} ;
struct End : public msmf::terminate_state<> {} ;
} ; /* End of State Machine class */
/***************************************************************/
/* Back-end */
class state_machine_impl{
std::unique_ptr<SM_> state_machine ;
public:
state_machine_impl()
: state_machine(new SM_()) {}
~state_machine_impl() {}
void runSM() {
state_machine->start() ;
state_machine->process_event( Event() ) ;
} /* End of runSM() */
} ; /* End of class state_machine_impl */
} /* End of namespace */
int main() {
std::unique_ptr<state_machine_impl> Sm_=
std::unique_ptr<state_machine_impl>(new state_machine_impl() ) ;
Sm_->runSM() ;
return 0 ;
}
The transition table works if I only have all the transitions up to state J, but once I add the transition from J to K, The compiler would throw an error covering 20,000.+ lines. My question is:
How can I insert more than 10 states, guards, and actions into the transition table without creating any error?
Thank you in advance!
The compiler error messages:
Scanning dependencies of target test_multiple_states
[ 86%] Building CXX object CMakeFiles/test_multiple_states.dir/src/test_multiple_states.cpp.o
In file included from /usr/include/boost/fusion/include/as_set.hpp:11:0,
from /usr/include/boost/msm/back/state_machine.hpp:28,
from /home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:2:
/usr/include/boost/fusion/container/set/convert.hpp: In instantiation of ‘struct boost::fusion::result_of::as_set<boost::mpl::s_item<{anonymous}::Shelf_Hooking::K, boost::mpl::s_item<{anonymous}::Shelf_Hooking::J, boost::mpl::s_item<{anonymous}::Shelf_Hooking::I, boost::mpl::s_item<{anonymous}::Shelf_Hooking::H, boost::mpl::s_item<{anonymous}::Shelf_Hooking::G, boost::mpl::s_item<{anonymous}::Shelf_Hooking::F, boost::mpl::s_item<{anonymous}::Shelf_Hooking::E, boost::mpl::s_item<{anonymous}::Shelf_Hooking::D, boost::mpl::s_item<{anonymous}::Shelf_Hooking::C, boost::mpl::s_item<{anonymous}::Shelf_Hooking::B, boost::mpl::s_item<{anonymous}::Shelf_Hooking::A, boost::mpl::set0<> > > > > > > > > > > > >’:
/usr/include/boost/msm/back/state_machine.hpp:1169:75: required from ‘class boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>’
/home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:94:29: required from here
/usr/include/boost/fusion/container/set/convert.hpp:27:13: error: invalid use of incomplete type ‘struct boost::fusion::detail::barrier::as_set<11>’
type;
^
In file included from /usr/include/boost/fusion/container/set/convert.hpp:11:0,
from /usr/include/boost/fusion/include/as_set.hpp:11,
from /usr/include/boost/msm/back/state_machine.hpp:28,
from /home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:2:
/usr/include/boost/fusion/container/set/detail/as_set.hpp:28:12: note: declaration of ‘struct boost::fusion::detail::barrier::as_set<11>’
struct as_set;
^
In file included from /home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:2:0:
/usr/include/boost/msm/back/state_machine.hpp: In instantiation of ‘boost::msm::back::state_machine<A0, A1, A2, A3, A4>::state_machine() [with A0 = {anonymous}::Shelf_Hooking; A1 = boost::msm::back::mpl_graph_fsm_check; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]’:
/home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:94:29: required from here
/usr/include/boost/msm/back/state_machine.hpp:1591:27: error: using invalid field ‘boost::msm::back::state_machine<A0, A1, A2, A3, A4>::m_substate_list’
,m_substate_list()
^
/usr/include/boost/msm/back/state_machine.hpp: In instantiation of ‘void boost::msm::back::state_machine<A0, A1, A2, A3, A4>::call_init<Event>::operator()(const boost::msm::wrap<State>&) [with State = {anonymous}::Shelf_Hooking::A; Event = boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::InitEvent; A0 = {anonymous}::Shelf_Hooking; A1 = boost::msm::back::mpl_graph_fsm_check; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]’:
/usr/include/boost/mpl/for_each.hpp:78:26: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::v_iter<boost::mpl::v_item<{anonymous}::Shelf_Hooking::A, boost::mpl::vector0<mpl_::na>, 0>, 0l>; LastIterator = boost::mpl::v_iter<boost::mpl::v_item<{anonymous}::Shelf_Hooking::A, boost::mpl::vector0<mpl_::na>, 0>, 1l>; TransformFunc = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::call_init<boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::InitEvent>]’
/usr/include/boost/mpl/for_each.hpp:105:18: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::v_item<{anonymous}::Shelf_Hooking::A, boost::mpl::vector0<mpl_::na>, 0>; TransformOp = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::call_init<boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::InitEvent>]’
/usr/include/boost/msm/back/state_machine.hpp:1225:13: required from ‘void boost::msm::back::state_machine<A0, A1, A2, A3, A4>::start() [with A0 = {anonymous}::Shelf_Hooking; A1 = boost::msm::back::mpl_graph_fsm_check; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]’
/home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:99:30: required from here
/usr/include/boost/msm/back/state_machine.hpp:2085:57: error: ‘boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::library_sm {aka class boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>}’ has no member named ‘m_substate_list’
execute_entry(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
^
(...)
/usr/include/boost/msm/back/state_machine.hpp:671:58: error: ‘boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::library_sm {aka class boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>}’ has no member named ‘m_substate_list’
(::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
^
CMakeFiles/test_multiple_states.dir/build.make:62: recipe for target 'CMakeFiles/test_multiple_states.dir/src/test_multiple_states.cpp.o' failed
make[2]: *** [CMakeFiles/test_multiple_states.dir/src/test_multiple_states.cpp.o] Error 1
CMakeFiles/Makefile2:400: recipe for target 'CMakeFiles/test_multiple_states.dir/all' failed
make[1]: *** [CMakeFiles/test_multiple_states.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
Compile with a recent boost, on c++11 compiler:
PS Don't abuse
#define
for type aliases
Live On Coliru (Clang)
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/back/mpl_graph_fsm_check.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <memory>
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace msmb = boost::msm::back;
namespace mpl = boost::mpl;
using None = msmf::none;
namespace {
class Shelf_Hooking;
// typedef msmb::state_machine<Shelf_Hooking> SM_ ;
typedef msmb::state_machine<Shelf_Hooking, msmb::mpl_graph_fsm_check> SM_;
struct Event {};
class Shelf_Hooking : public msmf::state_machine_def<Shelf_Hooking> {
/* States */
struct A;
struct B;
struct C;
struct D;
struct E;
struct F;
struct G;
struct H;
struct I;
struct J;
struct K;
struct L;
struct M;
struct End;
public:
Shelf_Hooking(){};
~Shelf_Hooking(){};
typedef A initial_state;
struct transition_table : mpl::vector<
msmf::Row<A, Event, B, None, None>,
msmf::Row<B, None, C, None, None>,
msmf::Row<C, None, D, None, None>,
msmf::Row<D, None, E, None, None>,
msmf::Row<E, None, F, None, None>,
msmf::Row<F, None, G, None, None>,
msmf::Row<G, None, H, None, None>,
msmf::Row<H, None, I, None, None>,
msmf::Row<I, None, J, None, None>,
msmf::Row<J, None, K, None, None>,
msmf::Row<K, None, L, None, None>,
msmf::Row<L, None, M, None, None>,
msmf::Row<M, None, End, None, None> > {};
private:
struct A : public msmf::state<> {};
struct B : public msmf::state<> {};
struct C : public msmf::state<> {};
struct D : public msmf::state<> {};
struct E : public msmf::state<> {};
struct F : public msmf::state<> {};
struct G : public msmf::state<> {};
struct H : public msmf::state<> {};
struct I : public msmf::state<> {};
struct J : public msmf::state<> {};
struct K : public msmf::state<> {};
struct L : public msmf::state<> {};
struct M : public msmf::state<> {};
struct End : public msmf::terminate_state<> {};
}; /* End of State Machine class */
/***************************************************************/
/* Back-end */
class state_machine_impl {
std::unique_ptr<SM_> state_machine;
public:
state_machine_impl() : state_machine(new SM_()) {}
~state_machine_impl() {}
void runSM() {
state_machine->start();
state_machine->process_event(Event());
} /* End of runSM() */
}; /* End of class state_machine_impl */
} /* End of namespace */
int main() {
std::unique_ptr<state_machine_impl> Sm_ = std::unique_ptr<state_machine_impl>(new state_machine_impl());
Sm_->runSM();
}