function_equal.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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_FUNCTION_EQUAL_HPP
  8. #define BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
  9. #include <boost/phoenix/core/limits.hpp>
  10. #include <boost/is_placeholder.hpp>
  11. #include <boost/mpl/bool.hpp>
  12. #include <boost/phoenix/core/terminal.hpp>
  13. #include <boost/proto/matches.hpp>
  14. #ifndef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
  15. # include <boost/phoenix/core/detail/index_sequence.hpp>
  16. #endif
  17. namespace boost
  18. {
  19. template <typename> class weak_ptr;
  20. }
  21. namespace boost { namespace phoenix
  22. {
  23. template <typename>
  24. struct actor;
  25. namespace detail
  26. {
  27. struct compare
  28. : proto::callable
  29. {
  30. typedef bool result_type;
  31. template <typename A0, typename A1>
  32. result_type operator()(A0 const & a0, A1 const & a1) const
  33. {
  34. return a0 == a1;
  35. }
  36. // hard wiring reference_wrapper and weak_ptr here ...
  37. // **TODO** find out why boost bind does this ...
  38. template <typename A0, typename A1>
  39. result_type
  40. operator()(
  41. reference_wrapper<A0> const & a0
  42. , reference_wrapper<A1> const & a1
  43. ) const
  44. {
  45. return a0.get_pointer() == a1.get_pointer();
  46. }
  47. template <typename A0, typename A1>
  48. result_type
  49. operator()(weak_ptr<A0> const & a0, weak_ptr<A1> const & a1) const
  50. {
  51. return !(a0 < a1) && !(a1 < a0);
  52. }
  53. };
  54. struct function_equal_otherwise;
  55. struct function_equal_
  56. : proto::when<
  57. proto::if_<
  58. proto::matches<proto::_, proto::_state>()
  59. , proto::or_<
  60. proto::when<
  61. proto::terminal<proto::_>
  62. , compare(
  63. proto::_value
  64. , proto::call<
  65. proto::_value(proto::_state)
  66. >
  67. )
  68. >
  69. , proto::otherwise<function_equal_otherwise(proto::_, proto::_state)>
  70. >
  71. , proto::call<function_equal_otherwise()>
  72. >
  73. >
  74. {};
  75. struct function_equal_otherwise
  76. : proto::callable
  77. {
  78. typedef bool result_type;
  79. result_type operator()() const
  80. {
  81. return false;
  82. }
  83. #ifdef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
  84. template <typename Expr1>
  85. result_type operator()(Expr1 const& e1, Expr1 const& e2) const
  86. {
  87. return
  88. this->evaluate(
  89. e1
  90. , e2
  91. , typename proto::arity_of<Expr1>::type()
  92. );
  93. }
  94. private:
  95. #include <boost/phoenix/core/detail/cpp03/function_equal.hpp>
  96. #else
  97. template <typename Expr1>
  98. result_type operator()(Expr1 const& e1, Expr1 const& e2) const
  99. {
  100. return
  101. this->evaluate(
  102. e1
  103. , e2
  104. , typename make_index_sequence<proto::arity_of<Expr1>::value>::type()
  105. );
  106. }
  107. private:
  108. template <typename Expr1>
  109. result_type
  110. evaluate(Expr1 const& /*e1*/, Expr1 const& /*e2*/, index_sequence<>) const
  111. {
  112. return true;
  113. }
  114. template <typename Expr1, std::size_t Head, std::size_t... Tail>
  115. result_type
  116. evaluate(Expr1 const& e1, Expr1 const& e2, index_sequence<Head, Tail...>) const
  117. {
  118. return
  119. function_equal_()(proto::child_c<Head>(e1), proto::child_c<Head>(e2)) &&
  120. this->evaluate(
  121. e1
  122. , e2
  123. , index_sequence<Tail...>()
  124. );
  125. }
  126. #endif
  127. };
  128. }
  129. template <typename Expr1, typename Expr2>
  130. inline bool function_equal_impl(actor<Expr1> const& a1, actor<Expr2> const& a2)
  131. {
  132. return detail::function_equal_()(a1, a2);
  133. }
  134. template <typename Expr1, typename Expr2>
  135. inline bool function_equal(actor<Expr1> const& a1, actor<Expr2> const& a2)
  136. {
  137. return function_equal_impl(a1, a2);
  138. }
  139. }}
  140. #endif