From ba50ac6da231fa4f2bbcbf6b3393abdeb4af0c10 Mon Sep 17 00:00:00 2001 From: humesikkins Date: Thu, 27 Feb 2003 15:51:56 +0000 Subject: [PATCH] added support for return type void git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@101 7ec92016-0320-0410-acc4-a06ded1c099a --- MSVC/1200/MultiMethods.h | 734 ++++++++++++++++++++++++++++----------- 1 file changed, 526 insertions(+), 208 deletions(-) diff --git a/MSVC/1200/MultiMethods.h b/MSVC/1200/MultiMethods.h index 12aa4a8..1303c2d 100644 --- a/MSVC/1200/MultiMethods.h +++ b/MSVC/1200/MultiMethods.h @@ -13,30 +13,29 @@ // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// -// Last update: Oct 28, 2002 -// Because MSVC 6.0 does not allow a functions with a return -// type of cv void to return an expression of type "cv void" (6.6.3), this -// port currently *does not* support void as return type. +// Last update: Feb 19, 2003 +// All dispatchers now support void as return type. +// // -// Because the VC 6.0 does not support explicit template argument specification -// for member functions (14.8.1), I added dummy parameters to functions -// requiring this feature. +// The port now uses Tye2Type-parameters instead of plain pointers as +// a workaround of VC's explicit template argument specification bug. +// // For example: // The original declaration of BasicDispatcher::Add looks like this: // // template // void Add(CallbackType fun); - +// // and you call it like this: // obj.Add(yourFun); // // This port uses: // // template -// void Add(CallbackType fun, SomeLhs* pDummy1, SomeRhs* pDummy2); +// void Add(CallbackType fun, Type2Type, Type2Type); // // and you call it like this: -// obj.Add(yourFun, (Type1*)0, (Type2*)0); +// obj.Add(yourFun, Type2Type(), Type2Type()); #ifndef MULTIMETHODS_INC_ @@ -55,36 +54,153 @@ namespace Loki { -//////////////////////////////////////////////////////////////////////////////// -// class template InvocationTraits (helper) -// Helps implementing optional symmetry -//////////////////////////////////////////////////////////////////////////////// - namespace Private +//////////////////////////////////////////////////////////////////////////////// +// Implementation helpers for StaticDispatcher +//////////////////////////////////////////////////////////////////////////////// + +namespace Private +{ + template + struct InvocationTraits { - template - struct InvocationTraits + static ResultType + DoDispatch(SomeLhs& lhs, SomeRhs& rhs, Executor& exec, Int2Type) { - static ResultType - DoDispatch(SomeLhs& lhs, SomeRhs& rhs, Executor& exec, Int2Type) - { - return exec.Fire(lhs, rhs); - } - static ResultType DoDispatch( SomeLhs& lhs, SomeRhs& rhs, - Executor& exec, Int2Type) - { - return exec.Fire(rhs, lhs); - } - }; - } + return exec.Fire(lhs, rhs); + } + static ResultType DoDispatch( SomeLhs& lhs, SomeRhs& rhs, + Executor& exec, Int2Type) + { + return exec.Fire(rhs, lhs); + } + }; + + template + struct InvocationTraitsVoid + { + typedef void ResultType; + static ResultType + DoDispatch(SomeLhs& lhs, SomeRhs& rhs, Executor& exec, Int2Type) + { + exec.Fire(lhs, rhs); + } + static ResultType DoDispatch( SomeLhs& lhs, SomeRhs& rhs, + Executor& exec, Int2Type) + { + exec.Fire(rhs, lhs); + } + }; + + // Implementation for StaticDispatcher with result type != void + template + class StaticDispatcherBase + { + template + static ResultType DispatchRhs( SomeLhs& lhs, BaseRhs& rhs, + Executor exec, NullType) + { return exec.OnError(lhs, rhs); } + + template + static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs, + Executor exec, Typelist) + { + if (Head* p2 = dynamic_cast(&rhs)) + { + Int2Type<(symmetric && + int(TL::IndexOf::value) < + int(TL::IndexOf::value))> i2t; + + typedef Private::InvocationTraits< + SomeLhs, Head, Executor, ResultType> CallTraits; + + return CallTraits::DoDispatch(lhs, *p2, exec, i2t); + } + return DispatchRhs(lhs, rhs, exec, Tail()); + } + + static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, + Executor exec, NullType) + { return exec.OnError(lhs, rhs); } + + template + static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, + Executor exec, Typelist) + { + if (Head* p1 = dynamic_cast(&lhs)) + { + return DispatchRhs(*p1, rhs, exec, TypesRhs()); + } + return DispatchLhs(lhs, rhs, exec, Tail()); + } + + public: + static ResultType Go( BaseLhs& lhs, BaseRhs& rhs, + Executor exec) + { return DispatchLhs(lhs, rhs, exec, TypesLhs()); } + }; + + // Implementation for StaticDispatcher with result type = void + template + class StaticDispatcherVoidBase + { + typedef void ResultType; + template + static ResultType DispatchRhs( SomeLhs& lhs, BaseRhs& rhs, + Executor exec, NullType) + { exec.OnError(lhs, rhs); } + + template + static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs, + Executor exec, Typelist) + { + if (Head* p2 = dynamic_cast(&rhs)) + { + Int2Type<(symmetric && + int(TL::IndexOf::value) < + int(TL::IndexOf::value))> i2t; + + typedef Private::InvocationTraitsVoid< + SomeLhs, Head, Executor> CallTraits; + + CallTraits::DoDispatch(lhs, *p2, exec, i2t); + return; + } + DispatchRhs(lhs, rhs, exec, Tail()); + } + + static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, + Executor exec, NullType) + { exec.OnError(lhs, rhs); } + + template + static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, + Executor exec, Typelist) + { + if (Head* p1 = dynamic_cast(&lhs)) + { + DispatchRhs(*p1, rhs, exec, TypesRhs()); + return; + } + DispatchLhs(lhs, rhs, exec, Tail()); + } + + public: + static ResultType Go( BaseLhs& lhs, BaseRhs& rhs, + Executor exec) + { DispatchLhs(lhs, rhs, exec, TypesLhs()); } + }; + +} // namespace Private //////////////////////////////////////////////////////////////////////////////// // class template StaticDispatcher // Implements an automatic static double dispatcher based on two typelists //////////////////////////////////////////////////////////////////////////////// - - template + template < class Executor, class BaseLhs, @@ -92,123 +208,166 @@ namespace Loki bool symmetric = true, class BaseRhs = BaseLhs, class TypesRhs = TypesLhs, - typename ResultType = int/*void*/ + typename ResultType = int > - class StaticDispatcher + class StaticDispatcher : public ::Loki::Select + < + ::Loki::Private::IsVoid::value, + ::Loki::Private::StaticDispatcherVoidBase, + ::Loki::Private::StaticDispatcherBase + >::Result { - template - static ResultType DispatchRhs( SomeLhs& lhs, BaseRhs& rhs, - Executor exec, NullType) - { return exec.OnError(lhs, rhs); } - template - static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs, - Executor exec, Typelist) - { - if (Head* p2 = dynamic_cast(&rhs)) - { - Int2Type<(symmetric && - int(TL::IndexOf::value) < - int(TL::IndexOf::value))> i2t; - - typedef Private::InvocationTraits< - SomeLhs, Head, Executor, ResultType> CallTraits; - - return CallTraits::DoDispatch(lhs, *p2, exec, i2t); - } - return DispatchRhs(lhs, rhs, exec, Tail()); - } - - static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, - Executor exec, NullType) - { return exec.OnError(lhs, rhs); } - - template - static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, - Executor exec, Typelist) - { - if (Head* p1 = dynamic_cast(&lhs)) - { - return DispatchRhs(*p1, rhs, exec, TypesRhs()); - } - return DispatchLhs(lhs, rhs, exec, Tail()); - } - public: - static ResultType Go( BaseLhs& lhs, BaseRhs& rhs, - Executor exec) - { return DispatchLhs(lhs, rhs, exec, TypesLhs()); } - }; - + // member functions moved to base class + // static ResultType Go( BaseLhs& lhs, BaseRhs& rhs, + // Executor exec) + }; + +//////////////////////////////////////////////////////////////////////////////// +// Implementation helpers for BasicDispatcher +//////////////////////////////////////////////////////////////////////////////// +namespace Private +{ + // Implementation for result types != void + template struct BasicDispatcherBase; + + // Implementation for result type = 0 + template struct BasicDispatcherVoidBase; + + // Common (independent of the result type) code for BasicDispatcher + template + class BasicDispatcherCommonBase + { + private: + void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun); + bool DoRemove(TypeInfo lhs, TypeInfo rhs); + protected: + typedef std::pair KeyType; + typedef CallbackType MappedType; + typedef AssocVector MapType; + MapType callbackMap_; + public: + template + void Add(CallbackType fun, ::Loki::Type2Type, + ::Loki::Type2Type) + { + DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun); + } + + + template + bool Remove(::Loki::Type2Type, ::Loki::Type2Type) + { + return DoRemove(typeid(SomeLhs), typeid(SomeRhs)); + } + + }; + + // Non-inline to reduce compile time overhead... + template + void BasicDispatcherCommonBase + ::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun) + { + callbackMap_[KeyType(lhs, rhs)] = fun; + } + + template + bool BasicDispatcherCommonBase + ::DoRemove(TypeInfo lhs, TypeInfo rhs) + { + return callbackMap_.erase(KeyType(lhs, rhs)) == 1; + } + + // Implementation for result types != void + template + struct BasicDispatcherBase : public BasicDispatcherCommonBase + { + typedef BasicDispatcherCommonBase Base; + + ResultType Go(BaseLhs& lhs, BaseRhs& rhs); + }; + template + ResultType + BasicDispatcherBase + ::Go(BaseLhs& lhs, BaseRhs& rhs) + { + + typename MapType::key_type k(typeid(lhs),typeid(rhs)); + typename MapType::iterator i = Base::callbackMap_.find(k); + if (i == Base::callbackMap_.end()) + { + throw std::runtime_error("Function not found"); + } + return (i->second)(lhs, rhs); + } + + // Implementation for result types = void + template + struct BasicDispatcherVoidBase : public BasicDispatcherCommonBase + { + typedef void ResultType; + typedef BasicDispatcherCommonBase Base; + + ResultType Go(BaseLhs& lhs, BaseRhs& rhs); + }; + template + typename BasicDispatcherVoidBase::ResultType + BasicDispatcherVoidBase + ::Go(BaseLhs& lhs, BaseRhs& rhs) + { + + typename MapType::key_type k(typeid(lhs),typeid(rhs)); + typename MapType::iterator i = Base::callbackMap_.find(k); + if (i == Base::callbackMap_.end()) + { + throw std::runtime_error("Function not found"); + } + (i->second)(lhs, rhs); + } +} // namespace Private + //////////////////////////////////////////////////////////////////////////////// // class template BasicDispatcher // Implements a logarithmic double dispatcher for functors (or functions) // Doesn't offer automated casts or symmetry //////////////////////////////////////////////////////////////////////////////// - - template + template < class BaseLhs, class BaseRhs = BaseLhs, - typename ResultType = int/*void*/, + typename ResultType = int, typename CallbackType = ResultType (*)(BaseLhs&, BaseRhs&) > - class BasicDispatcher + class BasicDispatcher : public ::Loki::Select + < + ::Loki::Private::IsVoid::value, + ::Loki::Private::BasicDispatcherVoidBase< + BaseLhs, BaseRhs, CallbackType>, + ::Loki::Private::BasicDispatcherBase< + BaseLhs, BaseRhs, ResultType, CallbackType> + >::Result { - typedef std::pair KeyType; - typedef CallbackType MappedType; - typedef AssocVector MapType; - MapType callbackMap_; - - void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun); - bool DoRemove(TypeInfo lhs, TypeInfo rhs); - - public: - template - void Add(CallbackType fun, SomeLhs* pDummy1, SomeRhs* pDummy2) - { - DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun); - } - - template - bool Remove(SomeLhs pDummy1, SomeRhs pDummy2) - { - return DoRemove(typeid(SomeLhs), typeid(SomeRhs)); - } - - ResultType Go(BaseLhs& lhs, BaseRhs& rhs); + public: + // member functions moved to base class + // template + // void Add(CallbackType fun, ::Loki::Type2Type, + // ::Loki::Type2Type) + // + // template + // bool Remove(::Loki::Type2Type, ::Loki::Type2Type) + // + // ResultType Go(BaseLhs& lhs, BaseRhs& rhs); }; - // Non-inline to reduce compile time overhead... - template - void BasicDispatcher - ::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun) - { - callbackMap_[KeyType(lhs, rhs)] = fun; - } - - template - bool BasicDispatcher - ::DoRemove(TypeInfo lhs, TypeInfo rhs) - { - return callbackMap_.erase(KeyType(lhs, rhs)) == 1; - } - - template - ResultType BasicDispatcher - ::Go(BaseLhs& lhs, BaseRhs& rhs) - { - typename MapType::key_type k(typeid(lhs),typeid(rhs)); - typename MapType::iterator i = callbackMap_.find(k); - if (i == callbackMap_.end()) - { - throw std::runtime_error("Function not found"); - } - return (i->second)(lhs, rhs); - } struct BasicDispatcherWrapper { @@ -249,7 +408,7 @@ namespace Loki { static To& Cast(From& obj) { - return dynamic_cast(obj); + return dynamic_cast(obj); } }; struct DynamicCasterWrapper @@ -265,26 +424,84 @@ namespace Loki // class template Private::FnDispatcherHelper // Implements trampolines and argument swapping used by FnDispatcher //////////////////////////////////////////////////////////////////////////////// - - namespace Private + namespace Private { - template + template + struct FnDispatcherBase + { + ApplyInnerType4::type backEnd_; + + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + return backEnd_.Go(lhs, rhs); + } + }; + + template + struct FnDispatcherVoidBase + { + typedef void ResultType; + ApplyInnerType4::type backEnd_; + + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + backEnd_.Go(lhs, rhs); + } + }; + + + template< class BaseLhs, class BaseRhs, class SomeLhs, class SomeRhs, + class CastLhs, class CastRhs, + void (*Callback)(SomeLhs&, SomeRhs&)> + struct FnDispatcherHelperVoidBase + { + typedef void ResultType; + static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs) + { + Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); + } + static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs) + { + Trampoline(lhs, rhs); + } + }; + + template + struct FnDispatcherHelperBase + { + typedef void ResultType; + static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs) + { + Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); + } + static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs) + { + Trampoline(lhs, rhs); + } + }; + + 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); - } - }; + struct FnDispatcherHelper : public ::Loki::Select + < + ::Loki::Private::IsVoid::value, + FnDispatcherHelperVoidBase, + FnDispatcherHelperBase + >::Result + {}; } //////////////////////////////////////////////////////////////////////////////// @@ -297,21 +514,36 @@ namespace Loki typename ResultType = int/*void*/, class CastingPolicy = DynamicCasterWrapper, class DispatcherBackend = BasicDispatcherWrapper> - class FnDispatcher + class FnDispatcher : public ::Loki::Select + < + ::Loki::Private::IsVoid::value, + ::Loki::Private::FnDispatcherVoidBase, + ::Loki::Private::FnDispatcherBase + >::Result { - ApplyInnerType4::type backEnd_; + typedef typename ::Loki::Select + <::Loki::Private::IsVoid::value, + ::Loki::Private::FnDispatcherVoidBase, + ::Loki::Private::FnDispatcherBase + >::Result Base; public: template - void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&), SomeLhs* pDummy1, SomeRhs* pDummy2) + void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&), + ::Loki::Type2Type, + ::Loki::Type2Type) { - return backEnd_.Add(pFun, pDummy1, pDummy2); + Base::backEnd_.Add(pFun, ::Loki::Type2Type(), + ::Loki::Type2Type()); } template - void Add(SomeLhs* pDummy1, SomeRhs* pDummy2) + void Add(::Loki::Type2Type, ::Loki::Type2Type) { typedef Private::FnDispatcherHelper< BaseLhs, BaseRhs, @@ -321,12 +553,14 @@ namespace Loki typename ApplyInnerType2::type, callback> Local; - Add(&Local::Trampoline, (SomeLhs*)0, (SomeRhs*)0); + Add(&Local::Trampoline, ::Loki::Type2Type(), + ::Loki::Type2Type()); } template - void Add(SomeLhs* pDummy1, SomeRhs* pDummy2, bool Symmetric) + void Add(::Loki::Type2Type, ::Loki::Type2Type, + bool Symmetric) { typedef Private::FnDispatcherHelper< BaseLhs, BaseRhs, @@ -336,23 +570,25 @@ namespace Loki typename ApplyInnerType2::type, callback> Local; - Add(&Local::Trampoline, (SomeLhs*)0, (SomeRhs*)0); + Add(&Local::Trampoline, ::Loki::Type2Type(), + ::Loki::Type2Type()); if (Symmetric) { - Add(&Local::Trampoline, (SomeLhs*)0, (SomeRhs*)0); + Add(&Local::Trampoline, ::Loki::Type2Type(), + ::Loki::Type2Type()); } } template - void Remove(SomeLhs* pDummy1, SomeRhs* pDummy2) + void Remove(::Loki::Type2Type, ::Loki::Type2Type) { - backEnd_.Remove(pDummy1, pDummy2); + Base::backEnd_.Remove(::Loki::Type2Type(), + ::Loki::Type2Type()); } - ResultType Go(BaseLhs& lhs, BaseRhs& rhs) - { - return backEnd_.Go(lhs, rhs); - } + + // moved to base class + // ResultType Go(BaseLhs& lhs, BaseRhs& rhs); }; //////////////////////////////////////////////////////////////////////////////// @@ -362,11 +598,8 @@ namespace Loki namespace Private { - template + template class FunctorDispatcherHelper { Fun fun_; @@ -386,6 +619,76 @@ namespace Loki return Fire(lhs,rhs,Int2Type()); } }; + + template + class FunctorDispatcherHelperVoid + { + Fun fun_; + typedef void ResultType; + ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type) + { + fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); + } + ResultType Fire(BaseLhs& rhs, BaseRhs& lhs,Int2Type) + { + fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); + } + public: + FunctorDispatcherHelperVoid(const Fun& fun) : fun_(fun) {} + + ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) + { + Fire(lhs,rhs,Int2Type()); + } + }; + + template + class FunctorDispatcherCommonBase + { + protected: + typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList; + typedef Functor FunctorType; + + ApplyInnerType4::type backEnd_; + }; + + template + class FunctorDispatcherBase : public FunctorDispatcherCommonBase + { + typedef FunctorDispatcherCommonBase Base; + public: + typedef typename Base::ArgsList ArgsList; + typedef typename Base::FunctorType FunctorType; + + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + return Base::backEnd_.Go(lhs, rhs); + } + }; + + template + class FunctorDispatcherVoidBase : public FunctorDispatcherCommonBase + { + typedef void ResultType; + typedef FunctorDispatcherCommonBase Base; + public: + typedef typename Base::ArgsList ArgsList; + typedef typename Base::FunctorType FunctorType; + + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + Base::backEnd_.Go(lhs, rhs); + } + + }; } //////////////////////////////////////////////////////////////////////////////// @@ -398,61 +701,74 @@ namespace Loki typename ResultType = int/*void*/, class CastingPolicy = DynamicCasterWrapper, class DispatcherBackend = BasicDispatcherWrapper> - class FunctorDispatcher + class FunctorDispatcher : public ::Loki::Select + < + ::Loki::Private::IsVoid::value, + ::Loki::Private::FunctorDispatcherVoidBase, + ::Loki::Private::FunctorDispatcherBase + >::Result { - typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList; - typedef Functor FunctorType; - - ApplyInnerType4::type backEnd_; - + typedef typename ::Loki::Select + < + ::Loki::Private::IsVoid::value, + ::Loki::Private::FunctorDispatcherVoidBase, + ::Loki::Private::FunctorDispatcherBase + >::Result Base; public: - template - void Add(const Fun& fun, SomeLhs* pDummy1, SomeRhs* pDummy2) + typedef Base::ArgsList ArgsList; + typedef Base::FunctorType FunctorType; + template + void Add(const Fun& fun, ::Loki::Type2Type, + ::Loki::Type2Type) { typedef typename ApplyInnerType2::type CastOne; typedef typename ApplyInnerType2::type CastTwo; - typedef Private::FunctorDispatcherHelper< - BaseLhs, BaseRhs, - SomeLhs, SomeRhs, - ResultType, - CastOne, - CastTwo, - Fun, false> Adapter; - - - - backEnd_.Add(FunctorType(Adapter(fun), (int*) 0), pDummy1, pDummy2); - } + typedef typename Select< + Private::IsVoid::value, + Private::FunctorDispatcherHelperVoid, + Private::FunctorDispatcherHelper + >::Result Adapter; + Base::backEnd_.Add(FunctorType(Adapter(fun), Loki::Disambiguate()), + Type2Type(), Type2Type()); + } template - void Add(const Fun& fun, SomeLhs* pDummy1, SomeRhs* pDummy2, bool symmetric) + void Add(const Fun& fun, ::Loki::Type2Type, + ::Loki::Type2Type, bool symmetric) { - Add(fun, pDummy1, pDummy2); + Add(fun, Type2Type(), Type2Type()); - if (symmetric) - { - // Note: symmetry only makes sense where BaseLhs==BaseRhs - typedef Private::FunctorDispatcherHelper< - BaseLhs, BaseLhs, - SomeLhs, SomeRhs, - ResultType, - ApplyInnerType2::type, - ApplyInnerType2::type, - Fun, true> AdapterR; + if (symmetric) + { + // Note: symmetry only makes sense where BaseLhs==BaseRhs + typedef typename ApplyInnerType2::type CastOne; + typedef typename ApplyInnerType2::type CastTwo; + typedef typename Select::value, + Private::FunctorDispatcherHelperVoid, + Private::FunctorDispatcherHelper + >::Result AdapterR; - backEnd_.Add(FunctorType(Adapter(fun)), pDummy1, pDummy2); - } + Base::backEnd_.Add(FunctorType(Adapter(fun)), + Type2Type(), Type2Type()); + } } template - void Remove(SomeLhs* pDummy1, SomeRhs* pDummy2) + void Remove(::Loki::Type2Type, ::Loki::Type2Type) { - backEnd_.Remove(pDummy1, pDummy2); + Base::backEnd_.Remove(Type2Type(), Type2Type()); } - ResultType Go(BaseLhs& lhs, BaseRhs& rhs) - { - return backEnd_.Go(lhs, rhs); - } + // moved to base class + // ResultType Go(BaseLhs& lhs, BaseRhs& rhs); + }; } // namespace Loki @@ -461,6 +777,8 @@ namespace Loki // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) // Oct 28, 2002: ported by Benjamin Kaufmann +// Feb 19, 2003: replaced pointer-Dummies with Type2Type-Parameters and added +// support for return type void. //////////////////////////////////////////////////////////////////////////////// #endif