]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/function/function_template.hpp
Logo AND Algorithmique Numérique Distribuée

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