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