source: NonGTP/Boost/boost/function/function_template.hpp @ 857

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