delegate in c++ (new version)

Delegate in C# is similar to a function pointer in C or C++, but it's type-safe and easy to use. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked.

This C++ delegate library implements the similar concept. You can use it to as type-safe callback, thread entry routine etc.
you can download it from here.

delegate.h
#ifndef WAN_DELEGATE_H
#define  WAN_DELEGATE_H
   
/* *
 * @author Kevin Wan <[email protected]>
 * @date   06/30/2005
 * Copyright (C) Kevin Wan
 
*/
#include 
" threadingmodel.h "
   
namespace  wan
{
namespace  local
{
template 
< typename >   class  ICallback;
template 
< typename >   class  NativeCallback;
template 
< typename, typename >   class  MemberCallback;
//  namespace local

template 
< typename, typename LockType  =   void >   class   delegate ;

#define  TEMPLATE_LIST_0
#define  TEMPLATE_LIST_1 TEMPLATE_LIST_0, typename T0
#define  TEMPLATE_LIST_2 TEMPLATE_LIST_1, typename T1
#define  TEMPLATE_LIST_3 TEMPLATE_LIST_2, typename T2
#define  TEMPLATE_LIST_4 TEMPLATE_LIST_3, typename T3
#define  TEMPLATE_LIST_5 TEMPLATE_LIST_4, typename T4
#define  TEMPLATE_LIST_6 TEMPLATE_LIST_5, typename T5

#define  TYPE_LIST_0
#define  TYPE_LIST_1 T0
#define  TYPE_LIST_2 TYPE_LIST_1, T1
#define  TYPE_LIST_3 TYPE_LIST_2, T2
#define  TYPE_LIST_4 TYPE_LIST_3, T3
#define  TYPE_LIST_5 TYPE_LIST_4, T4
#define  TYPE_LIST_6 TYPE_LIST_5, T5

#define  TYPE_PARAM_LIST_0
#define  TYPE_PARAM_LIST_1 T0 t0
#define  TYPE_PARAM_LIST_2 TYPE_PARAM_LIST_1, T1 t1
#define  TYPE_PARAM_LIST_3 TYPE_PARAM_LIST_2, T2 t2
#define  TYPE_PARAM_LIST_4 TYPE_PARAM_LIST_3, T3 t3
#define  TYPE_PARAM_LIST_5 TYPE_PARAM_LIST_4, T4 t4
#define  TYPE_PARAM_LIST_6 TYPE_PARAM_LIST_5, T5 t5

#define  PARAM_LIST_0
#define  PARAM_LIST_1 t0
#define  PARAM_LIST_2 PARAM_LIST_1, t1
#define  PARAM_LIST_3 PARAM_LIST_2, t2
#define  PARAM_LIST_4 PARAM_LIST_3, t3
#define  PARAM_LIST_5 PARAM_LIST_4, t4
#define  PARAM_LIST_6 PARAM_LIST_5, t5

#define  TEMPLATE_LIST     TEMPLATE_LIST_0
#define  TYPE_LIST         TYPE_LIST_0
#define  TYPE_PARAM_LIST TYPE_PARAM_LIST_0
#define  PARAM_LIST        PARAM_LIST_0
#include 
" __delegate.h "
#undef  TEMPLATE_LIST
#undef  TYPE_LIST
#undef  TYPE_PARAM_LIST
#undef  PARAM_LIST

#define  TEMPLATE_LIST     TEMPLATE_LIST_1
#define  TYPE_LIST         TYPE_LIST_1
#define  TYPE_PARAM_LIST TYPE_PARAM_LIST_1
#define  PARAM_LIST        PARAM_LIST_1
#include 
" __delegate.h "
#undef  TEMPLATE_LIST
#undef  TYPE_LIST
#undef  TYPE_PARAM_LIST
#undef  PARAM_LIST

#define  TEMPLATE_LIST     TEMPLATE_LIST_2
#define  TYPE_LIST         TYPE_LIST_2
#define  TYPE_PARAM_LIST TYPE_PARAM_LIST_2
#define  PARAM_LIST        PARAM_LIST_2
#include 
" __delegate.h "
#undef  TEMPLATE_LIST
#undef  TYPE_LIST
#undef  TYPE_PARAM_LIST
#undef  PARAM_LIST

#define  TEMPLATE_LIST     TEMPLATE_LIST_3
#define  TYPE_LIST         TYPE_LIST_3
#define  TYPE_PARAM_LIST TYPE_PARAM_LIST_3
#define  PARAM_LIST        PARAM_LIST_3
#include 
" __delegate.h "
#undef  TEMPLATE_LIST
#undef  TYPE_LIST
#undef  TYPE_PARAM_LIST
#undef  PARAM_LIST

#define  TEMPLATE_LIST     TEMPLATE_LIST_4
#define  TYPE_LIST         TYPE_LIST_4
#define  TYPE_PARAM_LIST TYPE_PARAM_LIST_4
#define  PARAM_LIST        PARAM_LIST_4
#include 
" __delegate.h "
#undef  TEMPLATE_LIST
#undef  TYPE_LIST
#undef  TYPE_PARAM_LIST
#undef  PARAM_LIST

#define  TEMPLATE_LIST     TEMPLATE_LIST_5
#define  TYPE_LIST         TYPE_LIST_5
#define  TYPE_PARAM_LIST TYPE_PARAM_LIST_5
#define  PARAM_LIST        PARAM_LIST_5
#include 
" __delegate.h "
#undef  TEMPLATE_LIST
#undef  TYPE_LIST
#undef  TYPE_PARAM_LIST
#undef  PARAM_LIST

#define  TEMPLATE_LIST     TEMPLATE_LIST_6
#define  TYPE_LIST         TYPE_LIST_6
#define  TYPE_PARAM_LIST TYPE_PARAM_LIST_6
#define  PARAM_LIST        PARAM_LIST_6
#include 
" __delegate.h "
#undef  TEMPLATE_LIST
#undef  TYPE_LIST
#undef  TYPE_PARAM_LIST
#undef  PARAM_LIST

//  remove the macros
#undef  TEMPLATE_LIST_0
#undef  TEMPLATE_LIST_1
#undef  TEMPLATE_LIST_2
#undef  TEMPLATE_LIST_3
#undef  TEMPLATE_LIST_4
#undef  TEMPLATE_LIST_5
#undef  TEMPLATE_LIST_6

#undef  TYPE_LIST_0
#undef  TYPE_LIST_1
#undef  TYPE_LIST_2
#undef  TYPE_LIST_3
#undef  TYPE_LIST_4
#undef  TYPE_LIST_5
#undef  TYPE_LIST_6

#undef  TYPE_PARAM_LIST_0
#undef  TYPE_PARAM_LIST_1
#undef  TYPE_PARAM_LIST_2
#undef  TYPE_PARAM_LIST_3
#undef  TYPE_PARAM_LIST_4
#undef  TYPE_PARAM_LIST_5
#undef  TYPE_PARAM_LIST_6

#undef  PARAM_LIST_0
#undef  PARAM_LIST_1
#undef  PARAM_LIST_2
#undef  PARAM_LIST_3
#undef  PARAM_LIST_4
#undef  PARAM_LIST_5
#undef  PARAM_LIST_6
//  namespace

#endif   //  WAN_DELEGATE_H

__delegate.h
/* *
 * @author Kevin Wan <[email protected]>
 * @date   06/30/2005
 * Copyright (C) Kevin Wan
 
*/
   
namespace  local
{
template 
< typename ReturnType TEMPLATE_LIST >
class  ICallback < ReturnType(TYPE_LIST) >
{
    typedef ICallback
< ReturnType(TYPE_LIST) >  SelfType;

public :
    
virtual   ~ ICallback() {}

    
virtual  ReturnType invoke(TYPE_LIST)  const   =   0 ;
    
virtual   bool  equals( const  SelfType *  pDelegate)  const   =   0 ;
    
virtual  SelfType *  clone()  const   =   0 ;
};

template 
< typename ReturnType TEMPLATE_LIST >
class  NativeCallback < ReturnType(TYPE_LIST) >
    : 
public  ICallback < ReturnType(TYPE_LIST) >
{
    typedef ICallback
< ReturnType(TYPE_LIST) >  SuperType;
    typedef NativeCallback
< ReturnType(TYPE_LIST) >  SelfType;
    typedef ReturnType (
* FunctionPtr)(TYPE_LIST);

public :
    
explicit  NativeCallback(FunctionPtr ptr)
        : m_handler(ptr)
    {
    }

    NativeCallback(
const  SelfType &  rhs)
        : ICallback
< ReturnType(TYPE_LIST) > (rhs)
        , m_handler(rhs.m_handler)
    {
    }

    ReturnType invoke(TYPE_PARAM_LIST) 
const
    {
        
return  ( * m_handler)(PARAM_LIST);
    }

    
bool  equals( const  SuperType *  pDelegate)  const
    {
        
const  SelfType *  pRhs  =  dynamic_cast < const  SelfType *> (pDelegate);
        
if  (pRhs  ==   0 return   false ;
        
if  (m_handler  ==  pRhs -> m_handler)  return   true ;
        
return   false ;
    }

    SelfType
*  clone()  const
    {
        
return   new  SelfType( * this );
    }

private :
    FunctionPtr m_handler;
};

template 
< typename ObjectType, typename ReturnType TEMPLATE_LIST >
class  MemberCallback < ObjectType, ReturnType(TYPE_LIST) >
    : 
public  ICallback < ReturnType(TYPE_LIST) >
{
    typedef ICallback
< ReturnType(TYPE_LIST) >  SuperType;
    typedef MemberCallback
< ObjectType, ReturnType(TYPE_LIST) >  SelfType;
    typedef ReturnType (ObjectType::
* FunctionPtr)(TYPE_LIST);
    typedef ReturnType (ObjectType::
* ConstFunctionPtr)(TYPE_LIST)  const ;

    
enum  { CONST_POINTER, NEED_DELETE, DONT_DELETE };
    
struct  ObjectManager
    {
        
bool  equals( const  ObjectManager &  rhs)
        {
            
return   object .pObject  ==  rhs. object .pObject;
        }

        union { ObjectType
*  pObject;  const  ObjectType *  pConstObject; }  object ;
        
int                  property;
        
int                  refCount;
    };

public :
    MemberCallback(ObjectType
*  t, FunctionPtr ptr,  bool  needDelete  =   false )
        : m_isConstMemFunc(
false )
    {
        m_pObjectManager 
=   new  ObjectManager();
        m_pObjectManager
-> object .pObject  =  t;
        m_pObjectManager
-> property  =  needDelete  ?  NEED_DELETE : DONT_DELETE;
        m_pObjectManager
-> refCount  =   0 ;
        m_handler.ptr 
=  ptr;
        incrementRefCount();
    }

    MemberCallback(ObjectType
*  t, ConstFunctionPtr ptr,  bool  needDelete  =   false )
        : m_isConstMemFunc(
true )
    {
        m_pObjectManager 
=   new  ObjectManager();
        m_pObjectManager
-> object .pObject  =  t;
        m_pObjectManager
-> property  =  needDelete  ?  NEED_DELETE : DONT_DELETE;
        m_pObjectManager
-> refCount  =   0 ;
        m_handler.constPtr 
=  ptr;
        incrementRefCount();
    }

    MemberCallback(
const  ObjectType *  t, ConstFunctionPtr ptr)
        : m_isConstMemFunc(
true )
    {
        m_pObjectManager 
=   new  ObjectManager();
        m_pObjectManager
-> object .pConstObject  =  t;
        m_pObjectManager
-> property  =  CONST_POINTER;
        m_pObjectManager
-> refCount  =   0 ;
        m_handler.constPtr 
=  ptr;
        incrementRefCount();
    }

    MemberCallback(
const  SelfType &  rhs)
        : ICallback
< ReturnType(TYPE_LIST) > (rhs)
        , m_pObjectManager(rhs.m_pObjectManager)
        , m_handler(rhs.m_handler)
        , m_isConstMemFunc(rhs.m_isConstMemFunc)
    {
        incrementRefCount();
    }

    
virtual   ~ MemberCallback()
    {
        decrementRefCount();
    }

    MemberCallback
&   operator = ( const  SelfType &  rhs)
    {
        
if  ( this   ==   & rhs)
            
return   * this ;
        decrementRefCount();
        m_pObjectManager 
=  rhs.m_pObjectManager;
        m_handler 
=  rhs.m_handler;
        m_isConstMemFunc 
=  rhs.m_isConstMemFunc;
        incrementRefCount();
        
return   * this ;
    }

    ReturnType invoke(TYPE_PARAM_LIST) 
const
    {
        
if  (m_isConstMemFunc)
        {
            
if  (m_pObjectManager -> property  ==  CONST_POINTER)
                
return  (m_pObjectManager -> object .pConstObject ->* (m_handler.constPtr))(PARAM_LIST);
            
return  (m_pObjectManager -> object .pObject ->* (m_handler.constPtr))(PARAM_LIST);
        }
        
return  (m_pObjectManager -> object .pObject ->* (m_handler.ptr))(PARAM_LIST);
    }

    
bool  equals( const  SuperType *  pDelegate)  const
    {
        
const  SelfType *  pRhs  =  dynamic_cast < const  SelfType *> (pDelegate);
        
if  (pRhs  ==   0 return   false ;
        
if  (m_pObjectManager -> equals( * pRhs -> m_pObjectManager)
                
&&  m_isConstMemFunc  ==  pRhs -> m_isConstMemFunc
                
&&  m_handler.ptr  ==  pRhs -> m_handler.ptr)
            
return   true ;
        
return   false ;
    }

    SelfType
*  clone()  const
    {
        
return   new  SelfType( * this );
    }

private :
    
void  incrementRefCount()
    {
        
++ m_pObjectManager -> refCount;
    }

    
void  decrementRefCount()
    {
        
if  ( -- m_pObjectManager -> refCount  ==   0 )
        {
            
if  (m_pObjectManager -> property  ==  NEED_DELETE)
                delete m_pObjectManager
-> object .pObject;

            delete m_pObjectManager;
        }
    }

private :
    ObjectManager
*   m_pObjectManager;
    union { FunctionPtr ptr; ConstFunctionPtr constPtr; } m_handler;
    
bool             m_isConstMemFunc;
};
/*  namespace local  */

template 
< typename ReturnType TEMPLATE_LIST, typename LockType >
class   delegate < ReturnType(TYPE_LIST), LockType >
    : 
public  local::ICallback < ReturnType(TYPE_LIST) >
    , 
public  ThreadingModel < LockType >
{
    typedef local::ICallback
< ReturnType(TYPE_LIST) >  SuperType;
    typedef 
delegate < ReturnType(TYPE_LIST), LockType >  SelfType;
    typedef ThreadingModel
< LockType >  ThreadingModelType;
    
struct  CallbackHolder
    {
        SuperType
*       instance;
        CallbackHolder
*  prev;
        ReturnType call(TYPE_PARAM_LIST)
        {
            
if  (prev  !=   0 ) prev -> call(PARAM_LIST);
            
return  instance -> invoke(PARAM_LIST);
        }
    };

public :
    
delegate () : m_pHolder( 0 ) {}

    
explicit   delegate (ReturnType ( * ptr)(TYPE_LIST))
        : m_pHolder(
0 )
    {
        
this -> add(ptr);
    }

    template 
< typename ObjectType >
    
delegate ( const  ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST)  const )
        : m_pHolder(
0 )
    {
        
this -> add(t, ptr);
    }

    template 
< typename ObjectType >
    
delegate (ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST),
            
bool  needDelete  =   false )
        : m_pHolder(
0 )
    {
        
this -> add(t, ptr, needDelete);
    }

    template 
< typename ObjectType >
    
delegate (ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST)  const ,
            
bool  needDelete  =   false )
        : m_pHolder(
0 )
    {
        
this -> add(t, ptr, needDelete);
    }

