fold_to_list.hpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. #ifndef BOOST_MSM_BACK_FOLD_TO_LIST_H
  10. #define BOOST_MSM_BACK_FOLD_TO_LIST_H
  11. #include <boost/msm/proto_config.hpp>
  12. #include <boost/proto/core.hpp>
  13. #include <boost/proto/transform.hpp>
  14. #include <boost/msm/msm_grammar.hpp>
  15. #include <boost/fusion/container/list/cons.hpp>
  16. namespace boost { namespace msm { namespace back
  17. {
  18. struct state_copy_tag
  19. {
  20. };
  21. template<class X = proto::is_proto_expr>
  22. struct define_states_creation
  23. {
  24. BOOST_PROTO_BASIC_EXTENDS(
  25. proto::terminal<state_copy_tag>::type
  26. , define_states_creation
  27. , boost::msm::msm_domain
  28. )
  29. };
  30. define_states_creation<> const states_ = {{{}}};
  31. struct FoldToList
  32. : ::boost::proto::or_<
  33. // Don't add the states_ terminal to the list
  34. ::boost::proto::when<
  35. ::boost::proto::terminal< state_copy_tag >
  36. , ::boost::proto::_state
  37. >
  38. // Put all other terminals at the head of the
  39. // list that we're building in the "state" parameter
  40. // first states for the eUML states
  41. , ::boost::proto::when<
  42. ::boost::proto::terminal< state_tag >
  43. , boost::fusion::cons< ::boost::proto::_, ::boost::proto::_state>(
  44. ::boost::proto::_, ::boost::proto::_state
  45. )
  46. >
  47. // then states from other front-ends
  48. , ::boost::proto::when<
  49. ::boost::proto::terminal< proto::_ >
  50. , boost::fusion::cons< ::boost::proto::_value, ::boost::proto::_state>(
  51. ::boost::proto::_value, ::boost::proto::_state
  52. )
  53. >
  54. // For left-shift operations, first fold the right
  55. // child to a list using the current state. Use
  56. // the result as the state parameter when folding
  57. // the left child to a list.
  58. , ::boost::proto::when<
  59. ::boost::proto::shift_left<FoldToList, FoldToList>
  60. , FoldToList(
  61. ::boost::proto::_left
  62. , ::boost::proto::call<FoldToList( ::boost::proto::_right, ::boost::proto::_state )>
  63. )
  64. >
  65. >
  66. {};
  67. }}}
  68. #endif //BOOST_MSM_BACK_FOLD_TO_LIST_H