Boost logo

Boost Users :

Subject: [Boost-users] [statechart] : choice_point example no worky
From: Noah Roberts (roberts.noah_at_[hidden])
Date: 2010-07-13 17:37:57


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/

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net