    template 
< typename FunctorType >
    
explicit   delegate ( const  FunctorType *  pFunctor)
        : m_pHolder(
0 )
    {
        
this -> add(pFunctor);
    }

    template 
< typename FunctorType >
    
explicit   delegate (FunctorType *  pFunctor,  bool  needDelete  =   false )
        : m_pHolder(
0 )
    {
        
this -> add(pFunctor, needDelete);
    }

    
delegate ( const  SelfType &  rhs)
        : local::ICallback
< ReturnType(TYPE_LIST) > (rhs)
        , ThreadingModelType()
    {
        copyFrom(rhs);
    }

    SelfType
&   operator = ( const  SelfType &  rhs)
    {
        
if  ( this   ==   & rhs)
            
return   * this ;
        
this -> release();
        copyFrom(rhs);
        
return   * this ;
    }

    
~ delegate ()
    {
        release();
    }

    
void  release()
    {
        typename ThreadingModelType::Lock guard(
* this );
        CallbackHolder
*  ptr  =  m_pHolder;
        
while  (ptr  !=   0 )
        {
            CallbackHolder
*  prev  =  ptr -> prev;
            delete ptr
-> instance;
            delete ptr;
            ptr 
=  prev;
        }
        m_pHolder 
=   0 ;
    }

    ReturnType 
operator ()(TYPE_PARAM_LIST)
    {
        
return   this -> invoke(PARAM_LIST);
    }

