Click here to Skip to main content
15,892,927 members
Articles / Programming Languages / C++

Fast C++ Delegate: Boost.Function 'drop-in' replacement and multicast

Rate me:
Please Sign up or sign in to vote.
4.86/5 (51 votes)
1 Jun 200733 min read 292.4K   1.9K   110  
An article on the implementation of a fast C++ delegate with many advanced features.
// FD.Delegate
// Do not include this header directly.

protected:
  /**
   * mfn_bind() for member function bind with calling convention.
   */
  template<typename UR FD_DELEGATE_COMMA FD_DELEGATE_TEMPLATE_PARMS2, typename U, typename T>
  self_type & FD_DELEGATE_CC_NAME(mfn_bind)(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2), T t, bool reset = true)
  {
    typedef struct
    {
      typedef UR (FD_DELEGATE_MF_CC U::*TFxn)(FD_DELEGATE_TEMPLATE_ARGS2);

      typedef
        FD_DELEGATE_MFN_BIND_ON_PTR<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA BOOST_DEDUCED_TYPENAME boost::remove_pointer<T>::type, TFxn>
        ptr_type;

      typedef
        FD_DELEGATE_MFN_BIND_ON_REF<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA T, TFxn>
        ref_type;

      typedef
        FD_DELEGATE_MFN_BIND_ON_OBJ<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA T, TFxn, Allocator>
        obj_type;

      typedef
        FD_DELEGATE_MFN_BIND_ON_CUSTOM<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA T, TFxn, Allocator>
        custom_type;

      typedef typename boost::ct_if<
        (::boost::is_pointer<T>::value),
        ptr_type,
        boost::ct_if<
          (::boost::is_reference_wrapper<T>::value),
          ref_type,
          boost::ct_if<
            (::fd::detail::delegate::is_<T *>::template pointer_of_<U>::value),
            obj_type,
            custom_type
          >
        >
      >::type type_1;

      typedef typename type_1::type type_2;
      typedef typename type_2::type type;

    } select_stub;

    if( reset ) this->clear();
    select_stub::type::init( this->get_holder(), t, fxn );
    return *this;
  }

  /**
   * mfn_bind_const() for member function bind with calling convention.
   */
  template<typename UR FD_DELEGATE_COMMA FD_DELEGATE_TEMPLATE_PARMS2, typename U, typename T>
  self_type & FD_DELEGATE_CC_NAME(mfn_bind_const)(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2) const, T t, bool reset = true)
  {
    typedef struct
    {
      typedef UR (FD_DELEGATE_MF_CC U::*TFxn)(FD_DELEGATE_TEMPLATE_ARGS2) const;

      typedef
        FD_DELEGATE_MFN_BIND_ON_PTR<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA BOOST_DEDUCED_TYPENAME boost::remove_pointer<T>::type, TFxn>
        ptr_type;

      typedef
        FD_DELEGATE_MFN_BIND_ON_REF<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA T, TFxn>
        ref_type;

      typedef
        FD_DELEGATE_MFN_BIND_ON_OBJ<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA T, TFxn, Allocator>
        obj_type;

      typedef
        FD_DELEGATE_MFN_BIND_ON_CUSTOM<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA T, TFxn, Allocator>
        custom_type;

      typedef typename boost::ct_if<
        (::boost::is_pointer<T>::value),
        ptr_type,
        boost::ct_if<
          (::boost::is_reference_wrapper<T>::value),
          ref_type,
          boost::ct_if<
            (::fd::detail::delegate::is_<T *>::template pointer_of_<U>::value),
            obj_type,
            custom_type
          >
        >
      >::type type_1;

      typedef typename type_1::type type_2;
      typedef typename type_2::type type;

    } select_stub;

    if( reset ) this->clear();
    select_stub::type::init( this->get_holder(), t, fxn );
    return *this;
  }

private:
  /**
   * 
   */
  template<typename UR FD_DELEGATE_COMMA FD_DELEGATE_TEMPLATE_PARMS2, typename U, typename T>
  self_type & fast_mfn_bind(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2), T t, bool reset)
  {
    this->FD_DELEGATE_CC_NAME(mfn_bind)( fxn, t, reset );
    return *this;
  }

  template<typename UR FD_DELEGATE_COMMA FD_DELEGATE_TEMPLATE_PARMS2, typename U, typename T>
  self_type & fast_mfn_bind(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2) const, T t, bool reset)
  {
    this->FD_DELEGATE_CC_NAME(mfn_bind_const)( fxn, t, reset );
    return *this;
  }

