]> git.lyx.org Git - lyx.git/blob - boost/boost/function/function_template.hpp
update to boost 1.32.0
[lyx.git] / boost / boost / function / function_template.hpp
1 // Boost.Function library
2
3 //  Copyright Douglas Gregor 2001-2003. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7
8 // For more information, see http://www.boost.org
9
10 // Note: this header is a header template and must NOT have multiple-inclusion
11 // protection.
12 #include <boost/function/detail/prologue.hpp>
13
14 #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
15
16 #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
17
18 #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
19
20 #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
21
22 #define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
23
24 #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
25   typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(arg, BOOST_PP_CAT(BOOST_PP_INC(I),_type));
26
27 #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
28
29 // Type of the default allocator
30 #ifndef BOOST_NO_STD_ALLOCATOR
31 #  define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
32 #else
33 #  define BOOST_FUNCTION_DEFAULT_ALLOCATOR int
34 #endif // BOOST_NO_STD_ALLOCATOR
35
36 // Comma if nonzero number of arguments
37 #if BOOST_FUNCTION_NUM_ARGS == 0
38 #  define BOOST_FUNCTION_COMMA
39 #else
40 #  define BOOST_FUNCTION_COMMA ,
41 #endif // BOOST_FUNCTION_NUM_ARGS > 0
42
43 // Class names used in this version of the code
44 #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
45 #define BOOST_FUNCTION_FUNCTION_INVOKER \
46   BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
47 #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
48   BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
49 #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
50   BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
51 #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
52   BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
53 #define BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER \
54   BOOST_JOIN(stateless_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
55 #define BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER \
56   BOOST_JOIN(stateless_void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
57 #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
58   BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
59 #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
60   BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
61 #define BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER \
62   BOOST_JOIN(get_stateless_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
63
64 namespace boost {
65   namespace detail {
66     namespace function {
67       template<
68         typename FunctionPtr,
69         typename R BOOST_FUNCTION_COMMA
70         BOOST_FUNCTION_TEMPLATE_PARMS
71         >
72       struct BOOST_FUNCTION_FUNCTION_INVOKER
73       {
74         static R invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
75                         BOOST_FUNCTION_PARMS)
76         {
77           FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
78           return f(BOOST_FUNCTION_ARGS);
79         }
80       };
81
82       template<
83         typename FunctionPtr,
84         typename R BOOST_FUNCTION_COMMA
85         BOOST_FUNCTION_TEMPLATE_PARMS
86         >
87       struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
88       {
89         static unusable invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA
90                                BOOST_FUNCTION_PARMS)
91
92         {
93           FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
94           f(BOOST_FUNCTION_ARGS);
95           return unusable();
96         }
97       };
98
99       template<
100         typename FunctionObj,
101         typename R BOOST_FUNCTION_COMMA
102         BOOST_FUNCTION_TEMPLATE_PARMS
103       >
104       struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
105       {
106         static R invoke(any_pointer function_obj_ptr BOOST_FUNCTION_COMMA
107                         BOOST_FUNCTION_PARMS)
108
109         {
110           FunctionObj* f = (FunctionObj*)(function_obj_ptr.obj_ptr);
111           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_VOID_FUNCTION_OBJ_INVOKER
121       {
122         static unusable invoke(any_pointer function_obj_ptr
123                                BOOST_FUNCTION_COMMA
124                                BOOST_FUNCTION_PARMS)
125
126         {
127           FunctionObj* f = (FunctionObj*)(function_obj_ptr.obj_ptr);
128           (*f)(BOOST_FUNCTION_ARGS);
129           return unusable();
130         }
131       };
132
133       template<
134         typename FunctionObj,
135         typename R BOOST_FUNCTION_COMMA
136         BOOST_FUNCTION_TEMPLATE_PARMS
137       >
138       struct BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER
139       {
140         static R invoke(any_pointer BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS)
141         {
142           FunctionObj f = FunctionObj();
143           return f(BOOST_FUNCTION_ARGS);
144         }
145       };
146
147       template<
148         typename FunctionObj,
149         typename R BOOST_FUNCTION_COMMA
150         BOOST_FUNCTION_TEMPLATE_PARMS
151       >
152       struct BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER
153       {
154         static unusable invoke(any_pointer BOOST_FUNCTION_COMMA
155                                BOOST_FUNCTION_PARMS)
156
157         {
158           FunctionObj f = FunctionObj();
159           f(BOOST_FUNCTION_ARGS);
160           return unusable();
161         }
162       };
163
164       template<
165         typename FunctionPtr,
166         typename R BOOST_FUNCTION_COMMA
167         BOOST_FUNCTION_TEMPLATE_PARMS
168       >
169       struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
170       {
171         typedef typename ct_if<(is_void<R>::value),
172                             BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
173                             FunctionPtr,
174                             R BOOST_FUNCTION_COMMA
175                             BOOST_FUNCTION_TEMPLATE_ARGS
176                           >,
177                           BOOST_FUNCTION_FUNCTION_INVOKER<
178                             FunctionPtr,
179                             R BOOST_FUNCTION_COMMA
180                             BOOST_FUNCTION_TEMPLATE_ARGS
181                           >
182                        >::type type;
183       };
184
185       template<
186         typename FunctionObj,
187         typename R BOOST_FUNCTION_COMMA
188         BOOST_FUNCTION_TEMPLATE_PARMS
189        >
190       struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
191       {
192         typedef typename ct_if<(is_void<R>::value),
193                             BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
194                             FunctionObj,
195                             R BOOST_FUNCTION_COMMA
196                             BOOST_FUNCTION_TEMPLATE_ARGS
197                           >,
198                           BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
199                             FunctionObj,
200                             R BOOST_FUNCTION_COMMA
201                             BOOST_FUNCTION_TEMPLATE_ARGS
202                           >
203                        >::type type;
204       };
205
206       template<
207         typename FunctionObj,
208         typename R BOOST_FUNCTION_COMMA
209         BOOST_FUNCTION_TEMPLATE_PARMS
210        >
211       struct BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
212       {
213         typedef typename ct_if<(is_void<R>::value),
214                             BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER<
215                             FunctionObj,
216                             R BOOST_FUNCTION_COMMA
217                             BOOST_FUNCTION_TEMPLATE_ARGS
218                           >,
219                           BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER<
220                             FunctionObj,
221                             R BOOST_FUNCTION_COMMA
222                             BOOST_FUNCTION_TEMPLATE_ARGS
223                           >
224                        >::type type;
225       };
226
227     } // end namespace function
228   } // end namespace detail
229
230   template<
231     typename R BOOST_FUNCTION_COMMA
232     BOOST_FUNCTION_TEMPLATE_PARMS,
233     typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
234   >
235   class BOOST_FUNCTION_FUNCTION : public function_base
236   {
237   public:
238     typedef typename detail::function::function_return_type<R>::type
239       internal_result_type;
240
241   private:
242     struct clear_type {};
243
244   public:
245     BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
246
247     // add signature for boost::lambda
248     template<typename Args>
249     struct sig
250     {
251       typedef internal_result_type type;
252     };
253
254 #if BOOST_FUNCTION_NUM_ARGS == 1
255     typedef T0 argument_type;
256 #elif BOOST_FUNCTION_NUM_ARGS == 2
257     typedef T0 first_argument_type;
258     typedef T1 second_argument_type;
259 #endif
260
261     BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
262     BOOST_FUNCTION_ARG_TYPES
263
264 #ifndef BOOST_NO_VOID_RETURNS
265     typedef R         result_type;
266 #else
267     typedef internal_result_type result_type;
268 #endif // BOOST_NO_VOID_RETURNS
269     typedef Allocator allocator_type;
270     typedef BOOST_FUNCTION_FUNCTION self_type;
271
272     BOOST_FUNCTION_FUNCTION() : function_base()
273                               , invoker(0) {}
274
275     // MSVC chokes if the following two constructors are collapsed into
276     // one with a default parameter.
277     template<typename Functor>
278     BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
279 #ifndef BOOST_NO_SFINAE
280                             ,typename enable_if_c<
281                             (::boost::type_traits::ice_not<
282                              (is_integral<Functor>::value)>::value),
283                                         int>::type = 0
284 #endif // BOOST_NO_SFINAE
285                             ) :
286       function_base(),
287       invoker(0)
288     {
289       this->assign_to(f);
290     }
291
292 #ifndef BOOST_NO_SFINAE
293     BOOST_FUNCTION_FUNCTION(clear_type*) : function_base(), invoker(0) {}
294 #else
295     BOOST_FUNCTION_FUNCTION(int zero) : function_base(), invoker(0)
296     {
297       BOOST_ASSERT(zero == 0);
298     }
299 #endif
300
301     BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) :
302       function_base(),
303       invoker(0)
304     {
305       this->assign_to_own(f);
306     }
307
308     ~BOOST_FUNCTION_FUNCTION() { clear(); }
309
310 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
311     // MSVC 6.0 and prior require all definitions to be inline, but
312     // these definitions can become very costly.
313     result_type operator()(BOOST_FUNCTION_PARMS) const
314     {
315       if (this->empty())
316         boost::throw_exception(bad_function_call());
317
318       internal_result_type result = invoker(this->functor
319                                             BOOST_FUNCTION_COMMA
320                                             BOOST_FUNCTION_ARGS);
321
322 #ifndef BOOST_NO_VOID_RETURNS
323       return static_cast<result_type>(result);
324 #else
325       return result;
326 #endif // BOOST_NO_VOID_RETURNS
327     }
328 #else
329     result_type operator()(BOOST_FUNCTION_PARMS) const;
330 #endif
331
332     // The distinction between when to use BOOST_FUNCTION_FUNCTION and
333     // when to use self_type is obnoxious. MSVC cannot handle self_type as
334     // the return type of these assignment operators, but Borland C++ cannot
335     // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
336     // construct.
337     template<typename Functor>
338 #ifndef BOOST_NO_SFINAE
339     typename enable_if_c<
340                (::boost::type_traits::ice_not<
341                  (is_integral<Functor>::value)>::value),
342                BOOST_FUNCTION_FUNCTION&>::type
343 #else
344     BOOST_FUNCTION_FUNCTION&
345 #endif
346     operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
347     {
348       self_type(f).swap(*this);
349       return *this;
350     }
351
352 #ifndef BOOST_NO_SFINAE
353     BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
354     {
355       this->clear();
356       return *this;
357     }
358 #else
359     BOOST_FUNCTION_FUNCTION& operator=(int zero)
360     {
361       BOOST_ASSERT(zero == 0);
362       this->clear();
363       return *this;
364     }
365 #endif
366
367     // Assignment from another BOOST_FUNCTION_FUNCTION
368     BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
369     {
370       if (&f == this)
371         return *this;
372
373       self_type(f).swap(*this);
374       return *this;
375     }
376
377     void swap(BOOST_FUNCTION_FUNCTION& other)
378     {
379       if (&other == this)
380         return;
381
382       std::swap(this->manager, other.manager);
383       std::swap(this->functor, other.functor);
384       std::swap(invoker, other.invoker);
385     }
386
387     // Clear out a target, if there is one
388     void clear()
389     {
390       if (this->manager) {
391         function_base::functor =
392           this->manager(this->functor, detail::function::destroy_functor_tag);
393       }
394
395       this->manager = 0;
396       invoker = 0;
397     }
398
399 #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
400     // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
401     operator bool () const { return !this->empty(); }
402 #else
403   private:
404     struct dummy {
405       void nonnull() {};
406     };
407
408     typedef void (dummy::*safe_bool)();
409
410   public:
411     operator safe_bool () const
412       { return (this->empty())? 0 : &dummy::nonnull; }
413
414     bool operator!() const
415       { return this->empty(); }
416 #endif
417
418   private:
419     void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
420     {
421       if (!f.empty()) {
422         invoker = f.invoker;
423         this->manager = f.manager;
424         this->functor =
425           f.manager(f.functor, detail::function::clone_functor_tag);
426       }
427     }
428
429     template<typename Functor>
430     void assign_to(Functor f)
431     {
432       typedef typename detail::function::get_function_tag<Functor>::type tag;
433       this->assign_to(f, tag());
434     }
435
436     template<typename FunctionPtr>
437     void assign_to(FunctionPtr f, detail::function::function_ptr_tag)
438     {
439       clear();
440
441       if (f) {
442         typedef typename detail::function::BOOST_FUNCTION_GET_FUNCTION_INVOKER<
443                            FunctionPtr,
444                            R BOOST_FUNCTION_COMMA
445                            BOOST_FUNCTION_TEMPLATE_ARGS
446                          >::type
447           actual_invoker_type;
448
449         invoker = &actual_invoker_type::invoke;
450         this->manager =
451           &detail::function::functor_manager<FunctionPtr, Allocator>::manage;
452         this->functor =
453           this->manager(detail::function::make_any_pointer(
454                             // should be a reinterpret cast, but some compilers
455                             // insist on giving cv-qualifiers to free functions
456                             (void (*)())(f)
457                           ),
458                           detail::function::clone_functor_tag);
459       }
460     }
461
462 #if BOOST_FUNCTION_NUM_ARGS > 0
463     template<typename MemberPtr>
464     void assign_to(MemberPtr f, detail::function::member_ptr_tag)
465     {
466       this->assign_to(mem_fn(f));
467     }
468 #endif // BOOST_FUNCTION_NUM_ARGS > 0
469
470     template<typename FunctionObj>
471     void assign_to(FunctionObj f, detail::function::function_obj_tag)
472     {
473       if (!detail::function::has_empty_target(addressof(f))) {
474         typedef
475           typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
476                                        FunctionObj,
477                                        R BOOST_FUNCTION_COMMA
478                                        BOOST_FUNCTION_TEMPLATE_ARGS
479                                      >::type
480           actual_invoker_type;
481
482         invoker = &actual_invoker_type::invoke;
483         this->manager = &detail::function::functor_manager<
484                                     FunctionObj, Allocator>::manage;
485 #ifndef BOOST_NO_STD_ALLOCATOR
486         typedef typename Allocator::template rebind<FunctionObj>::other
487           rebound_allocator_type;
488         typedef typename rebound_allocator_type::pointer pointer_type;
489         rebound_allocator_type allocator;
490         pointer_type copy = allocator.allocate(1);
491         allocator.construct(copy, f);
492
493         // Get back to the original pointer type
494         FunctionObj* new_f = static_cast<FunctionObj*>(copy);
495 #else
496         FunctionObj* new_f = new FunctionObj(f);
497 #endif // BOOST_NO_STD_ALLOCATOR
498         this->functor =
499           detail::function::make_any_pointer(static_cast<void*>(new_f));
500       }
501     }
502
503     template<typename FunctionObj>
504     void assign_to(const reference_wrapper<FunctionObj>& f,
505                    detail::function::function_obj_ref_tag)
506     {
507       if (!detail::function::has_empty_target(f.get_pointer())) {
508         typedef
509           typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
510                                        FunctionObj,
511                                        R BOOST_FUNCTION_COMMA
512                                        BOOST_FUNCTION_TEMPLATE_ARGS
513                                      >::type
514           actual_invoker_type;
515
516         invoker = &actual_invoker_type::invoke;
517         this->manager = &detail::function::trivial_manager<FunctionObj>::get;
518         this->functor =
519           this->manager(
520             detail::function::make_any_pointer(
521               const_cast<FunctionObj*>(f.get_pointer())),
522             detail::function::clone_functor_tag);
523       }
524     }
525
526     template<typename FunctionObj>
527     void assign_to(FunctionObj, detail::function::stateless_function_obj_tag)
528     {
529       typedef
530           typename detail::function::
531                      BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER<
532                        FunctionObj,
533                        R BOOST_FUNCTION_COMMA
534                        BOOST_FUNCTION_TEMPLATE_ARGS
535                      >::type
536           actual_invoker_type;
537       invoker = &actual_invoker_type::invoke;
538       this->manager = &detail::function::trivial_manager<FunctionObj>::get;
539       this->functor = detail::function::make_any_pointer(this);
540     }
541
542     typedef internal_result_type (*invoker_type)(detail::function::any_pointer
543                                                  BOOST_FUNCTION_COMMA
544                                                  BOOST_FUNCTION_TEMPLATE_ARGS);
545
546     invoker_type invoker;
547   };
548
549   template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
550            typename Allocator>
551   inline void swap(BOOST_FUNCTION_FUNCTION<
552                      R BOOST_FUNCTION_COMMA
553                      BOOST_FUNCTION_TEMPLATE_ARGS ,
554                      Allocator
555                    >& f1,
556                    BOOST_FUNCTION_FUNCTION<
557                      R BOOST_FUNCTION_COMMA
558                      BOOST_FUNCTION_TEMPLATE_ARGS,
559                      Allocator
560                    >& f2)
561   {
562     f1.swap(f2);
563   }
564
565 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
566   template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
567            typename Allocator>
568   typename BOOST_FUNCTION_FUNCTION<
569       R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS, 
570       Allocator>::result_type
571    BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS,
572
573                            Allocator>
574   ::operator()(BOOST_FUNCTION_PARMS) const
575   {
576       if (this->empty())
577         boost::throw_exception(bad_function_call());
578
579       internal_result_type result = invoker(this->functor
580                                             BOOST_FUNCTION_COMMA
581                                             BOOST_FUNCTION_ARGS);
582
583 #  ifndef BOOST_NO_VOID_RETURNS
584       return static_cast<result_type>(result);
585 #  else
586       return result;
587 #  endif // BOOST_NO_VOID_RETURNS
588     }
589 #endif
590
591 // Poison comparisons between boost::function objects of the same type.
592 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
593          typename Allocator>
594   void operator==(const BOOST_FUNCTION_FUNCTION<
595                           R BOOST_FUNCTION_COMMA
596                           BOOST_FUNCTION_TEMPLATE_ARGS ,
597                           Allocator>&,
598                   const BOOST_FUNCTION_FUNCTION<
599                           R BOOST_FUNCTION_COMMA
600                           BOOST_FUNCTION_TEMPLATE_ARGS ,
601                   Allocator>&);
602 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
603          typename Allocator>
604   void operator!=(const BOOST_FUNCTION_FUNCTION<
605                           R BOOST_FUNCTION_COMMA
606                           BOOST_FUNCTION_TEMPLATE_ARGS ,
607                           Allocator>&,
608                   const BOOST_FUNCTION_FUNCTION<
609                           R BOOST_FUNCTION_COMMA
610                           BOOST_FUNCTION_TEMPLATE_ARGS ,
611                   Allocator>&);
612
613 #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
614
615 #if BOOST_FUNCTION_NUM_ARGS == 0
616 #define BOOST_FUNCTION_PARTIAL_SPEC R (void)
617 #else
618 #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
619 #endif
620
621 template<typename R BOOST_FUNCTION_COMMA
622          BOOST_FUNCTION_TEMPLATE_PARMS,
623          typename Allocator>
624 class function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>
625   : public BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
626                                    BOOST_FUNCTION_COMMA Allocator>
627 {
628   typedef BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
629                                   BOOST_FUNCTION_COMMA Allocator> base_type;
630   typedef function self_type;
631
632   struct clear_type {};
633
634 public:
635   typedef typename base_type::allocator_type allocator_type;
636
637   function() : base_type() {}
638
639   template<typename Functor>
640   function(Functor f
641 #ifndef BOOST_NO_SFINAE
642            ,typename enable_if_c<
643                             (::boost::type_traits::ice_not<
644                           (is_integral<Functor>::value)>::value),
645                        int>::type = 0
646 #endif
647            ) :
648     base_type(f)
649   {
650   }
651
652 #ifndef BOOST_NO_SFINAE
653   function(clear_type*) : base_type() {}
654 #endif
655
656   function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
657
658   function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
659
660   self_type& operator=(const self_type& f)
661   {
662     self_type(f).swap(*this);
663     return *this;
664   }
665
666   template<typename Functor>
667 #ifndef BOOST_NO_SFINAE
668   typename enable_if_c<
669                             (::boost::type_traits::ice_not<
670                          (is_integral<Functor>::value)>::value),
671                       self_type&>::type
672 #else
673   self_type&
674 #endif
675   operator=(Functor f)
676   {
677     self_type(f).swap(*this);
678     return *this;
679   }
680
681 #ifndef BOOST_NO_SFINAE
682   self_type& operator=(clear_type*)
683   {
684     this->clear();
685     return *this;
686   }
687 #endif
688
689   self_type& operator=(const base_type& f)
690   {
691     self_type(f).swap(*this);
692     return *this;
693   }
694 };
695
696 #undef BOOST_FUNCTION_PARTIAL_SPEC
697 #endif // have partial specialization
698
699 } // end namespace boost
700
701 // Cleanup after ourselves...
702 #undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
703 #undef BOOST_FUNCTION_COMMA
704 #undef BOOST_FUNCTION_FUNCTION
705 #undef BOOST_FUNCTION_FUNCTION_INVOKER
706 #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
707 #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
708 #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
709 #undef BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER
710 #undef BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER
711 #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
712 #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
713 #undef BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
714 #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
715 #undef BOOST_FUNCTION_TEMPLATE_PARMS
716 #undef BOOST_FUNCTION_TEMPLATE_ARGS
717 #undef BOOST_FUNCTION_PARMS
718 #undef BOOST_FUNCTION_PARM
719 #undef BOOST_FUNCTION_ARGS
720 #undef BOOST_FUNCTION_ARG_TYPE
721 #undef BOOST_FUNCTION_ARG_TYPES