    ReturnType invoke(TYPE_PARAM_LIST) 
const
    {
        typename ThreadingModelType::Lock guard(
* this );
        
if  (m_pHolder  ==   0 return  ReturnType();
        
return  m_pHolder -> call(PARAM_LIST);
    }

    
bool  equals( const  SuperType *  pDelegate)  const
    {
        
const  SelfType *  pRhs  =  dynamic_cast < const  SelfType *> (pDelegate);
        
if  (pRhs  ==   0 return   false ;

        SelfType
*  temp  =   0 ;
        
const  SelfType *  pClone;
        cloneForComparison(pRhs, pClone, temp, typename ThreadingModelType::ThreadTag());

        typename ThreadingModelType::Lock guard(
* this );
        CallbackHolder
*  ptr1  =  m_pHolder;
        CallbackHolder
*  ptr2  =  pClone -> m_pHolder;
        
while  (ptr1  !=   0   &&  ptr2  !=   0 )
        {
            
if  ( ! ptr1 -> instance -> equals(ptr2 -> instance))
                
break ;
            ptr1 
=  ptr1 -> prev;
            ptr2 
=  ptr2 -> prev;
        }
        delete temp;
        
return  (ptr1  ==   0   &&  ptr2  ==   0 );
    }

    SelfType
*  clone()  const
    {
        SelfType
*  pClone  =   new  SelfType();
        typename ThreadingModelType::Lock guard(
* this );
        CallbackHolder
*  ptr  =  m_pHolder;
        CallbackHolder
*  pReverse  =   0 ;
        
while  (ptr  !=   0 )
        {
            CallbackHolder
*  pHolder  =   new  CallbackHolder();
            pHolder
-> instance  =  ptr -> instance -> clone();
            pHolder
-> prev  =  pReverse;
            pReverse 
=  pHolder;
            ptr 
=  ptr -> prev;
        }

        CallbackHolder
*  prev  =   0 ;
        
while  (pReverse  !=   0 )
        {
            CallbackHolder
*  next  =  pReverse -> prev;
            pReverse
-> prev  =  prev;
            prev 
=  pReverse;
            pReverse 
=  next;
        }
        pClone
-> m_pHolder  =  prev;

        
return  pClone;
    }

    
void  add(ReturnType ( * ptr)(TYPE_LIST))
    {
        SuperType
*  pNew  =   new  local::NativeCallback < ReturnType(TYPE_LIST) > (ptr);
        
this -> addImpl(pNew);
    }

    template 
< typename ObjectType >
    
void  add( const  ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST)  const )
    {
        SuperType
*  pNew  =   new  local::MemberCallback < ObjectType, ReturnType(TYPE_LIST) > (t, ptr);
        
this -> addImpl(pNew);
    }

    template 
< typename ObjectType >
    
void  add(ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST),  bool  needDelete  =   false )
    {
        SuperType
*  pNew  =   new  local::MemberCallback < ObjectType, ReturnType(TYPE_LIST) >
                (t, ptr, needDelete);
        
this -> addImpl(pNew);
    }

