Line data Source code
1 : // Boost.Function library
2 :
3 : // Copyright Douglas Gregor 2001-2006
4 : // Copyright Emil Dotchevski 2007
5 : // Use, modification and distribution is subject to the Boost Software License, Version 1.0.
6 : // (See accompanying file LICENSE_1_0.txt or copy at
7 : // http://www.boost.org/LICENSE_1_0.txt)
8 :
9 : // For more information, see http://www.boost.org
10 :
11 : // Note: this header is a header template and must NOT have multiple-inclusion
12 : // protection.
13 : #include <boost/function/detail/prologue.hpp>
14 : #include <boost/core/no_exceptions_support.hpp>
15 :
16 : #if defined(BOOST_MSVC)
17 : # pragma warning( push )
18 : # pragma warning( disable : 4127 ) // "conditional expression is constant"
19 : #endif
20 :
21 : #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
22 :
23 : #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
24 :
25 : #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
26 :
27 : #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
28 :
29 : #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
30 : # define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
31 : #else
32 : # define BOOST_FUNCTION_ARG(J,I,D) static_cast<BOOST_PP_CAT(T,I)&&>(BOOST_PP_CAT(a,I))
33 : # define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY)
34 : #endif
35 :
36 : #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
37 : typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
38 :
39 : #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
40 :
41 : // Comma if nonzero number of arguments
42 : #if BOOST_FUNCTION_NUM_ARGS == 0
43 : # define BOOST_FUNCTION_COMMA
44 : #else
45 : # define BOOST_FUNCTION_COMMA ,
46 : #endif // BOOST_FUNCTION_NUM_ARGS > 0
47 :
48 : // Class names used in this version of the code
49 : #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
50 : #define BOOST_FUNCTION_FUNCTION_INVOKER \
51 : BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
52 : #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
53 : BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
54 : #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
55 : BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
56 : #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
57 : BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
58 : #define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
59 : BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
60 : #define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
61 : BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
62 : #define BOOST_FUNCTION_MEMBER_INVOKER \
63 : BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
64 : #define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
65 : BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
66 : #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
67 : BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
68 : #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
69 : BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
70 : #define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
71 : BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
72 : #define BOOST_FUNCTION_GET_MEMBER_INVOKER \
73 : BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
74 : #define BOOST_FUNCTION_GET_INVOKER \
75 : BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
76 : #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
77 :
78 : #ifndef BOOST_NO_VOID_RETURNS
79 : # define BOOST_FUNCTION_VOID_RETURN_TYPE void
80 : # define BOOST_FUNCTION_RETURN(X) X
81 : #else
82 : # define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
83 : # define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
84 : #endif
85 :
86 : namespace boost {
87 : namespace detail {
88 : namespace function {
89 : template<
90 : typename FunctionPtr,
91 : typename R BOOST_FUNCTION_COMMA
92 : BOOST_FUNCTION_TEMPLATE_PARMS
93 : >
94 : struct BOOST_FUNCTION_FUNCTION_INVOKER
95 : {
96 : static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
97 : BOOST_FUNCTION_PARMS)
98 : {
99 : FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
100 : return f(BOOST_FUNCTION_ARGS);
101 : }
102 : };
103 :
104 : template<
105 : typename FunctionPtr,
106 : typename R BOOST_FUNCTION_COMMA
107 : BOOST_FUNCTION_TEMPLATE_PARMS
108 : >
109 : struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
110 : {
111 : static BOOST_FUNCTION_VOID_RETURN_TYPE
112 : invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
113 : BOOST_FUNCTION_PARMS)
114 :
115 : {
116 : FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
117 : BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
118 : }
119 : };
120 :
121 : template<
122 : typename FunctionObj,
123 : typename R BOOST_FUNCTION_COMMA
124 : BOOST_FUNCTION_TEMPLATE_PARMS
125 : >
126 : struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
127 : {
128 0 : static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
129 : BOOST_FUNCTION_PARMS)
130 :
131 : {
132 : FunctionObj* f;
133 : if (function_allows_small_object_optimization<FunctionObj>::value)
134 0 : f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
135 : else
136 0 : f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
137 0 : return (*f)(BOOST_FUNCTION_ARGS);
138 : }
139 : };
140 :
141 : template<
142 : typename FunctionObj,
143 : typename R BOOST_FUNCTION_COMMA
144 : BOOST_FUNCTION_TEMPLATE_PARMS
145 : >
146 : struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
147 : {
148 : static BOOST_FUNCTION_VOID_RETURN_TYPE
149 : invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
150 : BOOST_FUNCTION_PARMS)
151 :
152 : {
153 : FunctionObj* f;
154 : if (function_allows_small_object_optimization<FunctionObj>::value)
155 : f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
156 : else
157 : f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
158 : BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
159 : }
160 : };
161 :
162 : template<
163 : typename FunctionObj,
164 : typename R BOOST_FUNCTION_COMMA
165 : BOOST_FUNCTION_TEMPLATE_PARMS
166 : >
167 : struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
168 : {
169 : static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
170 : BOOST_FUNCTION_PARMS)
171 :
172 : {
173 : FunctionObj* f =
174 : reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
175 : return (*f)(BOOST_FUNCTION_ARGS);
176 : }
177 : };
178 :
179 : template<
180 : typename FunctionObj,
181 : typename R BOOST_FUNCTION_COMMA
182 : BOOST_FUNCTION_TEMPLATE_PARMS
183 : >
184 : struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
185 : {
186 : static BOOST_FUNCTION_VOID_RETURN_TYPE
187 : invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
188 : BOOST_FUNCTION_PARMS)
189 :
190 : {
191 : FunctionObj* f =
192 : reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
193 : BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
194 : }
195 : };
196 :
197 : #if BOOST_FUNCTION_NUM_ARGS > 0
198 : /* Handle invocation of member pointers. */
199 : template<
200 : typename MemberPtr,
201 : typename R BOOST_FUNCTION_COMMA
202 : BOOST_FUNCTION_TEMPLATE_PARMS
203 : >
204 : struct BOOST_FUNCTION_MEMBER_INVOKER
205 : {
206 : static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
207 : BOOST_FUNCTION_PARMS)
208 :
209 : {
210 : MemberPtr* f =
211 : reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
212 : return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
213 : }
214 : };
215 :
216 : template<
217 : typename MemberPtr,
218 : typename R BOOST_FUNCTION_COMMA
219 : BOOST_FUNCTION_TEMPLATE_PARMS
220 : >
221 : struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
222 : {
223 : static BOOST_FUNCTION_VOID_RETURN_TYPE
224 : invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
225 : BOOST_FUNCTION_PARMS)
226 :
227 : {
228 : MemberPtr* f =
229 : reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
230 : BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
231 : }
232 : };
233 : #endif
234 :
235 : template<
236 : typename FunctionPtr,
237 : typename R BOOST_FUNCTION_COMMA
238 : BOOST_FUNCTION_TEMPLATE_PARMS
239 : >
240 : struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
241 : {
242 : typedef typename conditional<(is_void<R>::value),
243 : BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
244 : FunctionPtr,
245 : R BOOST_FUNCTION_COMMA
246 : BOOST_FUNCTION_TEMPLATE_ARGS
247 : >,
248 : BOOST_FUNCTION_FUNCTION_INVOKER<
249 : FunctionPtr,
250 : R BOOST_FUNCTION_COMMA
251 : BOOST_FUNCTION_TEMPLATE_ARGS
252 : >
253 : >::type type;
254 : };
255 :
256 : template<
257 : typename FunctionObj,
258 : typename R BOOST_FUNCTION_COMMA
259 : BOOST_FUNCTION_TEMPLATE_PARMS
260 : >
261 : struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
262 : {
263 : typedef typename conditional<(is_void<R>::value),
264 : BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
265 : FunctionObj,
266 : R BOOST_FUNCTION_COMMA
267 : BOOST_FUNCTION_TEMPLATE_ARGS
268 : >,
269 : BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
270 : FunctionObj,
271 : R BOOST_FUNCTION_COMMA
272 : BOOST_FUNCTION_TEMPLATE_ARGS
273 : >
274 : >::type type;
275 : };
276 :
277 : template<
278 : typename FunctionObj,
279 : typename R BOOST_FUNCTION_COMMA
280 : BOOST_FUNCTION_TEMPLATE_PARMS
281 : >
282 : struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
283 : {
284 : typedef typename conditional<(is_void<R>::value),
285 : BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
286 : FunctionObj,
287 : R BOOST_FUNCTION_COMMA
288 : BOOST_FUNCTION_TEMPLATE_ARGS
289 : >,
290 : BOOST_FUNCTION_FUNCTION_REF_INVOKER<
291 : FunctionObj,
292 : R BOOST_FUNCTION_COMMA
293 : BOOST_FUNCTION_TEMPLATE_ARGS
294 : >
295 : >::type type;
296 : };
297 :
298 : #if BOOST_FUNCTION_NUM_ARGS > 0
299 : /* Retrieve the appropriate invoker for a member pointer. */
300 : template<
301 : typename MemberPtr,
302 : typename R BOOST_FUNCTION_COMMA
303 : BOOST_FUNCTION_TEMPLATE_PARMS
304 : >
305 : struct BOOST_FUNCTION_GET_MEMBER_INVOKER
306 : {
307 : typedef typename conditional<(is_void<R>::value),
308 : BOOST_FUNCTION_VOID_MEMBER_INVOKER<
309 : MemberPtr,
310 : R BOOST_FUNCTION_COMMA
311 : BOOST_FUNCTION_TEMPLATE_ARGS
312 : >,
313 : BOOST_FUNCTION_MEMBER_INVOKER<
314 : MemberPtr,
315 : R BOOST_FUNCTION_COMMA
316 : BOOST_FUNCTION_TEMPLATE_ARGS
317 : >
318 : >::type type;
319 : };
320 : #endif
321 :
322 : /* Given the tag returned by get_function_tag, retrieve the
323 : actual invoker that will be used for the given function
324 : object.
325 :
326 : Each specialization contains an "apply" nested class template
327 : that accepts the function object, return type, function
328 : argument types, and allocator. The resulting "apply" class
329 : contains two typedefs, "invoker_type" and "manager_type",
330 : which correspond to the invoker and manager types. */
331 : template<typename Tag>
332 : struct BOOST_FUNCTION_GET_INVOKER { };
333 :
334 : /* Retrieve the invoker for a function pointer. */
335 : template<>
336 : struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
337 : {
338 : template<typename FunctionPtr,
339 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
340 : struct apply
341 : {
342 : typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
343 : FunctionPtr,
344 : R BOOST_FUNCTION_COMMA
345 : BOOST_FUNCTION_TEMPLATE_ARGS
346 : >::type
347 : invoker_type;
348 :
349 : typedef functor_manager<FunctionPtr> manager_type;
350 : };
351 :
352 : template<typename FunctionPtr, typename Allocator,
353 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
354 : struct apply_a
355 : {
356 : typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
357 : FunctionPtr,
358 : R BOOST_FUNCTION_COMMA
359 : BOOST_FUNCTION_TEMPLATE_ARGS
360 : >::type
361 : invoker_type;
362 :
363 : typedef functor_manager<FunctionPtr> manager_type;
364 : };
365 : };
366 :
367 : #if BOOST_FUNCTION_NUM_ARGS > 0
368 : /* Retrieve the invoker for a member pointer. */
369 : template<>
370 : struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
371 : {
372 : template<typename MemberPtr,
373 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
374 : struct apply
375 : {
376 : typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
377 : MemberPtr,
378 : R BOOST_FUNCTION_COMMA
379 : BOOST_FUNCTION_TEMPLATE_ARGS
380 : >::type
381 : invoker_type;
382 :
383 : typedef functor_manager<MemberPtr> manager_type;
384 : };
385 :
386 : template<typename MemberPtr, typename Allocator,
387 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
388 : struct apply_a
389 : {
390 : typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
391 : MemberPtr,
392 : R BOOST_FUNCTION_COMMA
393 : BOOST_FUNCTION_TEMPLATE_ARGS
394 : >::type
395 : invoker_type;
396 :
397 : typedef functor_manager<MemberPtr> manager_type;
398 : };
399 : };
400 : #endif
401 :
402 : /* Retrieve the invoker for a function object. */
403 : template<>
404 : struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
405 : {
406 : template<typename FunctionObj,
407 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
408 : struct apply
409 : {
410 : typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
411 : FunctionObj,
412 : R BOOST_FUNCTION_COMMA
413 : BOOST_FUNCTION_TEMPLATE_ARGS
414 : >::type
415 : invoker_type;
416 :
417 : typedef functor_manager<FunctionObj> manager_type;
418 : };
419 :
420 : template<typename FunctionObj, typename Allocator,
421 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
422 : struct apply_a
423 : {
424 : typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
425 : FunctionObj,
426 : R BOOST_FUNCTION_COMMA
427 : BOOST_FUNCTION_TEMPLATE_ARGS
428 : >::type
429 : invoker_type;
430 :
431 : typedef functor_manager_a<FunctionObj, Allocator> manager_type;
432 : };
433 : };
434 :
435 : /* Retrieve the invoker for a reference to a function object. */
436 : template<>
437 : struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
438 : {
439 : template<typename RefWrapper,
440 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
441 : struct apply
442 : {
443 : typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
444 : typename RefWrapper::type,
445 : R BOOST_FUNCTION_COMMA
446 : BOOST_FUNCTION_TEMPLATE_ARGS
447 : >::type
448 : invoker_type;
449 :
450 : typedef reference_manager<typename RefWrapper::type> manager_type;
451 : };
452 :
453 : template<typename RefWrapper, typename Allocator,
454 : typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
455 : struct apply_a
456 : {
457 : typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
458 : typename RefWrapper::type,
459 : R BOOST_FUNCTION_COMMA
460 : BOOST_FUNCTION_TEMPLATE_ARGS
461 : >::type
462 : invoker_type;
463 :
464 : typedef reference_manager<typename RefWrapper::type> manager_type;
465 : };
466 : };
467 :
468 :
469 : /**
470 : * vtable for a specific boost::function instance. This
471 : * structure must be an aggregate so that we can use static
472 : * initialization in boost::function's assign_to and assign_to_a
473 : * members. It therefore cannot have any constructors,
474 : * destructors, base classes, etc.
475 : */
476 : template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
477 : struct BOOST_FUNCTION_VTABLE
478 : {
479 : #ifndef BOOST_NO_VOID_RETURNS
480 : typedef R result_type;
481 : #else
482 : typedef typename function_return_type<R>::type result_type;
483 : #endif // BOOST_NO_VOID_RETURNS
484 :
485 : typedef result_type (*invoker_type)(function_buffer&
486 : BOOST_FUNCTION_COMMA
487 : BOOST_FUNCTION_TEMPLATE_ARGS);
488 :
489 : template<typename F>
490 0 : bool assign_to(F f, function_buffer& functor) const
491 : {
492 : typedef typename get_function_tag<F>::type tag;
493 0 : return assign_to(f, functor, tag());
494 : }
495 : template<typename F,typename Allocator>
496 : bool assign_to_a(F f, function_buffer& functor, Allocator a) const
497 : {
498 : typedef typename get_function_tag<F>::type tag;
499 : return assign_to_a(f, functor, a, tag());
500 : }
501 :
502 0 : void clear(function_buffer& functor) const
503 : {
504 0 : if (base.manager)
505 0 : base.manager(functor, functor, destroy_functor_tag);
506 : }
507 :
508 : private:
509 : // Function pointers
510 : template<typename FunctionPtr>
511 : bool
512 : assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
513 : {
514 : this->clear(functor);
515 : if (f) {
516 : // should be a reinterpret cast, but some compilers insist
517 : // on giving cv-qualifiers to free functions
518 : functor.members.func_ptr = reinterpret_cast<void (*)()>(f);
519 : return true;
520 : } else {
521 : return false;
522 : }
523 : }
524 : template<typename FunctionPtr,typename Allocator>
525 : bool
526 : assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
527 : {
528 : return assign_to(f,functor,function_ptr_tag());
529 : }
530 :
531 : // Member pointers
532 : #if BOOST_FUNCTION_NUM_ARGS > 0
533 : template<typename MemberPtr>
534 : bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
535 : {
536 : // DPG TBD: Add explicit support for member function
537 : // objects, so we invoke through mem_fn() but we retain the
538 : // right target_type() values.
539 : if (f) {
540 : this->assign_to(boost::mem_fn(f), functor);
541 : return true;
542 : } else {
543 : return false;
544 : }
545 : }
546 : template<typename MemberPtr,typename Allocator>
547 : bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
548 : {
549 : // DPG TBD: Add explicit support for member function
550 : // objects, so we invoke through mem_fn() but we retain the
551 : // right target_type() values.
552 : if (f) {
553 : this->assign_to_a(boost::mem_fn(f), functor, a);
554 : return true;
555 : } else {
556 : return false;
557 : }
558 : }
559 : #endif // BOOST_FUNCTION_NUM_ARGS > 0
560 :
561 : // Function objects
562 : // Assign to a function object using the small object optimization
563 : template<typename FunctionObj>
564 : void
565 0 : assign_functor(FunctionObj f, function_buffer& functor, true_type) const
566 : {
567 0 : new (reinterpret_cast<void*>(functor.data)) FunctionObj(f);
568 : }
569 : template<typename FunctionObj,typename Allocator>
570 : void
571 : assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, true_type) const
572 : {
573 : assign_functor(f,functor,true_type());
574 : }
575 :
576 : // Assign to a function object allocated on the heap.
577 : template<typename FunctionObj>
578 : void
579 : assign_functor(FunctionObj f, function_buffer& functor, false_type) const
580 : {
581 : functor.members.obj_ptr = new FunctionObj(f);
582 : }
583 : template<typename FunctionObj,typename Allocator>
584 : void
585 : assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, false_type) const
586 : {
587 : typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
588 : #if defined(BOOST_NO_CXX11_ALLOCATOR)
589 : typedef typename Allocator::template rebind<functor_wrapper_type>::other
590 : wrapper_allocator_type;
591 : typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
592 : #else
593 : using wrapper_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<functor_wrapper_type>;
594 : using wrapper_allocator_pointer_type = typename std::allocator_traits<wrapper_allocator_type>::pointer;
595 : #endif
596 : wrapper_allocator_type wrapper_allocator(a);
597 : wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
598 : #if defined(BOOST_NO_CXX11_ALLOCATOR)
599 : wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
600 : #else
601 : std::allocator_traits<wrapper_allocator_type>::construct(wrapper_allocator, copy, functor_wrapper_type(f,a));
602 : #endif
603 : functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
604 : functor.members.obj_ptr = new_f;
605 : }
606 :
607 : template<typename FunctionObj>
608 : bool
609 0 : assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
610 : {
611 0 : if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
612 0 : assign_functor(f, functor,
613 : integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
614 0 : return true;
615 : } else {
616 : return false;
617 : }
618 : }
619 : template<typename FunctionObj,typename Allocator>
620 : bool
621 : assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
622 : {
623 : if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
624 : assign_functor_a(f, functor, a,
625 : integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
626 : return true;
627 : } else {
628 : return false;
629 : }
630 : }
631 :
632 : // Reference to a function object
633 : template<typename FunctionObj>
634 : bool
635 : assign_to(const reference_wrapper<FunctionObj>& f,
636 : function_buffer& functor, function_obj_ref_tag) const
637 : {
638 : functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer());
639 : functor.members.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
640 : functor.members.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
641 : return true;
642 : }
643 : template<typename FunctionObj,typename Allocator>
644 : bool
645 : assign_to_a(const reference_wrapper<FunctionObj>& f,
646 : function_buffer& functor, Allocator, function_obj_ref_tag) const
647 : {
648 : return assign_to(f,functor,function_obj_ref_tag());
649 : }
650 :
651 : public:
652 : vtable_base base;
653 : invoker_type invoker;
654 : };
655 : } // end namespace function
656 : } // end namespace detail
657 :
658 : template<
659 : typename R BOOST_FUNCTION_COMMA
660 : BOOST_FUNCTION_TEMPLATE_PARMS
661 : >
662 : class BOOST_FUNCTION_FUNCTION : public function_base
663 : {
664 : public:
665 : #ifndef BOOST_NO_VOID_RETURNS
666 : typedef R result_type;
667 : #else
668 : typedef typename boost::detail::function::function_return_type<R>::type
669 : result_type;
670 : #endif // BOOST_NO_VOID_RETURNS
671 :
672 : private:
673 : typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
674 : R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
675 : vtable_type;
676 :
677 0 : vtable_type* get_vtable() const {
678 : return reinterpret_cast<vtable_type*>(
679 0 : reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
680 : }
681 :
682 : struct clear_type {};
683 :
684 : public:
685 : BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
686 :
687 : // add signature for boost::lambda
688 : template<typename Args>
689 : struct sig
690 : {
691 : typedef result_type type;
692 : };
693 :
694 : #if BOOST_FUNCTION_NUM_ARGS == 1
695 : typedef T0 argument_type;
696 : #elif BOOST_FUNCTION_NUM_ARGS == 2
697 : typedef T0 first_argument_type;
698 : typedef T1 second_argument_type;
699 : #endif
700 :
701 : BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
702 : BOOST_FUNCTION_ARG_TYPES
703 :
704 : typedef BOOST_FUNCTION_FUNCTION self_type;
705 :
706 0 : BOOST_DEFAULTED_FUNCTION(BOOST_FUNCTION_FUNCTION(), : function_base() {})
707 :
708 : // MSVC chokes if the following two constructors are collapsed into
709 : // one with a default parameter.
710 : template<typename Functor>
711 0 : BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
712 : #ifndef BOOST_NO_SFINAE
713 : ,typename boost::enable_if_<
714 : !(is_integral<Functor>::value),
715 : int>::type = 0
716 : #endif // BOOST_NO_SFINAE
717 : ) :
718 0 : function_base()
719 : {
720 0 : this->assign_to(f);
721 0 : }
722 : template<typename Functor,typename Allocator>
723 : BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
724 : #ifndef BOOST_NO_SFINAE
725 : ,typename boost::enable_if_<
726 : !(is_integral<Functor>::value),
727 : int>::type = 0
728 : #endif // BOOST_NO_SFINAE
729 : ) :
730 : function_base()
731 : {
732 : this->assign_to_a(f,a);
733 : }
734 :
735 : #ifndef BOOST_NO_SFINAE
736 : BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
737 : #else
738 : BOOST_FUNCTION_FUNCTION(int zero) : function_base()
739 : {
740 : BOOST_ASSERT(zero == 0);
741 : }
742 : #endif
743 :
744 0 : BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
745 : {
746 0 : this->assign_to_own(f);
747 : }
748 :
749 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
750 : BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
751 : {
752 : this->move_assign(f);
753 : }
754 : #endif
755 :
756 0 : ~BOOST_FUNCTION_FUNCTION() { clear(); }
757 :
758 0 : result_type operator()(BOOST_FUNCTION_PARMS) const
759 : {
760 0 : if (this->empty())
761 0 : boost::throw_exception(bad_function_call());
762 :
763 0 : return get_vtable()->invoker
764 0 : (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
765 : }
766 :
767 : // The distinction between when to use BOOST_FUNCTION_FUNCTION and
768 : // when to use self_type is obnoxious. MSVC cannot handle self_type as
769 : // the return type of these assignment operators, but Borland C++ cannot
770 : // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
771 : // construct.
772 : template<typename Functor>
773 : #ifndef BOOST_NO_SFINAE
774 : typename boost::enable_if_<
775 : !(is_integral<Functor>::value),
776 : BOOST_FUNCTION_FUNCTION&>::type
777 : #else
778 : BOOST_FUNCTION_FUNCTION&
779 : #endif
780 : operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
781 : {
782 : this->clear();
783 : BOOST_TRY {
784 : this->assign_to(f);
785 : } BOOST_CATCH (...) {
786 : vtable = 0;
787 : BOOST_RETHROW;
788 : }
789 : BOOST_CATCH_END
790 : return *this;
791 : }
792 : template<typename Functor,typename Allocator>
793 : void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
794 : {
795 : this->clear();
796 : BOOST_TRY{
797 : this->assign_to_a(f,a);
798 : } BOOST_CATCH (...) {
799 : vtable = 0;
800 : BOOST_RETHROW;
801 : }
802 : BOOST_CATCH_END
803 : }
804 :
805 : #ifndef BOOST_NO_SFINAE
806 : BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
807 : {
808 : this->clear();
809 : return *this;
810 : }
811 : #else
812 : BOOST_FUNCTION_FUNCTION& operator=(int zero)
813 : {
814 : BOOST_ASSERT(zero == 0);
815 : this->clear();
816 : return *this;
817 : }
818 : #endif
819 :
820 : // Assignment from another BOOST_FUNCTION_FUNCTION
821 : BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
822 : {
823 : if (&f == this)
824 : return *this;
825 :
826 : this->clear();
827 : BOOST_TRY {
828 : this->assign_to_own(f);
829 : } BOOST_CATCH (...) {
830 : vtable = 0;
831 : BOOST_RETHROW;
832 : }
833 : BOOST_CATCH_END
834 : return *this;
835 : }
836 :
837 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
838 : // Move assignment from another BOOST_FUNCTION_FUNCTION
839 : BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
840 : {
841 : if (&f == this)
842 : return *this;
843 :
844 : this->clear();
845 : BOOST_TRY {
846 : this->move_assign(f);
847 : } BOOST_CATCH (...) {
848 : vtable = 0;
849 : BOOST_RETHROW;
850 : }
851 : BOOST_CATCH_END
852 : return *this;
853 : }
854 : #endif
855 :
856 : void swap(BOOST_FUNCTION_FUNCTION& other)
857 : {
858 : if (&other == this)
859 : return;
860 :
861 : BOOST_FUNCTION_FUNCTION tmp;
862 : tmp.move_assign(*this);
863 : this->move_assign(other);
864 : other.move_assign(tmp);
865 : }
866 :
867 : // Clear out a target, if there is one
868 0 : void clear()
869 : {
870 0 : if (vtable) {
871 0 : if (!this->has_trivial_copy_and_destroy())
872 0 : get_vtable()->clear(this->functor);
873 : vtable = 0;
874 : }
875 : }
876 :
877 : #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
878 : // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
879 : operator bool () const { return !this->empty(); }
880 : #else
881 : private:
882 : struct dummy {
883 0 : void nonnull() {}
884 : };
885 :
886 : typedef void (dummy::*safe_bool)();
887 :
888 : public:
889 0 : operator safe_bool () const
890 0 : { return (this->empty())? 0 : &dummy::nonnull; }
891 :
892 : bool operator!() const
893 : { return this->empty(); }
894 : #endif
895 :
896 : private:
897 0 : void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
898 : {
899 0 : if (!f.empty()) {
900 0 : this->vtable = f.vtable;
901 0 : if (this->has_trivial_copy_and_destroy())
902 : // Don't operate on storage directly since union type doesn't relax
903 : // strict aliasing rules, despite of having member char type.
904 0 : std::memcpy(this->functor.data, f.functor.data, sizeof(boost::detail::function::function_buffer));
905 : else
906 0 : get_vtable()->base.manager(f.functor, this->functor,
907 : boost::detail::function::clone_functor_tag);
908 : }
909 0 : }
910 :
911 : template<typename Functor>
912 0 : void assign_to(Functor f)
913 : {
914 : using boost::detail::function::vtable_base;
915 :
916 : typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
917 : typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
918 : typedef typename get_invoker::
919 : template apply<Functor, R BOOST_FUNCTION_COMMA
920 : BOOST_FUNCTION_TEMPLATE_ARGS>
921 : handler_type;
922 :
923 : typedef typename handler_type::invoker_type invoker_type;
924 : typedef typename handler_type::manager_type manager_type;
925 :
926 : // Note: it is extremely important that this initialization use
927 : // static initialization. Otherwise, we will have a race
928 : // condition here in multi-threaded code. See
929 : // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
930 : static const vtable_type stored_vtable =
931 : { { &manager_type::manage }, &invoker_type::invoke };
932 :
933 0 : if (stored_vtable.assign_to(f, functor)) {
934 0 : std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
935 : // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
936 : if (boost::has_trivial_copy_constructor<Functor>::value &&
937 : boost::has_trivial_destructor<Functor>::value &&
938 : boost::detail::function::function_allows_small_object_optimization<Functor>::value)
939 0 : value |= static_cast<std::size_t>(0x01);
940 0 : vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
941 : } else
942 0 : vtable = 0;
943 0 : }
944 :
945 : template<typename Functor,typename Allocator>
946 : void assign_to_a(Functor f,Allocator a)
947 : {
948 : using boost::detail::function::vtable_base;
949 :
950 : typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
951 : typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
952 : typedef typename get_invoker::
953 : template apply_a<Functor, Allocator, R BOOST_FUNCTION_COMMA
954 : BOOST_FUNCTION_TEMPLATE_ARGS>
955 : handler_type;
956 :
957 : typedef typename handler_type::invoker_type invoker_type;
958 : typedef typename handler_type::manager_type manager_type;
959 :
960 : // Note: it is extremely important that this initialization use
961 : // static initialization. Otherwise, we will have a race
962 : // condition here in multi-threaded code. See
963 : // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
964 : static const vtable_type stored_vtable =
965 : { { &manager_type::manage }, &invoker_type::invoke };
966 :
967 : if (stored_vtable.assign_to_a(f, functor, a)) {
968 : std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
969 : // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
970 : if (boost::has_trivial_copy_constructor<Functor>::value &&
971 : boost::has_trivial_destructor<Functor>::value &&
972 : boost::detail::function::function_allows_small_object_optimization<Functor>::value)
973 : value |= static_cast<std::size_t>(0x01);
974 : vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
975 : } else
976 : vtable = 0;
977 : }
978 :
979 : // Moves the value from the specified argument to *this. If the argument
980 : // has its function object allocated on the heap, move_assign will pass
981 : // its buffer to *this, and set the argument's buffer pointer to NULL.
982 : void move_assign(BOOST_FUNCTION_FUNCTION& f)
983 : {
984 : if (&f == this)
985 : return;
986 :
987 : BOOST_TRY {
988 : if (!f.empty()) {
989 : this->vtable = f.vtable;
990 : if (this->has_trivial_copy_and_destroy())
991 : // Don't operate on storage directly since union type doesn't relax
992 : // strict aliasing rules, despite of having member char type.
993 : std::memcpy(this->functor.data, f.functor.data, sizeof(this->functor.data));
994 : else
995 : get_vtable()->base.manager(f.functor, this->functor,
996 : boost::detail::function::move_functor_tag);
997 : f.vtable = 0;
998 : } else {
999 : clear();
1000 : }
1001 : } BOOST_CATCH (...) {
1002 : vtable = 0;
1003 : BOOST_RETHROW;
1004 : }
1005 : BOOST_CATCH_END
1006 : }
1007 : };
1008 :
1009 : template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1010 : inline void swap(BOOST_FUNCTION_FUNCTION<
1011 : R BOOST_FUNCTION_COMMA
1012 : BOOST_FUNCTION_TEMPLATE_ARGS
1013 : >& f1,
1014 : BOOST_FUNCTION_FUNCTION<
1015 : R BOOST_FUNCTION_COMMA
1016 : BOOST_FUNCTION_TEMPLATE_ARGS
1017 : >& f2)
1018 : {
1019 : f1.swap(f2);
1020 : }
1021 :
1022 : // Poison comparisons between boost::function objects of the same type.
1023 : template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1024 : void operator==(const BOOST_FUNCTION_FUNCTION<
1025 : R BOOST_FUNCTION_COMMA
1026 : BOOST_FUNCTION_TEMPLATE_ARGS>&,
1027 : const BOOST_FUNCTION_FUNCTION<
1028 : R BOOST_FUNCTION_COMMA
1029 : BOOST_FUNCTION_TEMPLATE_ARGS>&);
1030 : template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1031 : void operator!=(const BOOST_FUNCTION_FUNCTION<
1032 : R BOOST_FUNCTION_COMMA
1033 : BOOST_FUNCTION_TEMPLATE_ARGS>&,
1034 : const BOOST_FUNCTION_FUNCTION<
1035 : R BOOST_FUNCTION_COMMA
1036 : BOOST_FUNCTION_TEMPLATE_ARGS>& );
1037 :
1038 : #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
1039 :
1040 : #if BOOST_FUNCTION_NUM_ARGS == 0
1041 : #define BOOST_FUNCTION_PARTIAL_SPEC R (void)
1042 : #else
1043 : #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_FUNCTION_TEMPLATE_ARGS)
1044 : #endif
1045 :
1046 : template<typename R BOOST_FUNCTION_COMMA
1047 : BOOST_FUNCTION_TEMPLATE_PARMS>
1048 0 : class function<BOOST_FUNCTION_PARTIAL_SPEC>
1049 : : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
1050 : {
1051 : typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
1052 : typedef function self_type;
1053 :
1054 : struct clear_type {};
1055 :
1056 : public:
1057 :
1058 : BOOST_DEFAULTED_FUNCTION(function(), : base_type() {})
1059 :
1060 : template<typename Functor>
1061 : function(Functor f
1062 : #ifndef BOOST_NO_SFINAE
1063 : ,typename boost::enable_if_<
1064 : !(is_integral<Functor>::value),
1065 : int>::type = 0
1066 : #endif
1067 : ) :
1068 : base_type(f)
1069 : {
1070 : }
1071 : template<typename Functor,typename Allocator>
1072 : function(Functor f, Allocator a
1073 : #ifndef BOOST_NO_SFINAE
1074 : ,typename boost::enable_if_<
1075 : !(is_integral<Functor>::value),
1076 : int>::type = 0
1077 : #endif
1078 : ) :
1079 : base_type(f,a)
1080 : {
1081 : }
1082 :
1083 : #ifndef BOOST_NO_SFINAE
1084 : function(clear_type*) : base_type() {}
1085 : #endif
1086 :
1087 0 : function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1088 :
1089 : function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1090 :
1091 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1092 : // Move constructors
1093 : function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
1094 : function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
1095 : #endif
1096 :
1097 : self_type& operator=(const self_type& f)
1098 : {
1099 : self_type(f).swap(*this);
1100 : return *this;
1101 : }
1102 :
1103 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1104 : self_type& operator=(self_type&& f)
1105 : {
1106 : self_type(static_cast<self_type&&>(f)).swap(*this);
1107 : return *this;
1108 : }
1109 : #endif
1110 :
1111 : template<typename Functor>
1112 : #ifndef BOOST_NO_SFINAE
1113 : typename boost::enable_if_<
1114 : !(is_integral<Functor>::value),
1115 : self_type&>::type
1116 : #else
1117 : self_type&
1118 : #endif
1119 : operator=(Functor f)
1120 : {
1121 : self_type(f).swap(*this);
1122 : return *this;
1123 : }
1124 :
1125 : #ifndef BOOST_NO_SFINAE
1126 : self_type& operator=(clear_type*)
1127 : {
1128 : this->clear();
1129 : return *this;
1130 : }
1131 : #endif
1132 :
1133 : self_type& operator=(const base_type& f)
1134 : {
1135 : self_type(f).swap(*this);
1136 : return *this;
1137 : }
1138 :
1139 : #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1140 : self_type& operator=(base_type&& f)
1141 : {
1142 : self_type(static_cast<base_type&&>(f)).swap(*this);
1143 : return *this;
1144 : }
1145 : #endif
1146 : };
1147 :
1148 : #undef BOOST_FUNCTION_PARTIAL_SPEC
1149 : #endif // have partial specialization
1150 :
1151 : } // end namespace boost
1152 :
1153 : // Cleanup after ourselves...
1154 : #undef BOOST_FUNCTION_VTABLE
1155 : #undef BOOST_FUNCTION_COMMA
1156 : #undef BOOST_FUNCTION_FUNCTION
1157 : #undef BOOST_FUNCTION_FUNCTION_INVOKER
1158 : #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1159 : #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1160 : #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1161 : #undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
1162 : #undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1163 : #undef BOOST_FUNCTION_MEMBER_INVOKER
1164 : #undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
1165 : #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
1166 : #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1167 : #undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1168 : #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1169 : #undef BOOST_FUNCTION_GET_INVOKER
1170 : #undef BOOST_FUNCTION_TEMPLATE_PARMS
1171 : #undef BOOST_FUNCTION_TEMPLATE_ARGS
1172 : #undef BOOST_FUNCTION_PARMS
1173 : #undef BOOST_FUNCTION_PARM
1174 : #ifdef BOOST_FUNCTION_ARG
1175 : # undef BOOST_FUNCTION_ARG
1176 : #endif
1177 : #undef BOOST_FUNCTION_ARGS
1178 : #undef BOOST_FUNCTION_ARG_TYPE
1179 : #undef BOOST_FUNCTION_ARG_TYPES
1180 : #undef BOOST_FUNCTION_VOID_RETURN_TYPE
1181 : #undef BOOST_FUNCTION_RETURN
1182 :
1183 : #if defined(BOOST_MSVC)
1184 : # pragma warning( pop )
1185 : #endif
|