c++中function的实现原理

直接点击下面的链接去B站查看即可

视频链接

代码

#ifndef __JIE_FUNCTOR_H__
#define __JIE_FUNCTOR_H__

namespace Jie {

union AnyData {
    constexpr static int Max = 128;

    template <typename Type>
    constexpr Type* getPointer() noexcept {
        return Max >= sizeof(Type) ? reinterpret_cast<Type*>(buf) : reinterpret_cast<Type*>(pointer);
    }

    template <typename Type>
    void allocMemory() {
        pointer = std::malloc(sizeof(Type));      
    }

    void free() {
        std::free(pointer);              
    }

    void* pointer;
    char buf[Max];
};


template <typename FunctorType, bool IsMemory = (AnyData::Max < sizeof(FunctorType))>
struct AnyDataManage {
    constexpr static void Init(AnyData* dest, const FunctorType& source) {      
        dest->allocMemory<FunctorType>();                             
        new(dest->getPointer<FunctorType>()) FunctorType(source);        
    }

    constexpr static void Destruct(AnyData* source) {
        source->getPointer<FunctorType>()->~FunctorType();
        source->free();
    }
};

template <typename FunctorType>
struct AnyDataManage<FunctorType, false> {
    constexpr static void Init(AnyData* dest, const FunctorType& source) {                                 
        new(dest->getPointer<FunctorType>()) FunctorType(source);        
    }

    constexpr static void Destruct(AnyData* source) {
        source->getPointer<FunctorType>()->~FunctorType();        
    }
};

template <typename ResultType, typename FunctorType, typename ...ArgsType>
struct InvokeManage {
    constexpr static ResultType Invoke(AnyData* source, ArgsType&& ...args) {
        return (*source->getPointer<FunctorType>())(std::forward<ArgsType>(args) ...);
    }

    constexpr static void Destruct(AnyData* source) {
        AnyDataManage<FunctorType>::Destruct(source);
    }
};

template <typename FunctorType, typename ...ArgsType>
struct InvokeManage<void, FunctorType, ArgsType ...> {
    constexpr static void Invoke(AnyData* source, ArgsType&& ...args) {
        (*source->getPointer<FunctorType>())(std::forward<ArgsType>(args) ...);
    }

    constexpr static void Destruct(AnyData* source) {
        AnyDataManage<FunctorType>::Destruct(source);
    }
};

template <typename ...ArgsType>
struct Functor;

template <typename ResultType, typename ...ArgsType>
struct Functor<ResultType(ArgsType ...)> {
    using InvokeType = ResultType(*)(AnyData*, ArgsType&&...);
    using DestructType = void(*)(AnyData*);

    Functor() = default;

    template <typename FunctorType>
    Functor(FunctorType functor) {        
        AnyDataManage<FunctorType>::Init(&_anyData, functor);     
        _invoke = InvokeManage<ResultType, FunctorType, ArgsType...>::Invoke;
        _destruct = InvokeManage<ResultType, FunctorType, ArgsType...>::Destruct;
    }

    template <typename FunctorType>
    void setInvoke(FunctorType functor) {        
        AnyDataManage<FunctorType>::Init(&_anyData, functor);     
        _invoke = InvokeManage<ResultType, FunctorType, ArgsType...>::Invoke;
        _destruct = InvokeManage<ResultType, FunctorType, ArgsType...>::Destruct;
    }

    ResultType operator()(ArgsType&&... args) {    
        return _invoke(&_anyData, std::forward<ArgsType>(args) ...);
    }

    void free() {
        if (_destruct) {
            _destruct(&_anyData);
            _destruct = nullptr;
        }
    }

    ~Functor() {
        if (_destruct) 
            _destruct(&_anyData);
    }

private:
    AnyData _anyData;
    InvokeType _invoke;
    DestructType _destruct = nullptr;
};


template <typename ...ArgsType>
struct Functor<void(ArgsType ...)> {
    using InvokeType = void(*)(AnyData*, ArgsType&&...);
    using DestructType = void(*)(AnyData*);

    Functor() = default;

    template <typename FunctorType>
    Functor(FunctorType functor) {        
        AnyDataManage<FunctorType>::Init(&_anyData, functor);     
        _invoke = InvokeManage<void, FunctorType, ArgsType...>::Invoke;
        _destruct = InvokeManage<void, FunctorType, ArgsType...>::Destruct;
    }

    template <typename FunctorType>
    void setInvoke(FunctorType functor) {        
        AnyDataManage<FunctorType>::Init(&_anyData, functor);     
        _invoke = InvokeManage<void, FunctorType, ArgsType...>::Invoke;
        _destruct = InvokeManage<void, FunctorType, ArgsType...>::Destruct;
    }

    void operator()(ArgsType&&... args) {    
        _invoke(&_anyData, std::forward<ArgsType>(args) ...);
    }

    void free() {
        if (_destruct) {
            _destruct(&_anyData);
            _destruct = nullptr;
        }
    }

    ~Functor() {
        if (_destruct) 
            _destruct(&_anyData);
    }

private:
    AnyData _anyData;
    InvokeType _invoke;
    DestructType _destruct = nullptr;
};

}


#endif

你可能感兴趣的:(C/C++语法篇,c++)