1 // Boost.Function library
2 
3 //  Copyright Douglas Gregor 2004. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 
8 #include <boost/function.hpp>
9 #include <boost/core/lightweight_test.hpp>
10 #include <boost/ref.hpp>
11 
12 #define BOOST_CHECK BOOST_TEST
13 
forty_two()14 static int forty_two() { return 42; }
15 
16 struct Seventeen
17 {
operator ()Seventeen18   int operator()() const { return 17; }
19 };
20 
21 struct ReturnInt
22 {
ReturnIntReturnInt23   explicit ReturnInt(int value) : value(value) {}
24 
operator ()ReturnInt25   int operator()() const { return value; }
26 
27   int value;
28 };
29 
operator ==(const ReturnInt & x,const ReturnInt & y)30 bool operator==(const ReturnInt& x, const ReturnInt& y)
31 { return x.value == y.value; }
32 
operator !=(const ReturnInt & x,const ReturnInt & y)33 bool operator!=(const ReturnInt& x, const ReturnInt& y)
34 { return x.value != y.value; }
35 
36 namespace contain_test {
37 
38 struct ReturnIntFE
39 {
ReturnIntFEcontain_test::ReturnIntFE40   explicit ReturnIntFE(int value) : value(value) {}
41 
operator ()contain_test::ReturnIntFE42   int operator()() const { return value; }
43 
44   int value;
45 };
46 
47 }
48 
49 #ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
50 
51 namespace contain_test {
52 # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
function_equal(const ReturnIntFE & x,const ReturnIntFE & y)53 bool function_equal(const ReturnIntFE& x, const ReturnIntFE& y)
54 { return x.value == y.value; }
55 # else
56 bool function_equal_impl(const ReturnIntFE& x, const ReturnIntFE& y, int)
57 { return x.value == y.value; }
58 # endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
59 }
60 #else // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
61 namespace boost {
62 # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
63 bool
function_equal(const contain_test::ReturnIntFE & x,const contain_test::ReturnIntFE & y)64 function_equal(const contain_test::ReturnIntFE& x,
65                const contain_test::ReturnIntFE& y)
66 { return x.value == y.value; }
67 # else
68 bool
69 function_equal_impl(const contain_test::ReturnIntFE& x,
70                     const contain_test::ReturnIntFE& y, int)
71 { return x.value == y.value; }
72 # endif
73 }
74 #endif
75 
target_test()76 static void target_test()
77 {
78   boost::function0<int> f;
79 
80   f = &forty_two;
81   BOOST_CHECK(*f.target<int (*)()>() == &forty_two);
82   BOOST_CHECK(!f.target<Seventeen>());
83 
84   f = Seventeen();
85   BOOST_CHECK(!f.target<int (*)()>());
86   BOOST_CHECK(f.target<Seventeen>());
87 
88   Seventeen this_seventeen;
89   f = boost::ref(this_seventeen);
90   BOOST_CHECK(!f.target<int (*)()>());
91   BOOST_CHECK(f.target<Seventeen>());
92   BOOST_CHECK(f.target<Seventeen>() == &this_seventeen);
93 
94   const Seventeen const_seventeen = this_seventeen;
95   f = boost::ref(const_seventeen);
96   BOOST_CHECK(!f.target<int (*)()>());
97   BOOST_CHECK(f.target<const Seventeen>());
98   BOOST_CHECK(f.target<const Seventeen>() == &const_seventeen);
99   BOOST_CHECK(f.target<const volatile Seventeen>());
100   BOOST_CHECK(!f.target<Seventeen>());
101   BOOST_CHECK(!f.target<volatile Seventeen>());
102 }
103 
equal_test()104 static void equal_test()
105 {
106   boost::function0<int> f;
107 
108   f = &forty_two;
109   BOOST_CHECK(f == &forty_two);
110   BOOST_CHECK(f != ReturnInt(17));
111 #if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
112   BOOST_CHECK(&forty_two == f);
113   BOOST_CHECK(ReturnInt(17) != f);
114 #endif
115 
116   BOOST_CHECK(f.contains(&forty_two));
117 
118   f = ReturnInt(17);
119   BOOST_CHECK(f != &forty_two);
120   BOOST_CHECK(f == ReturnInt(17));
121   BOOST_CHECK(f != ReturnInt(16));
122 #if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
123   BOOST_CHECK(&forty_two != f);
124   BOOST_CHECK(ReturnInt(17) == f);
125   BOOST_CHECK(ReturnInt(16) != f);
126 #endif
127 
128   BOOST_CHECK(f.contains(ReturnInt(17)));
129 
130   f = contain_test::ReturnIntFE(17);
131   BOOST_CHECK(f != &forty_two);
132   BOOST_CHECK(f == contain_test::ReturnIntFE(17));
133   BOOST_CHECK(f != contain_test::ReturnIntFE(16));
134 #if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
135   BOOST_CHECK(&forty_two != f);
136   BOOST_CHECK(contain_test::ReturnIntFE(17) == f);
137   BOOST_CHECK(contain_test::ReturnIntFE(16) != f);
138 #endif
139 
140   BOOST_CHECK(f.contains(contain_test::ReturnIntFE(17)));
141 
142 #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
143   boost::function<int(void)> g;
144 
145   g = &forty_two;
146   BOOST_CHECK(g == &forty_two);
147   BOOST_CHECK(g != ReturnInt(17));
148 #  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
149   BOOST_CHECK(&forty_two == g);
150   BOOST_CHECK(ReturnInt(17) != g);
151 #  endif
152 
153   g = ReturnInt(17);
154   BOOST_CHECK(g != &forty_two);
155   BOOST_CHECK(g == ReturnInt(17));
156   BOOST_CHECK(g != ReturnInt(16));
157 #  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
158   BOOST_CHECK(&forty_two != g);
159   BOOST_CHECK(ReturnInt(17) == g);
160   BOOST_CHECK(ReturnInt(16) != g);
161 #  endif
162 #endif
163 }
164 
ref_equal_test()165 static void ref_equal_test()
166 {
167   {
168     ReturnInt ri(17);
169     boost::function0<int> f = boost::ref(ri);
170 
171     // References and values are equal
172     BOOST_CHECK(f == boost::ref(ri));
173     BOOST_CHECK(f == ri);
174     BOOST_CHECK(boost::ref(ri) == f);
175     BOOST_CHECK(!(f != boost::ref(ri)));
176     BOOST_CHECK(!(f != ri));
177     BOOST_CHECK(!(boost::ref(ri) != f));
178 #if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
179     BOOST_CHECK(ri == f);
180     BOOST_CHECK(!(ri != f));
181 #endif
182 
183     // Values equal, references inequal
184     ReturnInt ri2(17);
185     BOOST_CHECK(f == ri2);
186     BOOST_CHECK(f != boost::ref(ri2));
187     BOOST_CHECK(boost::ref(ri2) != f);
188     BOOST_CHECK(!(f != ri2));
189     BOOST_CHECK(!(f == boost::ref(ri2)));
190     BOOST_CHECK(!(boost::ref(ri2) == f));
191 #if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
192     BOOST_CHECK(ri2 == f);
193     BOOST_CHECK(!(ri2 != f));
194 #endif
195   }
196 
197 #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
198   {
199     ReturnInt ri(17);
200     boost::function<int(void)> f = boost::ref(ri);
201 
202     // References and values are equal
203     BOOST_CHECK(f == boost::ref(ri));
204     BOOST_CHECK(f == ri);
205     BOOST_CHECK(boost::ref(ri) == f);
206     BOOST_CHECK(!(f != boost::ref(ri)));
207     BOOST_CHECK(!(f != ri));
208     BOOST_CHECK(!(boost::ref(ri) != f));
209 #  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
210     BOOST_CHECK(ri == f);
211     BOOST_CHECK(!(ri != f));
212 #  endif
213 
214     // Values equal, references inequal
215     ReturnInt ri2(17);
216     BOOST_CHECK(f == ri2);
217     BOOST_CHECK(f != boost::ref(ri2));
218     BOOST_CHECK(boost::ref(ri2) != f);
219     BOOST_CHECK(!(f != ri2));
220     BOOST_CHECK(!(f == boost::ref(ri2)));
221     BOOST_CHECK(!(boost::ref(ri2) == f));
222 #  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
223     BOOST_CHECK(ri2 == f);
224     BOOST_CHECK(!(ri2 != f));
225 #  endif
226   }
227 #endif
228 }
229 
main()230 int main()
231 {
232   target_test();
233   equal_test();
234   ref_equal_test();
235 
236   return boost::report_errors();
237 }
238