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