~ubuntu-branches/ubuntu/saucy/merkaartor/saucy

« back to all changes in this revision

Viewing changes to include/builtin-boost/boost/function/function_template.hpp

Tags: upstream-0.15.3+svn20934
ImportĀ upstreamĀ versionĀ 0.15.3+svn20934

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
15
#if defined(BOOST_MSVC)
 
16
#   pragma warning( push )
 
17
#   pragma warning( disable : 4127 ) // "conditional expression is constant"
 
18
#endif       
 
19
 
 
20
#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
 
21
 
 
22
#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
 
23
 
 
24
#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
 
25
 
 
26
#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
 
27
 
 
28
#define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
 
29
 
 
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);
 
32
 
 
33
#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
 
34
 
 
35
// Comma if nonzero number of arguments
 
36
#if BOOST_FUNCTION_NUM_ARGS == 0
 
37
#  define BOOST_FUNCTION_COMMA
 
38
#else
 
39
#  define BOOST_FUNCTION_COMMA ,
 
40
#endif // BOOST_FUNCTION_NUM_ARGS > 0
 
41
 
 
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)
 
71
 
 
72
#ifndef BOOST_NO_VOID_RETURNS
 
73
#  define BOOST_FUNCTION_VOID_RETURN_TYPE void
 
74
#  define BOOST_FUNCTION_RETURN(X) X
 
75
#else
 
76
#  define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
 
77
#  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
 
78
#endif
 
79
 
 
80
namespace boost {
 
81
  namespace detail {
 
82
    namespace function {
 
83
      template<
 
84
        typename FunctionPtr,
 
85
        typename R BOOST_FUNCTION_COMMA
 
86
        BOOST_FUNCTION_TEMPLATE_PARMS
 
87
        >
 
88
      struct BOOST_FUNCTION_FUNCTION_INVOKER
 
89
      {
 
90
        static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
 
91
                        BOOST_FUNCTION_PARMS)
 
92
        {
 
93
          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
 
94
          return f(BOOST_FUNCTION_ARGS);
 
95
        }
 
96
      };
 
97
 
 
98
      template<
 
99
        typename FunctionPtr,
 
100
        typename R BOOST_FUNCTION_COMMA
 
101
        BOOST_FUNCTION_TEMPLATE_PARMS
 
102
        >
 
103
      struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
 
104
      {
 
105
        static BOOST_FUNCTION_VOID_RETURN_TYPE
 
106
        invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
 
107
               BOOST_FUNCTION_PARMS)
 
108
 
 
109
        {
 
110
          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
 
111
          BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
 
112
        }
 
113
      };
 
114
 
 
115
      template<
 
116
        typename FunctionObj,
 
117
        typename R BOOST_FUNCTION_COMMA
 
118
        BOOST_FUNCTION_TEMPLATE_PARMS
 
119
      >
 
120
      struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
 
121
      {
 
122
        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
 
123
                        BOOST_FUNCTION_PARMS)
 
124
 
 
125
        {
 
126
          FunctionObj* f;
 
127
          if (function_allows_small_object_optimization<FunctionObj>::value)
 
128
            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
 
129
          else
 
130
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
 
131
          return (*f)(BOOST_FUNCTION_ARGS);
 
132
        }
 
133
      };
 
134
 
 
135
      template<
 
136
        typename FunctionObj,
 
137
        typename R BOOST_FUNCTION_COMMA
 
138
        BOOST_FUNCTION_TEMPLATE_PARMS
 
139
      >
 
140
      struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
 
141
      {
 
142
        static BOOST_FUNCTION_VOID_RETURN_TYPE
 
143
        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
 
144
               BOOST_FUNCTION_PARMS)
 
145
 
 
146
        {
 
147
          FunctionObj* f;
 
148
          if (function_allows_small_object_optimization<FunctionObj>::value)
 
149
            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
 
150
          else
 
151
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
 
152
          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
 
153
        }
 
154
      };
 
155
 
 
156
      template<
 
157
        typename FunctionObj,
 
158
        typename R BOOST_FUNCTION_COMMA
 
159
        BOOST_FUNCTION_TEMPLATE_PARMS
 
160
      >
 
161
      struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
 
162
      {
 
163
        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
 
164
                        BOOST_FUNCTION_PARMS)
 
