dynamic.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*==============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Copyright (c) 2004 Daniel Wallin
  4. Copyright (c) 2010 Thomas Heller
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ==============================================================================*/
  8. #ifndef BOOST_PHOENIX_SCOPE_DYNAMIC_HPP
  9. #define BOOST_PHOENIX_SCOPE_DYNAMIC_HPP
  10. #include <boost/phoenix/core/limits.hpp>
  11. #include <boost/assert.hpp>
  12. #include <boost/noncopyable.hpp>
  13. #include <boost/fusion/sequence/intrinsic/at.hpp>
  14. #include <boost/phoenix/core/expression.hpp>
  15. #include <boost/phoenix/core/meta_grammar.hpp>
  16. #include <boost/phoenix/core/call.hpp>
  17. #include <boost/phoenix/support/iterate.hpp>
  18. #include <boost/preprocessor/seq/for_each.hpp>
  19. #include <boost/preprocessor/seq/fold_left.hpp>
  20. #include <boost/preprocessor/punctuation/comma.hpp>
  21. #include <boost/type_traits/remove_pointer.hpp>
  22. #define BOOST_PHOENIX_DYNAMIC_TEMPLATE_PARAMS(R, DATA, I, ELEM) \
  23. BOOST_PP_COMMA_IF(I) BOOST_PP_TUPLE_ELEM(2, 0, ELEM) \
  24. /**/
  25. #define BOOST_PHOENIX_DYNAMIC_CTOR_INIT(R, DATA, I, ELEM) \
  26. BOOST_PP_COMMA_IF(I) BOOST_PP_TUPLE_ELEM(2, 1, ELEM)(init<I>(this)) \
  27. /**/
  28. #define BOOST_PHOENIX_DYNAMIC_MEMBER(R, DATA, I, ELEM) \
  29. BOOST_PP_CAT(member, BOOST_PP_INC(I)) BOOST_PP_TUPLE_ELEM(2, 1, ELEM); \
  30. /**/
  31. #define BOOST_PHOENIX_DYNAMIC_FILLER_0(X, Y) \
  32. ((X, Y)) BOOST_PHOENIX_DYNAMIC_FILLER_1 \
  33. /**/
  34. #define BOOST_PHOENIX_DYNAMIC_FILLER_1(X, Y) \
  35. ((X, Y)) BOOST_PHOENIX_DYNAMIC_FILLER_0 \
  36. /**/
  37. #define BOOST_PHOENIX_DYNAMIC_FILLER_0_END
  38. #define BOOST_PHOENIX_DYNAMIC_FILLER_1_END
  39. #define BOOST_PHOENIX_DYNAMIC_BASE(NAME, MEMBER) \
  40. struct NAME \
  41. : ::boost::phoenix::dynamic< \
  42. BOOST_PP_SEQ_FOR_EACH_I( \
  43. BOOST_PHOENIX_DYNAMIC_TEMPLATE_PARAMS \
  44. , _ \
  45. , MEMBER) \
  46. > \
  47. { \
  48. NAME() \
  49. : BOOST_PP_SEQ_FOR_EACH_I(BOOST_PHOENIX_DYNAMIC_CTOR_INIT, _, MEMBER) \
  50. {} \
  51. \
  52. BOOST_PP_SEQ_FOR_EACH_I(BOOST_PHOENIX_DYNAMIC_MEMBER, _, MEMBER) \
  53. } \
  54. /**/
  55. #define BOOST_PHOENIX_DYNAMIC(NAME, MEMBER) \
  56. BOOST_PHOENIX_DYNAMIC_BASE( \
  57. NAME \
  58. , BOOST_PP_CAT(BOOST_PHOENIX_DYNAMIC_FILLER_0 MEMBER,_END) \
  59. ) \
  60. /**/
  61. BOOST_PHOENIX_DEFINE_EXPRESSION(
  62. (boost)(phoenix)(dynamic_member)
  63. , (proto::terminal<proto::_>)
  64. (proto::terminal<proto::_>)
  65. )
  66. namespace boost { namespace phoenix
  67. {
  68. template <typename DynamicScope>
  69. struct dynamic_frame : noncopyable
  70. {
  71. typedef typename DynamicScope::tuple_type tuple_type;
  72. dynamic_frame(DynamicScope const& s)
  73. : tuple()
  74. , save(s.frame)
  75. , scope(s)
  76. {
  77. scope.frame = this;
  78. }
  79. template <typename Tuple>
  80. dynamic_frame(DynamicScope const& s, Tuple const& init)
  81. : tuple(init)
  82. , save(s.frame)
  83. , scope(s)
  84. {
  85. scope.frame = this;
  86. }
  87. ~dynamic_frame()
  88. {
  89. scope.frame = save;
  90. }
  91. tuple_type& data() { return tuple; }
  92. tuple_type const& data() const { return tuple; }
  93. private:
  94. tuple_type tuple;
  95. dynamic_frame *save;
  96. DynamicScope const& scope;
  97. };
  98. struct dynamic_member_eval
  99. {
  100. template <typename Sig>
  101. struct result;
  102. template <typename This, typename N, typename Scope, typename Context>
  103. struct result<This(N, Scope, Context)>
  104. {
  105. typedef
  106. typename boost::remove_pointer<
  107. typename proto::detail::uncvref<
  108. typename proto::result_of::value<Scope>::type
  109. >::type
  110. >::type
  111. scope_type;
  112. typedef
  113. typename scope_type::dynamic_frame_type::tuple_type
  114. tuple_type;
  115. typedef
  116. typename fusion::result_of::at_c<
  117. tuple_type
  118. , proto::detail::uncvref<
  119. typename proto::result_of::value<N>::type
  120. >::type::value
  121. >::type
  122. type;
  123. };
  124. template <typename N, typename Scope, typename Context>
  125. typename result<dynamic_member_eval(N, Scope, Context)>::type
  126. operator()(N, Scope s, Context const &) const
  127. {
  128. return
  129. fusion::at_c<
  130. proto::detail::uncvref<
  131. typename proto::result_of::value<N>::type
  132. >::type::value
  133. >(
  134. proto::value(s)->frame->data()
  135. );
  136. }
  137. };
  138. template <typename Dummy>
  139. struct default_actions::when<rule::dynamic_member, Dummy>
  140. : call<dynamic_member_eval>
  141. {};
  142. //#if defined(BOOST_PHOENIX_NO_VARIADIC_SCOPE)
  143. template <
  144. BOOST_PHOENIX_typename_A_void(BOOST_PHOENIX_DYNAMIC_LIMIT)
  145. , typename Dummy = void
  146. >
  147. struct dynamic;
  148. // Bring in the rest ...
  149. #include <boost/phoenix/scope/detail/cpp03/dynamic.hpp>
  150. //#else
  151. // // TODO:
  152. //#endif
  153. }}
  154. #endif