diff --git a/MSVC/1200/MultiMethods.h b/MSVC/1200/MultiMethods.h index a21dff6..fea09ce 100644 --- a/MSVC/1200/MultiMethods.h +++ b/MSVC/1200/MultiMethods.h @@ -13,7 +13,24 @@ // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// -// Last update: Mar 06, 2003 +// Last update: Mar 20, 2003 +// Interface change for FnDispatcher::Add: +// The trampoline-Version of FnDispatcher::Add needs explicit template +// argument specification for type and non-type parameters. Unfortunately +// all workarounds used so far failed for this member-function. +// Therefore I need to use a new one which leads to another interface change: +// Example (see "Modern C++ Design" Section 11.6) +// ---------------------------------------------- +// Using the original one writes: +// typedef FnDispatcher Dispatcher; +// void Hatch(Rectangle& lhs, Poly& rhs) {...} +// +// Dispatcher dis; +// disp.Add(); +// +// Using this port the example becomes: +// Dispatcher::AddI()(dis); +// // All dispatchers now have void as default value for return types. // All dispatchers now support void as return type. // @@ -62,143 +79,158 @@ namespace Loki namespace Private { - template - struct InvocationTraits - { - 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); - } - }; + template + struct InvocationTraitsBase + { + protected: + template + struct BaseImpl + { + 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); + } + }; + template <> + struct BaseImpl + { + 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); + } + }; + public: + typedef BaseImpl Base; + }; + template + struct InvocationTraits : public InvocationTraitsBase + ::Base + { + + }; - 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); } + private: + // Base for ResultType != void + template + class In + { + 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; + 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; + typedef Private::InvocationTraits< + SomeLhs, Head, Executor, ResultType> CallTraits; - return CallTraits::DoDispatch(lhs, *p2, exec, i2t); + return CallTraits::DoDispatch(lhs, *p2, exec, i2t); + } + return DispatchRhs(lhs, rhs, exec, Tail()); } - return DispatchRhs(lhs, rhs, exec, Tail()); - } - static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, - Executor exec, NullType) - { return exec.OnError(lhs, rhs); } + 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()); + 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()); } - return DispatchLhs(lhs, rhs, exec, Tail()); - } - protected: - ~StaticDispatcherBase() {} - public: - static ResultType Go( BaseLhs& lhs, BaseRhs& rhs, + protected: + ~In() {} + 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); } + { return DispatchLhs(lhs, rhs, exec, TypesLhs()); } + }; // In + + // Base for ResultType == void + template <> + class In + { + 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; + 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; + typedef Private::InvocationTraits< + SomeLhs, Head, Executor, void> CallTraits; - CallTraits::DoDispatch(lhs, *p2, exec, i2t); - return; + CallTraits::DoDispatch(lhs, *p2, exec, i2t); + return; + } + DispatchRhs(lhs, rhs, exec, Tail()); } - DispatchRhs(lhs, rhs, exec, Tail()); - } - static ResultType DispatchLhs( BaseLhs& lhs, BaseRhs& rhs, - Executor exec, NullType) - { exec.OnError(lhs, rhs); } + 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; + 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()); } - DispatchLhs(lhs, rhs, exec, Tail()); - } - protected: - ~StaticDispatcherVoidBase() {} + protected: + ~In() {} + public: + static ResultType Go( BaseLhs& lhs, BaseRhs& rhs, + Executor exec) + { DispatchLhs(lhs, rhs, exec, TypesLhs()); } + }; // In public: - static ResultType Go( BaseLhs& lhs, BaseRhs& rhs, - Executor exec) - { DispatchLhs(lhs, rhs, exec, TypesLhs()); } - }; - + typedef In Base; + }; // StaticDispatcherBase + } // namespace Private //////////////////////////////////////////////////////////////////////////////// @@ -215,16 +247,11 @@ namespace Private class TypesRhs = TypesLhs, typename ResultType = Loki::Private::VoidWrap::type > - class StaticDispatcher : public ::Loki::Select + class StaticDispatcher : public ::Loki::Private::StaticDispatcherBase < - ::Loki::Private::IsVoid::value, - ::Loki::Private::StaticDispatcherVoidBase, - ::Loki::Private::StaticDispatcherBase - >::Result + Executor, BaseLhs, TypesLhs, symmetric, + BaseRhs, TypesRhs, ResultType + >::Base { public: @@ -238,111 +265,83 @@ namespace Private //////////////////////////////////////////////////////////////////////////////// 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 + typename CallbackType> + class BasicDispatcherBase { 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_; - ~BasicDispatcherCommonBase() {} - public: - template - void Add(CallbackType fun, ::Loki::Type2Type, - ::Loki::Type2Type) + // Common (independent of the result type) code for BasicDispatcher + class Common { - DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun); - } + private: + void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun) + { + callbackMap_[KeyType(lhs, rhs)] = fun; + } + bool DoRemove(TypeInfo lhs, TypeInfo rhs) + { + return callbackMap_.erase(KeyType(lhs, rhs)) == 1; + } + protected: + typedef std::pair KeyType; + typedef CallbackType MappedType; + typedef AssocVector MapType; + MapType callbackMap_; + ~Common() {} + public: + template + void Add(CallbackType fun, ::Loki::Type2Type, + ::Loki::Type2Type) + { + DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun); + } - template - bool Remove(::Loki::Type2Type, ::Loki::Type2Type) + template + bool Remove(::Loki::Type2Type, ::Loki::Type2Type) + { + return DoRemove(typeid(SomeLhs), typeid(SomeRhs)); + } + }; // Common + template // Base for ResultType != void + class In : public Common { - return DoRemove(typeid(SomeLhs), typeid(SomeRhs)); - } + public: + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + typename MapType::key_type k(typeid(lhs),typeid(rhs)); + typename MapType::iterator i = Common::callbackMap_.find(k); + if (i == Common::callbackMap_.end()) + { + throw std::runtime_error("Function not found"); + } + return (i->second)(lhs, rhs); + } + protected: + ~In() {} + }; // In + template <> // Base for ResultType == void + class In : public Common + { + public: + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + typename MapType::key_type k(typeid(lhs),typeid(rhs)); + typename MapType::iterator i = Common::callbackMap_.find(k); + if (i == Common::callbackMap_.end()) + { + throw std::runtime_error("Function not found"); + } + (i->second)(lhs, rhs); + } + protected: + ~In() {} + }; // In - }; - - // 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); - protected: - ~BasicDispatcherBase() {} - }; - 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); - protected: - ~BasicDispatcherVoidBase() {} - }; - 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); - } + public: + typedef In Base; + }; // BasicDispatcherBase + } // namespace Private //////////////////////////////////////////////////////////////////////////////// @@ -357,14 +356,10 @@ namespace Private typename ResultType = Loki::Private::VoidWrap::type, typename CallbackType = ResultType (*)(BaseLhs&, BaseRhs&) > - class BasicDispatcher : public ::Loki::Select + class BasicDispatcher : public ::Loki::Private::BasicDispatcherBase < - ::Loki::Private::IsVoid::value, - ::Loki::Private::BasicDispatcherVoidBase< - BaseLhs, BaseRhs, CallbackType>, - ::Loki::Private::BasicDispatcherBase< - BaseLhs, BaseRhs, ResultType, CallbackType> - >::Result + BaseLhs, BaseRhs, ResultType, CallbackType + >::Base { public: // member functions moved to base class @@ -436,72 +431,84 @@ namespace Private //////////////////////////////////////////////////////////////////////////////// namespace Private { - template - struct FnDispatcherBase + class FnDispatcherBase { - ApplyInnerType4 + class In + { + public: + ApplyInnerType4::type backEnd_; - ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + return backEnd_.Go(lhs, rhs); + } + protected: + ~In() {} + }; // In + // Implementation for ResultType == void + template <> + class In { - return backEnd_.Go(lhs, rhs); - } - protected: - ~FnDispatcherBase() {} - }; - - template - struct FnDispatcherVoidBase - { - typedef void ResultType; - ApplyInnerType4::type backEnd_; - ResultType Go(BaseLhs& lhs, BaseRhs& rhs) - { - backEnd_.Go(lhs, rhs); - } - protected: - ~FnDispatcherVoidBase() {} - }; - - + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + backEnd_.Go(lhs, rhs); + } + protected: + ~In() {} + }; // In + public: + typedef In Base; + }; // FnDispatcherBase + template< class BaseLhs, class BaseRhs, class SomeLhs, class SomeRhs, - class CastLhs, class CastRhs, + class ResultType, 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); - } - protected: - ~FnDispatcherHelperVoidBase() {} - }; - - 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); - } - protected: - ~FnDispatcherHelperBase() {} - }; + class FnDispatcherHelperBase + { + private: + template + class In + { + public: + 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); + } + protected: + ~In() {} + }; + template <> + class In + { + public: + static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs) + { + Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); + } + static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs) + { + Trampoline(lhs, rhs); + } + protected: + ~In() {} + }; + public: + typedef In Base; + }; template < @@ -509,46 +516,33 @@ namespace Private typename ResultType, class CastLhs, class CastRhs, ResultType (*Callback)(SomeLhs&, SomeRhs&) > - struct FnDispatcherHelper : public ::Loki::Select + struct FnDispatcherHelper : public FnDispatcherHelperBase < - ::Loki::Private::IsVoid::value, - FnDispatcherHelperVoidBase, - FnDispatcherHelperBase - >::Result + BaseLhs, BaseRhs, SomeLhs, SomeRhs, + ResultType, CastLhs, CastRhs, Callback + >::Base {}; } - //////////////////////////////////////////////////////////////////////////////// // class template FnDispatcher // Implements an automatic logarithmic double dispatcher for functions // Features automated conversions //////////////////////////////////////////////////////////////////////////////// - template - class FnDispatcher : public ::Loki::Select + class FnDispatcher : public ::Loki::Private::FnDispatcherBase < - ::Loki::Private::IsVoid::value, - ::Loki::Private::FnDispatcherVoidBase, - ::Loki::Private::FnDispatcherBase - >::Result + BaseLhs, BaseRhs, + ResultType, DispatcherBackend + >::Base + { - typedef typename ::Loki::Select - <::Loki::Private::IsVoid::value, - ::Loki::Private::FnDispatcherVoidBase, - ::Loki::Private::FnDispatcherBase - >::Result Base; - + typedef typename ::Loki::Private::FnDispatcherBase + < + BaseLhs, BaseRhs, ResultType, DispatcherBackend + >::Base Base; public: template void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&), @@ -559,44 +553,29 @@ namespace Private ::Loki::Type2Type()); } - template - void Add(::Loki::Type2Type, ::Loki::Type2Type) - { - typedef Private::FnDispatcherHelper< - BaseLhs, BaseRhs, - SomeLhs, SomeRhs, - ResultType, - typename ApplyInnerType2::type, - typename ApplyInnerType2::type, - callback> Local; - - Add(&Local::Trampoline, ::Loki::Type2Type(), - ::Loki::Type2Type()); - } - template - void Add(::Loki::Type2Type, ::Loki::Type2Type, - bool Symmetric) - { - typedef Private::FnDispatcherHelper< - BaseLhs, BaseRhs, - SomeLhs, SomeRhs, - ResultType, - typename ApplyInnerType2::type, - typename ApplyInnerType2::type, + template + struct AddI + { + void operator()(FnDispatcher& f) + { + typedef Private::FnDispatcherHelper< + BaseLhs, BaseRhs, SomeLhs, SomeRhs, ResultType, + ApplyInnerType2::type, + ApplyInnerType2::type, callback> Local; - - Add(&Local::Trampoline, ::Loki::Type2Type(), + f.Add(&Local::Trampoline, ::Loki::Type2Type(), ::Loki::Type2Type()); - if (Symmetric) - { - Add(&Local::Trampoline, ::Loki::Type2Type(), - ::Loki::Type2Type()); - } - } - + if (symmetric) + { + f.Add(&Local::TrampolineR, ::Loki::Type2Type(), + ::Loki::Type2Type()); + } + } + }; + template void Remove(::Loki::Type2Type, ::Loki::Type2Type) { @@ -608,7 +587,7 @@ namespace Private // moved to base class // ResultType Go(BaseLhs& lhs, BaseRhs& rhs); }; - + //////////////////////////////////////////////////////////////////////////////// // class template FunctorDispatcherAdaptor // permits use of FunctorDispatcher under gcc.2.95.2/3 @@ -618,99 +597,118 @@ namespace Private { template - class FunctorDispatcherHelper - { - Fun fun_; - ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type) - { - return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); - } - ResultType Fire(BaseLhs& rhs, BaseRhs& lhs,Int2Type) - { - 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()); - } - }; - - 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 + class FunctorDispatcherHelperBase { - protected: - typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList; - typedef Functor FunctorType; + template + class In + { + Fun fun_; + ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type) + { + return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); + } + ResultType Fire(BaseLhs& rhs, BaseRhs& lhs,Int2Type) + { + return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); + } + public: + In(const Fun& fun) : fun_(fun) {} - ApplyInnerType4::type backEnd_; - ~FunctorDispatcherCommonBase() {} + ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) + { + return Fire(lhs,rhs,Int2Type()); + } + }; + template <> + class In + { + Fun fun_; + 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: + In(const Fun& fun) : fun_(fun) {} + + ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) + { + Fire(lhs,rhs,Int2Type()); + } + }; + public: + typedef In Base; + }; // FunctorDispatcherHelperBase + + template + class FunctorDispatcherHelper : public FunctorDispatcherHelperBase + < + BaseLhs, BaseRhs, SomeLhs, SomeRhs, + ResultType, CastLhs, CastRhs, Fun, + SwapArgs + >::Base + { + private: + typedef typename FunctorDispatcherHelperBase + < + BaseLhs, BaseRhs, SomeLhs, SomeRhs, + ResultType, CastLhs, CastRhs, Fun, SwapArgs + >::Base Base; + public: + FunctorDispatcherHelper(const Fun& f) : Base(f) + {} }; template - class FunctorDispatcherBase : public FunctorDispatcherCommonBase + class FunctorDispatcherBase { - typedef FunctorDispatcherCommonBase Base; - public: - typedef typename Base::ArgsList ArgsList; - typedef typename Base::FunctorType FunctorType; - - ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + private: + class Common { - return Base::backEnd_.Go(lhs, rhs); - } - protected: - ~FunctorDispatcherBase() {} + protected: + typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList; + typedef Functor FunctorType; + + ApplyInnerType4::type backEnd_; + ~Common() {} + }; + + template + class In : public Common + { + public: + typedef typename Common::ArgsList ArgsList; + typedef typename Common::FunctorType FunctorType; + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + return Common::backEnd_.Go(lhs, rhs); + } + protected: + In() {} + }; + template <> + class In : public Common + { + public: + typedef typename Common::ArgsList ArgsList; + typedef typename Common::FunctorType FunctorType; + ResultType Go(BaseLhs& lhs, BaseRhs& rhs) + { + Common::backEnd_.Go(lhs, rhs); + } + protected: + In() {} + }; + public: + typedef In Base; }; - 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); - } - protected: - ~FunctorDispatcherVoidBase() {} - }; } //////////////////////////////////////////////////////////////////////////////// @@ -723,23 +721,15 @@ namespace Private typename ResultType = Loki::Private::VoidWrap::type, class CastingPolicy = DynamicCasterWrapper, class DispatcherBackend = BasicDispatcherWrapper> - class FunctorDispatcher : public ::Loki::Select - < - ::Loki::Private::IsVoid::value, - ::Loki::Private::FunctorDispatcherVoidBase, - ::Loki::Private::FunctorDispatcherBase - >::Result + class FunctorDispatcher : public ::Loki::Private::FunctorDispatcherBase + < + ResultType, BaseLhs, BaseRhs, DispatcherBackend + >::Base { - typedef typename ::Loki::Select - < - ::Loki::Private::IsVoid::value, - ::Loki::Private::FunctorDispatcherVoidBase, - ::Loki::Private::FunctorDispatcherBase - >::Result Base; + typedef typename ::Loki::Private::FunctorDispatcherBase + < + ResultType, BaseLhs, BaseRhs, DispatcherBackend + >::Base Base; public: typedef Base::ArgsList ArgsList; typedef Base::FunctorType FunctorType; @@ -749,13 +739,12 @@ namespace Private { typedef typename ApplyInnerType2::type CastOne; typedef typename ApplyInnerType2::type CastTwo; - typedef typename Select< - Private::IsVoid::value, - Private::FunctorDispatcherHelperVoid, - Private::FunctorDispatcherHelper - >::Result Adapter; + typedef typename + Private::FunctorDispatcherHelper + < + BaseLhs, BaseRhs, SomeLhs, SomeRhs, + ResultType,CastOne,CastTwo,Fun, false + >::Base Adapter; Base::backEnd_.Add(FunctorType(Adapter(fun), Loki::Disambiguate()), Type2Type(), Type2Type()); } @@ -770,15 +759,15 @@ namespace Private // 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; + typedef typename + Private::FunctorDispatcherHelper + < + BaseLhs, BaseRhs, SomeLhs, SomeRhs, + ResultType,CastOne,CastTwo,Fun, true + >::Base AdapterR; - Base::backEnd_.Add(FunctorType(Adapter(fun)), - Type2Type(), Type2Type()); + Base::backEnd_.Add(FunctorType(AdapterR(fun), Loki::Disambiguate()), + Type2Type(), Type2Type()); } } @@ -803,6 +792,9 @@ namespace Private // support for return type void. B.K. // Mar 06, 2003: Changed default values for return types to void. // Added protected destructors to private implementation classes B.K. +// Mar 20. 2003: Fixed Bugs in FnDispatcherHelperBase, FnDispatcher::Add and +// FunctorDispatcher::Add. +// New Interface for FnDispatcher::Add.B.K. //////////////////////////////////////////////////////////////////////////////// #endif