165
 
 
166
        {
 
167
          FunctionObj* f = 
 
168
            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
 
169
          return (*f)(BOOST_FUNCTION_ARGS);
 
170
        }
 
171
      };
 
172
 
 
173
      template<
 
174
        typename FunctionObj,
 
175
        typename R BOOST_FUNCTION_COMMA
 
176
        BOOST_FUNCTION_TEMPLATE_PARMS
 
177
      >
 
178
      struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
 
179
      {
 
180
        static BOOST_FUNCTION_VOID_RETURN_TYPE
 
181
        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
 
182
               BOOST_FUNCTION_PARMS)
 
183
 
 
184
        {
 
185
          FunctionObj* f = 
 
186
            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
 
187
          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
 
188
        }
 
189
      };
 
190
 
 
191
#if BOOST_FUNCTION_NUM_ARGS > 0
 
192
      /* Handle invocation of member pointers. */
 
193
      template<
 
194
        typename MemberPtr,
 
195
        typename R BOOST_FUNCTION_COMMA
 
196
        BOOST_FUNCTION_TEMPLATE_PARMS
 
197
      >
 
198
      struct BOOST_FUNCTION_MEMBER_INVOKER
 
199
      {
 
200
        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
 
201
                        BOOST_FUNCTION_PARMS)
 
202
 
 
203
        {
 
204
          MemberPtr* f = 
 
205
            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
 
206
          return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
 
207
        }
 
208
      };
 
209
 
 
210
      template<
 
211
        typename MemberPtr,
 
212
        typename R BOOST_FUNCTION_COMMA
 
213
        BOOST_FUNCTION_TEMPLATE_PARMS
 
214
      >
 
215
      struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
 
216
      {
 
217
        static BOOST_FUNCTION_VOID_RETURN_TYPE
 
218
        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
 
219
               BOOST_FUNCTION_PARMS)
 
220
 
 
221
        {
 
222
          MemberPtr* f = 
 
223
            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
 
224
          BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
 
225
        }
 
226
      };
 
227
#endif
 
228
 
 
229
      template<
 
230
        typename FunctionPtr,
 
231
        typename R BOOST_FUNCTION_COMMA
 
232
        BOOST_FUNCTION_TEMPLATE_PARMS
 
233
      >
 
234
      struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
 
235
      {
 
236
        typedef typename mpl::if_c<(is_void<R>::value),
 
237
                            BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
 
238
                            FunctionPtr,
 
239
                            R BOOST_FUNCTION_COMMA
 
240
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
241
                          >,
 
242
                          BOOST_FUNCTION_FUNCTION_INVOKER<
 
243
                            FunctionPtr,
 
244
                            R BOOST_FUNCTION_COMMA
 
245
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
246
                          >
 
247
                       >::type type;
 
248
      };
 
249
 
 
250
      template<
 
251
        typename FunctionObj,
 
252
        typename R BOOST_FUNCTION_COMMA
 
253
        BOOST_FUNCTION_TEMPLATE_PARMS
 
254
       >
 
255
      struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
 
256
      {
 
257
        typedef typename mpl::if_c<(is_void<R>::value),
 
258
                            BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
 
259
                            FunctionObj,
 
260
                            R BOOST_FUNCTION_COMMA
 
261
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
262
                          >,
 
263
                          BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
 
264
                            FunctionObj,
 
265
                            R BOOST_FUNCTION_COMMA
 
266
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
267
                          >
 
268
                       >::type type;
 
269
      };
 
270
 
 
271
      template<
 
272
        typename FunctionObj,
 
273
        typename R BOOST_FUNCTION_COMMA
 
274
        BOOST_FUNCTION_TEMPLATE_PARMS
 
275
       >
 
276
      struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
 
277
      {
 
278
        typedef typename mpl::if_c<(is_void<R>::value),
 
279
                            BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
 
280
                            FunctionObj,
 
281
                            R BOOST_FUNCTION_COMMA
 
282
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
283
                          >,
 
284
                          BOOST_FUNCTION_FUNCTION_REF_INVOKER<
 
285
                            FunctionObj,
 
286
                            R BOOST_FUNCTION_COMMA
 
287
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
288
                          >
 
289
                       >::type type;
 
290
      };
 
291
 
 
292
#if BOOST_FUNCTION_NUM_ARGS > 0
 
293
      /* Retrieve the appropriate invoker for a member pointer.  */
 
