]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/function/function_template.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / function / function_template.hpp
CommitLineData
7c673cae
FG
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>
92f5a8d4 14#include <boost/core/no_exceptions_support.hpp>
7c673cae
FG
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
92f5a8d4 32# define BOOST_FUNCTION_ARG(J,I,D) static_cast<BOOST_PP_CAT(T,I)&&>(BOOST_PP_CAT(a,I))
7c673cae
FG
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
86namespace 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 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 f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
135 else
136 f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
137 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 {
92f5a8d4 242 typedef typename conditional<(is_void<R>::value),
7c673cae
FG
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 {
92f5a8d4 263 typedef typename conditional<(is_void<R>::value),
7c673cae
FG
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 {
92f5a8d4 284 typedef typename conditional<(is_void<R>::value),
7c673cae
FG
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 {
92f5a8d4 307 typedef typename conditional<(is_void<R>::value),
7c673cae
FG
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
92f5a8d4
TL
352 template<typename FunctionPtr, typename Allocator,
353 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
7c673cae
FG
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
92f5a8d4
TL
386 template<typename MemberPtr, typename Allocator,
387 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
7c673cae
FG
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
92f5a8d4
TL
420 template<typename FunctionObj, typename Allocator,
421 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
7c673cae
FG
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
92f5a8d4
TL
453 template<typename RefWrapper, typename Allocator,
454 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
7c673cae
FG
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 bool assign_to(F f, function_buffer& functor) const
491 {
492 typedef typename get_function_tag<F>::type tag;
493 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 void clear(function_buffer& functor) const
503 {
504 if (base.manager)
505 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
92f5a8d4 565 assign_functor(FunctionObj f, function_buffer& functor, true_type) const
7c673cae
FG
566 {
567 new (reinterpret_cast<void*>(functor.data)) FunctionObj(f);
568 }
569 template<typename FunctionObj,typename Allocator>
570 void
92f5a8d4 571 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, true_type) const
7c673cae 572 {
92f5a8d4 573 assign_functor(f,functor,true_type());
7c673cae
FG
574 }
575
576 // Assign to a function object allocated on the heap.
577 template<typename FunctionObj>
578 void
92f5a8d4 579 assign_functor(FunctionObj f, function_buffer& functor, false_type) const
7c673cae
FG
580 {
581 functor.members.obj_ptr = new FunctionObj(f);
582 }
583 template<typename FunctionObj,typename Allocator>
584 void
92f5a8d4 585 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, false_type) const
7c673cae
FG
586 {
587 typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
11fdf7f2 588#if defined(BOOST_NO_CXX11_ALLOCATOR)
7c673cae
FG
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;
11fdf7f2
TL
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
7c673cae
FG
596 wrapper_allocator_type wrapper_allocator(a);
597 wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
11fdf7f2 598#if defined(BOOST_NO_CXX11_ALLOCATOR)
7c673cae 599 wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
11fdf7f2
TL
600#else
601 std::allocator_traits<wrapper_allocator_type>::construct(wrapper_allocator, copy, functor_wrapper_type(f,a));
602#endif
7c673cae
FG
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 assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
610 {
611 if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
612 assign_functor(f, functor,
92f5a8d4 613 integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
7c673cae
FG
614 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,
92f5a8d4 625 integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
7c673cae
FG
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
7c673cae
FG
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 vtable_type* get_vtable() const {
678 return reinterpret_cast<vtable_type*>(
679 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
92f5a8d4 706 BOOST_DEFAULTED_FUNCTION(BOOST_FUNCTION_FUNCTION(), : function_base() {})
7c673cae
FG
707
708 // MSVC chokes if the following two constructors are collapsed into
709 // one with a default parameter.
710 template<typename Functor>
711 BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
712#ifndef BOOST_NO_SFINAE
92f5a8d4 713 ,typename boost::enable_if_<
7c673cae
FG
714 !(is_integral<Functor>::value),
715 int>::type = 0
716#endif // BOOST_NO_SFINAE
717 ) :
718 function_base()
719 {
720 this->assign_to(f);
721 }
722 template<typename Functor,typename Allocator>
723 BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
724#ifndef BOOST_NO_SFINAE
92f5a8d4 725 ,typename boost::enable_if_<
7c673cae
FG
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 BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
745 {
746 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 ~BOOST_FUNCTION_FUNCTION() { clear(); }
757
758 result_type operator()(BOOST_FUNCTION_PARMS) const
759 {
760 if (this->empty())
761 boost::throw_exception(bad_function_call());
762
763 return get_vtable()->invoker
764 (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
92f5a8d4 774 typename boost::enable_if_<
7c673cae
FG
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 void clear()
869 {
870 if (vtable) {
871 if (!this->has_trivial_copy_and_destroy())
872 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 void nonnull() {}
884 };
885
886 typedef void (dummy::*safe_bool)();
887
888 public:
889 operator safe_bool () const
890 { return (this->empty())? 0 : &dummy::nonnull; }
891
892 bool operator!() const
893 { return this->empty(); }
894#endif
895
896 private:
897 void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
898 {
899 if (!f.empty()) {
900 this->vtable = f.vtable;
f67539c2 901 if (this->has_trivial_copy_and_destroy()) {
92f5a8d4
TL
902 // Don't operate on storage directly since union type doesn't relax
903 // strict aliasing rules, despite of having member char type.
f67539c2
TL
904# if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
905# pragma GCC diagnostic push
906 // This warning is technically correct, but we don't want to pay the price for initializing
907 // just to silence a warning: https://github.com/boostorg/function/issues/27
908# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
909# endif
92f5a8d4 910 std::memcpy(this->functor.data, f.functor.data, sizeof(boost::detail::function::function_buffer));
f67539c2
TL
911# if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
912# pragma GCC diagnostic pop
913# endif
914 } else
7c673cae
FG
915 get_vtable()->base.manager(f.functor, this->functor,
916 boost::detail::function::clone_functor_tag);
917 }
918 }
919
920 template<typename Functor>
921 void assign_to(Functor f)
922 {
923 using boost::detail::function::vtable_base;
924
925 typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
926 typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
927 typedef typename get_invoker::
928 template apply<Functor, R BOOST_FUNCTION_COMMA
929 BOOST_FUNCTION_TEMPLATE_ARGS>
930 handler_type;
931
932 typedef typename handler_type::invoker_type invoker_type;
933 typedef typename handler_type::manager_type manager_type;
934
935 // Note: it is extremely important that this initialization use
936 // static initialization. Otherwise, we will have a race
937 // condition here in multi-threaded code. See
938 // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
939 static const vtable_type stored_vtable =
940 { { &manager_type::manage }, &invoker_type::invoke };
941
942 if (stored_vtable.assign_to(f, functor)) {
943 std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
944 // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
945 if (boost::has_trivial_copy_constructor<Functor>::value &&
946 boost::has_trivial_destructor<Functor>::value &&
947 boost::detail::function::function_allows_small_object_optimization<Functor>::value)
948 value |= static_cast<std::size_t>(0x01);
949 vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
950 } else
951 vtable = 0;
952 }
953
954 template<typename Functor,typename Allocator>
955 void assign_to_a(Functor f,Allocator a)
956 {
957 using boost::detail::function::vtable_base;
958
959 typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
960 typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
961 typedef typename get_invoker::
92f5a8d4
TL
962 template apply_a<Functor, Allocator, R BOOST_FUNCTION_COMMA
963 BOOST_FUNCTION_TEMPLATE_ARGS>
7c673cae
FG
964 handler_type;
965
966 typedef typename handler_type::invoker_type invoker_type;
967 typedef typename handler_type::manager_type manager_type;
968
969 // Note: it is extremely important that this initialization use
970 // static initialization. Otherwise, we will have a race
971 // condition here in multi-threaded code. See
972 // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
973 static const vtable_type stored_vtable =
974 { { &manager_type::manage }, &invoker_type::invoke };
975
976 if (stored_vtable.assign_to_a(f, functor, a)) {
977 std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
978 // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
979 if (boost::has_trivial_copy_constructor<Functor>::value &&
980 boost::has_trivial_destructor<Functor>::value &&
981 boost::detail::function::function_allows_small_object_optimization<Functor>::value)
982 value |= static_cast<std::size_t>(0x01);
983 vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
984 } else
985 vtable = 0;
986 }
987
988 // Moves the value from the specified argument to *this. If the argument
989 // has its function object allocated on the heap, move_assign will pass
990 // its buffer to *this, and set the argument's buffer pointer to NULL.
991 void move_assign(BOOST_FUNCTION_FUNCTION& f)
992 {
993 if (&f == this)
994 return;
995
996 BOOST_TRY {
997 if (!f.empty()) {
998 this->vtable = f.vtable;
f67539c2 999 if (this->has_trivial_copy_and_destroy()) {
92f5a8d4
TL
1000 // Don't operate on storage directly since union type doesn't relax
1001 // strict aliasing rules, despite of having member char type.
f67539c2
TL
1002# if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
1003# pragma GCC diagnostic push
1004 // This warning is technically correct, but we don't want to pay the price for initializing
1005 // just to silence a warning: https://github.com/boostorg/function/issues/27
1006# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1007# endif
92f5a8d4 1008 std::memcpy(this->functor.data, f.functor.data, sizeof(this->functor.data));
f67539c2
TL
1009# if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
1010# pragma GCC diagnostic pop
1011# endif
1012 } else
1e59de90
TL
1013#if defined(BOOST_GCC) && (__GNUC__ == 11)
1014# pragma GCC diagnostic push
1015// False positive in GCC 11 for empty function objects (function_n_test.cpp:673)
1016# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1017#endif
7c673cae
FG
1018 get_vtable()->base.manager(f.functor, this->functor,
1019 boost::detail::function::move_functor_tag);
1e59de90
TL
1020#if defined(BOOST_GCC) && (__GNUC__ == 11)
1021# pragma GCC diagnostic pop
1022#endif
7c673cae
FG
1023 f.vtable = 0;
1024 } else {
1025 clear();
1026 }
1027 } BOOST_CATCH (...) {
1028 vtable = 0;
1029 BOOST_RETHROW;
1030 }
1031 BOOST_CATCH_END
1032 }
1033 };
1034
1035 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1036 inline void swap(BOOST_FUNCTION_FUNCTION<
1037 R BOOST_FUNCTION_COMMA
1038 BOOST_FUNCTION_TEMPLATE_ARGS
1039 >& f1,
1040 BOOST_FUNCTION_FUNCTION<
1041 R BOOST_FUNCTION_COMMA
1042 BOOST_FUNCTION_TEMPLATE_ARGS
1043 >& f2)
1044 {
1045 f1.swap(f2);
1046 }
1047
1048// Poison comparisons between boost::function objects of the same type.
1049template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1050 void operator==(const BOOST_FUNCTION_FUNCTION<
1051 R BOOST_FUNCTION_COMMA
1052 BOOST_FUNCTION_TEMPLATE_ARGS>&,
1053 const BOOST_FUNCTION_FUNCTION<
1054 R BOOST_FUNCTION_COMMA
1055 BOOST_FUNCTION_TEMPLATE_ARGS>&);
1056template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1057 void operator!=(const BOOST_FUNCTION_FUNCTION<
1058 R BOOST_FUNCTION_COMMA
1059 BOOST_FUNCTION_TEMPLATE_ARGS>&,
1060 const BOOST_FUNCTION_FUNCTION<
1061 R BOOST_FUNCTION_COMMA
1062 BOOST_FUNCTION_TEMPLATE_ARGS>& );
1063
1064#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
1065
1066#if BOOST_FUNCTION_NUM_ARGS == 0
1067#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
1068#else
92f5a8d4 1069#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_FUNCTION_TEMPLATE_ARGS)
7c673cae
FG
1070#endif
1071
1072template<typename R BOOST_FUNCTION_COMMA
1073 BOOST_FUNCTION_TEMPLATE_PARMS>
1074class function<BOOST_FUNCTION_PARTIAL_SPEC>
1075 : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
1076{
1077 typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
1078 typedef function self_type;
1079
1080 struct clear_type {};
1081
1082public:
1083
92f5a8d4 1084 BOOST_DEFAULTED_FUNCTION(function(), : base_type() {})
7c673cae
FG
1085
1086 template<typename Functor>
1087 function(Functor f
1088#ifndef BOOST_NO_SFINAE
92f5a8d4 1089 ,typename boost::enable_if_<
7c673cae
FG
1090 !(is_integral<Functor>::value),
1091 int>::type = 0
1092#endif
1093 ) :
1094 base_type(f)
1095 {
1096 }
1097 template<typename Functor,typename Allocator>
1098 function(Functor f, Allocator a
1099#ifndef BOOST_NO_SFINAE
92f5a8d4 1100 ,typename boost::enable_if_<
7c673cae
FG
1101 !(is_integral<Functor>::value),
1102 int>::type = 0
1103#endif
1104 ) :
1105 base_type(f,a)
1106 {
1107 }
1108
1109#ifndef BOOST_NO_SFINAE
1110 function(clear_type*) : base_type() {}
1111#endif
1112
1113 function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1114
1115 function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1116
1117#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1118 // Move constructors
1119 function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
1120 function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
1121#endif
1122
1123 self_type& operator=(const self_type& f)
1124 {
1125 self_type(f).swap(*this);
1126 return *this;
1127 }
1128
1129#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1130 self_type& operator=(self_type&& f)
1131 {
1132 self_type(static_cast<self_type&&>(f)).swap(*this);
1133 return *this;
1134 }
1135#endif
1136
1137 template<typename Functor>
1138#ifndef BOOST_NO_SFINAE
92f5a8d4 1139 typename boost::enable_if_<
7c673cae
FG
1140 !(is_integral<Functor>::value),
1141 self_type&>::type
1142#else
1143 self_type&
1144#endif
1145 operator=(Functor f)
1146 {
1147 self_type(f).swap(*this);
1148 return *this;
1149 }
1150
1151#ifndef BOOST_NO_SFINAE
1152 self_type& operator=(clear_type*)
1153 {
1154 this->clear();
1155 return *this;
1156 }
1157#endif
1158
1159 self_type& operator=(const base_type& f)
1160 {
1161 self_type(f).swap(*this);
1162 return *this;
1163 }
1164
1165#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1166 self_type& operator=(base_type&& f)
1167 {
1168 self_type(static_cast<base_type&&>(f)).swap(*this);
1169 return *this;
1170 }
1171#endif
1172};
1173
1174#undef BOOST_FUNCTION_PARTIAL_SPEC
1175#endif // have partial specialization
1176
1177} // end namespace boost
1178
1179// Cleanup after ourselves...
1180#undef BOOST_FUNCTION_VTABLE
1181#undef BOOST_FUNCTION_COMMA
1182#undef BOOST_FUNCTION_FUNCTION
1183#undef BOOST_FUNCTION_FUNCTION_INVOKER
1184#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1185#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1186#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1187#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
1188#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1189#undef BOOST_FUNCTION_MEMBER_INVOKER
1190#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
1191#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
1192#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1193#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1194#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1195#undef BOOST_FUNCTION_GET_INVOKER
1196#undef BOOST_FUNCTION_TEMPLATE_PARMS
1197#undef BOOST_FUNCTION_TEMPLATE_ARGS
1198#undef BOOST_FUNCTION_PARMS
1199#undef BOOST_FUNCTION_PARM
1200#ifdef BOOST_FUNCTION_ARG
1201# undef BOOST_FUNCTION_ARG
1202#endif
1203#undef BOOST_FUNCTION_ARGS
1204#undef BOOST_FUNCTION_ARG_TYPE
1205#undef BOOST_FUNCTION_ARG_TYPES
1206#undef BOOST_FUNCTION_VOID_RETURN_TYPE
1207#undef BOOST_FUNCTION_RETURN
1208
1209#if defined(BOOST_MSVC)
1210# pragma warning( pop )
1211#endif