1
// Boost.Function library
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)
9
// For more information, see http://www.boost.org
11
// Note: this header is a header template and must NOT have multiple-inclusion
13
#include <boost/function/detail/prologue.hpp>
15
#if defined(BOOST_MSVC)
16
# pragma warning( push )
17
# pragma warning( disable : 4127 ) // "conditional expression is constant"
20
#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
22
#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
24
#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
26
#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
28
#define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
30
#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
31
typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
33
#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
35
// Comma if nonzero number of arguments
36
#if BOOST_FUNCTION_NUM_ARGS == 0
37
# define BOOST_FUNCTION_COMMA
39
# define BOOST_FUNCTION_COMMA ,
40
#endif // BOOST_FUNCTION_NUM_ARGS > 0
42
// Class names used in this version of the code
43
#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
44
#define BOOST_FUNCTION_FUNCTION_INVOKER \
45
BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
46
#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
47
BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
48
#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
49
BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
50
#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
51
BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
52
#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
53
BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
54
#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
55
BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
56
#define BOOST_FUNCTION_MEMBER_INVOKER \
57
BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
58
#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
59
BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
60
#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
61
BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
62
#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
63
BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
64
#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
65
BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
66
#define BOOST_FUNCTION_GET_MEMBER_INVOKER \
67
BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
68
#define BOOST_FUNCTION_GET_INVOKER \
69
BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
70
#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
72
#ifndef BOOST_NO_VOID_RETURNS
73
# define BOOST_FUNCTION_VOID_RETURN_TYPE void
74
# define BOOST_FUNCTION_RETURN(X) X
76
# define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
77
# define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
85
typename R BOOST_FUNCTION_COMMA
86
BOOST_FUNCTION_TEMPLATE_PARMS
88
struct BOOST_FUNCTION_FUNCTION_INVOKER
90
static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
93
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
94
return f(BOOST_FUNCTION_ARGS);
100
typename R BOOST_FUNCTION_COMMA
101
BOOST_FUNCTION_TEMPLATE_PARMS
103
struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
105
static BOOST_FUNCTION_VOID_RETURN_TYPE
106
invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
107
BOOST_FUNCTION_PARMS)
110
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
111
BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
116
typename FunctionObj,
117
typename R BOOST_FUNCTION_COMMA
118
BOOST_FUNCTION_TEMPLATE_PARMS
120
struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
122
static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
123
BOOST_FUNCTION_PARMS)
127
if (function_allows_small_object_optimization<FunctionObj>::value)
128
f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
130
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
131
return (*f)(BOOST_FUNCTION_ARGS);
136
typename FunctionObj,
137
typename R BOOST_FUNCTION_COMMA
138
BOOST_FUNCTION_TEMPLATE_PARMS
140
struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
142
static BOOST_FUNCTION_VOID_RETURN_TYPE
143
invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
144
BOOST_FUNCTION_PARMS)
148
if (function_allows_small_object_optimization<FunctionObj>::value)
149
f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
151
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
152
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
157
typename FunctionObj,
158
typename R BOOST_FUNCTION_COMMA
159
BOOST_FUNCTION_TEMPLATE_PARMS
161
struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
163
static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
164
BOOST_FUNCTION_PARMS)
168
reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
169
return (*f)(BOOST_FUNCTION_ARGS);
174
typename FunctionObj,
175
typename R BOOST_FUNCTION_COMMA
176
BOOST_FUNCTION_TEMPLATE_PARMS
178
struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
180
static BOOST_FUNCTION_VOID_RETURN_TYPE
181
invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
182
BOOST_FUNCTION_PARMS)
186
reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
187
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
191
#if BOOST_FUNCTION_NUM_ARGS > 0
192
/* Handle invocation of member pointers. */
195
typename R BOOST_FUNCTION_COMMA
196
BOOST_FUNCTION_TEMPLATE_PARMS
198
struct BOOST_FUNCTION_MEMBER_INVOKER
200
static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
201
BOOST_FUNCTION_PARMS)
205
reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
206
return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
212
typename R BOOST_FUNCTION_COMMA
213
BOOST_FUNCTION_TEMPLATE_PARMS
215
struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
217
static BOOST_FUNCTION_VOID_RETURN_TYPE
218
invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
219
BOOST_FUNCTION_PARMS)
223
reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
224
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
230
typename FunctionPtr,
231
typename R BOOST_FUNCTION_COMMA
232
BOOST_FUNCTION_TEMPLATE_PARMS
234
struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
236
typedef typename mpl::if_c<(is_void<R>::value),
237
BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
239
R BOOST_FUNCTION_COMMA
240
BOOST_FUNCTION_TEMPLATE_ARGS
242
BOOST_FUNCTION_FUNCTION_INVOKER<
244
R BOOST_FUNCTION_COMMA
245
BOOST_FUNCTION_TEMPLATE_ARGS
251
typename FunctionObj,
252
typename R BOOST_FUNCTION_COMMA
253
BOOST_FUNCTION_TEMPLATE_PARMS
255
struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
257
typedef typename mpl::if_c<(is_void<R>::value),
258
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
260
R BOOST_FUNCTION_COMMA
261
BOOST_FUNCTION_TEMPLATE_ARGS
263
BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
265
R BOOST_FUNCTION_COMMA
266
BOOST_FUNCTION_TEMPLATE_ARGS
272
typename FunctionObj,
273
typename R BOOST_FUNCTION_COMMA
274
BOOST_FUNCTION_TEMPLATE_PARMS
276
struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
278
typedef typename mpl::if_c<(is_void<R>::value),
279
BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
281
R BOOST_FUNCTION_COMMA
282
BOOST_FUNCTION_TEMPLATE_ARGS
284
BOOST_FUNCTION_FUNCTION_REF_INVOKER<
286
R BOOST_FUNCTION_COMMA
287
BOOST_FUNCTION_TEMPLATE_ARGS
292
#if BOOST_FUNCTION_NUM_ARGS > 0
293
/* Retrieve the appropriate invoker for a member pointer. */
296
typename R BOOST_FUNCTION_COMMA
297
BOOST_FUNCTION_TEMPLATE_PARMS
299
struct BOOST_FUNCTION_GET_MEMBER_INVOKER
301
typedef typename mpl::if_c<(is_void<R>::value),
302
BOOST_FUNCTION_VOID_MEMBER_INVOKER<
304
R BOOST_FUNCTION_COMMA
305
BOOST_FUNCTION_TEMPLATE_ARGS
307
BOOST_FUNCTION_MEMBER_INVOKER<
309
R BOOST_FUNCTION_COMMA
310
BOOST_FUNCTION_TEMPLATE_ARGS
316
/* Given the tag returned by get_function_tag, retrieve the
317
actual invoker that will be used for the given function
320
Each specialization contains an "apply" nested class template
321
that accepts the function object, return type, function
322
argument types, and allocator. The resulting "apply" class
323
contains two typedefs, "invoker_type" and "manager_type",
324
which correspond to the invoker and manager types. */
325
template<typename Tag>
326
struct BOOST_FUNCTION_GET_INVOKER { };
328
/* Retrieve the invoker for a function pointer. */
330
struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
332
template<typename FunctionPtr,
333
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
336
typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
338
R BOOST_FUNCTION_COMMA
339
BOOST_FUNCTION_TEMPLATE_ARGS
343
typedef functor_manager<FunctionPtr> manager_type;
346
template<typename FunctionPtr,
347
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
351
typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
353
R BOOST_FUNCTION_COMMA
354
BOOST_FUNCTION_TEMPLATE_ARGS
358
typedef functor_manager<FunctionPtr> manager_type;
362
#if BOOST_FUNCTION_NUM_ARGS > 0
363
/* Retrieve the invoker for a member pointer. */
365
struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
367
template<typename MemberPtr,
368
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
371
typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
373
R BOOST_FUNCTION_COMMA
374
BOOST_FUNCTION_TEMPLATE_ARGS
378
typedef functor_manager<MemberPtr> manager_type;
381
template<typename MemberPtr,
382
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
386
typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
388
R BOOST_FUNCTION_COMMA
389
BOOST_FUNCTION_TEMPLATE_ARGS
393
typedef functor_manager<MemberPtr> manager_type;
398
/* Retrieve the invoker for a function object. */
400
struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
402
template<typename FunctionObj,
403
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
406
typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
408
R BOOST_FUNCTION_COMMA
409
BOOST_FUNCTION_TEMPLATE_ARGS
413
typedef functor_manager<FunctionObj> manager_type;
416
template<typename FunctionObj,
417
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
421
typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
423
R BOOST_FUNCTION_COMMA
424
BOOST_FUNCTION_TEMPLATE_ARGS
428
typedef functor_manager_a<FunctionObj, Allocator> manager_type;
432
/* Retrieve the invoker for a reference to a function object. */
434
struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
436
template<typename RefWrapper,
437
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
440
typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
441
typename RefWrapper::type,
442
R BOOST_FUNCTION_COMMA
443
BOOST_FUNCTION_TEMPLATE_ARGS
447
typedef reference_manager<typename RefWrapper::type> manager_type;
450
template<typename RefWrapper,
451
typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
455
typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
456
typename RefWrapper::type,
457
R BOOST_FUNCTION_COMMA
458
BOOST_FUNCTION_TEMPLATE_ARGS
462
typedef reference_manager<typename RefWrapper::type> manager_type;
468
* vtable for a specific boost::function instance. This
469
* structure must be an aggregate so that we can use static
470
* initialization in boost::function's assign_to and assign_to_a
471
* members. It therefore cannot have any constructors,
472
* destructors, base classes, etc.
474
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
475
struct BOOST_FUNCTION_VTABLE
477
#ifndef BOOST_NO_VOID_RETURNS
478
typedef R result_type;
480
typedef typename function_return_type<R>::type result_type;
481
#endif // BOOST_NO_VOID_RETURNS
483
typedef result_type (*invoker_type)(function_buffer&
485
BOOST_FUNCTION_TEMPLATE_ARGS);
488
bool assign_to(F f, function_buffer& functor)
490
typedef typename get_function_tag<F>::type tag;
491
return assign_to(f, functor, tag());
493
template<typename F,typename Allocator>
494
bool assign_to_a(F f, function_buffer& functor, Allocator a)
496
typedef typename get_function_tag<F>::type tag;
497
return assign_to_a(f, functor, a, tag());
500
void clear(function_buffer& functor)
503
base.manager(functor, functor, destroy_functor_tag);
508
template<typename FunctionPtr>
510
assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
512
this->clear(functor);
514
// should be a reinterpret cast, but some compilers insist
515
// on giving cv-qualifiers to free functions
516
functor.func_ptr = (void (*)())(f);
522
template<typename FunctionPtr,typename Allocator>
524
assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag)
526
return assign_to(f,functor,function_ptr_tag());
530
#if BOOST_FUNCTION_NUM_ARGS > 0
531
template<typename MemberPtr>
532
bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
534
// DPG TBD: Add explicit support for member function
535
// objects, so we invoke through mem_fn() but we retain the
536
// right target_type() values.
538
this->assign_to(mem_fn(f), functor);
544
template<typename MemberPtr,typename Allocator>
545
bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag)
547
// DPG TBD: Add explicit support for member function
548
// objects, so we invoke through mem_fn() but we retain the
549
// right target_type() values.
551
this->assign_to_a(mem_fn(f), functor, a);
557
#endif // BOOST_FUNCTION_NUM_ARGS > 0
560
// Assign to a function object using the small object optimization
561
template<typename FunctionObj>
563
assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
565
new ((void*)&functor.data) FunctionObj(f);
567
template<typename FunctionObj,typename Allocator>
569
assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_)
571
assign_functor(f,functor,mpl::true_());
574
// Assign to a function object allocated on the heap.
575
template<typename FunctionObj>
577
assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
579
functor.obj_ptr = new FunctionObj(f);
581
template<typename FunctionObj,typename Allocator>
583
assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_)
585
typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
586
typedef typename Allocator::template rebind<functor_wrapper_type>::other
587
wrapper_allocator_type;
588
typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
589
wrapper_allocator_type wrapper_allocator(a);
590
wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
591
wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
592
functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
593
functor.obj_ptr = new_f;
596
template<typename FunctionObj>
598
assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
600
if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
601
assign_functor(f, functor,
602
mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
608
template<typename FunctionObj,typename Allocator>
610
assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag)
612
if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
613
assign_functor_a(f, functor, a,
614
mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
621
// Reference to a function object
622
template<typename FunctionObj>
624
assign_to(const reference_wrapper<FunctionObj>& f,
625
function_buffer& functor, function_obj_ref_tag)
627
if (!boost::detail::function::has_empty_target(f.get_pointer())) {
628
functor.obj_ref.obj_ptr = (void *)f.get_pointer();
629
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
630
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
636
template<typename FunctionObj,typename Allocator>
638
assign_to_a(const reference_wrapper<FunctionObj>& f,
639
function_buffer& functor, Allocator, function_obj_ref_tag)
641
return assign_to(f,functor,function_obj_ref_tag());
646
invoker_type invoker;
648
} // end namespace function
649
} // end namespace detail
652
typename R BOOST_FUNCTION_COMMA
653
BOOST_FUNCTION_TEMPLATE_PARMS
655
class BOOST_FUNCTION_FUNCTION : public function_base
657
#if BOOST_FUNCTION_NUM_ARGS == 1
659
, public std::unary_function<T0,R>
661
#elif BOOST_FUNCTION_NUM_ARGS == 2
663
, public std::binary_function<T0,T1,R>
669
#ifndef BOOST_NO_VOID_RETURNS
670
typedef R result_type;
672
typedef typename boost::detail::function::function_return_type<R>::type
674
#endif // BOOST_NO_VOID_RETURNS
677
typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
678
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
681
struct clear_type {};
684
BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
686
// add signature for boost::lambda
687
template<typename Args>
690
typedef result_type type;
693
#if BOOST_FUNCTION_NUM_ARGS == 1
694
typedef T0 argument_type;
695
#elif BOOST_FUNCTION_NUM_ARGS == 2
696
typedef T0 first_argument_type;
697
typedef T1 second_argument_type;
700
BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
701
BOOST_FUNCTION_ARG_TYPES
703
typedef BOOST_FUNCTION_FUNCTION self_type;
705
BOOST_FUNCTION_FUNCTION() : function_base() { }
707
// MSVC chokes if the following two constructors are collapsed into
708
// one with a default parameter.
709
template<typename Functor>
710
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
711
#ifndef BOOST_NO_SFINAE
712
,typename enable_if_c<
713
(boost::type_traits::ice_not<
714
(is_integral<Functor>::value)>::value),
716
#endif // BOOST_NO_SFINAE
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 enable_if_c<
726
(boost::type_traits::ice_not<
727
(is_integral<Functor>::value)>::value),
729
#endif // BOOST_NO_SFINAE
733
this->assign_to_a(f,a);
736
#ifndef BOOST_NO_SFINAE
737
BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
739
BOOST_FUNCTION_FUNCTION(int zero) : function_base()
741
BOOST_ASSERT(zero == 0);
745
BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
747
this->assign_to_own(f);
750
~BOOST_FUNCTION_FUNCTION() { clear(); }
752
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
753
// MSVC 6.0 and prior require all definitions to be inline, but
754
// these definitions can become very costly.
755
result_type operator()(BOOST_FUNCTION_PARMS) const
758
boost::throw_exception(bad_function_call());
760
return static_cast<vtable_type*>(vtable)->invoker
761
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
764
result_type operator()(BOOST_FUNCTION_PARMS) const;
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
772
template<typename Functor>
773
#ifndef BOOST_NO_SFINAE
774
typename enable_if_c<
775
(boost::type_traits::ice_not<
776
(is_integral<Functor>::value)>::value),
777
BOOST_FUNCTION_FUNCTION&>::type
779
BOOST_FUNCTION_FUNCTION&
781
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
792
template<typename Functor,typename Allocator>
793
void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
797
this->assign_to_a(f,a);
804
#ifndef BOOST_NO_SFINAE
805
BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
811
BOOST_FUNCTION_FUNCTION& operator=(int zero)
813
BOOST_ASSERT(zero == 0);
819
// Assignment from another BOOST_FUNCTION_FUNCTION
820
BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
827
this->assign_to_own(f);
835
void swap(BOOST_FUNCTION_FUNCTION& other)
840
BOOST_FUNCTION_FUNCTION tmp;
841
tmp.move_assign(*this);
842
this->move_assign(other);
843
other.move_assign(tmp);
846
// Clear out a target, if there is one
850
reinterpret_cast<vtable_type*>(vtable)->clear(this->functor);
855
#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
856
// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
857
operator bool () const { return !this->empty(); }
864
typedef void (dummy::*safe_bool)();
867
operator safe_bool () const
868
{ return (this->empty())? 0 : &dummy::nonnull; }
870
bool operator!() const
871
{ return this->empty(); }
875
void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
878
this->vtable = f.vtable;
879
f.vtable->manager(f.functor, this->functor,
880
boost::detail::function::clone_functor_tag);
884
template<typename Functor>
885
void assign_to(Functor f)
887
using detail::function::vtable_base;
889
typedef typename detail::function::get_function_tag<Functor>::type tag;
890
typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
891
typedef typename get_invoker::
892
template apply<Functor, R BOOST_FUNCTION_COMMA
893
BOOST_FUNCTION_TEMPLATE_ARGS>
896
typedef typename handler_type::invoker_type invoker_type;
897
typedef typename handler_type::manager_type manager_type;
899
// Note: it is extremely important that this initialization use
900
// static initialization. Otherwise, we will have a race
901
// condition here in multi-threaded code. See
902
// http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
903
static vtable_type stored_vtable =
904
{ { &manager_type::manage }, &invoker_type::invoke };
906
if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable.base;
910
template<typename Functor,typename Allocator>
911
void assign_to_a(Functor f,Allocator a)
913
using detail::function::vtable_base;
915
typedef typename detail::function::get_function_tag<Functor>::type tag;
916
typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
917
typedef typename get_invoker::
918
template apply_a<Functor, R BOOST_FUNCTION_COMMA
919
BOOST_FUNCTION_TEMPLATE_ARGS,
923
typedef typename handler_type::invoker_type invoker_type;
924
typedef typename handler_type::manager_type manager_type;
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 vtable_type stored_vtable =
931
{ { &manager_type::manage }, &invoker_type::invoke };
933
if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable.base;
937
// Moves the value from the specified argument to *this. If the argument
938
// has its function object allocated on the heap, move_assign will pass
939
// its buffer to *this, and set the argument's buffer pointer to NULL.
940
void move_assign(BOOST_FUNCTION_FUNCTION& f)
945
#if !defined(BOOST_NO_EXCEPTIONS)
949
this->vtable = f.vtable;
950
f.vtable->manager(f.functor, this->functor,
951
boost::detail::function::move_functor_tag);
953
#if !defined(BOOST_NO_EXCEPTIONS)
965
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
966
inline void swap(BOOST_FUNCTION_FUNCTION<
967
R BOOST_FUNCTION_COMMA
968
BOOST_FUNCTION_TEMPLATE_ARGS
970
BOOST_FUNCTION_FUNCTION<
971
R BOOST_FUNCTION_COMMA
972
BOOST_FUNCTION_TEMPLATE_ARGS
978
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
979
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
980
typename BOOST_FUNCTION_FUNCTION<
981
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
982
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
983
::operator()(BOOST_FUNCTION_PARMS) const
986
boost::throw_exception(bad_function_call());
988
return reinterpret_cast<const vtable_type*>(vtable)->invoker
989
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
993
// Poison comparisons between boost::function objects of the same type.
994
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
995
void operator==(const BOOST_FUNCTION_FUNCTION<
996
R BOOST_FUNCTION_COMMA
997
BOOST_FUNCTION_TEMPLATE_ARGS>&,
998
const BOOST_FUNCTION_FUNCTION<
999
R BOOST_FUNCTION_COMMA
1000
BOOST_FUNCTION_TEMPLATE_ARGS>&);
1001
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1002
void operator!=(const BOOST_FUNCTION_FUNCTION<
1003
R BOOST_FUNCTION_COMMA
1004
BOOST_FUNCTION_TEMPLATE_ARGS>&,
1005
const BOOST_FUNCTION_FUNCTION<
1006
R BOOST_FUNCTION_COMMA
1007
BOOST_FUNCTION_TEMPLATE_ARGS>& );
1009
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
1011
#if BOOST_FUNCTION_NUM_ARGS == 0
1012
#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
1014
#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
1017
template<typename R BOOST_FUNCTION_COMMA
1018
BOOST_FUNCTION_TEMPLATE_PARMS>
1019
class function<BOOST_FUNCTION_PARTIAL_SPEC>
1020
: public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
1022
typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
1023
typedef function self_type;
1025
struct clear_type {};
1029
function() : base_type() {}
1031
template<typename Functor>
1033
#ifndef BOOST_NO_SFINAE
1034
,typename enable_if_c<
1035
(boost::type_traits::ice_not<
1036
(is_integral<Functor>::value)>::value),
1043
template<typename Functor,typename Allocator>
1044
function(Functor f, Allocator a
1045
#ifndef BOOST_NO_SFINAE
1046
,typename enable_if_c<
1047
(boost::type_traits::ice_not<
1048
(is_integral<Functor>::value)>::value),
1056
#ifndef BOOST_NO_SFINAE
1057
function(clear_type*) : base_type() {}
1060
function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1062
function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1064
self_type& operator=(const self_type& f)
1066
self_type(f).swap(*this);
1070
template<typename Functor>
1071
#ifndef BOOST_NO_SFINAE
1072
typename enable_if_c<
1073
(boost::type_traits::ice_not<
1074
(is_integral<Functor>::value)>::value),
1079
operator=(Functor f)
1081
self_type(f).swap(*this);
1085
#ifndef BOOST_NO_SFINAE
1086
self_type& operator=(clear_type*)
1093
self_type& operator=(const base_type& f)
1095
self_type(f).swap(*this);
1100
#undef BOOST_FUNCTION_PARTIAL_SPEC
1101
#endif // have partial specialization
1103
} // end namespace boost
1105
// Cleanup after ourselves...
1106
#undef BOOST_FUNCTION_VTABLE
1107
#undef BOOST_FUNCTION_COMMA
1108
#undef BOOST_FUNCTION_FUNCTION
1109
#undef BOOST_FUNCTION_FUNCTION_INVOKER
1110
#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1111
#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1112
#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1113
#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
1114
#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1115
#undef BOOST_FUNCTION_MEMBER_INVOKER
1116
#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
1117
#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
1118
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1119
#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1120
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1121
#undef BOOST_FUNCTION_GET_INVOKER
1122
#undef BOOST_FUNCTION_TEMPLATE_PARMS
1123
#undef BOOST_FUNCTION_TEMPLATE_ARGS
1124
#undef BOOST_FUNCTION_PARMS
1125
#undef BOOST_FUNCTION_PARM
1126
#undef BOOST_FUNCTION_ARGS
1127
#undef BOOST_FUNCTION_ARG_TYPE
1128
#undef BOOST_FUNCTION_ARG_TYPES
1129
#undef BOOST_FUNCTION_VOID_RETURN_TYPE
1130
#undef BOOST_FUNCTION_RETURN
1132
#if defined(BOOST_MSVC)
1133
# pragma warning( pop )