$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66592 - in trunk/boost/msm: back front/euml
From: christophe.j.henry_at_[hidden]
Date: 2010-11-15 16:04:54
Author: chenry
Date: 2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
New Revision: 66592
URL: http://svn.boost.org/trac/boost/changeset/66592
Log:
- added mpl_graph-based features (for entry states and checking of region orthogonality)
- added Boost.Parameter interface for back-end definition
Added:
   trunk/boost/msm/back/mpl_graph_fsm_check.hpp   (contents, props changed)
   trunk/boost/msm/back/no_fsm_check.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/msm/back/default_compile_policy.hpp |     1                                         
   trunk/boost/msm/back/favor_compile_time.hpp     |     1                                         
   trunk/boost/msm/back/history_policies.hpp       |     3                                         
   trunk/boost/msm/back/metafunctions.hpp          |   143 +++++++++++++++++++++++++++++++++++++++ 
   trunk/boost/msm/back/state_machine.hpp          |   113 ++++++++++++++++++++++++++----          
   trunk/boost/msm/front/euml/state_grammar.hpp    |     1                                         
   6 files changed, 244 insertions(+), 18 deletions(-)
Modified: trunk/boost/msm/back/default_compile_policy.hpp
==============================================================================
--- trunk/boost/msm/back/default_compile_policy.hpp	(original)
+++ trunk/boost/msm/back/default_compile_policy.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -17,6 +17,7 @@
 {
 struct favor_runtime_speed 
 {
+    typedef int compile_policy;
     typedef ::boost::mpl::true_ add_forwarding_rows;
 };
 
Modified: trunk/boost/msm/back/favor_compile_time.hpp
==============================================================================
--- trunk/boost/msm/back/favor_compile_time.hpp	(original)
+++ trunk/boost/msm/back/favor_compile_time.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -63,6 +63,7 @@
 
 struct favor_compile_time 
 {
+    typedef int compile_policy;
     typedef ::boost::mpl::false_ add_forwarding_rows;
 };
 
Modified: trunk/boost/msm/back/history_policies.hpp
==============================================================================
--- trunk/boost/msm/back/history_policies.hpp	(original)
+++ trunk/boost/msm/back/history_policies.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -152,6 +152,7 @@
 
 struct NoHistory
 {
+    typedef int history_policy;
     template <int NumberOfRegions>
     struct apply
     {
@@ -160,6 +161,7 @@
 };
 struct AlwaysHistory
 {
+    typedef int history_policy;
     template <int NumberOfRegions>
     struct apply
     {
@@ -169,6 +171,7 @@
 template <class Events>
 struct ShallowHistory
 {
+    typedef int history_policy;
     template <int NumberOfRegions>
     struct apply
     {
Modified: trunk/boost/msm/back/metafunctions.hpp
==============================================================================
--- trunk/boost/msm/back/metafunctions.hpp	(original)
+++ trunk/boost/msm/back/metafunctions.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -38,10 +38,15 @@
 #include <boost/mpl/insert_range.hpp>
 #include <boost/mpl/front.hpp>
 #include <boost/mpl/logical.hpp>
+#include <boost/mpl/plus.hpp>
 
 #include <boost/type_traits/is_same.hpp>
 #include <boost/utility/enable_if.hpp>
 
+// mpl_graph graph implementation and depth first search
+#include <boost/msm/mpl_graph/incidence_list_graph.hpp>
+#include <boost/msm/mpl_graph/depth_first_search.hpp>
+
 BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_creation)
 BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
 BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
@@ -168,6 +173,7 @@
 };
 
 // builds a mpl::vector of initial states
+//TODO remove duplicate from get_initial_states
 template <class region>
 struct get_regions_as_sequence 
 {
@@ -374,7 +380,7 @@
         ::boost::mpl::if_<
                  ::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
                  ::boost::mpl::placeholders::_1,
-                 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
+                 ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
                              not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > > 
                   >
         >::type with_init;
@@ -629,6 +635,141 @@
 {
     typedef typename StateType::initial_event type;
 };
+
+template <class TransitionTable, class InitState>
+struct build_one_orthogonal_region 
+{
+     template<typename Row>
+     struct row_to_incidence :
+         ::boost::mpl::vector<
+                ::boost::mpl::pair<
+                    typename Row::next_state_type, 
+                    typename Row::transition_event>, 
+                typename Row::current_state_type, 
+                typename Row::next_state_type
+         > {};
+     template<typename Row>
+     struct row_to_incidence2 :
+         ::boost::mpl::vector<
+                ::boost::mpl::pair<
+                    typename Row::transition_event, 
+                    typename Row::next_state_type>, 
+                typename Row::next_state_type, 
+                typename Row::current_state_type
+         > {};
+
+     template <class Seq, class Elt>
+     struct transition_incidence_list_helper 
+     {
+         typedef typename ::boost::mpl::push_back< Seq, row_to_incidence< Elt > >::type one_direction;
+         typedef typename ::boost::mpl::push_back< one_direction, row_to_incidence2< Elt > >::type type;
+     };
+
+     typedef typename ::boost::mpl::fold<
+         TransitionTable,
+         ::boost::mpl::vector<>,
+         transition_incidence_list_helper< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
+     >::type transition_incidence_list;
+
+     typedef ::boost::metagraph::mpl_graph::incidence_list_graph<transition_incidence_list>
+         transition_graph;
+
+     struct preordering_dfs_visitor : 
+         ::boost::metagraph::mpl_graph::dfs_default_visitor_operations 
+     {    
+         template<typename Node, typename Graph, typename State>
+         struct discover_vertex :
+             ::boost::mpl::insert<State, Node>
+         {};
+     };
+
+     typedef typename mpl::first< 
+         typename ::boost::metagraph::mpl_graph::depth_first_search<
+            transition_graph, 
+            preordering_dfs_visitor,
+            ::boost::mpl::set<>,
+            InitState
+         >::type
+     >::type type;
+};
+
+// build a vector of regions states (as a set)
+// one set of states for every region
+// version if initial_state is a not sequence
+template <class TransitionTable, class InitStates,class Enable=void>
+struct build_orthogonal_regions 
+{
+    typedef ::boost::mpl::set<typename build_one_orthogonal_region<TransitionTable,InitStates>::type> type;
+};
+
+// version if initial_state is a sequence
+template <class TransitionTable, class InitStates>
+struct build_orthogonal_regions
+    <TransitionTable,InitStates,
+     typename ::boost::enable_if< 
+        ::boost::mpl::is_sequence<typename InitStates> >::type > 
+{
+    typedef typename 
+        ::boost::mpl::fold<
+            InitStates, ::boost::mpl::vector<>,
+            ::boost::mpl::push_back< 
+                ::boost::mpl::placeholders::_1, 
+                build_one_orthogonal_region< TransitionTable, ::boost::mpl::placeholders::_2 > >
+        >::type type;
+};
+
+template <class GraphAsSeqOfSets, class StateType>
+struct find_region_index
+{
+    typedef typename 
+        ::boost::mpl::fold<
+            GraphAsSeqOfSets, ::boost::mpl::pair< ::boost::mpl::int_< -1 > /*res*/, ::boost::mpl::int_<0> /*counter*/ >,
+            ::boost::mpl::if_<
+                ::boost::mpl::has_key< ::boost::mpl::placeholders::_2, StateType >,
+                ::boost::mpl::pair< 
+                    ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
+                    ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
+                >,
+                ::boost::mpl::pair< 
+                    ::boost::mpl::first< ::boost::mpl::placeholders::_1 >,
+                    ::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
+                >
+            >
+        >::type result_pair;
+    typedef typename ::boost::mpl::first<result_pair>::type type;
+    enum {value = type::value};
+};
+
+template <typename Sequence, typename Range>
+struct set_insert_range
+{
+    typedef typename ::boost::mpl::fold<
+        Range,Sequence, 
+        ::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >
+    >::type type;
+};
+
+template <class Fsm>
+struct check_regions_orthogonality
+{
+    typedef typename build_orthogonal_regions<typename Fsm::stt,typename Fsm::initial_states>::type regions;
+    
+    typedef typename ::boost::mpl::fold<
+        regions, ::boost::mpl::int_<0>,
+        ::boost::mpl::plus< ::boost::mpl::placeholders::_1 , ::boost::mpl::size< ::boost::mpl::placeholders::_2> >
+    >::type number_of_states_in_regions;
+
+    typedef typename ::boost::mpl::fold<
+            regions,mpl::set0<>,
+            set_insert_range< 
+                    ::boost::mpl::placeholders::_1, 
+                    ::boost::mpl::placeholders::_2 > 
+    >::type one_big_states_set;
+
+    enum {states_in_regions_raw = number_of_states_in_regions::value};
+    enum {cumulated_states_in_regions_raw = ::boost::mpl::size<one_big_states_set>::value};
+};
+
 // helper to find out if a SM has an active exit state and is therefore waiting for exiting
 template <class StateType,class OwnerFct,class FSM>
 inline
Added: trunk/boost/msm/back/mpl_graph_fsm_check.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/msm/back/mpl_graph_fsm_check.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -0,0 +1,38 @@
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is an extended version of the state machine available in the boost::mpl library
+// Distributed under the same license as the original.
+// Copyright for the original version:
+// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
+// under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MSM_BACK_MPL_GRAPH_FSM_CHECK_H
+#define BOOST_MSM_BACK_MPL_GRAPH_FSM_CHECK_H
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/msm/back/metafunctions.hpp>
+
+namespace boost { namespace msm { namespace back
+{
+    struct mpl_graph_fsm_check
+    {
+        typedef int fsm_check;
+        // checks that regions are truly orthogonal (one state belongs to 1 region)
+        // using the mpl_graph library (part of metagraph)
+        template <class Fsm>
+        static void check_orthogonality()
+        {
+            BOOST_MPL_ASSERT_RELATION( ::boost::msm::back::check_regions_orthogonality<Fsm>::states_in_regions_raw,
+                                       ==, 
+                                       ::boost::msm::back::check_regions_orthogonality<Fsm>::cumulated_states_in_regions_raw );
+
+        }
+    };
+
+} } }//boost::msm::back
+
+
+#endif //BOOST_MSM_BACK_MPL_GRAPH_FSM_CHECK_H
Added: trunk/boost/msm/back/no_fsm_check.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/msm/back/no_fsm_check.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -0,0 +1,33 @@
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is an extended version of the state machine available in the boost::mpl library
+// Distributed under the same license as the original.
+// Copyright for the original version:
+// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
+// under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MSM_BACK_NO_FSM_CHECK_H
+#define BOOST_MSM_BACK_NO_FSM_CHECK_H
+
+#include <boost/mpl/assert.hpp>
+
+#include <boost/msm/back/metafunctions.hpp>
+
+namespace boost { namespace msm { namespace back
+{
+    struct no_fsm_check
+    {
+        typedef int fsm_check;
+        // no fsm structure checking
+        template <class Fsm>
+        static void check_orthogonality()
+        {
+        }
+    };
+
+} } }//boost::msm::back
+
+
+#endif //BOOST_MSM_BACK_NO_FSM_CHECK_H
Modified: trunk/boost/msm/back/state_machine.hpp
==============================================================================
--- trunk/boost/msm/back/state_machine.hpp	(original)
+++ trunk/boost/msm/back/state_machine.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -22,6 +22,7 @@
 
 #include <boost/mpl/contains.hpp>
 #include <boost/mpl/deref.hpp>
+#include <boost/mpl/assert.hpp>
 
 #include <boost/fusion/container/vector/convert.hpp>
 #include <boost/fusion/include/as_vector.hpp>
@@ -50,6 +51,8 @@
 
 #include <boost/serialization/base_object.hpp> 
 
+#include <boost/parameter.hpp>
+
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/back/fold_to_list.hpp>
 #include <boost/msm/back/metafunctions.hpp>
@@ -59,6 +62,7 @@
 #include <boost/msm/back/args.hpp>
 #include <boost/msm/back/default_compile_policy.hpp>
 #include <boost/msm/back/dispatch_table.hpp>
+#include <boost/msm/back/no_fsm_check.hpp>
 
 BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
@@ -66,6 +70,9 @@
 BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
 BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
 BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
 
 #ifndef BOOST_MSM_CONSTRUCTOR_ARG_SIZE
 #define BOOST_MSM_CONSTRUCTOR_ARG_SIZE 5 // default max number of arguments for constructors
@@ -89,15 +96,64 @@
 const boost::msm::back::dispatch_table<Fsm,Stt, Event,CompilePolicy>
 dispatch_table<Fsm,Stt, Event,CompilePolicy>::instance;
 
+BOOST_PARAMETER_TEMPLATE_KEYWORD(front_end)
+BOOST_PARAMETER_TEMPLATE_KEYWORD(history_policy)
+BOOST_PARAMETER_TEMPLATE_KEYWORD(compile_policy)
+BOOST_PARAMETER_TEMPLATE_KEYWORD(fsm_check_policy)
+
+typedef ::boost::parameter::parameters<
+    ::boost::parameter::required< ::boost::msm::back::tag::front_end >
+  , ::boost::parameter::optional< 
+        ::boost::parameter::deduced< ::boost::msm::back::tag::history_policy>, has_history_policy< ::boost::mpl::_ > 
+    >
+  , ::boost::parameter::optional< 
+        ::boost::parameter::deduced< ::boost::msm::back::tag::compile_policy>, has_compile_policy< ::boost::mpl::_ > 
+    >
+  , ::boost::parameter::optional< 
+        ::boost::parameter::deduced< ::boost::msm::back::tag::fsm_check_policy>, has_fsm_check< ::boost::mpl::_ > 
+    >
+> state_machine_signature;
+
+
 
 // library-containing class for state machines.  Pass the actual FSM class as
 // the Concrete parameter.
-template<class Derived,class HistoryPolicy=NoHistory,class CompilePolicy=favor_runtime_speed>
-class state_machine : public Derived
+// A0=Derived,A1=NoHistory,A2=CompilePolicy,A3=FsmCheckPolicy >
+template <
+      class A0
+    , class A1 = parameter::void_
+    , class A2 = parameter::void_
+    , class A3 = parameter::void_
+>
+class state_machine : //public Derived
+    public ::boost::parameter::binding<
+            typename state_machine_signature::bind<A0,A1,A2,A3>::type, ::boost::msm::back::tag::front_end
+    >::type
 {
+public:
+    // Create ArgumentPack
+    typedef typename
+        state_machine_signature::bind<A0,A1,A2,A3>::type
+        state_machine_args;
+
+    // Extract first logical parameter.
+    typedef typename ::boost::parameter::binding<
+        state_machine_args, ::boost::msm::back::tag::front_end>::type Derived;
+
+    typedef typename ::boost::parameter::binding<
+        state_machine_args, ::boost::msm::back::tag::history_policy, NoHistory >::type HistoryPolicy;
+
+    typedef typename ::boost::parameter::binding<
+        state_machine_args, ::boost::msm::back::tag::compile_policy, favor_runtime_speed >::type CompilePolicy;
+
+    typedef typename ::boost::parameter::binding<
+        state_machine_args, ::boost::msm::back::tag::fsm_check_policy, no_fsm_check >::type FsmCheckPolicy;
+
+
 private: 
-    typedef boost::msm::back::state_machine<Derived,
-        HistoryPolicy,CompilePolicy>                library_sm;
+
+    typedef boost::msm::back::state_machine<
+        A0,A1,A2,A3>                                library_sm;
 
     typedef ::boost::function<
         execute_return ()>                          transition_fct;
@@ -108,7 +164,7 @@
     typedef bool (*flag_handler)(library_sm&);
 
     // all state machines are friend with each other to allow embedding any of them in another fsm
-    template <class ,class , class
+    template <class ,class , class, class
     > friend class boost::msm::back::state_machine;
 
     // helper to add, if needed, visitors to all states
@@ -1267,7 +1323,7 @@
      }
 
      // Construct with the default initial states
-     state_machine<Derived,HistoryPolicy,CompilePolicy   >()
+     state_machine<A0,A1,A2,A3 >()
          :Derived()
          ,m_events_queue() 
          ,m_deferred_events_queue()
@@ -1285,7 +1341,7 @@
          fill_states(this);
      }
      template <class Expr>
-     state_machine<Derived,HistoryPolicy,CompilePolicy   >
+     state_machine<A0,A1,A2,A3 >
          (Expr const& expr,typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* =0)
          :Derived()
          ,m_events_queue() 
@@ -1313,7 +1369,7 @@
 #define MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n t ## n
 #define MSM_CONSTRUCTOR_HELPER_EXECUTE(z, n, unused)                                \
         template <BOOST_PP_ENUM_PARAMS(n, class ARG)>                               \
-        state_machine<Derived,HistoryPolicy,CompilePolicy                           \
+        state_machine<A0,A1,A2,A3                                                   \
         >(BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ),                 \
         typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type* =0 )                \
         :Derived(BOOST_PP_ENUM_PARAMS(n,t))                                         \
@@ -1331,7 +1387,7 @@
          fill_states(this);                                                         \
      }                                                                              \
         template <class Expr,BOOST_PP_ENUM_PARAMS(n, class ARG)>                    \
-        state_machine<Derived,HistoryPolicy,CompilePolicy                           \
+        state_machine<A0,A1,A2,A3                                                   \
         >(Expr const& expr,BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ), \
         typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* =0 ) \
         :Derived(BOOST_PP_ENUM_PARAMS(n,t))                                         \
@@ -1372,7 +1428,7 @@
          }
         return *this;
      }
