1// Boost.Signals2 library
2
3// Copyright Douglas Gregor 2001-2006.
4// Copyright Frank Mori Hess 2009.
5// Use, modification and
6// distribution is subject to the Boost Software License, Version
7// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
10// For more information, see http://www.boost.org
11
12#include <boost/signals2/signal.hpp>
13#include <boost/signals2/trackable.hpp>
14#define BOOST_TEST_MODULE trackable_test
15#include <boost/test/included/unit_test.hpp>
16#include <boost/bind/bind.hpp>
17#include <boost/core/ref.hpp>
18#include <boost/weak_ptr.hpp>
19
20using namespace boost::placeholders;
21
22struct short_lived : public boost::signals2::trackable {
23 ~short_lived() {}
24};
25
26struct swallow {
27 typedef int result_type;
28 template<typename T> int operator()(const T*, int i) { return i; }
29 template<typename T> int operator()(T &, int i) { return i; }
30 template<typename T> int operator()(boost::weak_ptr<T>, int i) { return i; }
31};
32
33template<typename T>
34struct max_or_default {
35 typedef T result_type;
36
37 template<typename InputIterator>
38 T operator()(InputIterator first, InputIterator last) const
39 {
40 if (first == last)
41 return T();
42
43 T max = *first++;
44 for (; first != last; ++first)
45 max = (*first > max)? *first : max;
46
47 return max;
48 }
49};
50
51struct self_deleting : public boost::signals2::trackable {
52 void delete_myself(boost::signals2::connection connection)
53 {
54 BOOST_CHECK(connection.connected());
55 delete this;
56 BOOST_CHECK(connection.connected() == false);
57 }
58};
59
60// test that slot assocated with signals2::trackable
61// gets disconnected immediately upon deletion of the
62// signals2::trackable, even when a signal invocation
63// is in progress.
64void test_immediate_disconnect_on_delete()
65{
66 boost::signals2::signal<void () > sig;
67 self_deleting *obj = new self_deleting();
68 sig.connect_extended(slot: boost::bind(f: &self_deleting::delete_myself, a1: obj, a2: _1));
69 sig();
70}
71
72BOOST_AUTO_TEST_CASE(test_main)
73{
74 typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type;
75 sig_type s1;
76
77 // Test auto-disconnection
78 BOOST_CHECK(s1(5) == 0);
79 {
80 short_lived shorty;
81 s1.connect(slot: boost::bind<int>(f: swallow(), a1: &shorty, a2: _1));
82 BOOST_CHECK(s1(5) == 5);
83 }
84 BOOST_CHECK(s1(5) == 0);
85 // Test auto-disconnection of trackable inside reference_wrapper
86 {
87 short_lived shorty;
88 s1.connect(slot: boost::bind<int>(f: swallow(), a1: boost::ref(t&: shorty), a2: _1));
89 BOOST_CHECK(s1(5) == 5);
90 }
91 BOOST_CHECK(s1(5) == 0);
92
93 // Test multiple arg slot constructor
94 {
95 short_lived shorty;
96 s1.connect(slot: sig_type::slot_type(swallow(), &shorty, _1));
97 BOOST_CHECK(s1(5) == 5);
98 }
99 BOOST_CHECK(s1(5) == 0);
100
101 // Test auto-disconnection of slot before signal connection
102 {
103 short_lived* shorty = new short_lived();
104
105 sig_type::slot_type slot(boost::bind<int>(f: swallow(), a1: shorty, a2: _1));
106 delete shorty;
107
108 BOOST_CHECK(s1(5) == 0);
109 }
110
111 test_immediate_disconnect_on_delete();
112}
113

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