    template 
< typename ObjectType >
    
void  add(ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST)  const ,
            
bool  needDelete  =   false )
    {
        SuperType
*  pNew  =   new  local::MemberCallback < ObjectType, ReturnType(TYPE_LIST) >
            (t, ptr, needDelete);
        
this -> addImpl(pNew);
    }

    template 
< typename FunctorType >
    
void  add(FunctorType *  pFunctor,  bool  needDelete  =   false )
    {
        
this -> add(pFunctor,  & FunctorType:: operator (), needDelete);
    }

    template 
< typename FunctorType >
    
void  add( const  FunctorType *  pFunctor)
    {
        
this -> add(pFunctor,  & FunctorType:: operator ());
    }

    
void  add( const  SelfType &  rhs)
    {
        SelfType
*  pClone  =  rhs.clone();
        
this -> addImpl(pClone);
    }

    
void  remove(ReturnType ( * ptr)(TYPE_LIST))
    {
        SuperType
*  pNew  =   new  local::NativeCallback < ReturnType(TYPE_LIST) > (ptr);
        
this -> removeImpl(pNew);
    }

    template 
< typename ObjectType >
    
void  remove( const  ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST)  const )
    {
        SuperType
*  pNew  =   new  local::MemberCallback < ObjectType, ReturnType(TYPE_LIST) > (t, ptr);
        
this -> removeImpl(pNew);
    }

