File indexing completed on 2025-01-18 09:45:07
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
0009 #define BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
0010
0011 #include <boost/phoenix/core/limits.hpp>
0012 #include <boost/is_placeholder.hpp>
0013 #include <boost/mpl/int.hpp>
0014 #include <boost/phoenix/core/terminal.hpp>
0015 #include <boost/proto/matches.hpp>
0016
0017 #ifndef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
0018 # include <boost/phoenix/core/detail/index_sequence.hpp>
0019 #endif
0020
0021 namespace boost
0022 {
0023 template <typename> class weak_ptr;
0024 }
0025
0026 namespace boost { namespace phoenix
0027 {
0028 template <typename>
0029 struct actor;
0030
0031 namespace detail
0032 {
0033 struct compare
0034 : proto::callable
0035 {
0036 typedef bool result_type;
0037
0038 template <typename A0, typename A1>
0039 result_type operator()(A0 const & a0, A1 const & a1) const
0040 {
0041 return a0 == a1;
0042 }
0043
0044
0045
0046 template <typename A0, typename A1>
0047 result_type
0048 operator()(
0049 reference_wrapper<A0> const & a0
0050 , reference_wrapper<A1> const & a1
0051 ) const
0052 {
0053 return a0.get_pointer() == a1.get_pointer();
0054 }
0055
0056 template <typename A0, typename A1>
0057 result_type
0058 operator()(weak_ptr<A0> const & a0, weak_ptr<A1> const & a1) const
0059 {
0060 return !(a0 < a1) && !(a1 < a0);
0061 }
0062 };
0063
0064 struct function_equal_otherwise;
0065
0066 struct function_equal_
0067 : proto::when<
0068 proto::if_<
0069 proto::matches<proto::_, proto::_state>()
0070 , proto::or_<
0071 proto::when<
0072 proto::terminal<proto::_>
0073 , compare(
0074 proto::_value
0075 , proto::call<
0076 proto::_value(proto::_state)
0077 >
0078 )
0079 >
0080 , proto::otherwise<function_equal_otherwise(proto::_, proto::_state)>
0081 >
0082 , proto::call<function_equal_otherwise()>
0083 >
0084 >
0085 {};
0086
0087 struct function_equal_otherwise
0088 : proto::callable
0089 {
0090 typedef bool result_type;
0091
0092 result_type operator()() const
0093 {
0094 return false;
0095 }
0096
0097 #ifdef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
0098 template <typename Expr1>
0099 result_type operator()(Expr1 const& e1, Expr1 const& e2) const
0100 {
0101 return
0102 this->evaluate(
0103 e1
0104 , e2
0105 , mpl::int_<proto::arity_of<Expr1>::value - 1>()
0106 );
0107 }
0108
0109 private:
0110 template <typename Expr1>
0111 static BOOST_FORCEINLINE result_type
0112 evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<0>)
0113 {
0114 return
0115 function_equal_()(
0116 proto::child_c<0>(e1)
0117 , proto::child_c<0>(e2)
0118 );
0119 }
0120
0121 template <typename Expr1, int N>
0122 static BOOST_FORCEINLINE result_type
0123 evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<N>)
0124 {
0125 return
0126 evaluate(
0127 e1
0128 , e2
0129 , mpl::int_<N - 1>()
0130 ) && function_equal_()(
0131 proto::child_c<N>(e1)
0132 , proto::child_c<N>(e2)
0133 );
0134 }
0135 #else
0136 template <typename Expr1>
0137 result_type operator()(Expr1 const& e1, Expr1 const& e2) const
0138 {
0139 return
0140 this->evaluate(
0141 e1
0142 , e2
0143 , typename make_index_sequence<proto::arity_of<Expr1>::value>::type()
0144 );
0145 }
0146
0147 private:
0148 template <typename Expr1, std::size_t... I>
0149 static BOOST_FORCEINLINE result_type
0150 evaluate(Expr1 const& e1, Expr1 const& e2, index_sequence<I...>)
0151 {
0152 bool result = true;
0153 int dummy[] = { (result && (
0154 result = function_equal_()(proto::child_c<I>(e1), proto::child_c<I>(e2))
0155 ))... };
0156 (void)dummy;
0157 return result;
0158 }
0159 #endif
0160 };
0161 }
0162
0163 template <typename Expr1, typename Expr2>
0164 inline bool function_equal_impl(actor<Expr1> const& a1, actor<Expr2> const& a2)
0165 {
0166 return detail::function_equal_()(a1, a2);
0167 }
0168
0169 template <typename Expr1, typename Expr2>
0170 inline bool function_equal(actor<Expr1> const& a1, actor<Expr2> const& a2)
0171 {
0172 return function_equal_impl(a1, a2);
0173 }
0174
0175 }}
0176
0177 #endif
0178