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