]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/signals2/test/signal_test.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / signals2 / test / signal_test.cpp
1 // Boost.Signals library
2
3 // Copyright Frank Mori Hess 2008-2009.
4 // Copyright Douglas Gregor 2001-2003.
5 //
6 // Use, modification and
7 // distribution is subject to the Boost Software License, Version
8 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 // For more information, see http://www.boost.org
12
13 #include <boost/bind.hpp>
14 #include <boost/optional.hpp>
15 #include <boost/test/minimal.hpp>
16 #include <boost/signals2.hpp>
17 #include <functional>
18 #include <iostream>
19 #include <typeinfo>
20
21 template<typename T>
22 struct max_or_default {
23 typedef T result_type;
24 template<typename InputIterator>
25 typename InputIterator::value_type
26 operator()(InputIterator first, InputIterator last) const
27 {
28 boost::optional<T> max;
29 for (; first != last; ++first)
30 {
31 try
32 {
33 if(!max) max = *first;
34 else max = (*first > max.get())? *first : max;
35 }
36 catch(const boost::bad_weak_ptr &)
37 {}
38 }
39 if(max) return max.get();
40 return T();
41 }
42 };
43
44 struct make_int {
45 make_int(int n, int cn) : N(n), CN(cn) {}
46
47 int operator()() { return N; }
48 int operator()() const { return CN; }
49
50 int N;
51 int CN;
52 };
53
54 template<int N>
55 struct make_increasing_int {
56 make_increasing_int() : n(N) {}
57
58 int operator()() const { return n++; }
59
60 mutable int n;
61 };
62
63 static void
64 test_zero_args()
65 {
66 make_int i42(42, 41);
67 make_int i2(2, 1);
68 make_int i72(72, 71);
69 make_int i63(63, 63);
70 make_int i62(62, 61);
71
72 {
73 boost::signals2::signal<int (), max_or_default<int> > s0;
74
75 std::cout << "sizeof(signal) = " << sizeof(s0) << std::endl;
76 boost::signals2::connection c2 = s0.connect(i2);
77 boost::signals2::connection c72 = s0.connect(72, i72);
78 boost::signals2::connection c62 = s0.connect(60, i62);
79 boost::signals2::connection c42 = s0.connect(i42);
80
81 BOOST_CHECK(s0() == 72);
82
83 s0.disconnect(72);
84 BOOST_CHECK(s0() == 62);
85
86 c72.disconnect(); // Double-disconnect should be safe
87 BOOST_CHECK(s0() == 62);
88
89 s0.disconnect(72); // Triple-disconect should be safe
90 BOOST_CHECK(s0() == 62);
91
92 // Also connect 63 in the same group as 62
93 s0.connect(60, i63);
94 BOOST_CHECK(s0() == 63);
95
96 // Disconnect all of the 60's
97 s0.disconnect(60);
98 BOOST_CHECK(s0() == 42);
99
100 c42.disconnect();
101 BOOST_CHECK(s0() == 2);
102
103 c2.disconnect();
104 BOOST_CHECK(s0() == 0);
105 }
106
107 {
108 boost::signals2::signal<int (), max_or_default<int> > s0;
109 boost::signals2::connection c2 = s0.connect(i2);
110 boost::signals2::connection c72 = s0.connect(i72);
111 boost::signals2::connection c62 = s0.connect(i62);
112 boost::signals2::connection c42 = s0.connect(i42);
113
114 const boost::signals2::signal<int (), max_or_default<int> >& cs0 = s0;
115 BOOST_CHECK(cs0() == 72);
116 }
117
118 {
119 make_increasing_int<7> i7;
120 make_increasing_int<10> i10;
121
122 boost::signals2::signal<int (), max_or_default<int> > s0;
123 boost::signals2::connection c7 = s0.connect(i7);
124 boost::signals2::connection c10 = s0.connect(i10);
125
126 BOOST_CHECK(s0() == 10);
127 BOOST_CHECK(s0() == 11);
128 }
129 }
130
131 static void
132 test_one_arg()
133 {
134 boost::signals2::signal<int (int value), max_or_default<int> > s1;
135
136 s1.connect(std::negate<int>());
137 s1.connect(boost::bind(std::multiplies<int>(), 2, _1));
138
139 BOOST_CHECK(s1(1) == 2);
140 BOOST_CHECK(s1(-1) == 1);
141 }
142
143 static void
144 test_signal_signal_connect()
145 {
146 typedef boost::signals2::signal<int (int value), max_or_default<int> > signal_type;
147 signal_type s1;
148
149 s1.connect(std::negate<int>());
150
151 BOOST_CHECK(s1(3) == -3);
152
153 {
154 signal_type s2;
155 s1.connect(s2);
156 s2.connect(boost::bind(std::multiplies<int>(), 2, _1));
157 s2.connect(boost::bind(std::multiplies<int>(), -3, _1));
158
159 BOOST_CHECK(s2(-3) == 9);
160 BOOST_CHECK(s1(3) == 6);
161 } // s2 goes out of scope and disconnects
162 BOOST_CHECK(s1(3) == -3);
163 }
164
165 template<typename ResultType>
166 ResultType disconnecting_slot(const boost::signals2::connection &conn, int)
167 {
168 conn.disconnect();
169 return ResultType();
170 }
171
172 #ifdef BOOST_NO_VOID_RETURNS
173 template<>
174 void disconnecting_slot<void>(const boost::signals2::connection &conn, int)
175 {
176 conn.disconnect();
177 return;
178 }
179 #endif
180
181 template<typename ResultType>
182 void test_extended_slot()
183 {
184 {
185 typedef boost::signals2::signal<ResultType (int)> signal_type;
186 typedef typename signal_type::extended_slot_type slot_type;
187 signal_type sig;
188 // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
189 ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
190 slot_type myslot(fp);
191 sig.connect_extended(myslot);
192 BOOST_CHECK(sig.num_slots() == 1);
193 sig(0);
194 BOOST_CHECK(sig.num_slots() == 0);
195 }
196 { // test 0 arg signal
197 typedef boost::signals2::signal<ResultType ()> signal_type;
198 typedef typename signal_type::extended_slot_type slot_type;
199 signal_type sig;
200 // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
201 ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
202 slot_type myslot(fp, _1, 0);
203 sig.connect_extended(myslot);
204 BOOST_CHECK(sig.num_slots() == 1);
205 sig();
206 BOOST_CHECK(sig.num_slots() == 0);
207 }
208 // test disconnection by slot
209 {
210 typedef boost::signals2::signal<ResultType (int)> signal_type;
211 typedef typename signal_type::extended_slot_type slot_type;
212 signal_type sig;
213 // attempting to work around msvc 7.1 bug by explicitly assigning to a function pointer
214 ResultType (*fp)(const boost::signals2::connection &conn, int) = &disconnecting_slot<ResultType>;
215 slot_type myslot(fp);
216 sig.connect_extended(myslot);
217 BOOST_CHECK(sig.num_slots() == 1);
218 sig.disconnect(fp);
219 BOOST_CHECK(sig.num_slots() == 0);
220 }
221 }
222
223 void increment_arg(int &value)
224 {
225 ++value;
226 }
227
228 static void
229 test_reference_args()
230 {
231 typedef boost::signals2::signal<void (int &)> signal_type;
232 signal_type s1;
233
234 s1.connect(&increment_arg);
235 int value = 0;
236 s1(value);
237 BOOST_CHECK(value == 1);
238 }
239
240 static void
241 test_typedefs_etc()
242 {
243 typedef boost::signals2::signal<int (double, long)> signal_type;
244 typedef signal_type::slot_type slot_type;
245
246 BOOST_CHECK(typeid(signal_type::slot_result_type) == typeid(int));
247 BOOST_CHECK(typeid(signal_type::result_type) == typeid(boost::optional<int>));
248 BOOST_CHECK(typeid(signal_type::arg<0>::type) == typeid(double));
249 BOOST_CHECK(typeid(signal_type::arg<1>::type) == typeid(long));
250 BOOST_CHECK(typeid(signal_type::arg<0>::type) == typeid(signal_type::first_argument_type));
251 BOOST_CHECK(typeid(signal_type::arg<1>::type) == typeid(signal_type::second_argument_type));
252 BOOST_CHECK(typeid(signal_type::signature_type) == typeid(int (double, long)));
253 BOOST_CHECK(signal_type::arity == 2);
254
255 BOOST_CHECK(typeid(slot_type::result_type) == typeid(signal_type::slot_result_type));
256 BOOST_CHECK(typeid(slot_type::arg<0>::type) == typeid(signal_type::arg<0>::type));
257 BOOST_CHECK(typeid(slot_type::arg<1>::type) == typeid(signal_type::arg<1>::type));
258 BOOST_CHECK(typeid(slot_type::arg<0>::type) == typeid(slot_type::first_argument_type));
259 BOOST_CHECK(typeid(slot_type::arg<1>::type) == typeid(slot_type::second_argument_type));
260 BOOST_CHECK(typeid(slot_type::signature_type) == typeid(signal_type::signature_type));
261 BOOST_CHECK(slot_type::arity == signal_type::arity);
262
263 typedef boost::signals2::signal<void (short)> unary_signal_type;
264 BOOST_CHECK(typeid(unary_signal_type::slot_result_type) == typeid(void));
265 BOOST_CHECK(typeid(unary_signal_type::argument_type) == typeid(short));
266 BOOST_CHECK(typeid(unary_signal_type::slot_type::argument_type) == typeid(short));
267 }
268
269 class dummy_combiner
270 {
271 public:
272 typedef int result_type;
273
274 dummy_combiner(result_type return_value): _return_value(return_value)
275 {}
276 template<typename SlotIterator>
277 result_type operator()(SlotIterator, SlotIterator)
278 {
279 return _return_value;
280 }
281 private:
282 result_type _return_value;
283 };
284
285 static void
286 test_set_combiner()
287 {
288 typedef boost::signals2::signal<int (), dummy_combiner> signal_type;
289 signal_type sig(dummy_combiner(0));
290 BOOST_CHECK(sig() == 0);
291 BOOST_CHECK(sig.combiner()(0,0) == 0);
292 sig.set_combiner(dummy_combiner(1));
293 BOOST_CHECK(sig() == 1);
294 BOOST_CHECK(sig.combiner()(0,0) == 1);
295 }
296
297 static void
298 test_swap()
299 {
300 typedef boost::signals2::signal<int (), dummy_combiner> signal_type;
301 signal_type sig1(dummy_combiner(1));
302 BOOST_CHECK(sig1() == 1);
303 signal_type sig2(dummy_combiner(2));
304 BOOST_CHECK(sig2() == 2);
305
306 sig1.swap(sig2);
307 BOOST_CHECK(sig1() == 2);
308 BOOST_CHECK(sig2() == 1);
309
310 using std::swap;
311 swap(sig1, sig2);
312 BOOST_CHECK(sig1() == 1);
313 BOOST_CHECK(sig2() == 2);
314 }
315
316 void test_move()
317 {
318 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
319 typedef boost::signals2::signal<int (), dummy_combiner> signal_type;
320 signal_type sig1(dummy_combiner(1));
321 BOOST_CHECK(sig1() == 1);
322 signal_type sig2(dummy_combiner(2));
323 BOOST_CHECK(sig2() == 2);
324
325 sig1 = std::move(sig2);
326 BOOST_CHECK(sig1() == 2);
327
328 signal_type sig3(std::move(sig1));
329 BOOST_CHECK(sig3() == 2);
330 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
331 }
332
333 int
334 test_main(int, char* [])
335 {
336 test_zero_args();
337 test_one_arg();
338 test_signal_signal_connect();
339 test_extended_slot<void>();
340 test_extended_slot<int>();
341 test_reference_args();
342 test_typedefs_etc();
343 test_set_combiner();
344 test_swap();
345 test_move();
346 return 0;
347 }