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