-     state_machine<Derived,HistoryPolicy,CompilePolicy> 
+     state_machine<A0,A1,A2,A3> 
          (library_sm const& rhs)
          : Derived(rhs)
      {
@@ -2046,6 +2102,26 @@
          region_start_helper< ::boost::mpl::int_<0> >::do_start(this,incomingEvent);
      }
 
+     template <class StateType>
+     struct find_region_id 
+     {
+         template <int region>
+         struct In
+         {
+             enum {region_index=region};
+         };
+         // if the user provides no region, find it!
+         template<>
+         struct In<-1>
+         {
+             typedef typename build_orthogonal_regions<
+                 stt,
+                 typename Derived::initial_state 
+             >::type all_regions;
+             enum {region_index= find_region_index<all_regions,StateType>::value };
+         };         
+         enum {region_index = In<StateType::zone_index>::region_index };
+     };
      // helper used to set the correct state as active state upon entry into a fsm
      struct direct_event_start_helper 
      {
@@ -2074,10 +2150,10 @@
          {
              (static_cast<Derived*>(self))->on_entry(evt,fsm);
              int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
-             BOOST_STATIC_ASSERT(EventType::active_state::zone_index >= 0);
-             BOOST_STATIC_ASSERT(EventType::active_state::zone_index <= nr_regions::value);
+             BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index >= 0);
+             BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index <= nr_regions::value);
              // just set the correct zone, the others will be default/history initialized
