Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/function/function_template.hpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 25.7 KB
Line 
1// Boost.Function library
2
3//  Copyright Douglas Gregor 2001-2006. 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(BOOST_PP_CAT(arg, 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_FUNCTION_REF_INVOKER \
54  BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
55#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
56  BOOST_JOIN(void_function_ref_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_FUNCTION_REF_INVOKER \
62  BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
63#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
64
65#ifndef BOOST_NO_VOID_RETURNS
66#  define BOOST_FUNCTION_VOID_RETURN_TYPE void
67#  define BOOST_FUNCTION_RETURN(X) X
68#else
69#  define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
70#  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
71#endif
72
73#ifdef BOOST_MSVC
74#  pragma warning(push)
75#  pragma warning(disable: 4127) // conditional expression is constant.
76#endif
77
78#ifdef BOOST_MSVC
79#  pragma warning(push)
80#  pragma warning(disable: 4127) // conditional expression is constant.
81#endif
82
83namespace boost {
84  namespace detail {
85    namespace function {
86      template<
87        typename FunctionPtr,
88        typename R BOOST_FUNCTION_COMMA
89        BOOST_FUNCTION_TEMPLATE_PARMS
90        >
91      struct BOOST_FUNCTION_FUNCTION_INVOKER
92      {
93        static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
94                        BOOST_FUNCTION_PARMS)
95        {
96          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
97          return f(BOOST_FUNCTION_ARGS);
98        }
99      };
100
101      template<
102        typename FunctionPtr,
103        typename R BOOST_FUNCTION_COMMA
104        BOOST_FUNCTION_TEMPLATE_PARMS
105        >
106      struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
107      {
108        static BOOST_FUNCTION_VOID_RETURN_TYPE
109        invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
110               BOOST_FUNCTION_PARMS)
111
112        {
113          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
114          BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
115        }
116      };
117
118      template<
119        typename FunctionObj,
120        typename R BOOST_FUNCTION_COMMA
121        BOOST_FUNCTION_TEMPLATE_PARMS
122      >
123      struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
124      {
125        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
126                        BOOST_FUNCTION_PARMS)
127
128        {
129          FunctionObj* f;
130          if (function_allows_small_object_optimization<FunctionObj>::value)
131            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
132          else
133            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
134          return (*f)(BOOST_FUNCTION_ARGS);
135        }
136      };
137
138      template<
139        typename FunctionObj,
140        typename R BOOST_FUNCTION_COMMA
141        BOOST_FUNCTION_TEMPLATE_PARMS
142      >
143      struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
144      {
145        static BOOST_FUNCTION_VOID_RETURN_TYPE
146        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
147               BOOST_FUNCTION_PARMS)
148
149        {
150          FunctionObj* f;
151          if (function_allows_small_object_optimization<FunctionObj>::value)
152            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
153          else
154            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
155          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
156        }
157      };
158
159      template<
160        typename FunctionObj,
161        typename R BOOST_FUNCTION_COMMA
162        BOOST_FUNCTION_TEMPLATE_PARMS
163      >
164      struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
165      {
166        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
167                        BOOST_FUNCTION_PARMS)
168
169        {
170          FunctionObj* f = 
171            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
172          return (*f)(BOOST_FUNCTION_ARGS);
173        }
174      };
175
176      template<
177        typename FunctionObj,
178        typename R BOOST_FUNCTION_COMMA
179        BOOST_FUNCTION_TEMPLATE_PARMS
180      >
181      struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
182      {
183        static BOOST_FUNCTION_VOID_RETURN_TYPE
184        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
185               BOOST_FUNCTION_PARMS)
186
187        {
188          FunctionObj* f = 
189            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
190          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
191        }
192      };
193
194      template<
195        typename FunctionPtr,
196        typename R BOOST_FUNCTION_COMMA
197        BOOST_FUNCTION_TEMPLATE_PARMS
198      >
199      struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
200      {
201        typedef typename mpl::if_c<(is_void<R>::value),
202                            BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
203                            FunctionPtr,
204                            R BOOST_FUNCTION_COMMA
205                            BOOST_FUNCTION_TEMPLATE_ARGS
206                          >,
207                          BOOST_FUNCTION_FUNCTION_INVOKER<
208                            FunctionPtr,
209                            R BOOST_FUNCTION_COMMA
210                            BOOST_FUNCTION_TEMPLATE_ARGS
211                          >
212                       >::type type;
213      };
214
215      template<
216        typename FunctionObj,
217        typename R BOOST_FUNCTION_COMMA
218        BOOST_FUNCTION_TEMPLATE_PARMS
219       >
220      struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
221      {
222        typedef typename mpl::if_c<(is_void<R>::value),
223                            BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
224                            FunctionObj,
225                            R BOOST_FUNCTION_COMMA
226                            BOOST_FUNCTION_TEMPLATE_ARGS
227                          >,
228                          BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
229                            FunctionObj,
230                            R BOOST_FUNCTION_COMMA
231                            BOOST_FUNCTION_TEMPLATE_ARGS
232                          >
233                       >::type type;
234      };
235
236      template<
237        typename FunctionObj,
238        typename R BOOST_FUNCTION_COMMA
239        BOOST_FUNCTION_TEMPLATE_PARMS
240       >
241      struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
242      {
243        typedef typename mpl::if_c<(is_void<R>::value),
244                            BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
245                            FunctionObj,
246                            R BOOST_FUNCTION_COMMA
247                            BOOST_FUNCTION_TEMPLATE_ARGS
248                          >,
249                          BOOST_FUNCTION_FUNCTION_REF_INVOKER<
250                            FunctionObj,
251                            R BOOST_FUNCTION_COMMA
252                            BOOST_FUNCTION_TEMPLATE_ARGS
253                          >
254                       >::type type;
255      };
256
257      /**
258       * vtable for a specific boost::function instance.
259       */
260      template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
261               typename Allocator>
262      struct BOOST_FUNCTION_VTABLE : vtable_base
263      {
264#ifndef BOOST_NO_VOID_RETURNS
265        typedef R         result_type;
266#else
267        typedef typename function_return_type<R>::type result_type;
268#endif // BOOST_NO_VOID_RETURNS
269
270        typedef result_type (*invoker_type)(function_buffer&
271                                            BOOST_FUNCTION_COMMA
272                                            BOOST_FUNCTION_TEMPLATE_ARGS);
273
274        template<typename F>
275        BOOST_FUNCTION_VTABLE(F f) : vtable_base(), invoker(0)
276        {
277          init(f);
278        }
279
280        template<typename F>
281        bool assign_to(F f, function_buffer& functor)
282        {
283          typedef typename get_function_tag<F>::type tag;
284          return assign_to(f, functor, tag());
285        }
286
287        void clear(function_buffer& functor)
288        {
289          if (manager)
290            manager(functor, functor, destroy_functor_tag);
291        }
292
293      private:
294        template<typename F>
295        void init(F f)
296        {
297          typedef typename get_function_tag<F>::type tag;
298          init(f, tag());
299        }
300
301        // Function pointers
302        template<typename FunctionPtr>
303        void init(FunctionPtr /*f*/, function_ptr_tag)
304        {
305          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
306                             FunctionPtr,
307                             R BOOST_FUNCTION_COMMA
308                             BOOST_FUNCTION_TEMPLATE_ARGS
309                           >::type
310            actual_invoker_type;
311
312          invoker = &actual_invoker_type::invoke;
313          manager = &functor_manager<FunctionPtr, Allocator>::manage;
314        }
315
316        template<typename FunctionPtr>
317        bool 
318        assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
319        {
320          this->clear(functor);
321          if (f) {
322            // should be a reinterpret cast, but some compilers insist
323            // on giving cv-qualifiers to free functions
324            functor.func_ptr = (void (*)())(f);
325            return true;
326          } else {
327            return false;
328          }
329        }
330
331        // Member pointers
332#if BOOST_FUNCTION_NUM_ARGS > 0
333        template<typename MemberPtr>
334        void init(MemberPtr f, member_ptr_tag)
335        {
336          // DPG TBD: Add explicit support for member function
337          // objects, so we invoke through mem_fn() but we retain the
338          // right target_type() values.
339          this->init(mem_fn(f));
340        }
341
342        template<typename MemberPtr>
343        bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
344        {
345          // DPG TBD: Add explicit support for member function
346          // objects, so we invoke through mem_fn() but we retain the
347          // right target_type() values.
348          if (f) {
349            this->assign_to(mem_fn(f), functor);
350            return true;
351          } else {
352            return false;
353          }
354        }
355#endif // BOOST_FUNCTION_NUM_ARGS > 0
356
357        // Function objects
358        template<typename FunctionObj>
359        void init(FunctionObj /*f*/, function_obj_tag)
360        {
361          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
362                             FunctionObj,
363                             R BOOST_FUNCTION_COMMA
364                             BOOST_FUNCTION_TEMPLATE_ARGS
365                           >::type
366            actual_invoker_type;
367
368          invoker = &actual_invoker_type::invoke;
369          manager = &functor_manager<FunctionObj, Allocator>::manage;
370        }
371
372        // Assign to a function object using the small object optimization
373        template<typename FunctionObj>
374        void 
375        assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
376        {
377          new ((void*)&functor.data) FunctionObj(f);
378        }
379
380        // Assign to a function object allocated on the heap.
381        template<typename FunctionObj>
382        void 
383        assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
384        {
385#ifndef BOOST_NO_STD_ALLOCATOR
386          typedef typename Allocator::template rebind<FunctionObj>::other
387            allocator_type;
388          typedef typename allocator_type::pointer pointer_type;
389
390          allocator_type allocator;
391          pointer_type copy = allocator.allocate(1);
392          allocator.construct(copy, f);
393
394          // Get back to the original pointer type
395          functor.obj_ptr = static_cast<FunctionObj*>(copy);
396#  else
397          functor.obj_ptr = new FunctionObj(f);
398#  endif // BOOST_NO_STD_ALLOCATOR
399        }
400
401        template<typename FunctionObj>
402        bool 
403        assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
404        {
405          if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
406            assign_functor(f, functor, 
407                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
408            return true;
409          } else {
410            return false;
411          }
412        }
413
414        // Reference to a function object
415        template<typename FunctionObj>
416        void 
417        init(const reference_wrapper<FunctionObj>& /*f*/, function_obj_ref_tag)
418        {
419          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
420                             FunctionObj,
421                             R BOOST_FUNCTION_COMMA
422                             BOOST_FUNCTION_TEMPLATE_ARGS
423                           >::type
424            actual_invoker_type;
425
426          invoker = &actual_invoker_type::invoke;
427          manager = &reference_manager<FunctionObj>::get;
428        }
429
430        template<typename FunctionObj>
431        bool 
432        assign_to(const reference_wrapper<FunctionObj>& f, 
433                  function_buffer& functor, function_obj_ref_tag)
434        {
435          if (!boost::detail::function::has_empty_target(f.get_pointer())) {
436            // DPG TBD: We might need to detect constness of
437            // FunctionObj to assign into obj_ptr or const_obj_ptr to
438            // be truly legit, but no platform in existence makes
439            // const void* different from void*.
440            functor.const_obj_ptr = f.get_pointer();
441            return true;
442          } else {
443            return false;
444          }
445        }
446
447      public:
448        invoker_type invoker;
449      };
450    } // end namespace function
451  } // end namespace detail
452
453  template<
454    typename R BOOST_FUNCTION_COMMA
455    BOOST_FUNCTION_TEMPLATE_PARMS,
456    typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
457  >
458  class BOOST_FUNCTION_FUNCTION : public function_base
459  {
460  public:
461#ifndef BOOST_NO_VOID_RETURNS
462    typedef R         result_type;
463#else
464    typedef  typename boost::detail::function::function_return_type<R>::type
465      result_type;
466#endif // BOOST_NO_VOID_RETURNS
467
468  private:
469    typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
470              R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS, Allocator>
471      vtable_type;
472
473    struct clear_type {};
474
475  public:
476    BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
477
478    // add signature for boost::lambda
479    template<typename Args>
480    struct sig
481    {
482      typedef result_type type;
483    };
484
485#if BOOST_FUNCTION_NUM_ARGS == 1
486    typedef T0 argument_type;
487#elif BOOST_FUNCTION_NUM_ARGS == 2
488    typedef T0 first_argument_type;
489    typedef T1 second_argument_type;
490#endif
491
492    BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
493    BOOST_FUNCTION_ARG_TYPES
494
495    typedef Allocator allocator_type;
496    typedef BOOST_FUNCTION_FUNCTION self_type;
497
498    BOOST_FUNCTION_FUNCTION() : function_base() { }
499
500    // MSVC chokes if the following two constructors are collapsed into
501    // one with a default parameter.
502    template<typename Functor>
503    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
504#ifndef BOOST_NO_SFINAE
505                            ,typename enable_if_c<
506                            (boost::type_traits::ice_not<
507                             (is_integral<Functor>::value)>::value),
508                                        int>::type = 0
509#endif // BOOST_NO_SFINAE
510                            ) :
511      function_base()
512    {
513      this->assign_to(f);
514    }
515
516#ifndef BOOST_NO_SFINAE
517    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
518#else
519    BOOST_FUNCTION_FUNCTION(int zero) : function_base()
520    {
521      BOOST_ASSERT(zero == 0);
522    }
523#endif
524
525    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
526    {
527      this->assign_to_own(f);
528    }
529
530    ~BOOST_FUNCTION_FUNCTION() { clear(); }
531
532#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
533    // MSVC 6.0 and prior require all definitions to be inline, but
534    // these definitions can become very costly.
535    result_type operator()(BOOST_FUNCTION_PARMS) const
536    {
537      if (this->empty())
538        boost::throw_exception(bad_function_call());
539
540      return static_cast<vtable_type*>(vtable)->invoker
541               (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
542    }
543#else
544    result_type operator()(BOOST_FUNCTION_PARMS) const;
545#endif
546
547    // The distinction between when to use BOOST_FUNCTION_FUNCTION and
548    // when to use self_type is obnoxious. MSVC cannot handle self_type as
549    // the return type of these assignment operators, but Borland C++ cannot
550    // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
551    // construct.
552    template<typename Functor>
553#ifndef BOOST_NO_SFINAE
554    typename enable_if_c<
555               (boost::type_traits::ice_not<
556                 (is_integral<Functor>::value)>::value),
557               BOOST_FUNCTION_FUNCTION&>::type
558#else
559    BOOST_FUNCTION_FUNCTION&
560#endif
561    operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
562    {
563      this->clear();
564      try {
565        this->assign_to(f);
566      } catch (...) {
567        vtable = 0;
568        throw;
569      }
570      return *this;
571    }
572
573#ifndef BOOST_NO_SFINAE
574    BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
575    {
576      this->clear();
577      return *this;
578    }
579#else
580    BOOST_FUNCTION_FUNCTION& operator=(int zero)
581    {
582      BOOST_ASSERT(zero == 0);
583      this->clear();
584      return *this;
585    }
586#endif
587
588    // Assignment from another BOOST_FUNCTION_FUNCTION
589    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
590    {
591      if (&f == this)
592        return *this;
593
594      this->clear();
595      try {
596        this->assign_to_own(f);
597      } catch (...) {
598        vtable = 0;
599        throw;
600      }
601      return *this;
602    }
603
604    void swap(BOOST_FUNCTION_FUNCTION& other)
605    {
606      if (&other == this)
607        return;
608
609      BOOST_FUNCTION_FUNCTION tmp = *this;
610      *this = other;
611      other = tmp;
612    }
613
614    // Clear out a target, if there is one
615    void clear()
616    {
617      if (vtable) {
618        static_cast<vtable_type*>(vtable)->clear(this->functor);
619        vtable = 0;
620      }
621    }
622
623#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
624    // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
625    operator bool () const { return !this->empty(); }
626#else
627  private:
628    struct dummy {
629      void nonnull() {};
630    };
631
632    typedef void (dummy::*safe_bool)();
633
634  public:
635    operator safe_bool () const
636      { return (this->empty())? 0 : &dummy::nonnull; }
637
638    bool operator!() const
639      { return this->empty(); }
640#endif
641
642  private:
643    void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
644    {
645      if (!f.empty()) {
646        this->vtable = f.vtable;
647        f.vtable->manager(f.functor, this->functor,
648                          boost::detail::function::clone_functor_tag);
649      }
650    }
651
652    template<typename Functor>
653    void assign_to(Functor f)
654    {
655      static vtable_type stored_vtable(f);
656      if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable;
657      else vtable = 0;
658    }
659  };
660
661  template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
662           typename Allocator>
663  inline void swap(BOOST_FUNCTION_FUNCTION<
664                     R BOOST_FUNCTION_COMMA
665                     BOOST_FUNCTION_TEMPLATE_ARGS ,
666                     Allocator
667                   >& f1,
668                   BOOST_FUNCTION_FUNCTION<
669                     R BOOST_FUNCTION_COMMA
670                     BOOST_FUNCTION_TEMPLATE_ARGS,
671                     Allocator
672                   >& f2)
673  {
674    f1.swap(f2);
675  }
676
677#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
678  template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
679           typename Allocator>
680  typename BOOST_FUNCTION_FUNCTION<
681      R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS,
682      Allocator>::result_type
683   BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS,
684
685                           Allocator>
686  ::operator()(BOOST_FUNCTION_PARMS) const
687  {
688    if (this->empty())
689      boost::throw_exception(bad_function_call());
690
691    return static_cast<vtable_type*>(vtable)->invoker
692             (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
693  }
694#endif
695
696// Poison comparisons between boost::function objects of the same type.
697template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
698         typename Allocator>
699  void operator==(const BOOST_FUNCTION_FUNCTION<
700                          R BOOST_FUNCTION_COMMA
701                          BOOST_FUNCTION_TEMPLATE_ARGS ,
702                          Allocator>&,
703                  const BOOST_FUNCTION_FUNCTION<
704                          R BOOST_FUNCTION_COMMA
705                          BOOST_FUNCTION_TEMPLATE_ARGS ,
706                  Allocator>&);
707template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
708         typename Allocator>
709  void operator!=(const BOOST_FUNCTION_FUNCTION<
710                          R BOOST_FUNCTION_COMMA
711                          BOOST_FUNCTION_TEMPLATE_ARGS ,
712                          Allocator>&,
713                  const BOOST_FUNCTION_FUNCTION<
714                          R BOOST_FUNCTION_COMMA
715                          BOOST_FUNCTION_TEMPLATE_ARGS ,
716                  Allocator>&);
717
718#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
719
720#if BOOST_FUNCTION_NUM_ARGS == 0
721#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
722#else
723#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
724#endif
725
726template<typename R BOOST_FUNCTION_COMMA
727         BOOST_FUNCTION_TEMPLATE_PARMS,
728         typename Allocator>
729class function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>
730  : public BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
731                                   BOOST_FUNCTION_COMMA Allocator>
732{
733  typedef BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
734                                  BOOST_FUNCTION_COMMA Allocator> base_type;
735  typedef function self_type;
736
737  struct clear_type {};
738
739public:
740  typedef typename base_type::allocator_type allocator_type;
741
742  function() : base_type() {}
743
744  template<typename Functor>
745  function(Functor f
746#ifndef BOOST_NO_SFINAE
747           ,typename enable_if_c<
748                            (boost::type_traits::ice_not<
749                          (is_integral<Functor>::value)>::value),
750                       int>::type = 0
751#endif
752           ) :
753    base_type(f)
754  {
755  }
756
757#ifndef BOOST_NO_SFINAE
758  function(clear_type*) : base_type() {}
759#endif
760
761  function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
762
763  function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
764
765  self_type& operator=(const self_type& f)
766  {
767    self_type(f).swap(*this);
768    return *this;
769  }
770
771  template<typename Functor>
772#ifndef BOOST_NO_SFINAE
773  typename enable_if_c<
774                            (boost::type_traits::ice_not<
775                         (is_integral<Functor>::value)>::value),
776                      self_type&>::type
777#else
778  self_type&
779#endif
780  operator=(Functor f)
781  {
782    self_type(f).swap(*this);
783    return *this;
784  }
785
786#ifndef BOOST_NO_SFINAE
787  self_type& operator=(clear_type*)
788  {
789    this->clear();
790    return *this;
791  }
792#endif
793
794  self_type& operator=(const base_type& f)
795  {
796    self_type(f).swap(*this);
797    return *this;
798  }
799};
800
801#ifdef BOOST_MSVC
802# pragma warning(pop)
803#endif
804
805#undef BOOST_FUNCTION_PARTIAL_SPEC
806#endif // have partial specialization
807
808} // end namespace boost
809
810#ifdef BOOST_MSVC
811# pragma warning(pop)
812#endif
813
814// Cleanup after ourselves...
815#undef BOOST_FUNCTION_VTABLE
816#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
817#undef BOOST_FUNCTION_COMMA
818#undef BOOST_FUNCTION_FUNCTION
819#undef BOOST_FUNCTION_FUNCTION_INVOKER
820#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
821#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
822#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
823#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
824#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
825#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
826#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
827#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
828#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
829#undef BOOST_FUNCTION_TEMPLATE_PARMS
830#undef BOOST_FUNCTION_TEMPLATE_ARGS
831#undef BOOST_FUNCTION_PARMS
832#undef BOOST_FUNCTION_PARM
833#undef BOOST_FUNCTION_ARGS
834#undef BOOST_FUNCTION_ARG_TYPE
835#undef BOOST_FUNCTION_ARG_TYPES
836#undef BOOST_FUNCTION_VOID_RETURN_TYPE
837#undef BOOST_FUNCTION_RETURN
Note: See TracBrowser for help on using the repository browser.