1/*==============================================================================
2 Copyright (c) 2005-2010 Joel de Guzman
3 Copyright (c) 2010 Thomas Heller
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7==============================================================================*/
8#ifndef BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
9#define BOOST_PHOENIX_CORE_FUNCTION_EQUAL_HPP
10
11#include <boost/phoenix/core/limits.hpp>
12#include <boost/is_placeholder.hpp>
13#include <boost/mpl/int.hpp>
14#include <boost/phoenix/core/terminal.hpp>
15#include <boost/proto/matches.hpp>
16
17#ifndef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
18# include <boost/phoenix/core/detail/index_sequence.hpp>
19#endif
20
21namespace boost
22{
23 template <typename> class weak_ptr;
24}
25
26namespace boost { namespace phoenix
27{
28 template <typename>
29 struct actor;
30
31 namespace detail
32 {
33 struct compare
34 : proto::callable
35 {
36 typedef bool result_type;
37
38 template <typename A0, typename A1>
39 result_type operator()(A0 const & a0, A1 const & a1) const
40 {
41 return a0 == a1;
42 }
43
44 // hard wiring reference_wrapper and weak_ptr here ...
45 // **TODO** find out why boost bind does this ...
46 template <typename A0, typename A1>
47 result_type
48 operator()(
49 reference_wrapper<A0> const & a0
50 , reference_wrapper<A1> const & a1
51 ) const
52 {
53 return a0.get_pointer() == a1.get_pointer();
54 }
55
56 template <typename A0, typename A1>
57 result_type
58 operator()(weak_ptr<A0> const & a0, weak_ptr<A1> const & a1) const
59 {
60 return !(a0 < a1) && !(a1 < a0);
61 }
62 };
63
64 struct function_equal_otherwise;
65
66 struct function_equal_
67 : proto::when<
68 proto::if_<
69 proto::matches<proto::_, proto::_state>()
70 , proto::or_<
71 proto::when<
72 proto::terminal<proto::_>
73 , compare(
74 proto::_value
75 , proto::call<
76 proto::_value(proto::_state)
77 >
78 )
79 >
80 , proto::otherwise<function_equal_otherwise(proto::_, proto::_state)>
81 >
82 , proto::call<function_equal_otherwise()>
83 >
84 >
85 {};
86
87 struct function_equal_otherwise
88 : proto::callable
89 {
90 typedef bool result_type;
91
92 result_type operator()() const
93 {
94 return false;
95 }
96
97#ifdef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL
98 template <typename Expr1>
99 result_type operator()(Expr1 const& e1, Expr1 const& e2) const
100 {
101 return
102 this->evaluate(
103 e1
104 , e2
105 , mpl::int_<proto::arity_of<Expr1>::value - 1>()
106 );
107 }
108
109 private:
110 template <typename Expr1>
111 static BOOST_FORCEINLINE result_type
112 evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<0>)
113 {
114 return
115 function_equal_()(
116 proto::child_c<0>(e1)
117 , proto::child_c<0>(e2)
118 );
119 }
120
121 template <typename Expr1, int N>
122 static BOOST_FORCEINLINE result_type
123 evaluate(Expr1 const& e1, Expr1 const& e2, mpl::int_<N>)
124 {
125 return
126 evaluate(
127 e1
128 , e2
129 , mpl::int_<N - 1>()
130 ) && function_equal_()(
131 proto::child_c<N>(e1)
132 , proto::child_c<N>(e2)
133 );
134 }
135#else
136 template <typename Expr1>
137 result_type operator()(Expr1 const& e1, Expr1 const& e2) const
138 {
139 return
140 this->evaluate(
141 e1
142 , e2
143 , typename make_index_sequence<proto::arity_of<Expr1>::value>::type()
144 );
145 }
146
147 private:
148 template <typename Expr1, std::size_t... I>
149 static BOOST_FORCEINLINE result_type
150 evaluate(Expr1 const& e1, Expr1 const& e2, index_sequence<I...>)
151 {
152 bool result = true;
153 int dummy[] = { (result && (
154 result = function_equal_()(proto::child_c<I>(e1), proto::child_c<I>(e2))
155 ))... };
156 (void)dummy;
157 return result;
158 }
159#endif
160 };
161 }
162
163 template <typename Expr1, typename Expr2>
164 inline bool function_equal_impl(actor<Expr1> const& a1, actor<Expr2> const& a2)
165 {
166 return detail::function_equal_()(a1, a2);
167 }
168
169 template <typename Expr1, typename Expr2>
170 inline bool function_equal(actor<Expr1> const& a1, actor<Expr2> const& a2)
171 {
172 return function_equal_impl(a1, a2);
173 }
174
175}}
176
177#endif
178
179

source code of boost/libs/phoenix/include/boost/phoenix/core/function_equal.hpp