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