    template 
< typename ObjectType >
    
void  remove(ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST),  bool  needDelete  =   false )
    {
        SuperType
*  pNew  =   new  local::MemberCallback < ObjectType, ReturnType(TYPE_LIST) >
            (t, ptr, needDelete);
        
this -> removeImpl(pNew);
    }

    template 
< typename ObjectType >
    
void  remove(ObjectType *  t, ReturnType(ObjectType:: * ptr)(TYPE_LIST)  const ,
            
bool  needDelete  =   false )
    {
        SuperType
*  pNew  =   new  local::MemberCallback < ObjectType, ReturnType(TYPE_LIST) >
            (t, ptr, needDelete);
        
this -> removeImpl(pNew);
    }

    template 
< typename FunctorType >
    
void  remove(FunctorType *  pFunctor,  bool  needDelete  =   false )
    {
        
this -> remove(pFunctor,  & FunctorType:: operator (), needDelete);
    }

    template 
< typename FunctorType >
    
void  remove( const  FunctorType *  pFunctor)
    {
        
this -> remove(pFunctor,  & FunctorType:: operator ());
    }

    
void  remove( const  SelfType &  rhs)
    {
        
this -> remove(rhs, typename ThreadingModelType::ThreadTag());
    }

private :
    
void  cloneForComparison( const  SelfType *  pRhs,  const  SelfType *&  pClone,
            SelfType
*&  ptrForDelete, SingleThreadTag)  const
    {
        pClone 
=  pRhs;
        ptrForDelete 
=   0 ;
    }

    