294
      template<
 
295
        typename MemberPtr,
 
296
        typename R BOOST_FUNCTION_COMMA
 
297
        BOOST_FUNCTION_TEMPLATE_PARMS
 
298
       >
 
299
      struct BOOST_FUNCTION_GET_MEMBER_INVOKER
 
300
      {
 
301
        typedef typename mpl::if_c<(is_void<R>::value),
 
302
                            BOOST_FUNCTION_VOID_MEMBER_INVOKER<
 
303
                            MemberPtr,
 
304
                            R BOOST_FUNCTION_COMMA
 
305
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
306
                          >,
 
307
                          BOOST_FUNCTION_MEMBER_INVOKER<
 
308
                            MemberPtr,
 
309
                            R BOOST_FUNCTION_COMMA
 
310
                            BOOST_FUNCTION_TEMPLATE_ARGS
 
311
                          >
 
312
                       >::type type;
 
313
      };
 
314
#endif
 
315
 
 
316
      /* Given the tag returned by get_function_tag, retrieve the
 
317
         actual invoker that will be used for the given function
 
318
         object. 
 
319
 
 
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 { };
 
327
 
 
328
      /* Retrieve the invoker for a function pointer. */
 
329
      template<>
 
330
      struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
 
331
      {
 
332
        template<typename FunctionPtr,
 
333
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
 
334
        struct apply
 
335
        {
 
336
          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
 
337
                             FunctionPtr,
 
338
                             R BOOST_FUNCTION_COMMA
 
339
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
340
                           >::type
 
341
            invoker_type;
 
342
 
 
343
          typedef functor_manager<FunctionPtr> manager_type;
 
344
        };
 
345
 
 
346
        template<typename FunctionPtr,
 
347
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
 
348
                 typename Allocator>
 
349
        struct apply_a
 
350
        {
 
351
          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
 
352
                             FunctionPtr,
 
353
                             R BOOST_FUNCTION_COMMA
 
354
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
355
                           >::type
 
356
            invoker_type;
 
357
 
 
358
          typedef functor_manager<FunctionPtr> manager_type;
 
359
        };
 
360
      };
 
361
 
 
362
#if BOOST_FUNCTION_NUM_ARGS > 0
 
363
      /* Retrieve the invoker for a member pointer. */
 
364
      template<>
 
365
      struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
 
366
      {
 
367
        template<typename MemberPtr,
 
368
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
 
369
        struct apply
 
370
        {
 
371
          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
 
372
                             MemberPtr,
 
373
                             R BOOST_FUNCTION_COMMA
 
374
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
375
                           >::type
 
376
            invoker_type;
 
377
 
 
378
          typedef functor_manager<MemberPtr> manager_type;
 
379
        };
 
380
 
 
381
        template<typename MemberPtr,
 
382
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
 
383
                 typename Allocator>
 
384
        struct apply_a
 
385
        {
 
386
          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
 
387
                             MemberPtr,
 
388
                             R BOOST_FUNCTION_COMMA
 
389
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
390
                           >::type
 
391
            invoker_type;
 
392
 
 
393
          typedef functor_manager<MemberPtr> manager_type;
 
394
        };
 
395
      };
 
396
#endif
 
397
 
 
398
      /* Retrieve the invoker for a function object. */
 
399
      template<>
 
400
      struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
 
401
      {
 
402
        template<typename FunctionObj,
 
403
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
 
404
        struct apply
 
405
        {
 
406
          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
 
407
                             FunctionObj,
 
408
                             R BOOST_FUNCTION_COMMA
 
409
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
410
                           >::type
 
411
            invoker_type;
 
412
 
 
413
          typedef functor_manager<FunctionObj> manager_type;
 
414
        };
 
415
 
 
416
        template<typename FunctionObj,
 
417
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
 
418
                 typename Allocator>
 
419
        struct apply_a
 
420
        {
 
421
          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
 
422
                             FunctionObj,
 
423
                             R BOOST_FUNCTION_COMMA
 
424
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
425
                           >::type
 
426
            invoker_type;
 
427
 
 
428
          typedef functor_manager_a<FunctionObj, Allocator> manager_type;
 
429
        };
 
430
      };
 
431
 
 
432
      /* Retrieve the invoker for a reference to a function object. */
 
433
      template<>
 
434
      struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
 
435
      {
 
436
        template<typename RefWrapper,
 
437
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
 
438
        struct apply
 
439
        {
 
440
          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
 
441
                             typename RefWrapper::type,
 
442
                             R BOOST_FUNCTION_COMMA
 
443
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
444
                           >::type
 
445
            invoker_type;
 
446
 
 
447
          typedef reference_manager<typename RefWrapper::type> manager_type;
 
448
        };
 
449
 
 
450
        template<typename RefWrapper,
 
451
                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
 
452
                 typename Allocator>
 
453
        struct apply_a
 
454
        {
 
455
          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
 
456
                             typename RefWrapper::type,
 
457
                             R BOOST_FUNCTION_COMMA
 
458
                             BOOST_FUNCTION_TEMPLATE_ARGS
 
459
                           >::type
 
460
            invoker_type;
 
461
 
 
462
          typedef reference_manager<typename RefWrapper::type> manager_type;
 
463
        };
 
464
      };
 
465
 
 
466
 
 
467
      /**
 
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.
 
473
       */
 
474
      template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
 
475
      struct BOOST_FUNCTION_VTABLE
 
476
      {
 
477
#ifndef BOOST_NO_VOID_RETURNS
 
478
        typedef R         result_type;
 
479
#else
 
480
        typedef typename function_return_type<R>::type result_type;
 
481
#endif // BOOST_NO_VOID_RETURNS
 
482
 
 
483
        typedef result_type (*invoker_type)(function_buffer&
 
484
                                            BOOST_FUNCTION_COMMA
 
485
                                            BOOST_FUNCTION_TEMPLATE_ARGS);
 
486
 
 
487
        template<typename F>
 
488
        bool assign_to(F f, function_buffer& functor)
 
489
        {
 
490
          typedef typename get_function_tag<F>::type tag;
 
491
          return assign_to(f, functor, tag());
 
492
        }
 
493
        template<typename F,typename Allocator>
 
494
        bool assign_to_a(F f, function_buffer& functor, Allocator a)
 
495
        {
 
496
          typedef typename get_function_tag<F>::type tag;
 
497
          return assign_to_a(f, functor, a, tag());
 
498
        }
 
499
 
 
500
        void clear(function_buffer& functor)
 
501
        {
 
502
          if (base.manager)
 
503
            base.manager(functor, functor, destroy_functor_tag);
 
504
        }
 
505
 
 
506
      private:
 
507
        // Function pointers
 
508
        template<typename FunctionPtr>
 
509
        bool 
 
510
        assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
 
511
        {
 
512
          this->clear(functor);
 
513
          if (f) {
 
514
            // should be a reinterpret cast, but some compilers insist
 
515
            // on giving cv-qualifiers to free functions
 
516
            functor.func_ptr = (void (*)())(f);
 
517
            return true;
 
518
          } else {
 
519
            return false;
 
520
          }
 
521
        }
 
522
        template<typename FunctionPtr,typename Allocator>
 
523
        bool 
 
524
        assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag)
 
525
        {
 
526
          return assign_to(f,functor,function_ptr_tag());
 
527
        }
 
528
 
 
529
        // Member pointers
 
530
#if BOOST_FUNCTION_NUM_ARGS > 0
 
531
        template<typename MemberPtr>
 
532
        bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
 
533
        {
 
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.
 
537
          if (f) {
 
538
            this->assign_to(mem_fn(f), functor);
 
539
            return true;
 
540
          } else {
 
541
            return false;
 
542
          }
 
543
        }
 
544
        template<typename MemberPtr,typename Allocator>
 
545
        bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag)
 
546
        {
 
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.
 
550
          if (f) {
 
551
            this->assign_to_a(mem_fn(f), functor, a);
 
552
            return true;
 
553
          } else {
 
554
            return false;
 
555
          }
 
556
        }
 
557
#endif // BOOST_FUNCTION_NUM_ARGS > 0
 
558
 
 
559
        // Function objects
 
560
        // Assign to a function object using the small object optimization
 
561
        template<typename FunctionObj>
 
562
        void 
 
563
        assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
 
564
        {
 
565
          new ((void*)&functor.data) FunctionObj(f);
 
566
        }
 
567
        template<typename FunctionObj,typename Allocator>
 
568
        void 
 
569
        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_)
 
570
        {
 
571
          assign_functor(f,functor,mpl::true_());
 
572
        }
 
