// Boost.Function library

//  Copyright Douglas Gregor 2001-2006
//  Copyright Emil Dotchevski 2007
//  Use, modification and distribution is subject to the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

// For more information, see http://www.boost.org

// Note: this header is a header template and must NOT have multiple-inclusion
// protection.
#include <ndnboost/function/detail/prologue.hpp>
#include <ndnboost/detail/no_exceptions_support.hpp>

#if defined(NDNBOOST_MSVC)
#   pragma warning( push )
#   pragma warning( disable : 4127 ) // "conditional expression is constant"
#endif       

#define NDNBOOST_FUNCTION_TEMPLATE_PARMS NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS, typename T)

#define NDNBOOST_FUNCTION_TEMPLATE_ARGS NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS, T)

#define NDNBOOST_FUNCTION_PARM(J,I,D) NDNBOOST_PP_CAT(T,I) NDNBOOST_PP_CAT(a,I)

#define NDNBOOST_FUNCTION_PARMS NDNBOOST_PP_ENUM(NDNBOOST_FUNCTION_NUM_ARGS,NDNBOOST_FUNCTION_PARM,NDNBOOST_PP_EMPTY)

#define NDNBOOST_FUNCTION_ARGS NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS, a)

#define NDNBOOST_FUNCTION_ARG_TYPE(J,I,D) \
  typedef NDNBOOST_PP_CAT(T,I) NDNBOOST_PP_CAT(NDNBOOST_PP_CAT(arg, NDNBOOST_PP_INC(I)),_type);

#define NDNBOOST_FUNCTION_ARG_TYPES NDNBOOST_PP_REPEAT(NDNBOOST_FUNCTION_NUM_ARGS,NDNBOOST_FUNCTION_ARG_TYPE,NDNBOOST_PP_EMPTY)

// Comma if nonzero number of arguments
#if NDNBOOST_FUNCTION_NUM_ARGS == 0
#  define NDNBOOST_FUNCTION_COMMA
#else
#  define NDNBOOST_FUNCTION_COMMA ,
#endif // NDNBOOST_FUNCTION_NUM_ARGS > 0

