]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Signals library |
2 | ||
3 | // Copyright Douglas Gregor 2001-2003. Use, modification and | |
4 | // distribution is subject to the Boost Software License, Version | |
5 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | // For more information, see http://www.boost.org | |
9 | ||
10 | #include <boost/test/minimal.hpp> | |
11 | #include <boost/signal.hpp> | |
12 | #include <functional> | |
13 | ||
14 | template<typename T> | |
15 | struct max_or_default { | |
16 | typedef T result_type; | |
17 | template<typename InputIterator> | |
18 | typename InputIterator::value_type | |
19 | operator()(InputIterator first, InputIterator last) const | |
20 | { | |
21 | if (first == last) | |
22 | return T(); | |
23 | ||
24 | T max = *first++; | |
25 | for (; first != last; ++first) | |
26 | max = (*first > max)? *first : max; | |
27 | ||
28 | return max; | |
29 | } | |
30 | }; | |
31 | ||
32 | struct make_int { | |
33 | make_int(int n, int cn) : N(n), CN(n) {} | |
34 | int operator()() { return N; } | |
35 | int operator()() const { return CN; } | |
36 | ||
37 | int N; | |
38 | int CN; | |
39 | }; | |
40 | ||
41 | template<int N> | |
42 | struct make_increasing_int { | |
43 | make_increasing_int() : n(N) {} | |
44 | ||
45 | int operator()() const { return n++; } | |
46 | ||
47 | mutable int n; | |
48 | }; | |
49 | ||
50 | int get_37() { return 37; } | |
51 | ||
52 | static void | |
53 | test_zero_args() | |
54 | { | |
55 | make_int i42(42, 41); | |
56 | make_int i2(2, 1); | |
57 | make_int i72(72, 71); | |
58 | make_int i63(63, 63); | |
59 | make_int i62(62, 61); | |
60 | ||
61 | { | |
62 | boost::signal0<int, max_or_default<int>, std::string> s0; | |
63 | boost::BOOST_SIGNALS_NAMESPACE::connection c2 = s0.connect(i2); | |
64 | boost::BOOST_SIGNALS_NAMESPACE::connection c72 = s0.connect("72", i72); | |
65 | boost::BOOST_SIGNALS_NAMESPACE::connection c62 = s0.connect("6x", i62); | |
66 | boost::BOOST_SIGNALS_NAMESPACE::connection c42 = s0.connect(i42); | |
67 | boost::BOOST_SIGNALS_NAMESPACE::connection c37 = s0.connect(&get_37); | |
68 | ||
69 | BOOST_CHECK(s0() == 72); | |
70 | ||
71 | s0.disconnect("72"); | |
72 | BOOST_CHECK(s0() == 62); | |
73 | ||
74 | c72.disconnect(); // Double-disconnect should be safe | |
75 | BOOST_CHECK(s0() == 62); | |
76 | ||
77 | s0.disconnect("72"); // Triple-disconect should be safe | |
78 | BOOST_CHECK(s0() == 62); | |
79 | ||
80 | // Also connect 63 in the same group as 62 | |
81 | s0.connect("6x", i63); | |
82 | BOOST_CHECK(s0() == 63); | |
83 | ||
84 | // Disconnect all of the 60's | |
85 | s0.disconnect("6x"); | |
86 | BOOST_CHECK(s0() == 42); | |
87 | ||
88 | c42.disconnect(); | |
89 | BOOST_CHECK(s0() == 37); | |
90 | ||
91 | c37.disconnect(); | |
92 | BOOST_CHECK(s0() == 2); | |
93 | ||
94 | c2.disconnect(); | |
95 | BOOST_CHECK(s0() == 0); | |
96 | } | |
97 | ||
98 | { | |
99 | boost::signal0<int, max_or_default<int> > s0; | |
100 | boost::BOOST_SIGNALS_NAMESPACE::connection c2 = s0.connect(i2); | |
101 | boost::BOOST_SIGNALS_NAMESPACE::connection c72 = s0.connect(i72); | |
102 | boost::BOOST_SIGNALS_NAMESPACE::connection c62 = s0.connect(i62); | |
103 | boost::BOOST_SIGNALS_NAMESPACE::connection c42 = s0.connect(i42); | |
104 | ||
105 | const boost::signal0<int, max_or_default<int> >& cs0 = s0; | |
106 | BOOST_CHECK(cs0() == 72); | |
107 | } | |
108 | ||
109 | { | |
110 | make_increasing_int<7> i7; | |
111 | make_increasing_int<10> i10; | |
112 | ||
113 | boost::signal0<int, max_or_default<int> > s0; | |
114 | boost::BOOST_SIGNALS_NAMESPACE::connection c7 = s0.connect(i7); | |
115 | boost::BOOST_SIGNALS_NAMESPACE::connection c10 = s0.connect(i10); | |
116 | ||
117 | BOOST_CHECK(s0() == 10); | |
118 | BOOST_CHECK(s0() == 11); | |
119 | } | |
120 | } | |
121 | ||
122 | static void | |
123 | test_one_arg() | |
124 | { | |
125 | boost::signal1<int, int, max_or_default<int> > s1; | |
126 | ||
127 | s1.connect(std::negate<int>()); | |
b32b8144 FG |
128 | |
129 | #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) | |
130 | ||
7c673cae | 131 | s1.connect(std::bind1st(std::multiplies<int>(), 2)); |
b32b8144 FG |
132 | |
133 | #else | |
134 | ||
135 | s1.connect(std::bind(std::multiplies<int>(), 2, std::placeholders::_1)); | |
136 | ||
137 | #endif | |
7c673cae FG |
138 | |
139 | BOOST_CHECK(s1(1) == 2); | |
140 | BOOST_CHECK(s1(-1) == 1); | |
141 | } | |
142 | ||
143 | static void | |
144 | test_signal_signal_connect() | |
145 | { | |
146 | boost::signal1<int, int, max_or_default<int> > s1; | |
147 | ||
148 | s1.connect(std::negate<int>()); | |
149 | ||
150 | BOOST_CHECK(s1(3) == -3); | |
151 | ||
152 | { | |
153 | boost::signal1<int, int, max_or_default<int> > s2; | |
154 | s1.connect(s2); | |
b32b8144 FG |
155 | |
156 | #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) | |
157 | ||
7c673cae FG |
158 | s2.connect(std::bind1st(std::multiplies<int>(), 2)); |
159 | s2.connect(std::bind1st(std::multiplies<int>(), -3)); | |
b32b8144 FG |
160 | |
161 | #else | |
162 | ||
163 | s2.connect(std::bind(std::multiplies<int>(), 2, std::placeholders::_1)); | |
164 | s2.connect(std::bind(std::multiplies<int>(), -3, std::placeholders::_1)); | |
165 | ||
166 | #endif | |
7c673cae FG |
167 | |
168 | BOOST_CHECK(s2(-3) == 9); | |
169 | BOOST_CHECK(s1(3) == 6); | |
170 | } // s2 goes out of scope and disconnects | |
171 | ||
172 | BOOST_CHECK(s1(3) == -3); | |
173 | } | |
174 | ||
175 | struct EventCounter | |
176 | { | |
177 | EventCounter() : count(0) {} | |
178 | ||
179 | void operator()() | |
180 | { | |
181 | ++count; | |
182 | } | |
183 | ||
184 | int count; | |
185 | }; | |
186 | ||
187 | static void | |
188 | test_ref() | |
189 | { | |
190 | EventCounter ec; | |
191 | boost::signal0<void> s; | |
192 | ||
193 | { | |
194 | boost::BOOST_SIGNALS_NAMESPACE::scoped_connection c = s.connect(boost::ref(ec)); | |
195 | BOOST_CHECK(ec.count == 0); | |
196 | s(); | |
197 | BOOST_CHECK(ec.count == 1); | |
198 | } | |
199 | s(); | |
200 | BOOST_CHECK(ec.count == 1); | |
201 | } | |
202 | ||
203 | int | |
204 | test_main(int, char* []) | |
205 | { | |
206 | test_zero_args(); | |
207 | test_one_arg(); | |
208 | test_signal_signal_connect(); | |
209 | test_ref(); | |
210 | return 0; | |
211 | } |