573
 
 
574
        // Assign to a function object allocated on the heap.
 
575
        template<typename FunctionObj>
 
576
        void 
 
577
        assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
 
578
        {
 
579
          functor.obj_ptr = new FunctionObj(f);
 
580
        }
 
581
        template<typename FunctionObj,typename Allocator>
 
582
        void 
 
583
        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_)
 
584
        {
 
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;
 
594
        }
 
595
 
 
596
        template<typename FunctionObj>
 
597
        bool 
 
598
        assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
 
599
        {
 
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)>());
 
603
            return true;
 
604
          } else {
 
605
            return false;
 
606
          }
 
607
        }
 
608
        template<typename FunctionObj,typename Allocator>
 
609
        bool 
 
610
        assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag)
 
611
        {
 
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)>());
 
615
            return true;
 
616
          } else {
 
617
            return false;
 
618
          }
 
619
        }
 
620
 
 
621
        // Reference to a function object
 
622
        template<typename FunctionObj>
 
623
        bool 
 
624
        assign_to(const reference_wrapper<FunctionObj>& f, 
 
625
                  function_buffer& functor, function_obj_ref_tag)
 
626
        {
 
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;
 
631
            return true;
 
632
          } else {
 
633
            return false;
 
634
          }
 
635
        }
 
636
        template<typename FunctionObj,typename Allocator>
 
637
        bool 
 
638
        assign_to_a(const reference_wrapper<FunctionObj>& f, 
 
639
                  function_buffer& functor, Allocator, function_obj_ref_tag)
 
640
        {
 
641
          return assign_to(f,functor,function_obj_ref_tag());
 
642
        }
 
643
 
 
644
      public:
 
645
        vtable_base base;
 
646
        invoker_type invoker;
 
647
      };
 
648
    } // end namespace function
 
649
  } // end namespace detail
 
650
 
 
651
  template<
 
652
    typename R BOOST_FUNCTION_COMMA
 
653
    BOOST_FUNCTION_TEMPLATE_PARMS
 
654
  >
 
655
  class BOOST_FUNCTION_FUNCTION : public function_base
 
656
 
 
657
#if BOOST_FUNCTION_NUM_ARGS == 1
 
658
 
 
659
    , public std::unary_function<T0,R>
 
660
 
 
661
#elif BOOST_FUNCTION_NUM_ARGS == 2
 
662
 
 
663
    , public std::binary_function<T0,T1,R>
 
664
 
 
665
#endif
 
666
 
 
667
  {
 
668
  public:
 
669
#ifndef BOOST_NO_VOID_RETURNS
 
670
    typedef R         result_type;
 
671
#else
 
672
    typedef  typename boost::detail::function::function_return_type<R>::type
 
673
      result_type;
 
674
#endif // BOOST_NO_VOID_RETURNS
 
675
 
 
676
  private:
 
677
    typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
 
678
              R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
 
679
      vtable_type;
 
680
 
 
681
    struct clear_type {};
 
682
 
 
683
  public:
 
684
    BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
 
685
 
 
686
    // add signature for boost::lambda
 
687
    template<typename Args>
 
688
    struct sig
 
689
    {
 
690
      typedef result_type type;
 
691
    };
 
692
 
 
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;
 
698
#endif
 
699
 
 
700
    BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
 
701
    BOOST_FUNCTION_ARG_TYPES
 
702
 
 
703
    typedef BOOST_FUNCTION_FUNCTION self_type;
 
704
 
 
705
    BOOST_FUNCTION_FUNCTION() : function_base() { }
 
706
 
 
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),
 
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
 
725
                            ,typename enable_if_c<
 
726
                            (boost::type_traits::ice_not<
 
727
                             (is_integral<Functor>::value)>::value),
 
728
                                        int>::type = 0
 
729
#endif // BOOST_NO_SFINAE
 
730
                            ) :
 
731
      function_base()
 
732
    {
 
733
      this->assign_to_a(f,a);
 
734
    }
 
735
 
 
736
#ifndef BOOST_NO_SFINAE
 
737
    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
 
738
#else
 
739
    BOOST_FUNCTION_FUNCTION(int zero) : function_base()
 
740
    {
 
741
      BOOST_ASSERT(zero == 0);
 
742
    }
 
743
#endif
 
744
 
 
745
    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
 
