1 | // thread_safe_signals library |
---|---|
2 | // Some assorted tests to expose various bugs that existed at some point, |
3 | // to make sure they stay fixed |
4 | |
5 | // Copyright Frank Mori Hess 2008 |
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/signals2.hpp> |
14 | #define BOOST_TEST_MODULE regression_test |
15 | #include <boost/test/included/unit_test.hpp> |
16 | |
17 | typedef boost::signals2::signal<void ()> sig0_type; |
18 | |
19 | // combiner that returns the number of slots invoked |
20 | struct slot_counter { |
21 | typedef unsigned result_type; |
22 | template<typename InputIterator> |
23 | unsigned operator()(InputIterator first, InputIterator last) const |
24 | { |
25 | unsigned count = 0; |
26 | for (; first != last; ++first) |
27 | { |
28 | try |
29 | { |
30 | *first; |
31 | ++count; |
32 | } |
33 | catch(const boost::bad_weak_ptr &) |
34 | {} |
35 | } |
36 | return count; |
37 | } |
38 | }; |
39 | |
40 | void my_slot() |
41 | { |
42 | } |
43 | |
44 | void my_connecting_slot(sig0_type &sig) |
45 | { |
46 | sig.connect(slot: &my_slot); |
47 | } |
48 | |
49 | void slot_connect_test() |
50 | { |
51 | sig0_type sig; |
52 | sig.connect(slot: sig0_type::slot_type(&my_connecting_slot, boost::ref(t&: sig)).track(signal: sig)); |
53 | /* 2008-02-28: the following signal invocation triggered a (bogus) failed assertion of _shared_state.unique() |
54 | at detail/signal_template.hpp:285 */ |
55 | sig(); |
56 | BOOST_CHECK(sig.num_slots() == 2); |
57 | sig.disconnect(slot: &my_slot); |
58 | BOOST_CHECK(sig.num_slots() == 1); |
59 | /* 2008-03-11: checked iterator barfed on next line, due to bad semantics of copy construction |
60 | for boost::signals2::detail::grouped_list */ |
61 | sig(); |
62 | BOOST_CHECK(sig.num_slots() == 2); |
63 | } |
64 | |
65 | /* 2008-03-10: we weren't disconnecting old connection in scoped_connection assignment operator */ |
66 | void scoped_connection_test() |
67 | { |
68 | typedef boost::signals2::signal<void (), slot_counter> signal_type; |
69 | signal_type sig; |
70 | { |
71 | boost::signals2::scoped_connection conn(sig.connect(slot: &my_slot)); |
72 | BOOST_CHECK(sig() == 1); |
73 | conn = sig.connect(slot: &my_slot); |
74 | BOOST_CHECK(sig() == 1); |
75 | } |
76 | BOOST_CHECK(sig() == 0); |
77 | } |
78 | |
79 | // testsignal that returns a reference type |
80 | |
81 | struct ref_returner |
82 | { |
83 | static int i; |
84 | |
85 | int& ref_return_slot() |
86 | { |
87 | return i; |
88 | } |
89 | }; |
90 | |
91 | int ref_returner::i = 0; |
92 | |
93 | void reference_return_test() |
94 | { |
95 | boost::signals2::signal<int& ()> rTest; |
96 | ref_returner rr; |
97 | rTest.connect(slot: boost::bind(f: &ref_returner::ref_return_slot, a1: &rr)); |
98 | int& r = *rTest(); |
99 | BOOST_CHECK(ref_returner::i == 0); |
100 | r = 1; |
101 | BOOST_CHECK(ref_returner::i == 1); |
102 | } |
103 | |
104 | |
105 | // disconnecting a function pointer by passing the function without an explicit |
106 | // address-of operator fails to compile in boost 1.83 due to |
107 | // commit 7a16fc1405f01e13463b6ce7723f30f40ba41fa4 |
108 | |
109 | void foo() { } |
110 | |
111 | void disconnect_by_function_test() |
112 | { |
113 | boost::signals2::signal<void ()> sig; |
114 | sig.connect(slot: foo); |
115 | sig.disconnect(slot&: foo); // compile failure in boost 1.83 |
116 | } |
117 | |
118 | BOOST_AUTO_TEST_CASE(test_main) |
119 | { |
120 | slot_connect_test(); |
121 | scoped_connection_test(); |
122 | reference_return_test(); |
123 | disconnect_by_function_test(); |
124 | } |
125 |