Changed pass-by-value to pass-by-reference.

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@984 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
rich_sposato 2009-02-02 06:23:28 +00:00
parent 2aa35ef4d7
commit 26d771c3a1

View file

@ -2,14 +2,14 @@
// The Loki Library // The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu // Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book: // This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any // Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright // purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this // notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation. // permission notice appear in supporting documentation.
// The author or Addison-Wesley Longman make no representations about the // The author or Addison-Wesley Longman make no representations about the
// suitability of this software for any purpose. It is provided "as is" // suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_MULTIMETHODS_INC_ #ifndef LOKI_MULTIMETHODS_INC_
@ -38,18 +38,18 @@ namespace Loki
namespace Private namespace Private
{ {
template <class SomeLhs, class SomeRhs, template <class SomeLhs, class SomeRhs,
class Executor, typename ResultType> class Executor, typename ResultType>
struct InvocationTraits struct InvocationTraits
{ {
static ResultType static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs, DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<false>) Executor& exec, Int2Type<false>)
{ {
return exec.Fire(lhs, rhs); return exec.Fire(lhs, rhs);
} }
static ResultType static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs, DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<true>) Executor& exec, Int2Type<true>)
{ {
return exec.Fire(rhs, lhs); return exec.Fire(rhs, lhs);
@ -65,7 +65,7 @@ namespace Loki
template template
< <
class Executor, class Executor,
class BaseLhs, class BaseLhs,
class TypesLhs, class TypesLhs,
bool symmetric = true, bool symmetric = true,
class BaseRhs = BaseLhs, class BaseRhs = BaseLhs,
@ -76,35 +76,35 @@ namespace Loki
{ {
template <class SomeLhs> template <class SomeLhs>
static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs, static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
Executor exec, NullType) Executor & exec, NullType)
{ return exec.OnError(lhs, rhs); } { return exec.OnError(lhs, rhs); }
template <class Head, class Tail, class SomeLhs> template <class Head, class Tail, class SomeLhs>
static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs, static ResultType DispatchRhs(SomeLhs& lhs, BaseRhs& rhs,
Executor exec, Typelist<Head, Tail>) Executor & exec, Typelist<Head, Tail>)
{ {
if (Head* p2 = dynamic_cast<Head*>(&rhs)) if (Head* p2 = dynamic_cast<Head*>(&rhs))
{ {
Int2Type<(symmetric && Int2Type<(symmetric &&
int(TL::IndexOf<TypesRhs, Head>::value) < int(TL::IndexOf<TypesRhs, Head>::value) <
int(TL::IndexOf<TypesLhs, SomeLhs>::value))> i2t; int(TL::IndexOf<TypesLhs, SomeLhs>::value))> i2t;
typedef Private::InvocationTraits< typedef Private::InvocationTraits<
SomeLhs, Head, Executor, ResultType> CallTraits; 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, static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
Executor exec, NullType) Executor & exec, NullType)
{ return exec.OnError(lhs, rhs); } { return exec.OnError(lhs, rhs); }
template <class Head, class Tail> template <class Head, class Tail>
static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs, static ResultType DispatchLhs(BaseLhs& lhs, BaseRhs& rhs,
Executor exec, Typelist<Head, Tail>) Executor & exec, Typelist<Head, Tail>)
{ {
if (Head* p1 = dynamic_cast<Head*>(&lhs)) if (Head* p1 = dynamic_cast<Head*>(&lhs))
{ {
return DispatchRhs(*p1, rhs, exec, TypesRhs()); return DispatchRhs(*p1, rhs, exec, TypesRhs());
@ -114,10 +114,10 @@ namespace Loki
public: public:
static ResultType Go(BaseLhs& lhs, BaseRhs& rhs, static ResultType Go(BaseLhs& lhs, BaseRhs& rhs,
Executor exec) Executor & exec)
{ return DispatchLhs(lhs, rhs, exec, TypesLhs()); } { return DispatchLhs(lhs, rhs, exec, TypesLhs()); }
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// class template BasicDispatcher // class template BasicDispatcher
// Implements a logarithmic double dispatcher for functors (or functions) // Implements a logarithmic double dispatcher for functors (or functions)
@ -137,36 +137,36 @@ namespace Loki
typedef CallbackType MappedType; typedef CallbackType MappedType;
typedef AssocVector<KeyType, MappedType> MapType; typedef AssocVector<KeyType, MappedType> MapType;
MapType callbackMap_; MapType callbackMap_;
void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun); void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun);
bool DoRemove(TypeInfo lhs, TypeInfo rhs); bool DoRemove(TypeInfo lhs, TypeInfo rhs);
public: public:
template <class SomeLhs, class SomeRhs> template <class SomeLhs, class SomeRhs>
void Add(CallbackType fun) void Add(CallbackType fun)
{ {
DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun); DoAdd(typeid(SomeLhs), typeid(SomeRhs), fun);
} }
template <class SomeLhs, class SomeRhs> template <class SomeLhs, class SomeRhs>
bool Remove() bool Remove()
{ {
return DoRemove(typeid(SomeLhs), typeid(SomeRhs)); return DoRemove(typeid(SomeLhs), typeid(SomeRhs));
} }
ResultType Go(BaseLhs& lhs, BaseRhs& rhs); ResultType Go(BaseLhs& lhs, BaseRhs& rhs);
}; };
// Non-inline to reduce compile time overhead... // Non-inline to reduce compile time overhead...
template <class BaseLhs, class BaseRhs, template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType> typename ResultType, typename CallbackType>
void BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType> void BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun) ::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun)
{ {
callbackMap_[KeyType(lhs, rhs)] = fun; callbackMap_[KeyType(lhs, rhs)] = fun;
} }
template <class BaseLhs, class BaseRhs, template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType> typename ResultType, typename CallbackType>
bool BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType> bool BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
::DoRemove(TypeInfo lhs, TypeInfo rhs) ::DoRemove(TypeInfo lhs, TypeInfo rhs)
@ -174,7 +174,7 @@ namespace Loki
return callbackMap_.erase(KeyType(lhs, rhs)) == 1; return callbackMap_.erase(KeyType(lhs, rhs)) == 1;
} }
template <class BaseLhs, class BaseRhs, template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType> typename ResultType, typename CallbackType>
ResultType BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType> ResultType BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
::Go(BaseLhs& lhs, BaseRhs& rhs) ::Go(BaseLhs& lhs, BaseRhs& rhs)
@ -254,42 +254,42 @@ namespace Loki
class DispatcherBackend = BasicDispatcher> class DispatcherBackend = BasicDispatcher>
class FnDispatcher class FnDispatcher
{ {
DispatcherBackend<BaseLhs, BaseRhs, ResultType, DispatcherBackend<BaseLhs, BaseRhs, ResultType,
ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_; ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_;
public: public:
template <class SomeLhs, class SomeRhs> template <class SomeLhs, class SomeRhs>
void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&)) void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&))
{ {
return backEnd_.template Add<SomeLhs, SomeRhs>(pFun); return backEnd_.template Add<SomeLhs, SomeRhs>(pFun);
} }
template <class SomeLhs, class SomeRhs, template <class SomeLhs, class SomeRhs,
ResultType (*callback)(SomeLhs&, SomeRhs&)> ResultType (*callback)(SomeLhs&, SomeRhs&)>
void Add() void Add()
{ {
typedef Private::FnDispatcherHelper< typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs, BaseLhs, BaseRhs,
SomeLhs, SomeRhs, SomeLhs, SomeRhs,
ResultType, ResultType,
CastingPolicy<SomeLhs,BaseLhs>, CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>, CastingPolicy<SomeRhs,BaseRhs>,
callback> Local; callback> Local;
Add<SomeLhs, SomeRhs>(&Local::Trampoline); Add<SomeLhs, SomeRhs>(&Local::Trampoline);
} }
template <class SomeLhs, class SomeRhs, template <class SomeLhs, class SomeRhs,
ResultType (*callback)(SomeLhs&, SomeRhs&), ResultType (*callback)(SomeLhs&, SomeRhs&),
bool symmetric> bool symmetric>
void Add(bool = true) // [gcc] dummy bool void Add(bool = true) // [gcc] dummy bool
{ {
typedef Private::FnDispatcherHelper< typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs, BaseLhs, BaseRhs,
SomeLhs, SomeRhs, SomeLhs, SomeRhs,
ResultType, ResultType,
CastingPolicy<SomeLhs,BaseLhs>, CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>, CastingPolicy<SomeRhs,BaseRhs>,
callback> Local; callback> Local;
Add<SomeLhs, SomeRhs>(&Local::Trampoline); Add<SomeLhs, SomeRhs>(&Local::Trampoline);
@ -298,7 +298,7 @@ namespace Loki
Add<SomeRhs, SomeLhs>(&Local::TrampolineR); Add<SomeRhs, SomeLhs>(&Local::TrampolineR);
} }
} }
template <class SomeLhs, class SomeRhs> template <class SomeLhs, class SomeRhs>
void Remove() void Remove()
{ {
@ -323,7 +323,7 @@ namespace Loki
typename ResultType, typename ResultType,
class CastLhs, class CastRhs, class CastLhs, class CastRhs,
class Fun, bool SwapArgs> class Fun, bool SwapArgs>
class FunctorDispatcherHelper class FunctorDispatcherHelper
{ {
Fun fun_; Fun fun_;
ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type<false>) ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type<false>)
@ -352,7 +352,7 @@ namespace Loki
template <class BaseLhs, class BaseRhs = BaseLhs, template <class BaseLhs, class BaseRhs = BaseLhs,
typename ResultType = void, typename ResultType = void,
template <class, class> class CastingPolicy = DynamicCaster, template <class, class> class CastingPolicy = DynamicCaster,
template <class, class, class, class> template <class, class, class, class>
class DispatcherBackend = BasicDispatcher> class DispatcherBackend = BasicDispatcher>
class FunctorDispatcher class FunctorDispatcher
@ -395,7 +395,7 @@ namespace Loki
backEnd_.template Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun))); backEnd_.template Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun)));
} }
} }
template <class SomeLhs, class SomeRhs> template <class SomeLhs, class SomeRhs>
void Remove() void Remove()
{ {