if.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*==============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Copyright (c) 2010 Eric Niebler
  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_STATEMENT_IF_HPP
  8. #define BOOST_PHOENIX_STATEMENT_IF_HPP
  9. #include <boost/phoenix/config.hpp>
  10. #include <boost/phoenix/core/limits.hpp>
  11. #include <boost/phoenix/core/actor.hpp>
  12. #include <boost/phoenix/core/call.hpp>
  13. #include <boost/phoenix/core/expression.hpp>
  14. #include <boost/phoenix/core/meta_grammar.hpp>
  15. #include <boost/phoenix/core/is_actor.hpp>
  16. #ifdef BOOST_MSVC
  17. #pragma warning(push)
  18. #pragma warning(disable: 4355) // 'this' used in base member initializer list
  19. #endif
  20. namespace boost { namespace phoenix
  21. {
  22. template <typename> struct if_actor;
  23. }}
  24. BOOST_PHOENIX_DEFINE_EXPRESSION_EXT(
  25. if_actor
  26. , (boost)(phoenix)(if_)
  27. , (meta_grammar) // Cond
  28. (meta_grammar) // Then
  29. )
  30. BOOST_PHOENIX_DEFINE_EXPRESSION(
  31. (boost)(phoenix)(if_else_statement)
  32. , (meta_grammar) // Cond
  33. (meta_grammar) // Then
  34. (meta_grammar) // Else
  35. )
  36. namespace boost { namespace phoenix
  37. {
  38. ////////////////////////////////////////////////////////////////////////////
  39. // If-Else statements
  40. ////////////////////////////////////////////////////////////////////////////
  41. // Function for evaluating lambdas like:
  42. // if_( foo )[ bar ]
  43. // and
  44. // if_( foo )[ bar ].else_[ baz ]
  45. struct if_else_eval
  46. {
  47. typedef void result_type;
  48. template<typename Cond, typename Then, typename Context>
  49. result_type
  50. operator()(Cond const & cond, Then const & then, Context const & ctx) const
  51. {
  52. if(boost::phoenix::eval(cond, ctx))
  53. boost::phoenix::eval(then, ctx);
  54. }
  55. template<typename Cond, typename Then, typename Else, typename Context>
  56. result_type
  57. operator()(
  58. Cond const & cond
  59. , Then const & then
  60. , Else const & else_
  61. , Context const & ctx
  62. ) const
  63. {
  64. if(boost::phoenix::eval(cond, ctx))
  65. boost::phoenix::eval(then, ctx);
  66. else
  67. boost::phoenix::eval(else_, ctx);
  68. }
  69. };
  70. template <typename Dummy>
  71. struct default_actions::when<rule::if_, Dummy>
  72. : call<if_else_eval, Dummy>
  73. {};
  74. template <typename Dummy>
  75. struct default_actions::when<rule::if_else_statement, Dummy>
  76. : call<if_else_eval, Dummy>
  77. {};
  78. // Generator for .else_[ expr ] branch.
  79. template<typename Cond, typename Then>
  80. struct else_gen
  81. {
  82. else_gen(Cond const & cond_, Then const & then_)
  83. : cond(cond_)
  84. , then(then_) {}
  85. template<typename Else>
  86. typename expression::if_else_statement<Cond, Then, Else>::type const
  87. operator[](Else const & else_) const
  88. {
  89. return expression::if_else_statement<Cond, Then, Else>::make(cond, then, else_);
  90. }
  91. Cond cond;
  92. Then then;
  93. };
  94. // We subclass actor so we can provide the member else_ (which is an
  95. // else_gen responsible for the .else_[ expr ] branch).
  96. template<typename Expr>
  97. struct if_actor : actor<Expr>
  98. {
  99. typedef actor<Expr> base_type;
  100. if_actor(base_type const & base)
  101. : base_type(base)
  102. , else_(proto::child_c<0>(*this), proto::child_c<1>(*this))
  103. {}
  104. typedef typename proto::result_of::child_c<Expr, 0>::type cond_type;
  105. typedef typename proto::result_of::child_c<Expr, 1>::type then_type;
  106. else_gen<cond_type, then_type> else_;
  107. };
  108. template <typename Expr>
  109. struct is_actor<if_actor<Expr> >
  110. : mpl::true_
  111. {};
  112. // Generator for if( cond )[ then ] branch.
  113. template<typename Cond>
  114. struct if_gen
  115. {
  116. if_gen(Cond const & cond_)
  117. : cond(cond_) {}
  118. template<typename Then>
  119. typename expression::if_<Cond, Then>::type const
  120. operator[](Then const & then) const
  121. {
  122. return expression::if_<Cond, Then>::make(cond, then);
  123. }
  124. Cond cond;
  125. };
  126. template<typename Cond>
  127. inline
  128. if_gen<Cond> const
  129. if_(Cond const & cond)
  130. {
  131. return if_gen<Cond>(cond);
  132. }
  133. }}
  134. #ifdef BOOST_MSVC
  135. #pragma warning(pop)
  136. #endif
  137. #endif