multimethods.h

来自「C++封装的视频采集代码」· C头文件 代码 · 共 463 行 · 第 1/2 页

H
463
字号
////////////////////////////////////////////////////////////////////////////////    template <class To, class From>    struct StaticCaster    {        static To& Cast(From& obj)        {            return static_cast<To&>(obj);        }    };////////////////////////////////////////////////////////////////////////////////// class template DynamicCaster// Implementation of the CastingPolicy used by FunctorDispatcher////////////////////////////////////////////////////////////////////////////////    template <class To, class From>    struct DynamicCaster    {        static To& Cast(From& obj)        {            return dynamic_cast<To&>(obj);        }    };////////////////////////////////////////////////////////////////////////////////// class template Private::FnDispatcherHelper// Implements trampolines and argument swapping used by FnDispatcher////////////////////////////////////////////////////////////////////////////////    namespace Private    {        template <class BaseLhs, class BaseRhs,	    class SomeLhs, class SomeRhs,            typename ResultType,            class CastLhs, class CastRhs,            ResultType (*Callback)(SomeLhs&, SomeRhs&)>        struct FnDispatcherHelper        {            static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs)            {                return Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs));            }            static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs)            {                return Trampoline(lhs, rhs);            }        };    }////////////////////////////////////////////////////////////////////////////////// class template FnDispatcher// Implements an automatic logarithmic double dispatcher for functions// Features automated conversions////////////////////////////////////////////////////////////////////////////////    template <class BaseLhs, class BaseRhs = BaseLhs,              typename ResultType = void,              template <class, class> class CastingPolicy = DynamicCaster,              template <class, class, class, class>              class DispatcherBackend = BasicDispatcher>    class FnDispatcher    {        DispatcherBackend<BaseLhs, BaseRhs, ResultType,            ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_;    public:        template <class SomeLhs, class SomeRhs>        //### BCB - here it was probably buggy        void Add(ResultType (*pFun)(SomeLhs&, SomeRhs&))        {            return backEnd_.Add<SomeLhs, SomeRhs>((ResultType (*)(BaseLhs&, BaseRhs&))pFun);        }        template <class SomeLhs, class SomeRhs,            ResultType (*callback)(SomeLhs&, SomeRhs&)>        void Add()        {	    typedef Private::FnDispatcherHelper<					BaseLhs, BaseRhs,					SomeLhs, SomeRhs,					ResultType,					CastingPolicy<SomeLhs,BaseLhs>,					CastingPolicy<SomeRhs,BaseRhs>,					callback> Local;            Add<SomeLhs, SomeRhs>(&Local::Trampoline);        }        template <class SomeLhs, class SomeRhs,            ResultType (*callback)(SomeLhs&, SomeRhs&),            bool symmetric>        void Add()        {	    typedef Private::FnDispatcherHelper<					BaseLhs, BaseRhs,					SomeLhs, SomeRhs,					ResultType,					CastingPolicy<SomeLhs,BaseLhs>,					CastingPolicy<SomeRhs,BaseRhs>,					callback> Local;            Add<SomeLhs, SomeRhs>(&Local::Trampoline);            if (symmetric)            {                Add<SomeRhs, SomeLhs>(&Local::TrampolineR);            }        }        template <class SomeLhs, class SomeRhs>        void Remove()        {            backEnd_.Remove<SomeLhs, SomeRhs>();        }        ResultType Go(BaseLhs& lhs, BaseRhs& rhs)        {            return backEnd_.Go(lhs, rhs);        }    };////////////////////////////////////////////////////////////////////////////////// class template FunctorDispatcherAdaptor// permits use of FunctorDispatcher under gcc.2.95.2/3///////////////////////////////////////////////////////////////////////////////    namespace Private    {	template <class BaseLhs, class BaseRhs,		  class SomeLhs, class SomeRhs,		  typename ResultType,		  class CastLhs, class CastRhs,		  class Fun, bool SwapArgs>        class FunctorDispatcherHelper        {            Fun fun_;            ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type<false>)            {                return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));            }            ResultType Fire(BaseLhs& rhs, BaseRhs& lhs,Int2Type<true>)            {                return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));            }        public:            FunctorDispatcherHelper(const Fun& fun) : fun_(fun) {}            ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)            {                return Fire(lhs,rhs,Int2Type<SwapArgs>());            }        };    }////////////////////////////////////////////////////////////////////////////////// class template FunctorDispatcher// Implements a logarithmic double dispatcher for functors// Features automated casting////////////////////////////////////////////////////////////////////////////////    template <class BaseLhs, class BaseRhs = BaseLhs,              typename ResultType = void,              template <class, class> class CastingPolicy = DynamicCaster,              template <class, class, class, class>              class DispatcherBackend = BasicDispatcher>    class FunctorDispatcher    {        typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList;        //### BCB - this causes compiler crash (even when only one parameter is used)        typedef Functor<ResultType, ArgsList, DEFAULT_THREADING> FunctorType;        DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType> backEnd_;    public:        template <class SomeLhs, class SomeRhs, class Fun>        void Add(const Fun& fun)        {            typedef Private::FunctorDispatcherHelper<					BaseLhs, BaseRhs,					SomeLhs, SomeRhs,					ResultType,					CastingPolicy<SomeLhs, BaseLhs>,					CastingPolicy<SomeRhs, BaseRhs>,					Fun, false> Adapter;            backEnd_.Add<SomeLhs, SomeRhs>(FunctorType(Adapter(fun)));	}        template <class SomeLhs, class SomeRhs, bool symmetric, class Fun>        void Add(const Fun& fun)        {	    Add<SomeLhs,SomeRhs>(fun);	    if (symmetric)	    {		// Note: symmetry only makes sense where BaseLhs==BaseRhs            	typedef Private::FunctorDispatcherHelper<					BaseLhs, BaseLhs,					SomeLhs, SomeRhs,					ResultType,					CastingPolicy<SomeLhs, BaseLhs>,					CastingPolicy<SomeRhs, BaseLhs>,					Fun, true> AdapterR;               	backEnd_.Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun)));	    }        }        template <class SomeLhs, class SomeRhs>        void Remove()        {            backEnd_.Remove<SomeLhs, SomeRhs>();        }        ResultType Go(BaseLhs& lhs, BaseRhs& rhs)        {            return backEnd_.Go(lhs, rhs);        }    };} // namespace Loki////////////////////////////////////////////////////////////////////////////////// Change log:// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!////////////////////////////////////////////////////////////////////////////////#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?