⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multimethods.h

📁 loki 程序库
💻 H
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////////

    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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -