Return-path: <boost-users-bounces@lists.boost.org>
Envelope-to: greened@obbligato.org
Received: from milliways.osl.iu.edu ([129.79.245.239])
	by johnson.obbligato.org with esmtp (Exim 4.60)
	(envelope-from <boost-users-bounces@lists.boost.org>)
	id 1FDnAc-0000LW-9h
	for greened@obbligato.org; Mon, 27 Feb 2006 12:34:47 -0600
Received: from milliways.osl.iu.edu (localhost [127.0.0.1])
	by milliways.osl.iu.edu (8.13.1/8.13.1/IUCS_Alternate_Port_1.9) with
	ESMTP id k1RILpDd021700; Mon, 27 Feb 2006 13:27:16 -0500
Received: from mail1.cray.com (mail1.cray.com [136.162.0.111])
	by milliways.osl.iu.edu (8.13.1/8.13.1/IUCS_2.72) with ESMTP id
	k1RH7lvk011006
	for <boost-users@lists.boost.org>; Mon, 27 Feb 2006 12:07:49 -0500
Received: from mh1750-1.us.cray.com (mh1750-1.us.cray.com [172.31.74.55])
	by mail1.cray.com (8.13.3/8.13.3/gw-5323) with ESMTP id k1RH7e6C015040
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK)
	for <boost-users@lists.boost.org>; Mon, 27 Feb 2006 11:07:42 -0600 (CST)
Received: from mh2650-1.us.cray.com (mh2650-1.us.cray.com [172.31.74.50])
	by mh1750-1.us.cray.com (8.13.4/8.13.3/hub-5273) with ESMTP id
	k1RH7eYh007835
	for <boost-users@lists.boost.org>; Mon, 27 Feb 2006 11:07:40 -0600
Received: from [172.31.18.98] (spruce95.us.cray.com [172.31.18.98])
	by mh2650-1.us.cray.com (8.13.4/8.13.3/spool-5907) with ESMTP id
	k1RH7caQ017951
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
	for <boost-users@lists.boost.org>; Mon, 27 Feb 2006 11:07:40 -0600
Message-ID: <440331DA.1010401@obbligato.org>
Date: Mon, 27 Feb 2006 11:07:38 -0600
From: David Greene <greened@obbligato.org>
User-Agent: Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.7.8) Gecko/20050512
X-Accept-Language: en-us, en
MIME-Version: 1.0
To: boost-users@lists.boost.org
X-Cray-VirusStatus: clean
X-PMX-Version: 4.7.1.128075, Antispam-Engine: 2.3.0.0,
	Antispam-Data: 2006.02.27.082605
Subject: [Boost-users] [statechart] Template States, Compile Error
X-BeenThere: boost-users@lists.boost.org
X-Mailman-Version: 2.1.6
Precedence: list
Reply-To: boost-users@lists.boost.org
List-Id: Boost Users mailing list <boost-users.lists.boost.org>
List-Unsubscribe: <http://lists.boost.org/mailman/listinfo.cgi/boost-users>,
	<mailto:boost-users-request@lists.boost.org?subject=unsubscribe>
List-Archive: <http://lists.boost.org/MailArchives/boost-users>
List-Post: <mailto:boost-users@lists.boost.org>
List-Help: <mailto:boost-users-request@lists.boost.org?subject=help>
List-Subscribe: <http://lists.boost.org/mailman/listinfo.cgi/boost-users>,
	<mailto:boost-users-request@lists.boost.org?subject=subscribe>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Sender: boost-users-bounces@lists.boost.org
Errors-To: boost-users-bounces@lists.boost.org

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 mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
