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/test/minimal.hpp>
14 #include <boost/signals2.hpp>
15
16 typedef boost::signals2::signal<void ()> sig0_type;
17
18 // combiner that returns the number of slots invoked
19 struct slot_counter {
20 typedef unsigned result_type;
21 template<typename InputIterator>
operator ()slot_counter22 unsigned operator()(InputIterator first, InputIterator last) const
23 {
24 unsigned count = 0;
25 for (; first != last; ++first)
26 {
27 try
28 {
29 *first;
30 ++count;
31 }
32 catch(const boost::bad_weak_ptr &)
33 {}
34 }
35 return count;
36 }
37 };
38
my_slot()39 void my_slot()
40 {
41 }
42
my_connecting_slot(sig0_type & sig)43 void my_connecting_slot(sig0_type &sig)
44 {
45 sig.connect(&my_slot);
46 }
47
slot_connect_test()48 void slot_connect_test()
49 {
50 sig0_type sig;
51 sig.connect(sig0_type::slot_type(&my_connecting_slot, boost::ref(sig)).track(sig));
52 /* 2008-02-28: the following signal invocation triggered a (bogus) failed assertion of _shared_state.unique()
53 at detail/signal_template.hpp:285 */
54 sig();
55 BOOST_CHECK(sig.num_slots() == 2);
56 sig.disconnect(&my_slot);
57 BOOST_CHECK(sig.num_slots() == 1);
58 /* 2008-03-11: checked iterator barfed on next line, due to bad semantics of copy construction
59 for boost::signals2::detail::grouped_list */
60 sig();
61 BOOST_CHECK(sig.num_slots() == 2);
62 }
63
64 /* 2008-03-10: we weren't disconnecting old connection in scoped_connection assignment operator */
scoped_connection_test()65 void scoped_connection_test()
66 {
67 typedef boost::signals2::signal<void (), slot_counter> signal_type;
68 signal_type sig;
69 {
70 boost::signals2::scoped_connection conn(sig.connect(&my_slot));
71 BOOST_CHECK(sig() == 1);
72 conn = sig.connect(&my_slot);
73 BOOST_CHECK(sig() == 1);
74 }
75 BOOST_CHECK(sig() == 0);
76 }
77
78 // testsignal that returns a reference type
79
80 struct ref_returner
81 {
82 static int i;
83
ref_return_slotref_returner84 int& ref_return_slot()
85 {
86 return i;
87 }
88 };
89
90 int ref_returner::i = 0;
91
reference_return_test()92 void reference_return_test()
93 {
94 boost::signals2::signal<int& ()> rTest;
95 ref_returner rr;
96 rTest.connect(boost::bind(&ref_returner::ref_return_slot, &rr));
97 int& r = *rTest();
98 BOOST_CHECK(ref_returner::i == 0);
99 r = 1;
100 BOOST_CHECK(ref_returner::i == 1);
101 }
102
test_main(int,char * [])103 int test_main(int, char*[])
104 {
105 slot_connect_test();
106 scoped_connection_test();
107 reference_return_test();
108
109 return 0;
110 }
111