scoped_environment.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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_SCOPE_SCOPED_ENVIRONMENT_HPP
  8. #define BOOST_PHOENIX_SCOPE_SCOPED_ENVIRONMENT_HPP
  9. #include <boost/phoenix/core/limits.hpp>
  10. #include <boost/mpl/int.hpp>
  11. #include <boost/fusion/sequence/sequence_facade.hpp>
  12. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  13. #include <boost/fusion/sequence/intrinsic/end.hpp>
  14. #include <boost/fusion/sequence/intrinsic/size.hpp>
  15. #include <boost/fusion/sequence/intrinsic/value_at.hpp>
  16. #include <boost/fusion/sequence/intrinsic/at.hpp>
  17. #include <boost/fusion/support/category_of.hpp>
  18. #include <boost/fusion/include/pop_front.hpp>
  19. #include <boost/utility/result_of.hpp>
  20. namespace boost { namespace phoenix
  21. {
  22. template<typename Env, typename OuterEnv, typename Locals, typename Map>
  23. struct scoped_environment
  24. : fusion::sequence_facade<
  25. scoped_environment<Env, OuterEnv, Locals, Map>
  26. , fusion::random_access_traversal_tag
  27. >
  28. {
  29. typedef Env env_type;
  30. typedef OuterEnv outer_env_type;
  31. typedef Locals locals_type;
  32. typedef Map map_type;
  33. scoped_environment(
  34. Env const & env_
  35. , OuterEnv const &outer_env_
  36. , Locals const &locals_
  37. )
  38. : env(env_)
  39. , outer_env(outer_env_)
  40. , locals(locals_)
  41. {}
  42. scoped_environment(scoped_environment const & o)
  43. : env(o.env)
  44. , outer_env(o.outer_env)
  45. , locals(o.locals)
  46. {}
  47. Env const & env;
  48. OuterEnv const & outer_env;
  49. Locals const & locals;
  50. typedef typename
  51. fusion::result_of::pop_front<
  52. typename add_const<
  53. typename proto::detail::uncvref<Env>::type
  54. >::type
  55. >::type
  56. args_type;
  57. args_type args() const
  58. {
  59. return fusion::pop_front(env);
  60. }
  61. #define BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(INTRINSIC) \
  62. template <typename Seq> \
  63. struct INTRINSIC \
  64. { \
  65. typedef \
  66. typename fusion::result_of::INTRINSIC< \
  67. typename mpl::eval_if_c< \
  68. is_const< \
  69. typename remove_reference< \
  70. typename Seq::env_type \
  71. >::type \
  72. >::value \
  73. , add_const< \
  74. typename proto::detail::uncvref< \
  75. typename Seq::env_type \
  76. >::type \
  77. > \
  78. , proto::detail::uncvref< \
  79. typename Seq::env_type \
  80. > \
  81. >::type \
  82. >::type \
  83. type; \
  84. \
  85. static type call(Seq & seq) \
  86. { \
  87. return fusion::INTRINSIC(seq.env); \
  88. } \
  89. } \
  90. /**/
  91. BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(begin);
  92. BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(end);
  93. BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(size);
  94. #undef BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT
  95. template <typename Seq, typename N>
  96. struct value_at
  97. {
  98. typedef
  99. typename fusion::result_of::value_at<
  100. typename mpl::eval_if_c<
  101. is_const<
  102. typename remove_reference<
  103. typename Seq::env_type
  104. >::type
  105. >::value
  106. , add_const<
  107. typename proto::detail::uncvref<
  108. typename Seq::env_type
  109. >::type
  110. >
  111. , proto::detail::uncvref<
  112. typename Seq::env_type
  113. >
  114. >::type
  115. , N
  116. >::type
  117. type;
  118. };
  119. template <typename Seq, typename N>
  120. struct at
  121. {
  122. typedef
  123. typename fusion::result_of::at<
  124. typename mpl::eval_if_c<
  125. is_const<
  126. typename remove_reference<
  127. typename Seq::env_type
  128. >::type
  129. >::value
  130. , add_const<
  131. typename proto::detail::uncvref<
  132. typename Seq::env_type
  133. >::type
  134. >
  135. , proto::detail::uncvref<
  136. typename Seq::env_type
  137. >
  138. >::type
  139. , N
  140. >::type
  141. type;
  142. static type call(Seq & seq)
  143. {
  144. return fusion::at<N>(seq.env);
  145. }
  146. };
  147. };
  148. template <typename Env, typename Dummy = void>
  149. struct is_scoped_environment : mpl::false_ {};
  150. template <typename Env>
  151. struct is_scoped_environment<Env&> : is_scoped_environment<Env> {};
  152. template <typename Env, typename OuterEnv, typename Locals, typename Map>
  153. struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> >
  154. : mpl::true_
  155. {};
  156. template <typename Env, typename OuterEnv, typename Locals, typename Map>
  157. struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> const>
  158. : mpl::true_
  159. {};
  160. }}
  161. #endif