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   	#include <boost/detail/no_exceptions_support.hpp>
15   	
16   	#if defined(BOOST_MSVC)
17   	#   pragma warning( push )
18   	#   pragma warning( disable : 4127 ) // "conditional expression is constant"
19   	#endif
20   	
21   	#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
22   	
23   	#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
24   	
25   	#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
26   	
27   	#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
28   	
29   	#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
30   	#   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
31   	#else
32   	#   include <boost/move/utility_core.hpp>
33   	#   define BOOST_FUNCTION_ARG(J,I,D) ::boost::forward< BOOST_PP_CAT(T,I) >(BOOST_PP_CAT(a,I))
34   	#   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY)
35   	#endif
36   	
37   	#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
38   	  typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
39   	
40   	#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
41   	
42   	// Comma if nonzero number of arguments
43   	#if BOOST_FUNCTION_NUM_ARGS == 0
44   	#  define BOOST_FUNCTION_COMMA
45   	#else
46   	#  define BOOST_FUNCTION_COMMA ,
47   	#endif // BOOST_FUNCTION_NUM_ARGS > 0
48   	
49   	// Class names used in this version of the code
50   	#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
51   	#define BOOST_FUNCTION_FUNCTION_INVOKER \
52   	  BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
53   	#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
54   	  BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
55   	#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
56   	  BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
57   	#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
58   	  BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
59   	#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
60   	  BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
61   	#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
62   	  BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
63   	#define BOOST_FUNCTION_MEMBER_INVOKER \
64   	  BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
65   	#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
66   	  BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
67   	#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
68   	  BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
69   	#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
70   	  BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
71   	#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
72   	  BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
73   	#define BOOST_FUNCTION_GET_MEMBER_INVOKER \
74   	  BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
75   	#define BOOST_FUNCTION_GET_INVOKER \
76   	  BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
77   	#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
78   	
79   	#ifndef BOOST_NO_VOID_RETURNS
80   	#  define BOOST_FUNCTION_VOID_RETURN_TYPE void
81   	#  define BOOST_FUNCTION_RETURN(X) X
82   	#else
83   	#  define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
84   	#  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
85   	#endif
86   	
87   	namespace boost {
88   	  namespace detail {
89   	    namespace function {
90   	      template<
91   	        typename FunctionPtr,
92   	        typename R BOOST_FUNCTION_COMMA
93   	        BOOST_FUNCTION_TEMPLATE_PARMS
94   	        >
95   	      struct BOOST_FUNCTION_FUNCTION_INVOKER
96   	      {
97   	        static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
98   	                        BOOST_FUNCTION_PARMS)
99   	        {
100  	          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
101  	          return f(BOOST_FUNCTION_ARGS);
102  	        }
103  	      };
104  	
105  	      template<
106  	        typename FunctionPtr,
107  	        typename R BOOST_FUNCTION_COMMA
108  	        BOOST_FUNCTION_TEMPLATE_PARMS
109  	        >
110  	      struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
111  	      {
112  	        static BOOST_FUNCTION_VOID_RETURN_TYPE
113  	        invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
114  	               BOOST_FUNCTION_PARMS)
115  	
116  	        {
117  	          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
118  	          BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
119  	        }
120  	      };
121  	
122  	      template<
123  	        typename FunctionObj,
124  	        typename R BOOST_FUNCTION_COMMA
125  	        BOOST_FUNCTION_TEMPLATE_PARMS
126  	      >
127  	      struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
128  	      {
129  	        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
130  	                        BOOST_FUNCTION_PARMS)
131  	
132  	        {
133  	          FunctionObj* f;
134  	          if (function_allows_small_object_optimization<FunctionObj>::value)
135  	            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
136  	          else
137  	            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
138  	          return (*f)(BOOST_FUNCTION_ARGS);
139  	        }
140  	      };
141  	
142  	      template<
143  	        typename FunctionObj,
144  	        typename R BOOST_FUNCTION_COMMA
145  	        BOOST_FUNCTION_TEMPLATE_PARMS
146  	      >
147  	      struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
148  	      {
149  	        static BOOST_FUNCTION_VOID_RETURN_TYPE
150  	        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
151  	               BOOST_FUNCTION_PARMS)
152  	
153  	        {
154  	          FunctionObj* f;
155  	          if (function_allows_small_object_optimization<FunctionObj>::value)
156  	            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
157  	          else
158  	            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
159  	          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
160  	        }
161  	      };
162  	
163  	      template<
164  	        typename FunctionObj,
165  	        typename R BOOST_FUNCTION_COMMA
166  	        BOOST_FUNCTION_TEMPLATE_PARMS
167  	      >
168  	      struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
169  	      {
170  	        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
171  	                        BOOST_FUNCTION_PARMS)
172  	
173  	        {
174  	          FunctionObj* f =
175  	            reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
176  	          return (*f)(BOOST_FUNCTION_ARGS);
177  	        }
178  	      };
179  	
180  	      template<
181  	        typename FunctionObj,
182  	        typename R BOOST_FUNCTION_COMMA
183  	        BOOST_FUNCTION_TEMPLATE_PARMS
184  	      >
185  	      struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
186  	      {
187  	        static BOOST_FUNCTION_VOID_RETURN_TYPE
188  	        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
189  	               BOOST_FUNCTION_PARMS)
190  	
191  	        {
192  	          FunctionObj* f =
193  	            reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
194  	          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
195  	        }
196  	      };
197  	
198  	#if BOOST_FUNCTION_NUM_ARGS > 0
199  	      /* Handle invocation of member pointers. */
200  	      template<
201  	        typename MemberPtr,
202  	        typename R BOOST_FUNCTION_COMMA
203  	        BOOST_FUNCTION_TEMPLATE_PARMS
204  	      >
205  	      struct BOOST_FUNCTION_MEMBER_INVOKER
206  	      {
207  	        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
208  	                        BOOST_FUNCTION_PARMS)
209  	
210  	        {
211  	          MemberPtr* f =
212  	            reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
213  	          return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
214  	        }
215  	      };
216  	
217  	      template<
218  	        typename MemberPtr,
219  	        typename R BOOST_FUNCTION_COMMA
220  	        BOOST_FUNCTION_TEMPLATE_PARMS
221  	      >
222  	      struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
223  	      {
224  	        static BOOST_FUNCTION_VOID_RETURN_TYPE
225  	        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
226  	               BOOST_FUNCTION_PARMS)
227  	
228  	        {
229  	          MemberPtr* f =
230  	            reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
231  	          BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
232  	        }
233  	      };
234  	#endif
235  	
236  	      template<
237  	        typename FunctionPtr,
238  	        typename R BOOST_FUNCTION_COMMA
239  	        BOOST_FUNCTION_TEMPLATE_PARMS
240  	      >
241  	      struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
242  	      {
243  	        typedef typename mpl::if_c<(is_void<R>::value),
244  	                            BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
245  	                            FunctionPtr,
246  	                            R BOOST_FUNCTION_COMMA
247  	                            BOOST_FUNCTION_TEMPLATE_ARGS
248  	                          >,
249  	                          BOOST_FUNCTION_FUNCTION_INVOKER<
250  	                            FunctionPtr,
251  	                            R BOOST_FUNCTION_COMMA
252  	                            BOOST_FUNCTION_TEMPLATE_ARGS
253  	                          >
254  	                       >::type type;
255  	      };
256  	
257  	      template<
258  	        typename FunctionObj,
259  	        typename R BOOST_FUNCTION_COMMA
260  	        BOOST_FUNCTION_TEMPLATE_PARMS
261  	       >
262  	      struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
263  	      {
264  	        typedef typename mpl::if_c<(is_void<R>::value),
265  	                            BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
266  	                            FunctionObj,
267  	                            R BOOST_FUNCTION_COMMA
268  	                            BOOST_FUNCTION_TEMPLATE_ARGS
269  	                          >,
270  	                          BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
271  	                            FunctionObj,
272  	                            R BOOST_FUNCTION_COMMA
273  	                            BOOST_FUNCTION_TEMPLATE_ARGS
274  	                          >
275  	                       >::type type;
276  	      };
277  	
278  	      template<
279  	        typename FunctionObj,
280  	        typename R BOOST_FUNCTION_COMMA
281  	        BOOST_FUNCTION_TEMPLATE_PARMS
282  	       >
283  	      struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
284  	      {
285  	        typedef typename mpl::if_c<(is_void<R>::value),
286  	                            BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
287  	                            FunctionObj,
288  	                            R BOOST_FUNCTION_COMMA
289  	                            BOOST_FUNCTION_TEMPLATE_ARGS
290  	                          >,
291  	                          BOOST_FUNCTION_FUNCTION_REF_INVOKER<
292  	                            FunctionObj,
293  	                            R BOOST_FUNCTION_COMMA
294  	                            BOOST_FUNCTION_TEMPLATE_ARGS
295  	                          >
296  	                       >::type type;
297  	      };
298  	
299  	#if BOOST_FUNCTION_NUM_ARGS > 0
300  	      /* Retrieve the appropriate invoker for a member pointer.  */
301  	      template<
302  	        typename MemberPtr,
303  	        typename R BOOST_FUNCTION_COMMA
304  	        BOOST_FUNCTION_TEMPLATE_PARMS
305  	       >
306  	      struct BOOST_FUNCTION_GET_MEMBER_INVOKER
307  	      {
308  	        typedef typename mpl::if_c<(is_void<R>::value),
309  	                            BOOST_FUNCTION_VOID_MEMBER_INVOKER<
310  	                            MemberPtr,
311  	                            R BOOST_FUNCTION_COMMA
312  	                            BOOST_FUNCTION_TEMPLATE_ARGS
313  	                          >,
314  	                          BOOST_FUNCTION_MEMBER_INVOKER<
315  	                            MemberPtr,
316  	                            R BOOST_FUNCTION_COMMA
317  	                            BOOST_FUNCTION_TEMPLATE_ARGS
318  	                          >
319  	                       >::type type;
320  	      };
321  	#endif
322  	
323  	      /* Given the tag returned by get_function_tag, retrieve the
324  	         actual invoker that will be used for the given function
325  	         object.
326  	
327  	         Each specialization contains an "apply" nested class template
328  	         that accepts the function object, return type, function
329  	         argument types, and allocator. The resulting "apply" class
330  	         contains two typedefs, "invoker_type" and "manager_type",
331  	         which correspond to the invoker and manager types. */
332  	      template<typename Tag>
333  	      struct BOOST_FUNCTION_GET_INVOKER { };
334  	
335  	      /* Retrieve the invoker for a function pointer. */
336  	      template<>
337  	      struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
338  	      {
339  	        template<typename FunctionPtr,
340  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
341  	        struct apply
342  	        {
343  	          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
344  	                             FunctionPtr,
345  	                             R BOOST_FUNCTION_COMMA
346  	                             BOOST_FUNCTION_TEMPLATE_ARGS
347  	                           >::type
348  	            invoker_type;
349  	
350  	          typedef functor_manager<FunctionPtr> manager_type;
351  	        };
352  	
353  	        template<typename FunctionPtr,
354  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
355  	                 typename Allocator>
356  	        struct apply_a
357  	        {
358  	          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
359  	                             FunctionPtr,
360  	                             R BOOST_FUNCTION_COMMA
361  	                             BOOST_FUNCTION_TEMPLATE_ARGS
362  	                           >::type
363  	            invoker_type;
364  	
365  	          typedef functor_manager<FunctionPtr> manager_type;
366  	        };
367  	      };
368  	
369  	#if BOOST_FUNCTION_NUM_ARGS > 0
370  	      /* Retrieve the invoker for a member pointer. */
371  	      template<>
372  	      struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
373  	      {
374  	        template<typename MemberPtr,
375  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
376  	        struct apply
377  	        {
378  	          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
379  	                             MemberPtr,
380  	                             R BOOST_FUNCTION_COMMA
381  	                             BOOST_FUNCTION_TEMPLATE_ARGS
382  	                           >::type
383  	            invoker_type;
384  	
385  	          typedef functor_manager<MemberPtr> manager_type;
386  	        };
387  	
388  	        template<typename MemberPtr,
389  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
390  	                 typename Allocator>
391  	        struct apply_a
392  	        {
393  	          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
394  	                             MemberPtr,
395  	                             R BOOST_FUNCTION_COMMA
396  	                             BOOST_FUNCTION_TEMPLATE_ARGS
397  	                           >::type
398  	            invoker_type;
399  	
400  	          typedef functor_manager<MemberPtr> manager_type;
401  	        };
402  	      };
403  	#endif
404  	
405  	      /* Retrieve the invoker for a function object. */
406  	      template<>
407  	      struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
408  	      {
409  	        template<typename FunctionObj,
410  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
411  	        struct apply
412  	        {
413  	          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
414  	                             FunctionObj,
415  	                             R BOOST_FUNCTION_COMMA
416  	                             BOOST_FUNCTION_TEMPLATE_ARGS
417  	                           >::type
418  	            invoker_type;
419  	
420  	          typedef functor_manager<FunctionObj> manager_type;
421  	        };
422  	
423  	        template<typename FunctionObj,
424  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
425  	                 typename Allocator>
426  	        struct apply_a
427  	        {
428  	          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
429  	                             FunctionObj,
430  	                             R BOOST_FUNCTION_COMMA
431  	                             BOOST_FUNCTION_TEMPLATE_ARGS
432  	                           >::type
433  	            invoker_type;
434  	
435  	          typedef functor_manager_a<FunctionObj, Allocator> manager_type;
436  	        };
437  	      };
438  	
439  	      /* Retrieve the invoker for a reference to a function object. */
440  	      template<>
441  	      struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
442  	      {
443  	        template<typename RefWrapper,
444  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
445  	        struct apply
446  	        {
447  	          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
448  	                             typename RefWrapper::type,
449  	                             R BOOST_FUNCTION_COMMA
450  	                             BOOST_FUNCTION_TEMPLATE_ARGS
451  	                           >::type
452  	            invoker_type;
453  	
454  	          typedef reference_manager<typename RefWrapper::type> manager_type;
455  	        };
456  	
457  	        template<typename RefWrapper,
458  	                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
459  	                 typename Allocator>
460  	        struct apply_a
461  	        {
462  	          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
463  	                             typename RefWrapper::type,
464  	                             R BOOST_FUNCTION_COMMA
465  	                             BOOST_FUNCTION_TEMPLATE_ARGS
466  	                           >::type
467  	            invoker_type;
468  	
469  	          typedef reference_manager<typename RefWrapper::type> manager_type;
470  	        };
471  	      };
472  	
473  	
474  	      /**
475  	       * vtable for a specific boost::function instance. This
476  	       * structure must be an aggregate so that we can use static
477  	       * initialization in boost::function's assign_to and assign_to_a
478  	       * members. It therefore cannot have any constructors,
479  	       * destructors, base classes, etc.
480  	       */
481  	      template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
482  	      struct BOOST_FUNCTION_VTABLE
483  	      {
484  	#ifndef BOOST_NO_VOID_RETURNS
485  	        typedef R         result_type;
486  	#else
487  	        typedef typename function_return_type<R>::type result_type;
488  	#endif // BOOST_NO_VOID_RETURNS
489  	
490  	        typedef result_type (*invoker_type)(function_buffer&
491  	                                            BOOST_FUNCTION_COMMA
492  	                                            BOOST_FUNCTION_TEMPLATE_ARGS);
493  	
494  	        template<typename F>
495  	        bool assign_to(F f, function_buffer& functor) const
496  	        {
497  	          typedef typename get_function_tag<F>::type tag;
498  	          return assign_to(f, functor, tag());
499  	        }
500  	        template<typename F,typename Allocator>
501  	        bool assign_to_a(F f, function_buffer& functor, Allocator a) const
502  	        {
503  	          typedef typename get_function_tag<F>::type tag;
504  	          return assign_to_a(f, functor, a, tag());
505  	        }
506  	
507  	        void clear(function_buffer& functor) const
508  	        {
509  	          if (base.manager)
510  	            base.manager(functor, functor, destroy_functor_tag);
511  	        }
512  	
513  	      private:
514  	        // Function pointers
515  	        template<typename FunctionPtr>
516  	        bool
517  	        assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
518  	        {
519  	          this->clear(functor);
520  	          if (f) {
521  	            // should be a reinterpret cast, but some compilers insist
522  	            // on giving cv-qualifiers to free functions
523  	            functor.members.func_ptr = reinterpret_cast<void (*)()>(f);
524  	            return true;
525  	          } else {
526  	            return false;
527  	          }
528  	        }
529  	        template<typename FunctionPtr,typename Allocator>
530  	        bool
531  	        assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
532  	        {
533  	          return assign_to(f,functor,function_ptr_tag());
534  	        }
535  	
536  	        // Member pointers
537  	#if BOOST_FUNCTION_NUM_ARGS > 0
538  	        template<typename MemberPtr>
539  	        bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
540  	        {
541  	          // DPG TBD: Add explicit support for member function
542  	          // objects, so we invoke through mem_fn() but we retain the
543  	          // right target_type() values.
544  	          if (f) {
545  	            this->assign_to(boost::mem_fn(f), functor);
546  	            return true;
547  	          } else {
548  	            return false;
549  	          }
550  	        }
551  	        template<typename MemberPtr,typename Allocator>
552  	        bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
553  	        {
554  	          // DPG TBD: Add explicit support for member function
555  	          // objects, so we invoke through mem_fn() but we retain the
556  	          // right target_type() values.
557  	          if (f) {
558  	            this->assign_to_a(boost::mem_fn(f), functor, a);
559  	            return true;
560  	          } else {
561  	            return false;
562  	          }
563  	        }
564  	#endif // BOOST_FUNCTION_NUM_ARGS > 0
565  	
566  	        // Function objects
567  	        // Assign to a function object using the small object optimization
568  	        template<typename FunctionObj>
569  	        void
570  	        assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const
571  	        {
572  	          new (reinterpret_cast<void*>(functor.data)) FunctionObj(f);
573  	        }
574  	        template<typename FunctionObj,typename Allocator>
575  	        void
576  	        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const
577  	        {
578  	          assign_functor(f,functor,mpl::true_());
579  	        }
580  	
581  	        // Assign to a function object allocated on the heap.
582  	        template<typename FunctionObj>
583  	        void
584  	        assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const
585  	        {
586  	          functor.members.obj_ptr = new FunctionObj(f);
587  	        }
588  	        template<typename FunctionObj,typename Allocator>
589  	        void
590  	        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const
591  	        {
592  	          typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
593  	#if defined(BOOST_NO_CXX11_ALLOCATOR)
594  	          typedef typename Allocator::template rebind<functor_wrapper_type>::other
595  	            wrapper_allocator_type;
596  	          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
597  	#else
598  	          using wrapper_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<functor_wrapper_type>;
599  	          using wrapper_allocator_pointer_type = typename std::allocator_traits<wrapper_allocator_type>::pointer;
600  	#endif
601  	          wrapper_allocator_type wrapper_allocator(a);
602  	          wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
603  	#if defined(BOOST_NO_CXX11_ALLOCATOR)
604  	          wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
605  	#else
606  	          std::allocator_traits<wrapper_allocator_type>::construct(wrapper_allocator, copy, functor_wrapper_type(f,a));
607  	#endif
608  	          functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
609  	          functor.members.obj_ptr = new_f;
610  	        }
611  	
612  	        template<typename FunctionObj>
613  	        bool
614  	        assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
615  	        {
616  	          if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
617  	            assign_functor(f, functor,
618  	                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
619  	            return true;
620  	          } else {
621  	            return false;
622  	          }
623  	        }
624  	        template<typename FunctionObj,typename Allocator>
625  	        bool
626  	        assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
627  	        {
628  	          if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
629  	            assign_functor_a(f, functor, a,
630  	                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
631  	            return true;
632  	          } else {
633  	            return false;
634  	          }
635  	        }
636  	
637  	        // Reference to a function object
638  	        template<typename FunctionObj>
639  	        bool
640  	        assign_to(const reference_wrapper<FunctionObj>& f,
641  	                  function_buffer& functor, function_obj_ref_tag) const
642  	        {
643  	          functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer());
644  	          functor.members.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
645  	          functor.members.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
646  	          return true;
647  	        }
648  	        template<typename FunctionObj,typename Allocator>
649  	        bool
650  	        assign_to_a(const reference_wrapper<FunctionObj>& f,
651  	                  function_buffer& functor, Allocator, function_obj_ref_tag) const
652  	        {
653  	          return assign_to(f,functor,function_obj_ref_tag());
654  	        }
655  	
656  	      public:
657  	        vtable_base base;
658  	        invoker_type invoker;
659  	      };
660  	    } // end namespace function
661  	  } // end namespace detail
662  	
663  	  template<
664  	    typename R BOOST_FUNCTION_COMMA
665  	    BOOST_FUNCTION_TEMPLATE_PARMS
666  	  >
667  	  class BOOST_FUNCTION_FUNCTION : public function_base
668  	  {
669  	  public:
670  	#ifndef BOOST_NO_VOID_RETURNS
671  	    typedef R         result_type;
672  	#else
673  	    typedef  typename boost::detail::function::function_return_type<R>::type
674  	      result_type;
675  	#endif // BOOST_NO_VOID_RETURNS
676  	
677  	  private:
678  	    typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
679  	              R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
680  	      vtable_type;
681  	
682  	    vtable_type* get_vtable() const {
683  	      return reinterpret_cast<vtable_type*>(
684  	               reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
685  	    }
686  	
687  	    struct clear_type {};
688  	
689  	  public:
690  	    BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
691  	
692  	    // add signature for boost::lambda
693  	    template<typename Args>
694  	    struct sig
695  	    {
696  	      typedef result_type type;
697  	    };
698  	
699  	#if BOOST_FUNCTION_NUM_ARGS == 1
700  	    typedef T0 argument_type;
701  	#elif BOOST_FUNCTION_NUM_ARGS == 2
702  	    typedef T0 first_argument_type;
703  	    typedef T1 second_argument_type;
704  	#endif
705  	
706  	    BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
707  	    BOOST_FUNCTION_ARG_TYPES
708  	
709  	    typedef BOOST_FUNCTION_FUNCTION self_type;
710  	
711  	    BOOST_FUNCTION_FUNCTION() : function_base() { }
712  	
713  	    // MSVC chokes if the following two constructors are collapsed into
714  	    // one with a default parameter.
715  	    template<typename Functor>
716  	    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
717  	#ifndef BOOST_NO_SFINAE
718  	                            ,typename boost::enable_if_c<
719  	                             !(is_integral<Functor>::value),
720  	                                        int>::type = 0
721  	#endif // BOOST_NO_SFINAE
722  	                            ) :
723  	      function_base()
724  	    {
725  	      this->assign_to(f);
726  	    }
727  	    template<typename Functor,typename Allocator>
728  	    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
729  	#ifndef BOOST_NO_SFINAE
730  	                            ,typename boost::enable_if_c<
731  	                              !(is_integral<Functor>::value),
732  	                                        int>::type = 0
733  	#endif // BOOST_NO_SFINAE
734  	                            ) :
735  	      function_base()
736  	    {
737  	      this->assign_to_a(f,a);
738  	    }
739  	
740  	#ifndef BOOST_NO_SFINAE
741  	    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
742  	#else
743  	    BOOST_FUNCTION_FUNCTION(int zero) : function_base()
744  	    {
745  	      BOOST_ASSERT(zero == 0);
746  	    }
747  	#endif
748  	
749  	    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
750  	    {
751  	      this->assign_to_own(f);
752  	    }
753  	
754  	#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
755  	    BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
756  	    {
757  	      this->move_assign(f);
758  	    }
759  	#endif
760  	
761  	    ~BOOST_FUNCTION_FUNCTION() { clear(); }
762  	
763  	    result_type operator()(BOOST_FUNCTION_PARMS) const
764  	    {
765  	      if (this->empty())
766  	        boost::throw_exception(bad_function_call());
767  	
768  	      return get_vtable()->invoker
769  	               (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
770  	    }
771  	
772  	    // The distinction between when to use BOOST_FUNCTION_FUNCTION and
773  	    // when to use self_type is obnoxious. MSVC cannot handle self_type as
774  	    // the return type of these assignment operators, but Borland C++ cannot
775  	    // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
776  	    // construct.
777  	    template<typename Functor>
778  	#ifndef BOOST_NO_SFINAE
779  	    typename boost::enable_if_c<
780  	                  !(is_integral<Functor>::value),
781  	               BOOST_FUNCTION_FUNCTION&>::type
782  	#else
783  	    BOOST_FUNCTION_FUNCTION&
784  	#endif
785  	    operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
786  	    {
787  	      this->clear();
788  	      BOOST_TRY  {
789  	        this->assign_to(f);
790  	      } BOOST_CATCH (...) {
791  	        vtable = 0;
792  	        BOOST_RETHROW;
793  	      }
794  	      BOOST_CATCH_END
795  	      return *this;
796  	    }
797  	    template<typename Functor,typename Allocator>
798  	    void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
799  	    {
800  	      this->clear();
801  	      BOOST_TRY{
802  	        this->assign_to_a(f,a);
803  	      } BOOST_CATCH (...) {
804  	        vtable = 0;
805  	        BOOST_RETHROW;
806  	      }
807  	      BOOST_CATCH_END
808  	    }
809  	
810  	#ifndef BOOST_NO_SFINAE
811  	    BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
812  	    {
813  	      this->clear();
814  	      return *this;
815  	    }
816  	#else
817  	    BOOST_FUNCTION_FUNCTION& operator=(int zero)
818  	    {
819  	      BOOST_ASSERT(zero == 0);
820  	      this->clear();
821  	      return *this;
822  	    }
823  	#endif
824  	
825  	    // Assignment from another BOOST_FUNCTION_FUNCTION
826  	    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
827  	    {
828  	      if (&f == this)
829  	        return *this;
830  	
831  	      this->clear();
832  	      BOOST_TRY {
833  	        this->assign_to_own(f);
834  	      } BOOST_CATCH (...) {
835  	        vtable = 0;
836  	        BOOST_RETHROW;
837  	      }
838  	      BOOST_CATCH_END
839  	      return *this;
840  	    }
841  	
842  	#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
843  	    // Move assignment from another BOOST_FUNCTION_FUNCTION
844  	    BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
845  	    {
846  	      if (&f == this)
847  	        return *this;
848  	
849  	      this->clear();
850  	      BOOST_TRY {
851  	        this->move_assign(f);
852  	      } BOOST_CATCH (...) {
853  	        vtable = 0;
854  	        BOOST_RETHROW;
855  	      }
856  	      BOOST_CATCH_END
857  	      return *this;
858  	    }
859  	#endif
860  	
861  	    void swap(BOOST_FUNCTION_FUNCTION& other)
862  	    {
863  	      if (&other == this)
864  	        return;
865  	
866  	      BOOST_FUNCTION_FUNCTION tmp;
867  	      tmp.move_assign(*this);
868  	      this->move_assign(other);
869  	      other.move_assign(tmp);
870  	    }
871  	
872  	    // Clear out a target, if there is one
873  	    void clear()
874  	    {
875  	      if (vtable) {
876  	        if (!this->has_trivial_copy_and_destroy())
877  	          get_vtable()->clear(this->functor);
878  	        vtable = 0;
879  	      }
880  	    }
881  	
882  	#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
883  	    // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
884  	    operator bool () const { return !this->empty(); }
885  	#else
886  	  private:
887  	    struct dummy {
888  	      void nonnull() {}
889  	    };
890  	
891  	    typedef void (dummy::*safe_bool)();
892  	
893  	  public:
894  	    operator safe_bool () const
895  	      { return (this->empty())? 0 : &dummy::nonnull; }
896  	
897  	    bool operator!() const
898  	      { return this->empty(); }
899  	#endif
900  	
901  	  private:
902  	    void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
903  	    {
904  	      if (!f.empty()) {
905  	        this->vtable = f.vtable;
906  	        if (this->has_trivial_copy_and_destroy())
907  	          this->functor = f.functor;
908  	        else
909  	          get_vtable()->base.manager(f.functor, this->functor,
910  	                                     boost::detail::function::clone_functor_tag);
911  	      }
912  	    }
913  	
914  	    template<typename Functor>
(1) Event pass_by_value: Passing parameter f of type "boost::_bi::bind_t<int, boost::_mfi::mf7<int, librados::TestIoCtxImpl, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const &, librados::TestClassHandler *, char const *, char const *, ceph::buffer::v14_2_0::list &, ceph::buffer::v14_2_0::list *, SnapContext const &>, boost::_bi::list8<boost::arg<1>, boost::arg<2>, boost::_bi::value<librados::TestClassHandler *>, boost::_bi::value<char const *>, boost::_bi::value<char const *>, boost::_bi::value<ceph::buffer::v14_2_0::list>, boost::_bi::value<ceph::buffer::v14_2_0::list *>, boost::_bi::value<SnapContext> > >" (size 152 bytes) by value.
915  	    void assign_to(Functor f)
916  	    {
917  	      using boost::detail::function::vtable_base;
918  	
919  	      typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
920  	      typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
921  	      typedef typename get_invoker::
922  	                         template apply<Functor, R BOOST_FUNCTION_COMMA
923  	                        BOOST_FUNCTION_TEMPLATE_ARGS>
924  	        handler_type;
925  	
926  	      typedef typename handler_type::invoker_type invoker_type;
927  	      typedef typename handler_type::manager_type manager_type;
928  	
929  	      // Note: it is extremely important that this initialization use
930  	      // static initialization. Otherwise, we will have a race
931  	      // condition here in multi-threaded code. See
932  	      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
933  	      static const vtable_type stored_vtable =
934  	        { { &manager_type::manage }, &invoker_type::invoke };
935  	
936  	      if (stored_vtable.assign_to(f, functor)) {
937  	        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
938  	        // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
939  	        if (boost::has_trivial_copy_constructor<Functor>::value &&
940  	            boost::has_trivial_destructor<Functor>::value &&
941  	            boost::detail::function::function_allows_small_object_optimization<Functor>::value)
942  	          value |= static_cast<std::size_t>(0x01);
943  	        vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
944  	      } else
945  	        vtable = 0;
946  	    }
947  	
948  	    template<typename Functor,typename Allocator>
949  	    void assign_to_a(Functor f,Allocator a)
950  	    {
951  	      using boost::detail::function::vtable_base;
952  	
953  	      typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
954  	      typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
955  	      typedef typename get_invoker::
956  	                         template apply_a<Functor, R BOOST_FUNCTION_COMMA
957  	                         BOOST_FUNCTION_TEMPLATE_ARGS,
958  	                         Allocator>
959  	        handler_type;
960  	
961  	      typedef typename handler_type::invoker_type invoker_type;
962  	      typedef typename handler_type::manager_type manager_type;
963  	
964  	      // Note: it is extremely important that this initialization use
965  	      // static initialization. Otherwise, we will have a race
966  	      // condition here in multi-threaded code. See
967  	      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
968  	      static const vtable_type stored_vtable =
969  	        { { &manager_type::manage }, &invoker_type::invoke };
970  	
971  	      if (stored_vtable.assign_to_a(f, functor, a)) {
972  	        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
973  	        // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
974  	        if (boost::has_trivial_copy_constructor<Functor>::value &&
975  	            boost::has_trivial_destructor<Functor>::value &&
976  	            boost::detail::function::function_allows_small_object_optimization<Functor>::value)
977  	          value |= static_cast<std::size_t>(0x01);
978  	        vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
979  	      } else
980  	        vtable = 0;
981  	    }
982  	
983  	    // Moves the value from the specified argument to *this. If the argument
984  	    // has its function object allocated on the heap, move_assign will pass
985  	    // its buffer to *this, and set the argument's buffer pointer to NULL.
986  	    void move_assign(BOOST_FUNCTION_FUNCTION& f)
987  	    {
988  	      if (&f == this)
989  	        return;
990  	
991  	      BOOST_TRY {
992  	        if (!f.empty()) {
993  	          this->vtable = f.vtable;
994  	          if (this->has_trivial_copy_and_destroy())
995  	            this->functor = f.functor;
996  	          else
997  	            get_vtable()->base.manager(f.functor, this->functor,
998  	                                     boost::detail::function::move_functor_tag);
999  	          f.vtable = 0;
1000 	        } else {
1001 	          clear();
1002 	        }
1003 	      } BOOST_CATCH (...) {
1004 	        vtable = 0;
1005 	        BOOST_RETHROW;
1006 	      }
1007 	      BOOST_CATCH_END
1008 	    }
1009 	  };
1010 	
1011 	  template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1012 	  inline void swap(BOOST_FUNCTION_FUNCTION<
1013 	                     R BOOST_FUNCTION_COMMA
1014 	                     BOOST_FUNCTION_TEMPLATE_ARGS
1015 	                   >& f1,
1016 	                   BOOST_FUNCTION_FUNCTION<
1017 	                     R BOOST_FUNCTION_COMMA
1018 	                     BOOST_FUNCTION_TEMPLATE_ARGS
1019 	                   >& f2)
1020 	  {
1021 	    f1.swap(f2);
1022 	  }
1023 	
1024 	// Poison comparisons between boost::function objects of the same type.
1025 	template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1026 	  void operator==(const BOOST_FUNCTION_FUNCTION<
1027 	                          R BOOST_FUNCTION_COMMA
1028 	                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
1029 	                  const BOOST_FUNCTION_FUNCTION<
1030 	                          R BOOST_FUNCTION_COMMA
1031 	                          BOOST_FUNCTION_TEMPLATE_ARGS>&);
1032 	template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1033 	  void operator!=(const BOOST_FUNCTION_FUNCTION<
1034 	                          R BOOST_FUNCTION_COMMA
1035 	                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
1036 	                  const BOOST_FUNCTION_FUNCTION<
1037 	                          R BOOST_FUNCTION_COMMA
1038 	                          BOOST_FUNCTION_TEMPLATE_ARGS>& );
1039 	
1040 	#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
1041 	
1042 	#if BOOST_FUNCTION_NUM_ARGS == 0
1043 	#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
1044 	#else
1045 	#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
1046 	#endif
1047 	
1048 	template<typename R BOOST_FUNCTION_COMMA
1049 	         BOOST_FUNCTION_TEMPLATE_PARMS>
1050 	class function<BOOST_FUNCTION_PARTIAL_SPEC>
1051 	  : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
1052 	{
1053 	  typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
1054 	  typedef function self_type;
1055 	
1056 	  struct clear_type {};
1057 	
1058 	public:
1059 	
1060 	  function() : base_type() {}
1061 	
1062 	  template<typename Functor>
1063 	  function(Functor f
1064 	#ifndef BOOST_NO_SFINAE
1065 	           ,typename boost::enable_if_c<
1066 	                          !(is_integral<Functor>::value),
1067 	                       int>::type = 0
1068 	#endif
1069 	           ) :
1070 	    base_type(f)
1071 	  {
1072 	  }
1073 	  template<typename Functor,typename Allocator>
1074 	  function(Functor f, Allocator a
1075 	#ifndef BOOST_NO_SFINAE
1076 	           ,typename boost::enable_if_c<
1077 	                           !(is_integral<Functor>::value),
1078 	                       int>::type = 0
1079 	#endif
1080 	           ) :
1081 	    base_type(f,a)
1082 	  {
1083 	  }
1084 	
1085 	#ifndef BOOST_NO_SFINAE
1086 	  function(clear_type*) : base_type() {}
1087 	#endif
1088 	
1089 	  function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1090 	
1091 	  function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1092 	
1093 	#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1094 	  // Move constructors
1095 	  function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
1096 	  function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
1097 	#endif
1098 	
1099 	  self_type& operator=(const self_type& f)
1100 	  {
1101 	    self_type(f).swap(*this);
1102 	    return *this;
1103 	  }
1104 	
1105 	#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1106 	  self_type& operator=(self_type&& f)
1107 	  {
1108 	    self_type(static_cast<self_type&&>(f)).swap(*this);
1109 	    return *this;
1110 	  }
1111 	#endif
1112 	
1113 	  template<typename Functor>
1114 	#ifndef BOOST_NO_SFINAE
1115 	  typename boost::enable_if_c<
1116 	                         !(is_integral<Functor>::value),
1117 	                      self_type&>::type
1118 	#else
1119 	  self_type&
1120 	#endif
1121 	  operator=(Functor f)
1122 	  {
1123 	    self_type(f).swap(*this);
1124 	    return *this;
1125 	  }
1126 	
1127 	#ifndef BOOST_NO_SFINAE
1128 	  self_type& operator=(clear_type*)
1129 	  {
1130 	    this->clear();
1131 	    return *this;
1132 	  }
1133 	#endif
1134 	
1135 	  self_type& operator=(const base_type& f)
1136 	  {
1137 	    self_type(f).swap(*this);
1138 	    return *this;
1139 	  }
1140 	
1141 	#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1142 	  self_type& operator=(base_type&& f)
1143 	  {
1144 	    self_type(static_cast<base_type&&>(f)).swap(*this);
1145 	    return *this;
1146 	  }
1147 	#endif
1148 	};
1149 	
1150 	#undef BOOST_FUNCTION_PARTIAL_SPEC
1151 	#endif // have partial specialization
1152 	
1153 	} // end namespace boost
1154 	
1155 	// Cleanup after ourselves...
1156 	#undef BOOST_FUNCTION_VTABLE
1157 	#undef BOOST_FUNCTION_COMMA
1158 	#undef BOOST_FUNCTION_FUNCTION
1159 	#undef BOOST_FUNCTION_FUNCTION_INVOKER
1160 	#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1161 	#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1162 	#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1163 	#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
1164 	#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1165 	#undef BOOST_FUNCTION_MEMBER_INVOKER
1166 	#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
1167 	#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
1168 	#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1169 	#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1170 	#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1171 	#undef BOOST_FUNCTION_GET_INVOKER
1172 	#undef BOOST_FUNCTION_TEMPLATE_PARMS
1173 	#undef BOOST_FUNCTION_TEMPLATE_ARGS
1174 	#undef BOOST_FUNCTION_PARMS
1175 	#undef BOOST_FUNCTION_PARM
1176 	#ifdef BOOST_FUNCTION_ARG
1177 	#   undef BOOST_FUNCTION_ARG
1178 	#endif
1179 	#undef BOOST_FUNCTION_ARGS
1180 	#undef BOOST_FUNCTION_ARG_TYPE
1181 	#undef BOOST_FUNCTION_ARG_TYPES
1182 	#undef BOOST_FUNCTION_VOID_RETURN_TYPE
1183 	#undef BOOST_FUNCTION_RETURN
1184 	
1185 	#if defined(BOOST_MSVC)
1186 	#   pragma warning( pop )
1187 	#endif
1188