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