[statechart] : choice_point example no worky

I've scoured the web for a reason why and have found no links at all, which is surprising since I suspect the documentation is actually in error. The documentation for statechart has this: http://www.boost.org/doc/libs/1_42_ 0/libs/statechart/doc/rationale.html#Limitations (see dynamic choice points) I'm using boost 1.42 so this should be the right document. So I tried it...and it failed with a compiler error that I looked into and makes perfect sense. The state<> template expects the third parameter to be a context, which custom_reaction is apparently not. So I made my own short version which is basically just a copy paste of the example code: #include <boost/statechart/state_machine.hpp> #include <boost/statechart/simple_state.hpp> #include <boost/statechart/state.hpp> #include <boost/statechart/custom_reaction.hpp> #include <boost/statechart/event.hpp> #include <boost/statechart/transition.hpp> #include <boost/mpl/list.hpp> #include <iostream> namespace sc = boost::statechart; struct make_choice : sc::event< make_choice > {}; // universal choice point base class template template< class MostDerived, class Context > struct choice_point : sc::state< MostDerived, Context, sc::custom_reaction< make_choice > > { typedef sc::state< MostDerived, Context, sc::custom_reaction< make_choice > > base_type; typedef typename base_type::my_context my_context; typedef choice_point my_base; choice_point( my_context ctx ) : base_type( ctx ) { this->post_event( boost::intrusive_ptr< make_choice >( new make_choice() ) ); } }; // ... struct MyChoicePoint; struct Machine : sc::state_machine< Machine, MyChoicePoint > {}; struct Dest1 : sc::simple_state< Dest1, Machine > {}; struct Dest2 : sc::simple_state< Dest2, Machine > { Dest2() { std::cout << "Dest2\n"; } }; struct Dest3 : sc::simple_state< Dest3, Machine > {}; struct MyChoicePoint : choice_point< MyChoicePoint, Machine > { MyChoicePoint( my_context ctx ) : my_base( ctx ) {} sc::result react( const make_choice & ) { if ( 0 ) { return transit< Dest1 >(); } else if ( 1 ) { return transit< Dest2 >(); } else { return transit< Dest3 >(); } } }; int main() { Machine machine; machine.initiate(); std::cin.get(); } Resulting error is the same: 1>------ Build started: Project: 2010scratch, Configuration: Debug Win32 ------ 1> scratch.cpp 1>e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost-1.42-msvc10 \include\boost\statechart\simple_state.hpp(893): error C3083: 'context_type': the symbol to the left of a '::' must be a type 1> e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost- 1.42-msvc10\include\boost\statechart\simple_state.hpp(632) : see reference to function template instantiation 'void boost::statechart::simple_state <MostDerived,Context,InnerInitial,historyMode>::deep_construct_inner_imp l_non_empty::deep_construct_inner_impl<InnerList>(const boost::intrusive_ptr<T> &,boost::statechart::state_machine <Machine,InitialState> &)' being compiled 1> with 1> [ 1> MostDerived=MyChoicePoint, 1> Context=Machine, 1> InnerInitial=boost::statechart::custom_reaction <make_choice>, 1> historyMode=has_no_history, 1> InnerList=boost::mpl::list <boost::statechart::custom_reaction<make_choice>>, 1> T=MyChoicePoint, 1> InitialState=MyChoicePoint 1> ] 1> e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost- 1.42-msvc10\include\boost\statechart\state.hpp(81) : see reference to function template instantiation 'void boost::statechart::simple_state <MostDerived,Context,InnerInitial,historyMode>::deep_construct_inner <boost::mpl::list<T0>>(const boost::intrusive_ptr<T> &,boost::statechart::state_machine<Machine,InitialState> &)' being compiled 1> with 1> [ 1> MostDerived=MyChoicePoint, 1> Context=Machine, 1> InnerInitial=boost::statechart::custom_reaction <make_choice>, 1> historyMode=has_no_history, 1> T0=boost::statechart::custom_reaction<make_choice>, 1> T=MyChoicePoint, 1> InitialState=MyChoicePoint 1> ] 1> e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost- 1.42-msvc10\include\boost\statechart\state.hpp(77) : while compiling class template member function 'void boost::statechart::state <MostDerived,Context,InnerInitial>::deep_construct (boost::statechart::state_machine<Machine,InitialState> *const &,boost::statechart::state_machine<Machine,InitialState> &)' 1> with 1> [ 1> MostDerived=MyChoicePoint, 1> Context=Machine, 1> InnerInitial=boost::statechart::custom_reaction <make_choice>, 1> InitialState=MyChoicePoint 1> ] 1> e:\dev_workspace\experimental\2010scratch\2010scratch \scratch.cpp(19) : see reference to class template instantiation 'boost::statechart::state<MostDerived,Context,InnerInitial>' being compiled 1> with 1> [ 1> MostDerived=MyChoicePoint, 1> Context=Machine, 1> InnerInitial=boost::statechart::custom_reaction <make_choice> 1> ] 1> e:\dev_workspace\experimental\2010scratch\2010scratch \scratch.cpp(45) : see reference to class template instantiation 'choice_point<MostDerived,Context>' being compiled 1> with 1> [ 1> MostDerived=MyChoicePoint, 1> Context=Machine 1> ] 1>e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost-1.42-msvc10 \include\boost\statechart\simple_state.hpp(893): error C2039: 'inner_initial_list' : is not a member of 'boost::statechart::custom_reaction<Event>' 1> with 1> [ 1> Event=make_choice 1> ] 1>e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost-1.42-msvc10 \include\boost\statechart\simple_state.hpp(893): error C2039: 'orthogonal_position' : is not a member of 'boost::statechart::custom_reaction<Event>' 1> with 1> [ 1> Event=make_choice 1> ] 1>e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost-1.42-msvc10 \include\boost\statechart\simple_state.hpp(899): error C2039: 'deep_construct' : is not a member of 'boost::statechart::custom_reaction<Event>' 1> with 1> [ 1> Event=make_choice 1> ] 1>e:\dev_workspace\production.2010rc\3rd_party\boost-1\boost-1.42-msvc10 \include\boost\statechart\simple_state.hpp(899): error C2664: 'boost::statechart::simple_state <MostDerived,Context,InnerInitial,historyMode>::deep_construct' : cannot convert parameter 1 from 'const boost::intrusive_ptr<T>' to 'boost::statechart::state_machine<MostDerived,InitialState> *const &' 1> with 1> [ 1> MostDerived=MyChoicePoint, 1> Context=Machine, 1> InnerInitial=boost::statechart::custom_reaction <make_choice>, 1> historyMode=has_no_history 1> ] 1> and 1> [ 1> T=MyChoicePoint 1> ] 1> and 1> [ 1> MostDerived=Machine, 1> InitialState=MyChoicePoint 1> ] 1> Reason: cannot convert from 'const boost::intrusive_ptr<T>' to 'boost::statechart::state_machine<MostDerived,InitialState> *const ' 1> with 1> [ 1> T=MyChoicePoint 1> ] 1> and 1> [ 1> MostDerived=Machine, 1> InitialState=MyChoicePoint 1> ] 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called So, how do I really do this? -- http://crazyeddiecpp.blogspot.com/

