1 // Copyright 2008 Christophe Henry
2 // henry UNDERSCORE christophe AT hotmail DOT com
3 // This is taken from Boost.Proto's documentation
4 // Copyright for the original version:
5 // Copyright 2008 Eric Niebler. Distributed
6 // under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 #ifndef BOOST_MSM_BACK_FOLD_TO_LIST_H
11 #define BOOST_MSM_BACK_FOLD_TO_LIST_H
12 
13 #include <boost/msm/proto_config.hpp>
14 #include <boost/proto/core.hpp>
15 #include <boost/proto/transform.hpp>
16 #include <boost/msm/msm_grammar.hpp>
17 #include <boost/fusion/container/list/cons.hpp>
18 
19 namespace boost { namespace msm { namespace back
20 {
21  struct state_copy_tag
22  {
23  };
24 
25 template<class X = proto::is_proto_expr>
26 struct define_states_creation
27 {
28    BOOST_PROTO_BASIC_EXTENDS(
29        proto::terminal<state_copy_tag>::type
30      , define_states_creation
31      , boost::msm::msm_domain
32    )
33 };
34 
35 define_states_creation<> const states_ = {{{}}};
36 
37  struct FoldToList
38   : ::boost::proto::or_<
39         // Don't add the states_ terminal to the list
40         ::boost::proto::when<
41             ::boost::proto::terminal< state_copy_tag >
42           , ::boost::proto::_state
43         >
44         // Put all other terminals at the head of the
45         // list that we're building in the "state" parameter
46         // first states for the eUML states
47       , ::boost::proto::when<
48             ::boost::proto::terminal< state_tag >
49             , boost::fusion::cons< ::boost::proto::_, ::boost::proto::_state>(
50                 ::boost::proto::_, ::boost::proto::_state
51             )
52         >
53         // then states from other front-ends
54       , ::boost::proto::when<
55       ::boost::proto::terminal< proto::_ >
56             , boost::fusion::cons< ::boost::proto::_value, ::boost::proto::_state>(
57                 ::boost::proto::_value, ::boost::proto::_state
58     )
59         >
60         // For left-shift operations, first fold the right
61         // child to a list using the current state. Use
62         // the result as the state parameter when folding
63         // the left child to a list.
64       , ::boost::proto::when<
65             ::boost::proto::shift_left<FoldToList, FoldToList>
66           , FoldToList(
67                 ::boost::proto::_left
68               , ::boost::proto::call<FoldToList( ::boost::proto::_right, ::boost::proto::_state )>
69             )
70         >
71     >
72  {};
73 
74 }}}
75 
76 #endif //BOOST_MSM_BACK_FOLD_TO_LIST_H
77 
78