|
Boost Users : |
From: David Greene (greened_at_[hidden])
Date: 2006-02-27 12:07:38
The attached testcase doesn't compile with g++ 4.0.2 or g++ 3.2.3.
The compiler generates a series of error messages like this:
boost/statechart/simple_state.hpp:189: error: no type named
'inner_context_type' in 'struct Test::NormalMode<int>'
I hastily sketched this out based on a larger code. If there
are typos or other mistakes, let me know but the main problem I'm
trying to solve is the "no type named" problem. I typedef it
right in the template definition for NormalMode!
This is using the current CVS for statechart, 1.33.1 for mpl.
Is it possibly a compiler bug?
Thanks!
-Dave
----------------
Testcase
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/custom_reaction.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/mpl/list.hpp>
#include <iostream>
// Switch finite state machine for multiplexor schedule policy
namespace Test {
namespace sc = boost::statechart;
namespace mpl = boost::mpl;
// Inner states
template <typename Type> struct On;
template <typename Type> struct Off;
template <typename Type> struct Error;
// Outer states
template <typename Type> struct NormalMode;
template <typename Type> struct ErrorMode;
// Events
struct End : public sc::event<End> {};
struct UnconsumedEvent : public sc::event<UnconsumedEvent> {
std::string st;
UnconsumedEvent(const std::string &s) : st(s) {};
const std::string &state(void) const { return(st); };
};
template<typename Derived, typename Type>
struct SwitchEvent : public sc::event<Derived> {
typedef Type value_type;
value_type ev;
SwitchEvent(value_type e) : ev(e) {};
value_type value(void) const { return(ev); }
};
template<typename Type>
struct TurnOn : public SwitchEvent<TurnOn<Type>, Type> {
TurnOn(Type value) : SwitchEvent<TurnOn<Type>, Type>(value) {};
};
template<typename Type>
struct TurnOff : public SwitchEvent<TurnOff<Type>, Type> {
TurnOff(Type value) : SwitchEvent<TurnOff<Type>, Type>(value) {};
};
template<typename Type> struct Switch;
namespace detail {
template<typename Type>
struct typedefs {
typedef Type value_type;
typedef Switch<value_type> switch_context;
typedef TurnOn<value_type> turn_on;
typedef TurnOff<value_type> turn_off;
typedef On<value_type> on;
typedef Off<value_type> off;
};
};
// The state machine
template<typename Type>
struct Switch :
public sc::state_machine<Switch<Type>,
NormalMode<Type> >,
public detail::typedefs<Type>
{
typedef sc::state_machine<Switch<Type>,
NormalMode<Type> > Base;
typedef Switch<Type> This;
std::string state(void) const {
if (this->template state_cast<const typename This::on *>()) {
return("ON");
}
else if (this->template state_cast<const typename This::off *>()) {
return("OFF");
}
else {
std::cerr << "Unknown state" << std::endl;
std::abort();
return("ERROR");
}
};
// Abort on unexpected events
void unconsumed_event(const sc::event_base &event)
{
std::cerr << "Unexpected event in state " << state() << std::endl;
std::abort();
this->post_event(new UnconsumedEvent(state()));
};
};
// Define states
// Outer
template<typename Type>
struct NormalMode : public sc::simple_state<NormalMode<Type>,
Switch<Type>,
Off<Type> >,
public detail::typedefs<Type> {
typedef sc::simple_state<NormalMode<Type>,
Switch<Type>,
Off<Type> >
state_base;
typedef typename state_base::inner_context_type inner_context_type;
};
template<typename Type>
struct ErrorMode : public sc::simple_state<ErrorMode<Type>,
Switch<Type>,
Error<Type> >,
public detail::typedefs<Type> {
typedef sc::simple_state<ErrorMode<Type>,
Switch<Type>,
Error<Type> >
state_base;
typedef typename state_base::inner_context_type inner_context_type;
};
// Inner
template<typename Type>
struct Off : public sc::simple_state<Off<Type>,
NormalMode<Type> >,
public detail::typedefs<Type> {
typedef Off<Type> This;
typedef mpl::list<
sc::custom_reaction<typename This::on>,
sc::custom_reaction<End>
> reactions;
sc::result react(const typename This::on &) {
this->template context<typename
This::switch_context>().transit("OFF", "ON");
return(this->template transit<typename This::on>());
};
sc::result react(const End &) {
this->terminate();
};
};
template<typename Type>
struct On : public sc::simple_state<On<Type>,
NormalMode<Type> >,
public detail::typedefs<Type> {
typedef On<Type> This;
typedef mpl::list<
sc::custom_reaction<typename This::off>,
sc::custom_reaction<End>
> reactions;
sc::result react(const typename This::off &) {
this->template context<typename
This::switch_context>().transit("ON", "OFF");
return(this->template transit<typename This::off>());
};
sc::result react(const End &) {
this->terminate();
};
};
template<typename Type>
struct Error : sc::simple_state<Error<Type>,
ErrorMode<Type> >,
public detail::typedefs<Type> {
};
};
int main(void)
{
Test::Switch<int> machine;
machine.initiate();
machine.process_event( Test::TurnOn<int>(0) );
std::cout << "Now in state " << machine.state() << std::endl;
machine.process_event( Test::TurnOff<int>(0) );
std::cout << "Now in state " << machine.state() << std::endl;
machine.process_event( Test::TurnOff<int>(0) ); // Should produce error
std::cout << "Now in state " << machine.state() << std::endl;
machine.process_event( Test::End() );
}
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