]> git.lyx.org Git - lyx.git/blob - boost/boost/function/function_template.hpp
Boost 1.31.0
[lyx.git] / boost / boost / function / function_template.hpp
1 // Boost.Function library
2
3 //  Copyright Doug 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     result_type operator()(BOOST_FUNCTION_PARMS) const
311     {
312       if (this->empty())
313         boost::throw_exception(bad_function_call());
314
315       internal_result_type result = invoker(this->functor
316                                             BOOST_FUNCTION_COMMA
317                                             BOOST_FUNCTION_ARGS);
318
319 #ifndef BOOST_NO_VOID_RETURNS
320       return static_cast<result_type>(result);
321 #else
322       return result;
323 #endif // BOOST_NO_VOID_RETURNS
324     }
325
326     // The distinction between when to use BOOST_FUNCTION_FUNCTION and
327     // when to use self_type is obnoxious. MSVC cannot handle self_type as
328     // the return type of these assignment operators, but Borland C++ cannot
329     // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
330     // construct.
331     template<typename Functor>
332 #ifndef BOOST_NO_SFINAE
333     typename enable_if_c<
334                (::boost::type_traits::ice_not<
335                  (is_integral<Functor>::value)>::value),
336                BOOST_FUNCTION_FUNCTION&>::type
337 #else
338     BOOST_FUNCTION_FUNCTION&
339 #endif
340     operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
341     {
342       self_type(f).swap(*this);
343       return *this;
344     }
345
346 #ifndef BOOST_NO_SFINAE
347     BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
348     {
349       this->clear();
350       return *this;
351     }
352 #else
353     BOOST_FUNCTION_FUNCTION& operator=(int zero)
354     {
355       BOOST_ASSERT(zero == 0);
356       this->clear();
357       return *this;
358     }
359 #endif
360
361     // Assignment from another BOOST_FUNCTION_FUNCTION
362     BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
363     {
364       if (&f == this)
365         return *this;
366
367       self_type(f).swap(*this);
368       return *this;
369     }
370
371     void swap(BOOST_FUNCTION_FUNCTION& other)
372     {
373       if (&other == this)
374         return;
375
376       std::swap(this->manager, other.manager);
377       std::swap(this->functor, other.functor);
378       std::swap(invoker, other.invoker);
379     }
380
381     // Clear out a target, if there is one
382     void clear()
383     {
384       if (this->manager) {
385         function_base::functor =
386           this->manager(this->functor, detail::function::destroy_functor_tag);
387       }
388
389       this->manager = 0;
390       invoker = 0;
391     }
392
393 #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
394     // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
395     operator bool () const { return !this->empty(); }
396 #else
397   private:
398     struct dummy {
399       void nonnull() {};
400     };
401
402     typedef void (dummy::*safe_bool)();
403
404   public:
405     operator safe_bool () const
406       { return (this->empty())? 0 : &dummy::nonnull; }
407
408     bool operator!() const
409       { return this->empty(); }
410 #endif
411
412   private:
413     void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
414     {
415       if (!f.empty()) {
416         invoker = f.invoker;
417         this->manager = f.manager;
418         this->functor =
419           f.manager(f.functor, detail::function::clone_functor_tag);
420       }
421     }
422
423     template<typename Functor>
424     void assign_to(Functor f)
425     {
426       typedef typename detail::function::get_function_tag<Functor>::type tag;
427       this->assign_to(f, tag());
428     }
429
430     template<typename FunctionPtr>
431     void assign_to(FunctionPtr f, detail::function::function_ptr_tag)
432     {
433       clear();
434
435       if (f) {
436         typedef typename detail::function::BOOST_FUNCTION_GET_FUNCTION_INVOKER<
437                            FunctionPtr,
438                            R BOOST_FUNCTION_COMMA
439                            BOOST_FUNCTION_TEMPLATE_ARGS
440                          >::type
441           invoker_type;
442
443         invoker = &invoker_type::invoke;
444         this->manager =
445           &detail::function::functor_manager<FunctionPtr, Allocator>::manage;
446         this->functor =
447           this->manager(detail::function::make_any_pointer(
448                             // should be a reinterpret cast, but some compilers
449                             // insist on giving cv-qualifiers to free functions
450                             (void (*)())(f)
451                           ),
452                           detail::function::clone_functor_tag);
453       }
454     }
455
456 #if BOOST_FUNCTION_NUM_ARGS > 0
457     template<typename MemberPtr>
458     void assign_to(MemberPtr f, detail::function::member_ptr_tag)
459     {
460       this->assign_to(mem_fn(f));
461     }
462 #endif // BOOST_FUNCTION_NUM_ARGS > 0
463
464     template<typename FunctionObj>
465     void assign_to(FunctionObj f, detail::function::function_obj_tag)
466     {
467       if (!detail::function::has_empty_target(addressof(f))) {
468         typedef
469           typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
470                                        FunctionObj,
471                                        R BOOST_FUNCTION_COMMA
472                                        BOOST_FUNCTION_TEMPLATE_ARGS
473                                      >::type
474           invoker_type;
475
476         invoker = &invoker_type::invoke;
477         this->manager = &detail::function::functor_manager<
478                                     FunctionObj, Allocator>::manage;
479 #ifndef BOOST_NO_STD_ALLOCATOR
480         typedef typename Allocator::template rebind<FunctionObj>::other
481           allocator_type;
482         typedef typename allocator_type::pointer pointer_type;
483         allocator_type allocator;
484         pointer_type copy = allocator.allocate(1);
485         allocator.construct(copy, f);
486
487         // Get back to the original pointer type
488         FunctionObj* new_f = static_cast<FunctionObj*>(copy);
489 #else
490         FunctionObj* new_f = new FunctionObj(f);
491 #endif // BOOST_NO_STD_ALLOCATOR
492         this->functor =
493           detail::function::make_any_pointer(static_cast<void*>(new_f));
494       }
495     }
496
497     template<typename FunctionObj>
498     void assign_to(const reference_wrapper<FunctionObj>& f,
499                    detail::function::function_obj_ref_tag)
500     {
501       if (!detail::function::has_empty_target(f.get_pointer())) {
502         typedef
503           typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
504                                        FunctionObj,
505                                        R BOOST_FUNCTION_COMMA
506                                        BOOST_FUNCTION_TEMPLATE_ARGS
507                                      >::type
508           invoker_type;
509
510         invoker = &invoker_type::invoke;
511         this->manager = &detail::function::trivial_manager;
512         this->functor =
513           this->manager(
514             detail::function::make_any_pointer(
515               const_cast<FunctionObj*>(f.get_pointer())),
516             detail::function::clone_functor_tag);
517       }
518     }
519
520     template<typename FunctionObj>
521     void assign_to(FunctionObj, detail::function::stateless_function_obj_tag)
522     {
523       typedef
524           typename detail::function::
525                      BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER<
526                        FunctionObj,
527                        R BOOST_FUNCTION_COMMA
528                        BOOST_FUNCTION_TEMPLATE_ARGS
529                      >::type
530           invoker_type;
531       invoker = &invoker_type::invoke;
532       this->manager = &detail::function::trivial_manager;
533       this->functor = detail::function::make_any_pointer(this);
534     }
535
536     typedef internal_result_type (*invoker_type)(detail::function::any_pointer
537                                                  BOOST_FUNCTION_COMMA
538                                                  BOOST_FUNCTION_TEMPLATE_ARGS);
539
540     invoker_type invoker;
541   };
542
543   template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
544            typename Allocator>
545   inline void swap(BOOST_FUNCTION_FUNCTION<
546                      R BOOST_FUNCTION_COMMA
547                      BOOST_FUNCTION_TEMPLATE_ARGS ,
548                      Allocator
549                    >& f1,
550                    BOOST_FUNCTION_FUNCTION<
551                      R BOOST_FUNCTION_COMMA
552                      BOOST_FUNCTION_TEMPLATE_ARGS,
553                      Allocator
554                    >& f2)
555   {
556     f1.swap(f2);
557   }
558
559 #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
560
561 #if BOOST_FUNCTION_NUM_ARGS == 0
562 #define BOOST_FUNCTION_PARTIAL_SPEC R (void)
563 #else
564 #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
565 #endif
566
567 template<typename R BOOST_FUNCTION_COMMA
568          BOOST_FUNCTION_TEMPLATE_PARMS,
569          typename Allocator>
570 class function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>
571   : public BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
572                                    BOOST_FUNCTION_COMMA Allocator>
573 {
574   typedef BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
575                                   BOOST_FUNCTION_COMMA Allocator> base_type;
576   typedef function self_type;
577
578   struct clear_type {};
579
580 public:
581   typedef typename base_type::allocator_type allocator_type;
582
583   function() : base_type() {}
584
585   template<typename Functor>
586   function(Functor f
587 #ifndef BOOST_NO_SFINAE
588            ,typename enable_if_c<
589                             (::boost::type_traits::ice_not<
590                           (is_integral<Functor>::value)>::value),
591                        int>::type = 0
592 #endif
593            ) :
594     base_type(f)
595   {
596   }
597
598 #ifndef BOOST_NO_SFINAE
599   function(clear_type*) : base_type() {}
600 #endif
601
602   function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
603
604   function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
605
606   self_type& operator=(const self_type& f)
607   {
608     self_type(f).swap(*this);
609     return *this;
610   }
611
612   template<typename Functor>
613 #ifndef BOOST_NO_SFINAE
614   typename enable_if_c<
615                             (::boost::type_traits::ice_not<
616                          (is_integral<Functor>::value)>::value),
617                       self_type&>::type
618 #else
619   self_type&
620 #endif
621   operator=(Functor f)
622   {
623     self_type(f).swap(*this);
624     return *this;
625   }
626
627 #ifndef BOOST_NO_SFINAE
628   self_type& operator=(clear_type*)
629   {
630     this->clear();
631     return *this;
632   }
633 #endif
634
635   self_type& operator=(const base_type& f)
636   {
637     self_type(f).swap(*this);
638     return *this;
639   }
640 };
641
642 #undef BOOST_FUNCTION_PARTIAL_SPEC
643 #endif // have partial specialization
644
645 } // end namespace boost
646
647 // Cleanup after ourselves...
648 #undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
649 #undef BOOST_FUNCTION_COMMA
650 #undef BOOST_FUNCTION_FUNCTION
651 #undef BOOST_FUNCTION_FUNCTION_INVOKER
652 #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
653 #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
654 #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
655 #undef BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER
656 #undef BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER
657 #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
658 #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
659 #undef BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
660 #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
661 #undef BOOST_FUNCTION_TEMPLATE_PARMS
662 #undef BOOST_FUNCTION_TEMPLATE_ARGS
663 #undef BOOST_FUNCTION_PARMS
664 #undef BOOST_FUNCTION_PARM
665 #undef BOOST_FUNCTION_ARGS
666 #undef BOOST_FUNCTION_ARG_TYPE
667 #undef BOOST_FUNCTION_ARG_TYPES