#if FD_DELEGATE_NUM_ARGS > 0

protected:
  /**
   * mfn() for member function bind with calling convention.
   */
  template<typename UR FD_DELEGATE_COMMA_SP FD_DELEGATE_TEMPLATE_PARMS2_SP, typename U>
  self_type & FD_DELEGATE_CC_NAME(mfn)(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2_SP), bool reset = true)
  {
    typedef struct
    {
      typedef UR (FD_DELEGATE_MF_CC U::*TFxn)(FD_DELEGATE_TEMPLATE_ARGS2_SP);

      typedef
        FD_DELEGATE_MFN_ON_PTR<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        ptr_type;

      typedef
        FD_DELEGATE_MFN_ON_OBJ<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        obj_type;

      typedef
        FD_DELEGATE_MFN_ON_REF<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        ref_type;

      typedef
        FD_DELEGATE_MFN_ON_CUSTOM<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        custom_type;

      typedef typename boost::ct_if<
        (::fd::detail::delegate::is_<T0>::template pointer_of_<U>::value),
        ptr_type,
        boost::ct_if<
          (::boost::is_same<T0, U>::value),
          obj_type,
          boost::ct_if<
            (::fd::detail::delegate::is_<T0>::template reference_of_<U>::value),
            ref_type,
            custom_type
          >
        >
      >::type type_1;

      typedef typename type_1::type type_2;
      typedef typename type_2::type type;

    } select_stub;

    if( reset ) this->clear();
    select_stub::type::init( this->get_holder(), fxn );
    return *this;
  }

  /**
   * mfn_const() for member function bind with calling convention.
   */
  template<typename UR FD_DELEGATE_COMMA_SP FD_DELEGATE_TEMPLATE_PARMS2_SP, typename U>
  self_type & FD_DELEGATE_CC_NAME(mfn_const)(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2_SP) const, bool reset = true)
  {
    typedef struct
    {
      typedef UR (FD_DELEGATE_MF_CC U::*TFxn)(FD_DELEGATE_TEMPLATE_ARGS2_SP) const;

      typedef
        FD_DELEGATE_MFN_ON_PTR<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        ptr_type;

      typedef
        FD_DELEGATE_MFN_ON_OBJ<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        obj_type;

      typedef
        FD_DELEGATE_MFN_ON_REF<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        ref_type;

      typedef
        FD_DELEGATE_MFN_ON_CUSTOM<result_type, FD_DELEGATE_TEMPLATE_ARGS FD_DELEGATE_COMMA TFxn>
        custom_type;

      typedef typename boost::ct_if<
        (::fd::detail::delegate::is_<T0>::template pointer_of_<U>::value),
        ptr_type,
        boost::ct_if<
          (::boost::type_traits::ice_or<(::boost::is_same<T0, U>::value), (::boost::is_same<T0, U const>::value)>::value),
          obj_type,
          boost::ct_if<
            (::fd::detail::delegate::is_<T0>::template reference_of_<U>::value),
            ref_type,
            custom_type
          >
        >
      >::type type_1;

      typedef typename type_1::type type_2;
      typedef typename type_2::type type;

    } select_stub;

    if( reset ) this->clear();
    select_stub::type::init( this->get_holder(), fxn );
    return *this;
  }

private:
  /**
   * 
   */
  template<typename UR FD_DELEGATE_COMMA_SP FD_DELEGATE_TEMPLATE_PARMS2_SP, typename U>
  self_type & fast_mfn_assign_to(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2_SP), bool reset)
  {
    this->FD_DELEGATE_CC_NAME(mfn)( fxn, reset );
    return *this;
  }

  template<typename UR FD_DELEGATE_COMMA_SP FD_DELEGATE_TEMPLATE_PARMS2_SP, typename U>
  self_type & fast_mfn_assign_to(UR (FD_DELEGATE_MF_CC U::*fxn)(FD_DELEGATE_TEMPLATE_ARGS2_SP) const, bool reset)
  {
    this->FD_DELEGATE_CC_NAME(mfn_const)( fxn, reset );
    return *this;
  }

#endif // #if FD_DELEGATE_NUM_ARGS > 0

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Other
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions