1 // Boost.Signals2 library
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)
9 // For more information, see http://www.boost.org
11 #include <boost/test/minimal.hpp>
12 #include <boost/signals2.hpp>
16 static boost::signals2::connection connections
[5];
18 static std::string test_output
;
20 struct remove_connection
{
21 explicit remove_connection(int v
= 0, int i
= -1) : value(v
), idx(i
) {}
23 void operator()() const {
25 connections
[idx
].disconnect();
28 std::cout
<< value
<< " ";
30 test_output
+= static_cast<char>(value
+ '0');
37 bool operator==(const remove_connection
& x
, const remove_connection
& y
)
38 { return x
.value
== y
.value
&& x
.idx
== y
.idx
; }
43 boost::signals2::signal
<void ()> s0
;
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));
50 std::cout
<< "Deleting 2" << std::endl
;
53 s0(); std::cout
<< std::endl
;
54 BOOST_CHECK(test_output
== "0123");
57 s0(); std::cout
<< std::endl
;
58 BOOST_CHECK(test_output
== "013");
60 s0
.disconnect_all_slots();
61 BOOST_CHECK(s0
.empty());
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));
68 std::cout
<< "Deleting 3" << std::endl
;
71 s0(); std::cout
<< std::endl
;
72 BOOST_CHECK(test_output
== "0123");
75 s0(); std::cout
<< std::endl
;
76 BOOST_CHECK(test_output
== "012");
78 s0
.disconnect_all_slots();
79 BOOST_CHECK(s0
.num_slots() == 0);
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));
86 std::cout
<< "Deleting 0" << std::endl
;
89 s0(); std::cout
<< std::endl
;
90 BOOST_CHECK(test_output
== "0123");
93 s0(); std::cout
<< std::endl
;
94 BOOST_CHECK(test_output
== "123");
96 s0
.disconnect_all_slots();
97 BOOST_CHECK(s0
.empty());
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));
104 std::cout
<< "Mass suicide" << std::endl
;
107 s0(); std::cout
<< std::endl
;
108 BOOST_CHECK(test_output
== "0123");
111 s0(); std::cout
<< std::endl
;
112 BOOST_CHECK(test_output
== "");
118 boost::signals2::signal
<void ()> s0
;
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));
125 std::cout
<< "1 removes 0" << std::endl
;
128 s0(); std::cout
<< std::endl
;
129 BOOST_CHECK(test_output
== "0123");
132 s0(); std::cout
<< std::endl
;
133 BOOST_CHECK(test_output
== "123");
135 s0
.disconnect_all_slots();
136 BOOST_CHECK(s0
.empty());
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));
143 std::cout
<< "3 removes 2" << std::endl
;
146 s0(); std::cout
<< std::endl
;
147 BOOST_CHECK(test_output
== "0123");
150 s0(); std::cout
<< std::endl
;
151 BOOST_CHECK(test_output
== "013");
157 boost::signals2::signal
<void ()> s0
;
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));
164 std::cout
<< "0 removes 1" << std::endl
;
167 s0(); std::cout
<< std::endl
;
168 BOOST_CHECK(test_output
== "023");
171 s0(); std::cout
<< std::endl
;
172 BOOST_CHECK(test_output
== "023");
174 s0
.disconnect_all_slots();
175 BOOST_CHECK(s0
.empty());
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));
182 std::cout
<< "1 removes 3" << std::endl
;
185 s0(); std::cout
<< std::endl
;
186 BOOST_CHECK(test_output
== "012");
189 s0(); std::cout
<< std::endl
;
190 BOOST_CHECK(test_output
== "012");
196 boost::signals2::signal
<void ()> s0
;
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));
203 std::cout
<< "0 removes 1, 2 removes 0, 3 removes 2" << std::endl
;
206 s0(); std::cout
<< std::endl
;
207 BOOST_CHECK(test_output
== "023");
210 s0(); std::cout
<< std::endl
;
211 BOOST_CHECK(test_output
== "3");
215 test_disconnect_equal()
217 boost::signals2::signal
<void ()> s0
;
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));
224 std::cout
<< "Deleting 2" << std::endl
;
227 s0(); std::cout
<< std::endl
;
228 BOOST_CHECK(test_output
== "0123");
230 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
231 connections
[2].disconnect();
233 s0
.disconnect(remove_connection(2));
237 s0(); std::cout
<< std::endl
;
238 BOOST_CHECK(test_output
== "013");
241 struct signal_deletion_tester
244 signal_deletion_tester() {
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));
251 ~signal_deletion_tester()
269 boost::signals2::signal
<void(void)> *sig
;
271 boost::signals2::connection connection0
;
272 boost::signals2::connection connection1
;
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()
281 signal_deletion_tester tester
;
283 BOOST_CHECK(tester
.b_has_run
);
284 BOOST_CHECK(tester
.connection0
.connected() == false);
285 BOOST_CHECK(tester
.connection1
.connected() == false);
288 int test_main(int, char* [])
294 test_disconnect_equal();
295 test_signal_deletion();