// Class names used in this version of the code
#define NDNBOOST_FUNCTION_FUNCTION NDNBOOST_JOIN(function,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_FUNCTION_INVOKER \
  NDNBOOST_JOIN(function_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER \
  NDNBOOST_JOIN(void_function_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
  NDNBOOST_JOIN(function_obj_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
  NDNBOOST_JOIN(void_function_obj_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER \
  NDNBOOST_JOIN(function_ref_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
  NDNBOOST_JOIN(void_function_ref_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_MEMBER_INVOKER \
  NDNBOOST_JOIN(function_mem_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER \
  NDNBOOST_JOIN(function_void_mem_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER \
  NDNBOOST_JOIN(get_function_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
  NDNBOOST_JOIN(get_function_obj_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
  NDNBOOST_JOIN(get_function_ref_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_GET_MEMBER_INVOKER \
  NDNBOOST_JOIN(get_member_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_GET_INVOKER \
  NDNBOOST_JOIN(get_invoker,NDNBOOST_FUNCTION_NUM_ARGS)
#define NDNBOOST_FUNCTION_VTABLE NDNBOOST_JOIN(basic_vtable,NDNBOOST_FUNCTION_NUM_ARGS)

#ifndef NDNBOOST_NO_VOID_RETURNS
#  define NDNBOOST_FUNCTION_VOID_RETURN_TYPE void
#  define NDNBOOST_FUNCTION_RETURN(X) X
#else
#  define NDNBOOST_FUNCTION_VOID_RETURN_TYPE ndnboost::detail::function::unusable
#  define NDNBOOST_FUNCTION_RETURN(X) X; return NDNBOOST_FUNCTION_VOID_RETURN_TYPE ()
#endif

namespace ndnboost {
  namespace detail {
    namespace function {
      template<
        typename FunctionPtr,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
        >
      struct NDNBOOST_FUNCTION_FUNCTION_INVOKER
      {
        static R invoke(function_buffer& function_ptr NDNBOOST_FUNCTION_COMMA
                        NDNBOOST_FUNCTION_PARMS)
        {
          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
          return f(NDNBOOST_FUNCTION_ARGS);
        }
      };

      template<
        typename FunctionPtr,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
        >
      struct NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER
      {
        static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
        invoke(function_buffer& function_ptr NDNBOOST_FUNCTION_COMMA
               NDNBOOST_FUNCTION_PARMS)

        {
          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
          NDNBOOST_FUNCTION_RETURN(f(NDNBOOST_FUNCTION_ARGS));
        }
      };

      template<
        typename FunctionObj,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
      >
      struct NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER
      {
        static R invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
                        NDNBOOST_FUNCTION_PARMS)

        {
          FunctionObj* f;
          if (function_allows_small_object_optimization<FunctionObj>::value)
            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
          else
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
          return (*f)(NDNBOOST_FUNCTION_ARGS);
        }
      };

      template<
        typename FunctionObj,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
      >
      struct NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
      {
        static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
        invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
               NDNBOOST_FUNCTION_PARMS)

        {
          FunctionObj* f;
          if (function_allows_small_object_optimization<FunctionObj>::value)
            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
          else
            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
          NDNBOOST_FUNCTION_RETURN((*f)(NDNBOOST_FUNCTION_ARGS));
        }
      };

      template<
        typename FunctionObj,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
      >
      struct NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER
      {
        static R invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
                        NDNBOOST_FUNCTION_PARMS)

        {
          FunctionObj* f = 
            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
          return (*f)(NDNBOOST_FUNCTION_ARGS);
        }
      };

      template<
        typename FunctionObj,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
      >
      struct NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
      {
        static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
        invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
               NDNBOOST_FUNCTION_PARMS)

        {
          FunctionObj* f = 
            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
          NDNBOOST_FUNCTION_RETURN((*f)(NDNBOOST_FUNCTION_ARGS));
        }
      };

#if NDNBOOST_FUNCTION_NUM_ARGS > 0
      /* Handle invocation of member pointers. */
      template<
        typename MemberPtr,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
      >
      struct NDNBOOST_FUNCTION_MEMBER_INVOKER
      {
        static R invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
                        NDNBOOST_FUNCTION_PARMS)

        {
          MemberPtr* f = 
            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
          return ndnboost::mem_fn(*f)(NDNBOOST_FUNCTION_ARGS);
        }
      };

      template<
        typename MemberPtr,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
      >
      struct NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER
      {
        static NDNBOOST_FUNCTION_VOID_RETURN_TYPE
        invoke(function_buffer& function_obj_ptr NDNBOOST_FUNCTION_COMMA
               NDNBOOST_FUNCTION_PARMS)

        {
          MemberPtr* f = 
            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
          NDNBOOST_FUNCTION_RETURN(ndnboost::mem_fn(*f)(NDNBOOST_FUNCTION_ARGS));
        }
      };
#endif

      template<
        typename FunctionPtr,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
      >
      struct NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER
      {
        typedef typename mpl::if_c<(is_void<R>::value),
                            NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER<
                            FunctionPtr,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >,
                          NDNBOOST_FUNCTION_FUNCTION_INVOKER<
                            FunctionPtr,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >
                       >::type type;
      };

      template<
        typename FunctionObj,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
       >
      struct NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
      {
        typedef typename mpl::if_c<(is_void<R>::value),
                            NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
                            FunctionObj,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >,
                          NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
                            FunctionObj,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >
                       >::type type;
      };

      template<
        typename FunctionObj,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
       >
      struct NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
      {
        typedef typename mpl::if_c<(is_void<R>::value),
                            NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
                            FunctionObj,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >,
                          NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER<
                            FunctionObj,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >
                       >::type type;
      };

#if NDNBOOST_FUNCTION_NUM_ARGS > 0
      /* Retrieve the appropriate invoker for a member pointer.  */
      template<
        typename MemberPtr,
        typename R NDNBOOST_FUNCTION_COMMA
        NDNBOOST_FUNCTION_TEMPLATE_PARMS
       >
      struct NDNBOOST_FUNCTION_GET_MEMBER_INVOKER
      {
        typedef typename mpl::if_c<(is_void<R>::value),
                            NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER<
                            MemberPtr,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >,
                          NDNBOOST_FUNCTION_MEMBER_INVOKER<
                            MemberPtr,
                            R NDNBOOST_FUNCTION_COMMA
                            NDNBOOST_FUNCTION_TEMPLATE_ARGS
                          >
                       >::type type;
      };
#endif

      /* Given the tag returned by get_function_tag, retrieve the
         actual invoker that will be used for the given function
         object. 

         Each specialization contains an "apply" nested class template
         that accepts the function object, return type, function
         argument types, and allocator. The resulting "apply" class
         contains two typedefs, "invoker_type" and "manager_type",
         which correspond to the invoker and manager types. */
      template<typename Tag>
      struct NDNBOOST_FUNCTION_GET_INVOKER { };

      /* Retrieve the invoker for a function pointer. */
      template<>
      struct NDNBOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
      {
        template<typename FunctionPtr,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
        struct apply
        {
          typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER<
                             FunctionPtr,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef functor_manager<FunctionPtr> manager_type;
        };

        template<typename FunctionPtr,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
                 typename Allocator>
        struct apply_a
        {
          typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER<
                             FunctionPtr,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef functor_manager<FunctionPtr> manager_type;
        };
      };

#if NDNBOOST_FUNCTION_NUM_ARGS > 0
      /* Retrieve the invoker for a member pointer. */
      template<>
      struct NDNBOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
      {
        template<typename MemberPtr,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
        struct apply
        {
          typedef typename NDNBOOST_FUNCTION_GET_MEMBER_INVOKER<
                             MemberPtr,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef functor_manager<MemberPtr> manager_type;
        };

        template<typename MemberPtr,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
                 typename Allocator>
        struct apply_a
        {
          typedef typename NDNBOOST_FUNCTION_GET_MEMBER_INVOKER<
                             MemberPtr,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef functor_manager<MemberPtr> manager_type;
        };
      };
#endif

      /* Retrieve the invoker for a function object. */
      template<>
      struct NDNBOOST_FUNCTION_GET_INVOKER<function_obj_tag>
      {
        template<typename FunctionObj,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
        struct apply
        {
          typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
                             FunctionObj,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef functor_manager<FunctionObj> manager_type;
        };

        template<typename FunctionObj,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
                 typename Allocator>
        struct apply_a
        {
          typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
                             FunctionObj,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef functor_manager_a<FunctionObj, Allocator> manager_type;
        };
      };

      /* Retrieve the invoker for a reference to a function object. */
      template<>
      struct NDNBOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
      {
        template<typename RefWrapper,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
        struct apply
        {
          typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
                             typename RefWrapper::type,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef reference_manager<typename RefWrapper::type> manager_type;
        };

        template<typename RefWrapper,
                 typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS,
                 typename Allocator>
        struct apply_a
        {
          typedef typename NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
                             typename RefWrapper::type,
                             R NDNBOOST_FUNCTION_COMMA
                             NDNBOOST_FUNCTION_TEMPLATE_ARGS
                           >::type
            invoker_type;

          typedef reference_manager<typename RefWrapper::type> manager_type;
        };
      };


      /**
       * vtable for a specific ndnboost::function instance. This
       * structure must be an aggregate so that we can use static
       * initialization in ndnboost::function's assign_to and assign_to_a
       * members. It therefore cannot have any constructors,
       * destructors, base classes, etc.
       */
      template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
      struct NDNBOOST_FUNCTION_VTABLE
      {
#ifndef NDNBOOST_NO_VOID_RETURNS
        typedef R         result_type;
#else
        typedef typename function_return_type<R>::type result_type;
#endif // NDNBOOST_NO_VOID_RETURNS

        typedef result_type (*invoker_type)(function_buffer&
                                            NDNBOOST_FUNCTION_COMMA
                                            NDNBOOST_FUNCTION_TEMPLATE_ARGS);

        template<typename F>
        bool assign_to(F f, function_buffer& functor) const
        {
          typedef typename get_function_tag<F>::type tag;
          return assign_to(f, functor, tag());
        }
        template<typename F,typename Allocator>
        bool assign_to_a(F f, function_buffer& functor, Allocator a) const
        {
          typedef typename get_function_tag<F>::type tag;
          return assign_to_a(f, functor, a, tag());
        }

        void clear(function_buffer& functor) const
        {
          if (base.manager)
            base.manager(functor, functor, destroy_functor_tag);
        }

      private:
        // Function pointers
        template<typename FunctionPtr>
        bool 
        assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
        {
          this->clear(functor);
          if (f) {
            // should be a reinterpret cast, but some compilers insist
            // on giving cv-qualifiers to free functions
            functor.func_ptr = reinterpret_cast<void (*)()>(f);
            return true;
          } else {
            return false;
          }
        }
        template<typename FunctionPtr,typename Allocator>
        bool 
        assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
        {
          return assign_to(f,functor,function_ptr_tag());
        }

        // Member pointers
#if NDNBOOST_FUNCTION_NUM_ARGS > 0
        template<typename MemberPtr>
        bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
        {
          // DPG TBD: Add explicit support for member function
          // objects, so we invoke through mem_fn() but we retain the
          // right target_type() values.
          if (f) {
            this->assign_to(ndnboost::mem_fn(f), functor);
            return true;
          } else {
            return false;
          }
        }
        template<typename MemberPtr,typename Allocator>
        bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
        {
          // DPG TBD: Add explicit support for member function
          // objects, so we invoke through mem_fn() but we retain the
          // right target_type() values.
          if (f) {
            this->assign_to_a(ndnboost::mem_fn(f), functor, a);
            return true;
          } else {
            return false;
          }
        }
#endif // NDNBOOST_FUNCTION_NUM_ARGS > 0

        // Function objects
        // Assign to a function object using the small object optimization
        template<typename FunctionObj>
        void 
        assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const
        {
          new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f);
        }
        template<typename FunctionObj,typename Allocator>
        void 
        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const
        {
          assign_functor(f,functor,mpl::true_());
        }

        // Assign to a function object allocated on the heap.
        template<typename FunctionObj>
        void 
        assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const
        {
          functor.obj_ptr = new FunctionObj(f);
        }
        template<typename FunctionObj,typename Allocator>
        void 
        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const
        {
          typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
          typedef typename Allocator::template rebind<functor_wrapper_type>::other
            wrapper_allocator_type;
          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
          wrapper_allocator_type wrapper_allocator(a);
          wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
          wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
          functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
          functor.obj_ptr = new_f;
        }

        template<typename FunctionObj>
        bool 
        assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
        {
          if (!ndnboost::detail::function::has_empty_target(ndnboost::addressof(f))) {
            assign_functor(f, functor, 
                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
            return true;
          } else {
            return false;
          }
        }
        template<typename FunctionObj,typename Allocator>
        bool 
        assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
        {
          if (!ndnboost::detail::function::has_empty_target(ndnboost::addressof(f))) {
            assign_functor_a(f, functor, a,
                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
            return true;
          } else {
            return false;
          }
        }

        // Reference to a function object
        template<typename FunctionObj>
        bool 
        assign_to(const reference_wrapper<FunctionObj>& f, 
                  function_buffer& functor, function_obj_ref_tag) const
        {
          functor.obj_ref.obj_ptr = (void *)(f.get_pointer());
          functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
          functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
          return true;
        }
        template<typename FunctionObj,typename Allocator>
        bool 
        assign_to_a(const reference_wrapper<FunctionObj>& f, 
                  function_buffer& functor, Allocator, function_obj_ref_tag) const
        {
          return assign_to(f,functor,function_obj_ref_tag());
        }

      public:
        vtable_base base;
        invoker_type invoker;
      };
    } // end namespace function
  } // end namespace detail

  template<
    typename R NDNBOOST_FUNCTION_COMMA
    NDNBOOST_FUNCTION_TEMPLATE_PARMS
  >
  class NDNBOOST_FUNCTION_FUNCTION : public function_base

#if NDNBOOST_FUNCTION_NUM_ARGS == 1

    , public std::unary_function<T0,R>

#elif NDNBOOST_FUNCTION_NUM_ARGS == 2

    , public std::binary_function<T0,T1,R>

#endif

  {
  public:
#ifndef NDNBOOST_NO_VOID_RETURNS
    typedef R         result_type;
#else
    typedef  typename ndnboost::detail::function::function_return_type<R>::type
      result_type;
#endif // NDNBOOST_NO_VOID_RETURNS

  private:
    typedef ndnboost::detail::function::NDNBOOST_FUNCTION_VTABLE<
              R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_ARGS>
      vtable_type;

    vtable_type* get_vtable() const {
      return reinterpret_cast<vtable_type*>(
               reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
    }

    struct clear_type {};

  public:
    NDNBOOST_STATIC_CONSTANT(int, args = NDNBOOST_FUNCTION_NUM_ARGS);

    // add signature for ndnboost::lambda
    template<typename Args>
    struct sig
    {
      typedef result_type type;
    };

#if NDNBOOST_FUNCTION_NUM_ARGS == 1
    typedef T0 argument_type;
#elif NDNBOOST_FUNCTION_NUM_ARGS == 2
    typedef T0 first_argument_type;
    typedef T1 second_argument_type;
#endif

    NDNBOOST_STATIC_CONSTANT(int, arity = NDNBOOST_FUNCTION_NUM_ARGS);
    NDNBOOST_FUNCTION_ARG_TYPES

    typedef NDNBOOST_FUNCTION_FUNCTION self_type;

    NDNBOOST_FUNCTION_FUNCTION() : function_base() { }

    // MSVC chokes if the following two constructors are collapsed into
    // one with a default parameter.
    template<typename Functor>
    NDNBOOST_FUNCTION_FUNCTION(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f
#ifndef NDNBOOST_NO_SFINAE
                            ,typename enable_if_c<
                            (ndnboost::type_traits::ice_not<
                             (is_integral<Functor>::value)>::value),
                                        int>::type = 0
#endif // NDNBOOST_NO_SFINAE
                            ) :
      function_base()
    {
      this->assign_to(f);
    }
    template<typename Functor,typename Allocator>
    NDNBOOST_FUNCTION_FUNCTION(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
#ifndef NDNBOOST_NO_SFINAE
                            ,typename enable_if_c<
                            (ndnboost::type_traits::ice_not<
                             (is_integral<Functor>::value)>::value),
                                        int>::type = 0
#endif // NDNBOOST_NO_SFINAE
                            ) :
      function_base()
    {
      this->assign_to_a(f,a);
    }

#ifndef NDNBOOST_NO_SFINAE
    NDNBOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
#else
    NDNBOOST_FUNCTION_FUNCTION(int zero) : function_base()
    {
      NDNBOOST_ASSERT(zero == 0);
    }
#endif

    NDNBOOST_FUNCTION_FUNCTION(const NDNBOOST_FUNCTION_FUNCTION& f) : function_base()
    {
      this->assign_to_own(f);
    }
    
#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
    NDNBOOST_FUNCTION_FUNCTION(NDNBOOST_FUNCTION_FUNCTION&& f) : function_base()
    {
      this->move_assign(f);
    }
#endif
    
    ~NDNBOOST_FUNCTION_FUNCTION() { clear(); }

    result_type operator()(NDNBOOST_FUNCTION_PARMS) const
    {
      if (this->empty())
        ndnboost::throw_exception(bad_function_call());

      return get_vtable()->invoker
               (this->functor NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_ARGS);
    }

    // The distinction between when to use NDNBOOST_FUNCTION_FUNCTION and
    // when to use self_type is obnoxious. MSVC cannot handle self_type as
    // the return type of these assignment operators, but Borland C++ cannot
    // handle NDNBOOST_FUNCTION_FUNCTION as the type of the temporary to
    // construct.
    template<typename Functor>
#ifndef NDNBOOST_NO_SFINAE
    typename enable_if_c<
               (ndnboost::type_traits::ice_not<
                 (is_integral<Functor>::value)>::value),
               NDNBOOST_FUNCTION_FUNCTION&>::type
#else
    NDNBOOST_FUNCTION_FUNCTION&
#endif
    operator=(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f)
    {
      this->clear();
      NDNBOOST_TRY  {
        this->assign_to(f);
      } NDNBOOST_CATCH (...) {
        vtable = 0;
        NDNBOOST_RETHROW;
      }
      NDNBOOST_CATCH_END
      return *this;
    }
    template<typename Functor,typename Allocator>
    void assign(Functor NDNBOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
    {
      this->clear();
      NDNBOOST_TRY{
        this->assign_to_a(f,a);
      } NDNBOOST_CATCH (...) {
        vtable = 0;
        NDNBOOST_RETHROW;
      }
      NDNBOOST_CATCH_END
    }

#ifndef NDNBOOST_NO_SFINAE
    NDNBOOST_FUNCTION_FUNCTION& operator=(clear_type*)
    {
      this->clear();
      return *this;
    }
#else
    NDNBOOST_FUNCTION_FUNCTION& operator=(int zero)
    {
      NDNBOOST_ASSERT(zero == 0);
      this->clear();
      return *this;
    }
#endif

    // Assignment from another NDNBOOST_FUNCTION_FUNCTION
    NDNBOOST_FUNCTION_FUNCTION& operator=(const NDNBOOST_FUNCTION_FUNCTION& f)
    {
      if (&f == this)
        return *this;

      this->clear();
      NDNBOOST_TRY {
        this->assign_to_own(f);
      } NDNBOOST_CATCH (...) {
        vtable = 0;
        NDNBOOST_RETHROW;
      }
      NDNBOOST_CATCH_END
      return *this;
    }
    
#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
    // Move assignment from another NDNBOOST_FUNCTION_FUNCTION
    NDNBOOST_FUNCTION_FUNCTION& operator=(NDNBOOST_FUNCTION_FUNCTION&& f)
    {
      
      if (&f == this)
        return *this;

      this->clear();
      NDNBOOST_TRY {
        this->move_assign(f);
      } NDNBOOST_CATCH (...) {
        vtable = 0;
        NDNBOOST_RETHROW;
      }
      NDNBOOST_CATCH_END
      return *this;
    }
#endif

    void swap(NDNBOOST_FUNCTION_FUNCTION& other)
    {
      if (&other == this)
        return;

      NDNBOOST_FUNCTION_FUNCTION tmp;
      tmp.move_assign(*this);
      this->move_assign(other);
      other.move_assign(tmp);
    }

    // Clear out a target, if there is one
    void clear()
    {
      if (vtable) {
        if (!this->has_trivial_copy_and_destroy())
          get_vtable()->clear(this->functor);
        vtable = 0;
      }
    }

#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined NDNBOOST_NO_COMPILER_CONFIG)
    // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
    operator bool () const { return !this->empty(); }
#else
  private:
    struct dummy {
      void nonnull() {}
    };

    typedef void (dummy::*safe_bool)();

  public:
    operator safe_bool () const
      { return (this->empty())? 0 : &dummy::nonnull; }

    bool operator!() const
      { return this->empty(); }
#endif

  private:
    void assign_to_own(const NDNBOOST_FUNCTION_FUNCTION& f)
    {
      if (!f.empty()) {
        this->vtable = f.vtable;
        if (this->has_trivial_copy_and_destroy())
          this->functor = f.functor;
        else
          get_vtable()->base.manager(f.functor, this->functor,
                                     ndnboost::detail::function::clone_functor_tag);
      }
    }

    template<typename Functor>
    void assign_to(Functor f)
    {
      using detail::function::vtable_base;

      typedef typename detail::function::get_function_tag<Functor>::type tag;
      typedef detail::function::NDNBOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
      typedef typename get_invoker::
                         template apply<Functor, R NDNBOOST_FUNCTION_COMMA 
                        NDNBOOST_FUNCTION_TEMPLATE_ARGS>
        handler_type;
      
      typedef typename handler_type::invoker_type invoker_type;
      typedef typename handler_type::manager_type manager_type;

      // Note: it is extremely important that this initialization use
      // static initialization. Otherwise, we will have a race
      // condition here in multi-threaded code. See
      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
      static const vtable_type stored_vtable = 
        { { &manager_type::manage }, &invoker_type::invoke };

      if (stored_vtable.assign_to(f, functor)) {
        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
        if (ndnboost::has_trivial_copy_constructor<Functor>::value &&
            ndnboost::has_trivial_destructor<Functor>::value &&
            detail::function::function_allows_small_object_optimization<Functor>::value)
          value |= static_cast<size_t>(0x01);
        vtable = reinterpret_cast<detail::function::vtable_base *>(value);
      } else 
        vtable = 0;
    }

    template<typename Functor,typename Allocator>
    void assign_to_a(Functor f,Allocator a)
    {
      using detail::function::vtable_base;

      typedef typename detail::function::get_function_tag<Functor>::type tag;
      typedef detail::function::NDNBOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
      typedef typename get_invoker::
                         template apply_a<Functor, R NDNBOOST_FUNCTION_COMMA 
                         NDNBOOST_FUNCTION_TEMPLATE_ARGS,
                         Allocator>
        handler_type;
      
      typedef typename handler_type::invoker_type invoker_type;
      typedef typename handler_type::manager_type manager_type;

      // Note: it is extremely important that this initialization use
      // static initialization. Otherwise, we will have a race
      // condition here in multi-threaded code. See
      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
      static const vtable_type stored_vtable =
        { { &manager_type::manage }, &invoker_type::invoke };

      if (stored_vtable.assign_to_a(f, functor, a)) { 
        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
        if (ndnboost::has_trivial_copy_constructor<Functor>::value &&
            ndnboost::has_trivial_destructor<Functor>::value &&
            detail::function::function_allows_small_object_optimization<Functor>::value)
          value |= static_cast<std::size_t>(0x01);
        vtable = reinterpret_cast<detail::function::vtable_base *>(value);
      } else 
        vtable = 0;
    }

    // Moves the value from the specified argument to *this. If the argument 
    // has its function object allocated on the heap, move_assign will pass 
    // its buffer to *this, and set the argument's buffer pointer to NULL. 
    void move_assign(NDNBOOST_FUNCTION_FUNCTION& f) 
    { 
      if (&f == this)
        return;

      NDNBOOST_TRY {
        if (!f.empty()) {
          this->vtable = f.vtable;
          if (this->has_trivial_copy_and_destroy())
            this->functor = f.functor;
          else
            get_vtable()->base.manager(f.functor, this->functor,
                                     ndnboost::detail::function::move_functor_tag);
          f.vtable = 0;
        } else {
          clear();
        }
      } NDNBOOST_CATCH (...) {
        vtable = 0;
        NDNBOOST_RETHROW;
      }
      NDNBOOST_CATCH_END
    }
  };

  template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
  inline void swap(NDNBOOST_FUNCTION_FUNCTION<
                     R NDNBOOST_FUNCTION_COMMA
                     NDNBOOST_FUNCTION_TEMPLATE_ARGS
                   >& f1,
                   NDNBOOST_FUNCTION_FUNCTION<
                     R NDNBOOST_FUNCTION_COMMA
                     NDNBOOST_FUNCTION_TEMPLATE_ARGS
                   >& f2)
  {
    f1.swap(f2);
  }

// Poison comparisons between ndnboost::function objects of the same type.
template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
  void operator==(const NDNBOOST_FUNCTION_FUNCTION<
                          R NDNBOOST_FUNCTION_COMMA
                          NDNBOOST_FUNCTION_TEMPLATE_ARGS>&,
                  const NDNBOOST_FUNCTION_FUNCTION<
                          R NDNBOOST_FUNCTION_COMMA
                          NDNBOOST_FUNCTION_TEMPLATE_ARGS>&);
template<typename R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_PARMS>
  void operator!=(const NDNBOOST_FUNCTION_FUNCTION<
                          R NDNBOOST_FUNCTION_COMMA
                          NDNBOOST_FUNCTION_TEMPLATE_ARGS>&,
                  const NDNBOOST_FUNCTION_FUNCTION<
                          R NDNBOOST_FUNCTION_COMMA
                          NDNBOOST_FUNCTION_TEMPLATE_ARGS>& );

#if !defined(NDNBOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)

#if NDNBOOST_FUNCTION_NUM_ARGS == 0
#define NDNBOOST_FUNCTION_PARTIAL_SPEC R (void)
#else
#define NDNBOOST_FUNCTION_PARTIAL_SPEC R (NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_FUNCTION_NUM_ARGS,T))
#endif

template<typename R NDNBOOST_FUNCTION_COMMA
         NDNBOOST_FUNCTION_TEMPLATE_PARMS>
class function<NDNBOOST_FUNCTION_PARTIAL_SPEC>
  : public NDNBOOST_FUNCTION_FUNCTION<R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_ARGS>
{
  typedef NDNBOOST_FUNCTION_FUNCTION<R NDNBOOST_FUNCTION_COMMA NDNBOOST_FUNCTION_TEMPLATE_ARGS> base_type;
  typedef function self_type;

  struct clear_type {};

public:

  function() : base_type() {}

  template<typename Functor>
  function(Functor f
#ifndef NDNBOOST_NO_SFINAE
           ,typename enable_if_c<
                            (ndnboost::type_traits::ice_not<
                          (is_integral<Functor>::value)>::value),
                       int>::type = 0
#endif
           ) :
    base_type(f)
  {
  }
  template<typename Functor,typename Allocator>
  function(Functor f, Allocator a
#ifndef NDNBOOST_NO_SFINAE
           ,typename enable_if_c<
                            (ndnboost::type_traits::ice_not<
                          (is_integral<Functor>::value)>::value),
                       int>::type = 0
#endif
           ) :
    base_type(f,a)
  {
  }

#ifndef NDNBOOST_NO_SFINAE
  function(clear_type*) : base_type() {}
#endif

  function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}

  function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}

#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
  // Move constructors
  function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
  function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
#endif
  
  self_type& operator=(const self_type& f)
  {
    self_type(f).swap(*this);
    return *this;
  }

#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
  self_type& operator=(self_type&& f)
  {
    self_type(static_cast<self_type&&>(f)).swap(*this);
    return *this;
  }
#endif  

  template<typename Functor>
#ifndef NDNBOOST_NO_SFINAE
  typename enable_if_c<
                            (ndnboost::type_traits::ice_not<
                         (is_integral<Functor>::value)>::value),
                      self_type&>::type
#else
  self_type&
#endif
  operator=(Functor f)
  {
    self_type(f).swap(*this);
    return *this;
  }

#ifndef NDNBOOST_NO_SFINAE
  self_type& operator=(clear_type*)
  {
    this->clear();
    return *this;
  }
#endif

  self_type& operator=(const base_type& f)
  {
    self_type(f).swap(*this);
    return *this;
  }
  
#ifndef NDNBOOST_NO_CXX11_RVALUE_REFERENCES
  self_type& operator=(base_type&& f)
  {
    self_type(static_cast<base_type&&>(f)).swap(*this);
    return *this;
  }
#endif 
};

#undef NDNBOOST_FUNCTION_PARTIAL_SPEC
#endif // have partial specialization

} // end namespace ndnboost

// Cleanup after ourselves...
#undef NDNBOOST_FUNCTION_VTABLE
#undef NDNBOOST_FUNCTION_COMMA
#undef NDNBOOST_FUNCTION_FUNCTION
#undef NDNBOOST_FUNCTION_FUNCTION_INVOKER
#undef NDNBOOST_FUNCTION_VOID_FUNCTION_INVOKER
#undef NDNBOOST_FUNCTION_FUNCTION_OBJ_INVOKER
#undef NDNBOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
#undef NDNBOOST_FUNCTION_FUNCTION_REF_INVOKER
#undef NDNBOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
#undef NDNBOOST_FUNCTION_MEMBER_INVOKER
#undef NDNBOOST_FUNCTION_VOID_MEMBER_INVOKER
#undef NDNBOOST_FUNCTION_GET_FUNCTION_INVOKER
#undef NDNBOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
#undef NDNBOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
#undef NDNBOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
#undef NDNBOOST_FUNCTION_GET_INVOKER
#undef NDNBOOST_FUNCTION_TEMPLATE_PARMS
#undef NDNBOOST_FUNCTION_TEMPLATE_ARGS
#undef NDNBOOST_FUNCTION_PARMS
#undef NDNBOOST_FUNCTION_PARM
#undef NDNBOOST_FUNCTION_ARGS
#undef NDNBOOST_FUNCTION_ARG_TYPE
#undef NDNBOOST_FUNCTION_ARG_TYPES
#undef NDNBOOST_FUNCTION_VOID_RETURN_TYPE
#undef NDNBOOST_FUNCTION_RETURN

#if defined(NDNBOOST_MSVC)
#   pragma warning( pop )
#endif       
