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