1// Boost.Signals library
2
3// Copyright Douglas Gregor 2001-2006
4// Copyright Frank Mori Hess 2007
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 <memory>
13#include <boost/core/ref.hpp>
14#include <boost/optional.hpp>
15#include <boost/shared_ptr.hpp>
16#include <boost/signals2.hpp>
17#define BOOST_TEST_MODULE track_test
18#include <boost/test/included/unit_test.hpp>
19#include <boost/bind/bind.hpp>
20
21using namespace boost::placeholders;
22
23struct swallow {
24 typedef int result_type;
25 template<typename T> result_type operator()(const T*, int i) { return i; }
26};
27
28template<typename T>
29struct max_or_default {
30 typedef T result_type;
31
32 template<typename InputIterator>
33 T operator()(InputIterator first, InputIterator last) const
34 {
35 boost::optional<T> max;
36 for(; first != last; ++first)
37 {
38 T value = *first;
39 if(!max)
40 {
41 max = value;
42 }else if(value > *max)
43 {
44 max = value;
45 }
46 }
47 if(max) return *max;
48 else return T();
49 }
50};
51
52static int myfunc(int i, double z)
53{
54 return i;
55}
56
57BOOST_AUTO_TEST_CASE(test_main)
58{
59 typedef boost::signals2::signal<int (int), max_or_default<int> > sig_type;
60 sig_type s1;
61 boost::signals2::connection connection;
62
63 // Test auto-disconnection
64 BOOST_CHECK(s1(5) == 0);
65 {
66 boost::shared_ptr<int> shorty(new int());
67 s1.connect(slot: sig_type::slot_type(swallow(), shorty.get(), _1).track(tracked: shorty));
68 BOOST_CHECK(s1(5) == 5);
69 }
70 BOOST_CHECK(s1(5) == 0);
71
72 // Test auto-disconnection of slot before signal connection
73 {
74 boost::shared_ptr<int> shorty(new int(1));
75// doesn't work on gcc 3.3.5, it says: error: type specifier omitted for parameter `shorty'
76// does work on gcc 4.1.2
77// sig_type::slot_type slot(swallow(), shorty.get(), _1);
78 swallow myswallow;
79 sig_type::slot_type slot(myswallow, shorty.get(), _1);
80
81 slot.track(tracked: shorty);
82 shorty.reset();
83 s1.connect(slot);
84 BOOST_CHECK(s1(5) == 0);
85 }
86
87 // Test binding of a slot to another slot
88 {
89 boost::shared_ptr<int> shorty(new int(2));
90 boost::signals2::slot<int (double)> other_slot(&myfunc, boost::cref(t: *shorty.get()), _1);
91 other_slot.track(tracked: shorty);
92 connection = s1.connect(slot: sig_type::slot_type(other_slot, 0.5).track(slot: other_slot));
93 BOOST_CHECK(s1(3) == 2);
94 }
95 BOOST_CHECK(connection.connected() == false);
96 BOOST_CHECK(s1(3) == 0);
97
98 // Test binding of a signal as a slot
99 {
100 sig_type s2;
101 s1.connect(slot: s2);
102 s2.connect(slot: sig_type::slot_type(&myfunc, _1, 0.7));
103 BOOST_CHECK(s1(4) == 4);
104 }
105 BOOST_CHECK(s1(4) == 0);
106
107 // Test tracking of null but not empty shared_ptr
108 BOOST_CHECK(s1(2) == 0);
109 {
110 boost::shared_ptr<int> shorty((int*)(0));
111 s1.connect(slot: sig_type::slot_type(swallow(), shorty.get(), _1).track(tracked: shorty));
112 BOOST_CHECK(s1(2) == 2);
113 }
114 BOOST_CHECK(s1(2) == 0);
115
116#ifndef BOOST_NO_CXX11_SMART_PTR
117 // Test tracking through std::shared_ptr/weak_ptr
118 BOOST_CHECK(s1(5) == 0);
119 {
120 std::shared_ptr<int> shorty(new int());
121 s1.connect(slot: sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(tracked: shorty));
122 BOOST_CHECK(s1(5) == 5);
123 }
124 BOOST_CHECK(s1(5) == 0);
125 {
126 std::shared_ptr<int> shorty(new int());
127 s1.connect
128 (
129 slot: sig_type::slot_type
130 (
131 swallow(),
132 shorty.get(),
133 _1
134 ).track_foreign
135 (
136 tracked: std::weak_ptr<int>(shorty)
137 )
138 );
139 BOOST_CHECK(s1(5) == 5);
140 }
141 BOOST_CHECK(s1(5) == 0);
142 // make sure tracking foreign shared_ptr<const void> works
143 {
144 std::shared_ptr<const void> shorty(new int());
145 s1.connect(slot: sig_type::slot_type(swallow(), shorty.get(), _1).track_foreign(tracked: shorty));
146 BOOST_CHECK(s1(5) == 5);
147 }
148 {
149 std::shared_ptr<int> shorty(new int());
150 s1.connect
151 (
152 slot: sig_type::slot_type
153 (
154 swallow(),
155 shorty.get(),
156 _1
157 ).track_foreign
158 (
159 tracked: std::weak_ptr<const void>(shorty)
160 )
161 );
162 BOOST_CHECK(s1(5) == 5);
163 }
164 BOOST_CHECK(s1(5) == 0);
165 BOOST_CHECK(s1(5) == 0);
166#endif
167}
168

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