746
    {
 
747
      this->assign_to_own(f);
 
748
    }
 
749
 
 
750
    ~BOOST_FUNCTION_FUNCTION() { clear(); }
 
751
 
 
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
 
756
    {
 
757
      if (this->empty())
 
758
        boost::throw_exception(bad_function_call());
 
759
 
 
760
      return static_cast<vtable_type*>(vtable)->invoker
 
761
               (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
 
762
    }
 
763
#else
 
764
    result_type operator()(BOOST_FUNCTION_PARMS) const;
 
765
#endif
 
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 enable_if_c<
 
775
               (boost::type_traits::ice_not<
 
776
                 (is_integral<Functor>::value)>::value),
 
777
               BOOST_FUNCTION_FUNCTION&>::type
 
778
#else
 
779
    BOOST_FUNCTION_FUNCTION&
 
780
#endif
 
781
    operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
 
782
    {
 
783
      this->clear();
 
784
      try {
 
785
        this->assign_to(f);
 
786
      } catch (...) {
 
787
        vtable = 0;
 
788
        throw;
 
789
      }
 
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
      try {
 
797
        this->assign_to_a(f,a);
 
798
      } catch (...) {
 
799
        vtable = 0;
 
800
        throw;
 
801
      }
 
802
    }
 
803
 
 
804
#ifndef BOOST_NO_SFINAE
 
805
    BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
 
806
    {
 
807
      this->clear();
 
808
      return *this;
 
809
    }
 
810
#else
 
811
    BOOST_FUNCTION_FUNCTION& operator=(int zero)
 
812
    {
 
813
      BOOST_ASSERT(zero == 0);
 
814
      this->clear();
 
815
      return *this;
 
816
    }
 
817
#endif
 
818
 
 
819
    // Assignment from another BOOST_FUNCTION_FUNCTION
 
820
    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
 
821
    {
 
822
      if (&f == this)
 
823
        return *this;
 
824
 
 
825
      this->clear();
 
826
      try {
 
827
        this->assign_to_own(f);
 
828
      } catch (...) {
 
829
        vtable = 0;
 
830
        throw;
 
831
      }
 
832
      return *this;
 
833
    }
 
834
 
 
835
    void swap(BOOST_FUNCTION_FUNCTION& other)
 
836
    {
 
837
      if (&other == this)
 
838
        return;
 
839
 
 
840
      BOOST_FUNCTION_FUNCTION tmp;
 
841
      tmp.move_assign(*this);
 
842
      this->move_assign(other);
 
843
      other.move_assign(tmp);
 
844
    }
 
845
 
 
846
    // Clear out a target, if there is one
 
847
    void clear()
 
848
    {
 
849
      if (vtable) {
 
850
        reinterpret_cast<vtable_type*>(vtable)->clear(this->functor);
 
851
        vtable = 0;
 
852
      }
 
853
    }
 
854
 
 
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(); }
 
858
#else
 
859
  private:
 
860
    struct dummy {
 
861
      void nonnull() {};
 
862
    };
 
863
 
 
864
    typedef void (dummy::*safe_bool)();
 
865
 
 
866
  public:
 
867
    operator safe_bool () const
 
868
      { return (this->empty())? 0 : &dummy::nonnull; }
 
869
 
 
870
    bool operator!() const
 
871
      { return this->empty(); }
 
872
#endif
 
873
 
 
874
  private:
 
875
    void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
 
876
    {
 
877
      if (!f.empty()) {
 
878
        this->vtable = f.vtable;
 
879
        f.vtable->manager(f.functor, this->functor,
 
880
                          boost::detail::function::clone_functor_tag);
 
881
      }
 
882
    }
 
883
 
 
884
    template<typename Functor>
 
885
    void assign_to(Functor f)
 
886
    {
 
887
      using detail::function::vtable_base;
 
888
 
 
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>
 
894
        handler_type;
 
895
      
 
896
      typedef typename handler_type::invoker_type invoker_type;
 
897
      typedef typename handler_type::manager_type manager_type;
 
898
 
 
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 };
 
905
 
 
906
      if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable.base;
 
907
      else vtable = 0;
 
908
    }
 
909
 
 
910
    template<typename Functor,typename Allocator>
 
911
    void assign_to_a(Functor f,Allocator a)
 
