zoukankan      html  css  js  c++  java
  • 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 <wanjunfeng@gmail.com>
     * @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 <wanjunfeng@gmail.com>
     * @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 == 0return 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 == 0return 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 == 0return ReturnType();
            
    return m_pHolder->call(PARAM_LIST);
        }

        
    bool equals(const SuperType* pDelegate) const
        {
            
    const SelfType* pRhs = dynamic_cast<const SelfType*>(pDelegate);
            
    if (pRhs == 0return 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 <wanjunfeng@gmail.com>
     * @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);
    }

  • 相关阅读:
    激光雷达slam之LOAM中的坐标转换与IMU融合
    记录一次失败的coding面
    因子图相关理论汇总
    [ICP]手推SVD方法
    SLAM中的卡方分布
    第五篇 openvslam建图与优化模块梳理
    第四篇 跟踪过程以及openvslam中的相关实现详解
    第三篇 视觉里程计(VO)的初始化过程以及openvslam中的相关实现详解
    第二篇 特征点匹配以及openvslam中的相关实现详解
    第一篇 特征提取以及openvslam中的相关实现详解
  • 原文地址:https://www.cnblogs.com/kevinwan/p/586793.html
Copyright © 2011-2022 走看看