Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/signals/signal_template.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Boost.Signals library | |
2 | |
3 // Copyright Douglas Gregor 2001-2004. 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 // This file intentionally does not have include guards, because it is meant | |
11 // to be included multiple times (one for each signalN class). The | |
12 // BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED macro merely serves to | |
13 // suppress reinclusion of the files that this header depends on. | |
14 | |
15 #ifndef BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED | |
16 #define BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED | |
17 # include <boost/config.hpp> | |
18 # include <boost/signals/connection.hpp> | |
19 # include <boost/utility.hpp> | |
20 # include <boost/ref.hpp> | |
21 # include <boost/signals/slot.hpp> | |
22 # include <boost/last_value.hpp> | |
23 # include <boost/signals/detail/signal_base.hpp> | |
24 # include <boost/signals/detail/slot_call_iterator.hpp> | |
25 # include <boost/mpl/bool.hpp> | |
26 # include <boost/type_traits/is_convertible.hpp> | |
27 # include <cassert> | |
28 # include <functional> | |
29 # include <memory> | |
30 #endif // !BOOST_SIGNALS_SIGNAL_TEMPLATE_HEADER_INCLUDED | |
31 | |
32 #ifdef BOOST_HAS_ABI_HEADERS | |
33 # include BOOST_ABI_PREFIX | |
34 #endif | |
35 | |
36 // Include the appropriate functionN header | |
37 #define BOOST_SIGNAL_FUNCTION_N_HEADER BOOST_JOIN(<boost/function/function,BOOST_SIGNALS_NUM_ARGS.hpp>) | |
38 #include BOOST_SIGNAL_FUNCTION_N_HEADER | |
39 | |
40 // Determine if a comma should follow a listing of the arguments/parameters | |
41 #if BOOST_SIGNALS_NUM_ARGS == 0 | |
42 # define BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
43 #else | |
44 # define BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS , | |
45 #endif // BOOST_SIGNALS_NUM_ARGS > 0 | |
46 | |
47 // Define class names used | |
48 #define BOOST_SIGNALS_SIGNAL BOOST_JOIN(signal,BOOST_SIGNALS_NUM_ARGS) | |
49 #define BOOST_SIGNALS_FUNCTION BOOST_JOIN(function,BOOST_SIGNALS_NUM_ARGS) | |
50 #define BOOST_SIGNALS_ARGS_STRUCT BOOST_JOIN(args,BOOST_SIGNALS_NUM_ARGS) | |
51 #define BOOST_SIGNALS_CALL_BOUND BOOST_JOIN(call_bound,BOOST_SIGNALS_NUM_ARGS) | |
52 | |
53 // Define commonly-used instantiations | |
54 #define BOOST_SIGNALS_ARGS_STRUCT_INST \ | |
55 BOOST_SIGNALS_NAMESPACE::detail::BOOST_SIGNALS_ARGS_STRUCT<BOOST_SIGNALS_TEMPLATE_ARGS> | |
56 | |
57 namespace boost { | |
58 namespace BOOST_SIGNALS_NAMESPACE { | |
59 namespace detail { | |
60 // Holds the arguments for a bound slot call in a single place | |
61 template<BOOST_SIGNALS_TEMPLATE_PARMS | |
62 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
63 typename Dummy = int> | |
64 struct BOOST_SIGNALS_ARGS_STRUCT { | |
65 BOOST_SIGNALS_ARGS_STRUCT(BOOST_SIGNALS_COPY_PARMS) | |
66 BOOST_SIGNALS_INIT_ARGS | |
67 { | |
68 } | |
69 | |
70 BOOST_SIGNALS_ARGS_AS_MEMBERS | |
71 }; | |
72 | |
73 // Function object that calls the function object given to it, passing | |
74 // the bound arguments along to that underlying function object | |
75 template<typename R> | |
76 struct BOOST_SIGNALS_CALL_BOUND { | |
77 template<BOOST_SIGNALS_TEMPLATE_PARMS | |
78 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
79 typename F> | |
80 struct caller { | |
81 typedef BOOST_SIGNALS_ARGS_STRUCT<BOOST_SIGNALS_TEMPLATE_ARGS>* | |
82 args_type; | |
83 | |
84 args_type args; | |
85 | |
86 typedef R result_type; | |
87 | |
88 caller() {} | |
89 caller(args_type a) : args(a) {} | |
90 | |
91 template<typename Pair> | |
92 R operator()(const Pair& slot) const | |
93 { | |
94 F* target = const_cast<F*>(unsafe_any_cast<F>(&slot.second)); | |
95 return (*target)(BOOST_SIGNALS_BOUND_ARGS); | |
96 } | |
97 }; | |
98 }; | |
99 | |
100 template<> | |
101 struct BOOST_SIGNALS_CALL_BOUND<void> { | |
102 template<BOOST_SIGNALS_TEMPLATE_PARMS | |
103 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
104 typename F> | |
105 struct caller { | |
106 typedef BOOST_SIGNALS_ARGS_STRUCT<BOOST_SIGNALS_TEMPLATE_ARGS>* | |
107 args_type; | |
108 | |
109 args_type args; | |
110 | |
111 typedef unusable result_type; | |
112 | |
113 caller(args_type a) : args(a) {} | |
114 | |
115 template<typename Pair> | |
116 unusable operator()(const Pair& slot) const | |
117 { | |
118 F* target = const_cast<F*>(unsafe_any_cast<F>(&slot.second)); | |
119 (*target)(BOOST_SIGNALS_BOUND_ARGS); | |
120 return unusable(); | |
121 } | |
122 }; | |
123 }; | |
124 } // namespace detail | |
125 } // namespace BOOST_SIGNALS_NAMESPACE | |
126 | |
127 // The actual signalN class | |
128 template< | |
129 typename R, | |
130 BOOST_SIGNALS_TEMPLATE_PARMS | |
131 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
132 typename Combiner = last_value<R>, | |
133 typename Group = int, | |
134 typename GroupCompare = std::less<Group>, | |
135 typename SlotFunction = BOOST_SIGNALS_FUNCTION< | |
136 R BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
137 BOOST_SIGNALS_TEMPLATE_ARGS> | |
138 > | |
139 class BOOST_SIGNALS_SIGNAL : | |
140 public BOOST_SIGNALS_NAMESPACE::detail::signal_base, // management of slot list | |
141 public BOOST_SIGNALS_NAMESPACE::trackable // signals are trackable | |
142 { | |
143 public: | |
144 // The slot function type | |
145 typedef SlotFunction slot_function_type; | |
146 | |
147 // Result type of a slot | |
148 typedef typename BOOST_SIGNALS_NAMESPACE::detail::slot_result_type<R>::type | |
149 slot_result_type; | |
150 | |
151 // Argument types | |
152 BOOST_SIGNALS_ARG_TYPES | |
153 | |
154 #if BOOST_SIGNALS_NUM_ARGS == 1 | |
155 typedef T1 argument_type; | |
156 #elif BOOST_SIGNALS_NUM_ARGS == 2 | |
157 typedef T1 first_argument_type; | |
158 typedef T2 second_argument_type; | |
159 #endif | |
160 | |
161 private: | |
162 // The real slot name comparison object type | |
163 typedef BOOST_SIGNALS_NAMESPACE::detail::group_bridge_compare<GroupCompare, Group> | |
164 real_group_compare_type; | |
165 | |
166 // The function object passed to the slot call iterator that will call | |
167 // the underlying slot function with its arguments bound | |
168 typedef BOOST_SIGNALS_NAMESPACE::detail::BOOST_SIGNALS_CALL_BOUND<R> | |
169 outer_bound_slot_caller; | |
170 typedef typename outer_bound_slot_caller::template | |
171 caller<BOOST_SIGNALS_TEMPLATE_ARGS | |
172 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
173 slot_function_type> | |
174 call_bound_slot; | |
175 | |
176 public: | |
177 // Combiner's result type | |
178 typedef typename Combiner::result_type result_type; | |
179 | |
180 // Combiner type | |
181 typedef Combiner combiner_type; | |
182 | |
183 // Slot type | |
184 typedef slot<slot_function_type> slot_type; | |
185 | |
186 // Slot name type and comparison | |
187 typedef Group group_type; | |
188 typedef GroupCompare group_compare_type; | |
189 | |
190 typedef BOOST_SIGNALS_NAMESPACE::detail::slot_call_iterator< | |
191 call_bound_slot, iterator> slot_call_iterator; | |
192 | |
193 explicit | |
194 BOOST_SIGNALS_SIGNAL(const Combiner& c = Combiner(), | |
195 const GroupCompare& comp = GroupCompare()) : | |
196 BOOST_SIGNALS_NAMESPACE::detail::signal_base(real_group_compare_type(comp), | |
197 c) | |
198 { | |
199 } | |
200 | |
201 // Connect a slot to this signal | |
202 BOOST_SIGNALS_NAMESPACE::connection | |
203 connect(const slot_type&, | |
204 BOOST_SIGNALS_NAMESPACE::connect_position at | |
205 = BOOST_SIGNALS_NAMESPACE::at_back); | |
206 | |
207 | |
208 BOOST_SIGNALS_NAMESPACE::connection | |
209 connect(const group_type&, const slot_type&, | |
210 BOOST_SIGNALS_NAMESPACE::connect_position at | |
211 = BOOST_SIGNALS_NAMESPACE::at_back); | |
212 | |
213 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
214 // MSVC 6.0 and 7.0 don't handle the is_convertible test well | |
215 void disconnect(const group_type& group) | |
216 { | |
217 impl->disconnect(group); | |
218 } | |
219 #else | |
220 template<typename T> | |
221 void disconnect(const T& t) | |
222 { | |
223 typedef mpl::bool_<(is_convertible<T, group_type>::value)> is_group; | |
224 this->do_disconnect(t, is_group()); | |
225 } | |
226 | |
227 private: | |
228 // Disconnect a named slot | |
229 void do_disconnect(const group_type& group, mpl::bool_<true>) | |
230 { | |
231 impl->disconnect(group); | |
232 } | |
233 | |
234 template<typename Function> | |
235 void do_disconnect(const Function& f, mpl::bool_<false>) | |
236 { | |
237 // Notify the slot handling code that we are iterating through the slots | |
238 BOOST_SIGNALS_NAMESPACE::detail::call_notification notification(this->impl); | |
239 | |
240 for (iterator i = impl->slots_.begin(); i != impl->slots_.end(); ++i) { | |
241 slot_function_type& s = *unsafe_any_cast<slot_function_type>(&i->second); | |
242 if (s == f) i->first.disconnect(); | |
243 } | |
244 } | |
245 #endif | |
246 | |
247 public: | |
248 | |
249 // Emit the signal | |
250 result_type operator()(BOOST_SIGNALS_PARMS); | |
251 result_type operator()(BOOST_SIGNALS_PARMS) const; | |
252 | |
253 Combiner& combiner() | |
254 { return *unsafe_any_cast<Combiner>(&impl->combiner_); } | |
255 | |
256 const Combiner& combiner() const | |
257 { return *unsafe_any_cast<const Combiner>(&impl->combiner_); } | |
258 }; | |
259 | |
260 template< | |
261 typename R, | |
262 BOOST_SIGNALS_TEMPLATE_PARMS | |
263 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
264 typename Combiner, | |
265 typename Group, | |
266 typename GroupCompare, | |
267 typename SlotFunction | |
268 > | |
269 BOOST_SIGNALS_NAMESPACE::connection | |
270 BOOST_SIGNALS_SIGNAL< | |
271 R, BOOST_SIGNALS_TEMPLATE_ARGS | |
272 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
273 Combiner, Group, GroupCompare, SlotFunction | |
274 >::connect(const slot_type& in_slot, | |
275 BOOST_SIGNALS_NAMESPACE::connect_position at) | |
276 { | |
277 using boost::BOOST_SIGNALS_NAMESPACE::detail::stored_group; | |
278 | |
279 // If the slot has been disconnected, just return a disconnected | |
280 // connection | |
281 if (!in_slot.is_active()) { | |
282 return BOOST_SIGNALS_NAMESPACE::connection(); | |
283 } | |
284 | |
285 return impl->connect_slot(in_slot.get_slot_function(), stored_group(), | |
286 in_slot.get_data(), at); | |
287 } | |
288 | |
289 template< | |
290 typename R, | |
291 BOOST_SIGNALS_TEMPLATE_PARMS | |
292 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
293 typename Combiner, | |
294 typename Group, | |
295 typename GroupCompare, | |
296 typename SlotFunction | |
297 > | |
298 BOOST_SIGNALS_NAMESPACE::connection | |
299 BOOST_SIGNALS_SIGNAL< | |
300 R, BOOST_SIGNALS_TEMPLATE_ARGS | |
301 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
302 Combiner, Group, GroupCompare, SlotFunction | |
303 >::connect(const group_type& group, | |
304 const slot_type& in_slot, | |
305 BOOST_SIGNALS_NAMESPACE::connect_position at) | |
306 { | |
307 // If the slot has been disconnected, just return a disconnected | |
308 // connection | |
309 if (!in_slot.is_active()) { | |
310 return BOOST_SIGNALS_NAMESPACE::connection(); | |
311 } | |
312 | |
313 return impl->connect_slot(in_slot.get_slot_function(), group, | |
314 in_slot.get_data(), at); | |
315 } | |
316 | |
317 template< | |
318 typename R, | |
319 BOOST_SIGNALS_TEMPLATE_PARMS | |
320 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
321 typename Combiner, | |
322 typename Group, | |
323 typename GroupCompare, | |
324 typename SlotFunction | |
325 > | |
326 typename BOOST_SIGNALS_SIGNAL< | |
327 R, BOOST_SIGNALS_TEMPLATE_ARGS | |
328 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
329 Combiner, Group, GroupCompare, SlotFunction>::result_type | |
330 BOOST_SIGNALS_SIGNAL< | |
331 R, BOOST_SIGNALS_TEMPLATE_ARGS | |
332 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
333 Combiner, Group, GroupCompare, SlotFunction | |
334 >::operator()(BOOST_SIGNALS_PARMS) | |
335 { | |
336 // Notify the slot handling code that we are making a call | |
337 BOOST_SIGNALS_NAMESPACE::detail::call_notification notification(this->impl); | |
338 | |
339 // Construct a function object that will call the underlying slots | |
340 // with the given arguments. | |
341 #if BOOST_SIGNALS_NUM_ARGS == 0 | |
342 BOOST_SIGNALS_ARGS_STRUCT_INST args; | |
343 #else | |
344 BOOST_SIGNALS_ARGS_STRUCT_INST args(BOOST_SIGNALS_ARGS); | |
345 #endif // BOOST_SIGNALS_NUM_ARGS > 0 | |
346 call_bound_slot f(&args); | |
347 | |
348 typedef typename call_bound_slot::result_type call_result_type; | |
349 optional<call_result_type> cache; | |
350 // Let the combiner call the slots via a pair of input iterators | |
351 return combiner()(slot_call_iterator(notification.impl->slots_.begin(), | |
352 impl->slots_.end(), f, cache), | |
353 slot_call_iterator(notification.impl->slots_.end(), | |
354 impl->slots_.end(), f, cache)); | |
355 } | |
356 | |
357 template< | |
358 typename R, | |
359 BOOST_SIGNALS_TEMPLATE_PARMS | |
360 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
361 typename Combiner, | |
362 typename Group, | |
363 typename GroupCompare, | |
364 typename SlotFunction | |
365 > | |
366 typename BOOST_SIGNALS_SIGNAL< | |
367 R, BOOST_SIGNALS_TEMPLATE_ARGS | |
368 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
369 Combiner, Group, GroupCompare, SlotFunction>::result_type | |
370 BOOST_SIGNALS_SIGNAL< | |
371 R, BOOST_SIGNALS_TEMPLATE_ARGS | |
372 BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
373 Combiner, Group, GroupCompare, SlotFunction | |
374 >::operator()(BOOST_SIGNALS_PARMS) const | |
375 { | |
376 // Notify the slot handling code that we are making a call | |
377 BOOST_SIGNALS_NAMESPACE::detail::call_notification notification(this->impl); | |
378 | |
379 // Construct a function object that will call the underlying slots | |
380 // with the given arguments. | |
381 #if BOOST_SIGNALS_NUM_ARGS == 0 | |
382 BOOST_SIGNALS_ARGS_STRUCT_INST args; | |
383 #else | |
384 BOOST_SIGNALS_ARGS_STRUCT_INST args(BOOST_SIGNALS_ARGS); | |
385 #endif // BOOST_SIGNALS_NUM_ARGS > 0 | |
386 | |
387 call_bound_slot f(&args); | |
388 | |
389 typedef typename call_bound_slot::result_type call_result_type; | |
390 optional<call_result_type> cache; | |
391 | |
392 // Let the combiner call the slots via a pair of input iterators | |
393 return combiner()(slot_call_iterator(notification.impl->slots_.begin(), | |
394 impl->slots_.end(), f, cache), | |
395 slot_call_iterator(notification.impl->slots_.end(), | |
396 impl->slots_.end(), f, cache)); | |
397 } | |
398 } // namespace boost | |
399 | |
400 #undef BOOST_SIGNAL_FUNCTION_N_HEADER | |
401 #undef BOOST_SIGNALS_ARGS_STRUCT_INST | |
402 #undef BOOST_SIGNALS_CALL_BOUND | |
403 #undef BOOST_SIGNALS_ARGS_STRUCT | |
404 #undef BOOST_SIGNALS_FUNCTION | |
405 #undef BOOST_SIGNALS_SIGNAL | |
406 #undef BOOST_SIGNALS_COMMA_IF_NONZERO_ARGS | |
407 | |
408 #ifdef BOOST_HAS_ABI_HEADERS | |
409 # include BOOST_ABI_SUFFIX | |
410 #endif |