912
    {
 
913
      using detail::function::vtable_base;
 
914
 
 
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,
 
920
                         Allocator>
 
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 vtable_type stored_vtable =
 
931
        { { &manager_type::manage }, &invoker_type::invoke };
 
932
 
 
933
      if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable.base;
 
934
      else vtable = 0;
 
935
    }
 
936
 
 
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) 
 
941
    { 
 
942
      if (&f == this)
 
943
        return;
 
944
 
 
945
#if !defined(BOOST_NO_EXCEPTIONS)      
 
946
      try {
 
947
#endif
 
948
        if (!f.empty()) {
 
949
          this->vtable = f.vtable;
 
950
          f.vtable->manager(f.functor, this->functor,
 
951
                            boost::detail::function::move_functor_tag);
 
952
                  f.vtable = 0;
 
953
#if !defined(BOOST_NO_EXCEPTIONS)      
 
954
        } else {
 
955
          clear();
 
956
        }
 
957
      } catch (...) {
 
958
        vtable = 0;
 
959
        throw;
 
960
      }
 
961
#endif
 
962
    }
 
963
  };
 
964
 
 
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
 
969
                   >& f1,
 
970
                   BOOST_FUNCTION_FUNCTION<
 
971
                     R BOOST_FUNCTION_COMMA
 
972
                     BOOST_FUNCTION_TEMPLATE_ARGS
 
973
                   >& f2)
 
974
  {
 
975
    f1.swap(f2);
 
976
  }
 
977
 
 
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
 
984
  {
 
985
    if (this->empty())
 
986
      boost::throw_exception(bad_function_call());
 
987
 
 
988
    return reinterpret_cast<const vtable_type*>(vtable)->invoker
 
989
             (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
 
990
  }
 
991
#endif
 
992
 
 
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>& );
 
1008
 
 
1009
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
 
1010
 
 
1011
#if BOOST_FUNCTION_NUM_ARGS == 0
 
1012
#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
 
1013
#else
 
1014
#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
 
1015
#endif
 
1016
 
 
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>
 
1021
{
 
1022
  typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
 
1023
  typedef function self_type;
 
1024
 
 
1025
  struct clear_type {};
 
1026
 
 
1027
public:
 
1028
 
 
1029
  function() : base_type() {}
 
1030
 
 
1031
  template<typename Functor>
 
1032
  function(Functor f
 
1033
#ifndef BOOST_NO_SFINAE
 
1034
           ,typename enable_if_c<
 
1035
                            (boost::type_traits::ice_not<
 
1036
                          (is_integral<Functor>::value)>::value),
 
1037
                       int>::type = 0
 
1038
#endif
 
1039
           ) :
 
1040
    base_type(f)
 
1041
  {
 
1042
  }
 
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),
 
1049
                       int>::type = 0
 
1050
#endif
 
1051
           ) :
 
1052
    base_type(f,a)
 
1053
  {
 
1054
  }
 
1055
 
 
1056
#ifndef BOOST_NO_SFINAE
 
1057
  function(clear_type*) : base_type() {}
 
1058
#endif
 
1059
 
 
1060
  function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
 
1061
 
 
1062
  function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
 
1063
 
 
1064
  self_type& operator=(const self_type& f)
 
1065
  {
 
1066
    self_type(f).swap(*this);
 
1067
    return *this;
 
1068
  }
 
1069
 
 
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),
 
1075
                      self_type&>::type
 
1076
#else
 
1077
  self_type&
 
1078
#endif
 
1079
  operator=(Functor f)
 
1080
  {
 
1081
    self_type(f).swap(*this);
 
1082
    return *this;
 
1083
  }
 
1084
 
 
1085
#ifndef BOOST_NO_SFINAE
 
1086
  self_type& operator=(clear_type*)
 
1087
  {
 
1088
    this->clear();
 
1089
    return *this;
 
1090
  }
 
1091
#endif
 
1092
 
 
1093
  self_type& operator=(const base_type& f)
 
1094
  {
 
1095
    self_type(f).swap(*this);
 
1096
    return *this;
 
1097
  }
 
1098
};
 
1099
 
 
1100
#undef BOOST_FUNCTION_PARTIAL_SPEC
 
1101
#endif // have partial specialization
 
1102
 
 
1103
} // end namespace boost
 
1104
 
 
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
 
1131
 
 
1132
#if defined(BOOST_MSVC)
 
1133
#   pragma warning( pop )
 
1134
#endif