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
17typedef boost::signals2::signal<void ()> sig0_type;
18
19// combiner that returns the number of slots invoked
20struct 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
40void my_slot()
41{
42}
43
44void my_connecting_slot(sig0_type &sig)
45{
46 sig.connect(slot: &my_slot);
47}
48
49void 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 */
66void 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
81struct ref_returner
82{
83 static int i;
84
85 int& ref_return_slot()
86 {
87 return i;
88 }
89};
90
91int ref_returner::i = 0;
92
93void 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
109void foo() { }
110
111void 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
118BOOST_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

source code of boost/libs/signals2/test/regression_test.cpp