terminal.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*==============================================================================
  2. Copyright (c) 2005-2010 Joel de Guzman
  3. Copyright (c) 2010 Thomas Heller
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef BOOST_PHOENIX_CORE_TERMINAL_HPP
  8. #define BOOST_PHOENIX_CORE_TERMINAL_HPP
  9. #include <boost/phoenix/core/limits.hpp>
  10. #include <boost/call_traits.hpp>
  11. #include <boost/is_placeholder.hpp>
  12. #include <boost/phoenix/core/actor.hpp>
  13. #include <boost/phoenix/core/meta_grammar.hpp>
  14. #include <boost/phoenix/core/terminal_fwd.hpp>
  15. #include <boost/proto/matches.hpp>
  16. #include <boost/proto/transform/lazy.hpp>
  17. #include <boost/proto/functional/fusion/at.hpp>
  18. #include <boost/type_traits/remove_pointer.hpp>
  19. #define BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(Template, Terminal, IsNullary, EvalFun)\
  20. namespace boost { namespace phoenix \
  21. { \
  22. namespace result_of \
  23. { \
  24. Template \
  25. struct is_nullary< \
  26. custom_terminal< \
  27. Terminal \
  28. > \
  29. > \
  30. : IsNullary \
  31. {}; \
  32. } \
  33. Template \
  34. struct is_custom_terminal<Terminal >: mpl::true_ {}; \
  35. \
  36. Template \
  37. struct custom_terminal<Terminal > : proto::call<EvalFun > {}; \
  38. }} \
  39. /**/
  40. namespace boost { namespace phoenix
  41. {
  42. template <typename T, typename Dummy>
  43. struct is_custom_terminal
  44. : mpl::false_ {};
  45. template <typename T, typename Dummy>
  46. struct custom_terminal;
  47. namespace expression
  48. {
  49. template <typename T, template <typename> class Actor = actor>
  50. struct terminal
  51. : proto::terminal<
  52. T//typename call_traits<T>::value_type
  53. >
  54. {
  55. typedef
  56. proto::basic_expr<
  57. proto::tag::terminal
  58. , proto::term<T>
  59. , 0
  60. >
  61. base_type;
  62. typedef Actor<base_type> type;
  63. static const type make(typename call_traits<T>::param_type t)
  64. {
  65. actor<base_type> const e = {base_type::make(t)};
  66. return e;
  67. }
  68. };
  69. }
  70. namespace rule
  71. {
  72. struct argument
  73. : proto::if_<boost::is_placeholder<proto::_value>()>
  74. {};
  75. struct custom_terminal
  76. : proto::if_<boost::phoenix::is_custom_terminal<proto::_value>()>
  77. {};
  78. struct terminal
  79. : proto::terminal<proto::_>
  80. {};
  81. }
  82. template <typename Dummy>
  83. struct meta_grammar::case_<proto::tag::terminal, Dummy>
  84. : proto::or_<
  85. enable_rule<rule::argument , Dummy>
  86. , enable_rule<rule::custom_terminal, Dummy>
  87. , enable_rule<rule::terminal , Dummy>
  88. >
  89. {};
  90. template <typename Dummy>
  91. struct default_actions::when<rule::custom_terminal, Dummy>
  92. : proto::lazy<
  93. custom_terminal<proto::_value>(
  94. proto::_value
  95. , _context
  96. )
  97. >
  98. {};
  99. namespace detail
  100. {
  101. template <typename N>
  102. struct placeholder_idx
  103. : mpl::int_<N::value>
  104. {};
  105. }
  106. template <typename Grammar>
  107. struct default_actions::when<rule::argument, Grammar>
  108. : proto::call<
  109. proto::functional::at(
  110. _env
  111. , proto::make<
  112. detail::placeholder_idx<
  113. proto::make<
  114. boost::is_placeholder<proto::_value>()
  115. >
  116. >()
  117. >
  118. )
  119. >
  120. {};
  121. }}
  122. #endif