]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/signals2/test/deletion_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / signals2 / test / deletion_test.cpp
1 // Boost.Signals2 library
2
3 // Copyright Douglas Gregor 2001-2003.
4 // Use, modification and
5 // distribution is subject to the Boost Software License, Version
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8
9 // For more information, see http://www.boost.org
10
11 #include <boost/test/minimal.hpp>
12 #include <boost/signals2.hpp>
13 #include <iostream>
14 #include <string>
15
16 static boost::signals2::connection connections[5];
17
18 static std::string test_output;
19
20 struct remove_connection {
21 explicit remove_connection(int v = 0, int i = -1) : value(v), idx(i) {}
22
23 void operator()() const {
24 if (idx >= 0)
25 connections[idx].disconnect();
26
27 //return value;
28 std::cout << value << " ";
29
30 test_output += static_cast<char>(value + '0');
31 }
32
33 int value;
34 int idx;
35 };
36
37 bool operator==(const remove_connection& x, const remove_connection& y)
38 { return x.value == y.value && x.idx == y.idx; }
39
40 static void
41 test_remove_self()
42 {
43 boost::signals2::signal<void ()> s0;
44
45 connections[0] = s0.connect(remove_connection(0));
46 connections[1] = s0.connect(remove_connection(1));
47 connections[2] = s0.connect(remove_connection(2, 2));
48 connections[3] = s0.connect(remove_connection(3));
49
50 std::cout << "Deleting 2" << std::endl;
51
52 test_output = "";
53 s0(); std::cout << std::endl;
54 BOOST_CHECK(test_output == "0123");
55
56 test_output = "";
57 s0(); std::cout << std::endl;
58 BOOST_CHECK(test_output == "013");
59
60 s0.disconnect_all_slots();
61 BOOST_CHECK(s0.empty());
62
63 connections[0] = s0.connect(remove_connection(0));
64 connections[1] = s0.connect(remove_connection(1));
65 connections[2] = s0.connect(remove_connection(2));
66 connections[3] = s0.connect(remove_connection(3, 3));
67
68 std::cout << "Deleting 3" << std::endl;
69
70 test_output = "";
71 s0(); std::cout << std::endl;
72 BOOST_CHECK(test_output == "0123");
73
74 test_output = "";
75 s0(); std::cout << std::endl;
76 BOOST_CHECK(test_output == "012");
77
78 s0.disconnect_all_slots();
79 BOOST_CHECK(s0.num_slots() == 0);
80
81 connections[0] = s0.connect(remove_connection(0, 0));
82 connections[1] = s0.connect(remove_connection(1));
83 connections[2] = s0.connect(remove_connection(2));
84 connections[3] = s0.connect(remove_connection(3));
85
86 std::cout << "Deleting 0" << std::endl;
87
88 test_output = "";
89 s0(); std::cout << std::endl;
90 BOOST_CHECK(test_output == "0123");
91
92 test_output = "";
93 s0(); std::cout << std::endl;
94 BOOST_CHECK(test_output == "123");
95
96 s0.disconnect_all_slots();
97 BOOST_CHECK(s0.empty());
98
99 connections[0] = s0.connect(remove_connection(0, 0));
100 connections[1] = s0.connect(remove_connection(1, 1));
101 connections[2] = s0.connect(remove_connection(2, 2));
102 connections[3] = s0.connect(remove_connection(3, 3));
103
104 std::cout << "Mass suicide" << std::endl;
105
106 test_output = "";
107 s0(); std::cout << std::endl;
108 BOOST_CHECK(test_output == "0123");
109
110 test_output = "";
111 s0(); std::cout << std::endl;
112 BOOST_CHECK(test_output == "");
113 }
114
115 static void
116 test_remove_prior()
117 {
118 boost::signals2::signal<void ()> s0;
119
120 connections[0] = s0.connect(remove_connection(0));
121 connections[1] = s0.connect(remove_connection(1, 0));
122 connections[2] = s0.connect(remove_connection(2));
123 connections[3] = s0.connect(remove_connection(3));
124
125 std::cout << "1 removes 0" << std::endl;
126
127 test_output = "";
128 s0(); std::cout << std::endl;
129 BOOST_CHECK(test_output == "0123");
130
131 test_output = "";
132 s0(); std::cout << std::endl;
133 BOOST_CHECK(test_output == "123");
134
135 s0.disconnect_all_slots();
136 BOOST_CHECK(s0.empty());
137
138 connections[0] = s0.connect(remove_connection(0));
139 connections[1] = s0.connect(remove_connection(1));
140 connections[2] = s0.connect(remove_connection(2));
141 connections[3] = s0.connect(remove_connection(3, 2));
142
143 std::cout << "3 removes 2" << std::endl;
144
145 test_output = "";
146 s0(); std::cout << std::endl;
147 BOOST_CHECK(test_output == "0123");
148
149 test_output = "";
150 s0(); std::cout << std::endl;
151 BOOST_CHECK(test_output == "013");
152 }
153
154 static void
155 test_remove_after()
156 {
157 boost::signals2::signal<void ()> s0;
158
159 connections[0] = s0.connect(remove_connection(0, 1));
160 connections[1] = s0.connect(remove_connection(1));
161 connections[2] = s0.connect(remove_connection(2));
162 connections[3] = s0.connect(remove_connection(3));
163
164 std::cout << "0 removes 1" << std::endl;
165
166 test_output = "";
167 s0(); std::cout << std::endl;
168 BOOST_CHECK(test_output == "023");
169
170 test_output = "";
171 s0(); std::cout << std::endl;
172 BOOST_CHECK(test_output == "023");
173
174 s0.disconnect_all_slots();
175 BOOST_CHECK(s0.empty());
176
177 connections[0] = s0.connect(remove_connection(0));
178 connections[1] = s0.connect(remove_connection(1, 3));
179 connections[2] = s0.connect(remove_connection(2));
180 connections[3] = s0.connect(remove_connection(3));
181
182 std::cout << "1 removes 3" << std::endl;
183
184 test_output = "";
185 s0(); std::cout << std::endl;
186 BOOST_CHECK(test_output == "012");
187
188 test_output = "";
189 s0(); std::cout << std::endl;
190 BOOST_CHECK(test_output == "012");
191 }
192
193 static void
194 test_bloodbath()
195 {
196 boost::signals2::signal<void ()> s0;
197
198 connections[0] = s0.connect(remove_connection(0, 1));
199 connections[1] = s0.connect(remove_connection(1, 1));
200 connections[2] = s0.connect(remove_connection(2, 0));
201 connections[3] = s0.connect(remove_connection(3, 2));
202
203 std::cout << "0 removes 1, 2 removes 0, 3 removes 2" << std::endl;
204
205 test_output = "";
206 s0(); std::cout << std::endl;
207 BOOST_CHECK(test_output == "023");
208
209 test_output = "";
210 s0(); std::cout << std::endl;
211 BOOST_CHECK(test_output == "3");
212 }
213
214 static void
215 test_disconnect_equal()
216 {
217 boost::signals2::signal<void ()> s0;
218
219 connections[0] = s0.connect(remove_connection(0));
220 connections[1] = s0.connect(remove_connection(1));
221 connections[2] = s0.connect(remove_connection(2));
222 connections[3] = s0.connect(remove_connection(3));
223
224 std::cout << "Deleting 2" << std::endl;
225
226 test_output = "";
227 s0(); std::cout << std::endl;
228 BOOST_CHECK(test_output == "0123");
229
230 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
231 connections[2].disconnect();
232 #else
233 s0.disconnect(remove_connection(2));
234 #endif
235
236 test_output = "";
237 s0(); std::cout << std::endl;
238 BOOST_CHECK(test_output == "013");
239 }
240
241 struct signal_deletion_tester
242 {
243 public:
244 signal_deletion_tester() {
245 b_has_run = false;
246 sig = new boost::signals2::signal<void(void)>();
247 connection0 = sig->connect(0, boost::bind(&signal_deletion_tester::a, this));
248 connection1 = sig->connect(1, boost::bind(&signal_deletion_tester::b, this));
249 }
250
251 ~signal_deletion_tester()
252 {
253 if(sig != 0)
254 delete sig;
255 }
256
257 void a()
258 {
259 if(sig != 0)
260 delete sig;
261 sig = 0;
262 }
263
264 void b()
265 {
266 b_has_run = true;
267 }
268
269 boost::signals2::signal<void(void)> *sig;
270 bool b_has_run;
271 boost::signals2::connection connection0;
272 boost::signals2::connection connection1;
273 };
274
275 // If a signal is deleted mid-invocation, the invocation in progress
276 // should complete normally. Once all invocations complete, all
277 // slots which were connected to the deleted signal should be in the
278 // disconnected state.
279 static void test_signal_deletion()
280 {
281 signal_deletion_tester tester;
282 (*tester.sig)();
283 BOOST_CHECK(tester.b_has_run);
284 BOOST_CHECK(tester.connection0.connected() == false);
285 BOOST_CHECK(tester.connection1.connected() == false);
286 }
287
288 int test_main(int, char* [])
289 {
290 test_remove_self();
291 test_remove_prior();
292 test_remove_after();
293 test_bloodbath();
294 test_disconnect_equal();
295 test_signal_deletion();
296 return 0;
297 }