In article <MPG.26a67c94f6d5c21098968b@news.gmane.org>, roberts.noah@gmail.com says...
So I tried it...and it failed with a compiler error that I looked into and makes perfect sense. The state<> template expects the third parameter to be a context, which custom_reaction is apparently not
Err, not a context, an InitialInnerState. As far as I can tell, a custom_reaction<> will never match that concept. -- http://crazyeddiecpp.blogspot.com/

In article <MPG.26a67c94f6d5c21098968b@news.gmane.org>, roberts.noah@gmail.com says... OK, I fixed it...or so it seems. I did it by turning this:
// universal choice point base class template template< class MostDerived, class Context > struct choice_point : sc::state< MostDerived, Context, sc::custom_reaction< make_choice > > { typedef sc::state< MostDerived, Context, sc::custom_reaction< make_choice > > base_type; typedef typename base_type::my_context my_context; typedef choice_point my_base;
choice_point( my_context ctx ) : base_type( ctx ) { this->post_event( boost::intrusive_ptr< make_choice >( new make_choice() ) ); } };
to this: // universal choice point base class template template< class MostDerived, class Context > struct choice_point : sc::state< MostDerived, Context > { typedef sc::state< MostDerived, Context > base_type; typedef typename base_type::my_context my_context; typedef choice_point my_base; typedef sc::custom_reaction<make_choice> reactions; choice_point( my_context ctx ) : base_type( ctx ) { this->post_event( boost::intrusive_ptr< make_choice >( new make_choice() ) ); } }; It seems to do the trick. If it's the right way to do it I'd suggest updating the documentation. -- http://crazyeddiecpp.blogspot.com/

"Noah Roberts" <roberts.noah@gmail.com> wrote in message news:MPG.26a691501a049aa398968d@news.gmane.org... [snip]
It seems to do the trick. If it's the right way to do it I'd suggest updating the documentation.
Done & merged to the release branch (rev 64179). Sorry for the trouble and thanks for the report! Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
participants (2)
-
Andreas Huber
-
Noah Roberts