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