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 + -
显示快捷键?