/Src/Dependencies/Boost/boost/spirit/home/phoenix/statement/detail/switch.hpp

http://hadesmem.googlecode.com/ · C++ Header · 172 lines · 141 code · 24 blank · 7 comment · 0 complexity · 0ad99af3f6fade09dde466d9fe3aea13 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2007 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #ifndef PHOENIX_STATEMENT_DETAIL_SWITCH_HPP
  7. #define PHOENIX_STATEMENT_DETAIL_SWITCH_HPP
  8. #include <boost/spirit/home/phoenix/core/nothing.hpp>
  9. #include <boost/fusion/include/vector.hpp>
  10. #include <boost/fusion/include/as_vector.hpp>
  11. #include <boost/fusion/include/push_back.hpp>
  12. #include <boost/fusion/include/push_front.hpp>
  13. #include <boost/fusion/include/begin.hpp>
  14. #include <boost/fusion/include/size.hpp>
  15. #include <boost/fusion/include/value_of.hpp>
  16. #include <boost/fusion/include/is_sequence.hpp>
  17. #include <boost/mpl/identity.hpp>
  18. #include <boost/mpl/bool.hpp>
  19. #include <boost/mpl/eval_if.hpp>
  20. #include <boost/mpl/if.hpp>
  21. namespace boost { namespace phoenix
  22. {
  23. template <typename Actor, typename K, K Value>
  24. struct switch_case;
  25. template <typename Actor>
  26. struct default_case;
  27. namespace detail
  28. {
  29. template <typename T>
  30. struct is_default_case : mpl::bool_<T::is_default> {};
  31. template <typename A0, typename A1>
  32. struct compose_case_a
  33. {
  34. // here, A0 and A1 are both switch cases
  35. typedef typename
  36. mpl::if_<
  37. is_default_case<A1>
  38. , fusion::vector<actor<A1>, actor<A0> >
  39. , fusion::vector<actor<A0>, actor<A1> >
  40. >::type
  41. type;
  42. static type
  43. eval(A0 const& _0, A1 const& _1, mpl::false_)
  44. {
  45. return type(_0, _1);
  46. }
  47. static type
  48. eval(A0 const& _0, A1 const& _1, mpl::true_)
  49. {
  50. return type(_1, _0);
  51. }
  52. static type
  53. eval(A0 const& _0, A1 const& _1)
  54. {
  55. return eval(_0, _1, is_default_case<A1>());
  56. }
  57. };
  58. template <typename Seq, typename Case>
  59. struct compose_case_b
  60. {
  61. typedef typename fusion::result_of::as_vector<
  62. typename mpl::eval_if<
  63. is_default_case<Case>
  64. , fusion::result_of::push_front<Seq const, actor<Case> >
  65. , fusion::result_of::push_back<Seq const, actor<Case> >
  66. >::type>::type
  67. type;
  68. static type
  69. eval(Seq const& seq, Case const& case_, mpl::false_)
  70. {
  71. return fusion::as_vector(
  72. fusion::push_back(seq, actor<Case>(case_)));
  73. }
  74. static type
  75. eval(Seq const& seq, Case const& case_, mpl::true_)
  76. {
  77. return fusion::as_vector(
  78. fusion::push_front(seq, actor<Case>(case_)));
  79. }
  80. static type
  81. eval(Seq const& seq, Case const& case_)
  82. {
  83. return eval(seq, case_, is_default_case<Case>());
  84. }
  85. };
  86. template <typename Cases>
  87. struct ensure_default
  88. {
  89. typedef
  90. is_default_case<
  91. typename fusion::result_of::value_of<
  92. typename fusion::result_of::begin<Cases>::type
  93. >::type
  94. >
  95. is_default_case_;
  96. typedef typename
  97. mpl::eval_if<
  98. is_default_case_
  99. , mpl::identity<Cases>
  100. , fusion::result_of::push_front<
  101. Cases const, actor<default_case<actor<null_actor> > > >
  102. >::type
  103. type;
  104. static type
  105. eval(Cases const& cases, mpl::false_);
  106. static type
  107. eval(Cases const& cases, mpl::true_)
  108. {
  109. return cases;
  110. }
  111. static type
  112. eval(Cases const& cases)
  113. {
  114. return eval(cases, is_default_case_());
  115. }
  116. };
  117. template <typename Cond, typename Cases>
  118. struct switch_composite
  119. {
  120. BOOST_STATIC_ASSERT(fusion::traits::is_sequence<Cases>::value);
  121. typedef ensure_default<Cases> ensure_default_;
  122. typedef typename
  123. fusion::result_of::as_vector<
  124. typename fusion::result_of::push_front<
  125. typename ensure_default_::type, Cond>::type
  126. >::type
  127. tuple_type;
  128. typedef
  129. composite<
  130. detail::switch_eval<fusion::result_of::size<tuple_type>::value-2>
  131. , tuple_type>
  132. type;
  133. static type
  134. eval(Cond const& cond, Cases const& cases)
  135. {
  136. return fusion::as_vector(
  137. fusion::push_front(ensure_default_::eval(cases), cond));
  138. }
  139. };
  140. template <typename Cond, typename Cases>
  141. struct switch_composite_actor
  142. {
  143. typedef actor<typename switch_composite<Cond, Cases>::type> type;
  144. };
  145. }
  146. }}
  147. #endif