-             self->m_states[EventType::active_state::zone_index] = state_id;
+             self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
              self->start(evt.m_event);
          }
 
@@ -2113,7 +2189,7 @@
              (static_cast<Derived*>(self))->on_entry(evt,fsm);
              int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
              // given region starts with the entry pseudo state as active state
-             self->m_states[EventType::active_state::zone_index] = state_id;
+             self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
              self->start(evt.m_event);
              // and we process the transition in the zone of the newly active state
              // (entry pseudo states are, according to UML, a state connecting 1 transition outside to 1 inside
@@ -2131,9 +2207,9 @@
              void operator()( ::boost::msm::wrap<StateType> const& )
              {
                  int state_id = get_state_id<stt,typename StateType::wrapped_entry>::value;
-                 BOOST_STATIC_ASSERT(StateType::zone_index >= 0);
-                 BOOST_STATIC_ASSERT(StateType::zone_index <= nr_regions::value);
-                 helper_self->m_states[StateType::zone_index] = state_id;
+                 BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index >= 0);
+                 BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index <= nr_regions::value);
+                 helper_self->m_states[find_region_id<typename StateType::wrapped_entry>::region_index] = state_id;
              }
          private:
              library_sm*        helper_self;
@@ -2322,6 +2398,9 @@
     template <class ContainingSM>
     void fill_states(ContainingSM* containing_sm=0)
     {
+        // checks that regions are truly orthogonal
+        FsmCheckPolicy::template check_orthogonality<library_sm>();
+
         BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
         // allocate the place without reallocation
         m_visitors.fill_visitors(max_state);
Modified: trunk/boost/msm/front/euml/state_grammar.hpp
==============================================================================
--- trunk/boost/msm/front/euml/state_grammar.hpp	(original)
+++ trunk/boost/msm/front/euml/state_grammar.hpp	2010-11-15 16:04:53 EST (Mon, 15 Nov 2010)
@@ -18,6 +18,7 @@
 
 #include <boost/mpl/remove_if.hpp>
 #include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/assert.hpp>
 
 #include <boost/msm/row_tags.hpp>
 #include <boost/msm/front/common_states.hpp>