void  cloneForComparison( const  SelfType *  pRhs,  const  SelfType *&  pClone,
            SelfType
*&  ptrForDelete, MultiThreadTag)  const
    {
            ptrForDelete 
=  pRhs -> clone();
            pClone 
=  ptrForDelete;
    }

    
void  copyFrom( const  SelfType &  rhs)
    {
        SelfType
*  pClone  =  rhs.clone();
        m_pHolder 
=  pClone -> m_pHolder;
        pClone
-> m_pHolder  =   0 ;
        delete pClone;
    }

    
void  remove( const  SelfType &  rhs, SingleThreadTag)
    {
        
this -> removeImpl( & rhs);
    }

    
void  remove( const  SelfType &  rhs, MultiThreadTag)
    {
        
this -> removeImpl(rhs.clone());
    }

    
void  addImpl(SuperType *  pRhs)
    {
        typename ThreadingModelType::Lock guard(
* this );
        CallbackHolder
*  pH  =   new  CallbackHolder();
        pH
-> instance  =  pRhs;
        pH
-> prev  =  m_pHolder;
        m_pHolder 
=  pH;
    }

    
void  removeImpl( const  SuperType *  pRhs)
    {
        typename ThreadingModelType::Lock guard(
* this );
        CallbackHolder
*  ptr  =  m_pHolder;
        CallbackHolder
*  prev  =   0 ;
        
while  (ptr  !=   0 )
        {
            
if  (ptr -> instance -> equals(pRhs))
            {
                
if  (prev  ==   0 ) m_pHolder  =  ptr -> prev;
                
else  prev -> prev  =  ptr -> prev;
                delete ptr
-> instance;
                delete ptr;
                
break ;
            }
            prev 
=  ptr;
            ptr 
=  ptr -> prev;
        }
    }

    
