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