void  removeImpl(SuperType *  pRhs)
    {
        
const  SuperType *  pConst  =  pRhs;
        
this -> removeImpl(pConst);
        delete pRhs;
    }

private :
    CallbackHolder
*  m_pHolder;
};

threadingmodel.h
#ifndef WAN_THREADINGMODEL_H
#define  WAN_THREADINGMODEL_H

/* *
 * @author Kevin Wan <[email protected]>
 * @date   12/30/2005
 * Copyright (C) Kevin Wan
 
*/

namespace  wan
{
struct  SingleThreadTag {};
struct  MultiThreadTag {};

template 
< typename LockType >
class  ThreadingModel
{
public :
    typedef MultiThreadTag ThreadTag;

    
class  Lock
    {
        Lock(
const  Lock & );
        
void   operator = ( const  Lock & );

    
public :
        
explicit  Lock( const  ThreadingModel &  host)
            : m_host(host)
        {
            m_host.m_mutex.
lock ();
        }
        
~ Lock()
        {
            m_host.m_mutex.unlock();
        }

    
private :
        
const  ThreadingModel &  m_host;
    };

    friend 
class  Lock;

    ThreadingModel() {}

private :
    ThreadingModel(
const  ThreadingModel & );
    ThreadingModel
&   operator = ( const  ThreadingModel & );

private :
    mutable LockType    m_mutex;
};

template 
<>
class  ThreadingModel < void >
{
public :
    typedef SingleThreadTag ThreadTag;

    
struct  Lock
    {
        
explicit  Lock( const  ThreadingModel & ) {}
    };

    ThreadingModel() {}

private :
    ThreadingModel(
const  ThreadingModel & );
    ThreadingModel
&   operator = ( const  ThreadingModel & );
};
//  namespace

#endif   //  WAN_THREADINGMODEL_H

example.cc
#include  < stdio.h >
#include 
" delegate.h "

const   char *  bar  =   " ########################################## " ;

void  native_func( int  value)
{
    printf(
" %s\n " , bar);
    printf(
" native function, value = %d\n " , value);
}

class  Object
{
public :
    
static   void  static_member_func( int  value)
    {
        printf(
" %s\n " , bar);
        printf(
" static member function, value = %d\n " , value);
    }
    
void  non_const_member_func( int  value)
    {
        printf(
" %s\n " , bar);
        printf(
" non-const member function, value = %d\n " , value);
    }
    
void  const_member_func( int  value)  const
    {
        printf(
" %s\n " , bar);
        printf(
" const member function, value = %d\n " , value);
    }
};

class  Functor
{
public :
    
void   operator ()( int  value)
    {
        printf(
" %s\n " , bar);
        printf(
" non-const functor, value = %d\n " , value);
    }
};

class  ConstFunctor
{
public :
    
void   operator ()( int  value)  const
    {
        printf(
" %s\n " , bar);
        printf(
" const functor, value = %d\n " , value);
    }
};

int  main()
{
    typedef wan::
delegate < void ( int ) >  MyDelegate;

    Object obj;
    Functor functor;
    ConstFunctor constFunctor;
    MyDelegate dele;
    dele.add(
& native_func);
    dele.add(
& Object::static_member_func);
    dele.add(
& obj,  & Object::non_const_member_func);
    dele.add(
& obj,  & Object::const_member_func);
    dele.add(
& functor);
    dele.add(
& constFunctor);
    dele(
111 );

    printf(
" %s\n " , bar);
    printf(
" \n\nafter remove operations\n\n " );

    dele.remove(
& native_func);
    dele.remove(
& obj,  & Object::non_const_member_func);
    dele(
222 );

    printf(
" %s\n " , bar);
    printf(
" \n\nadd delegate object to delegate object\n\n " );

    MyDelegate temp;
    temp.add(
& native_func);
    temp.add(
& obj,  & Object::non_const_member_func);
    dele.add(
& temp);
    dele(
333 );

    printf(
" %s\n " , bar);
}

你可能感兴趣的:(delegate)