June 20, 2001 revision:

* ported by Nick Thurn to gcc
* many bug fixes


git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@7 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
aandrei 2001-11-21 09:31:45 +00:00
parent 2ffd6b016f
commit 1fadda9836
24 changed files with 612 additions and 686 deletions

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef ABSTRACTFACTORY_INC_
#define ABSTRACTFACTORY_INC_
@ -76,7 +76,7 @@ namespace Loki
typedef typename BaseProductList::Tail ProductList;
public:
typedef BaseProductList::Head AbstractProduct;
typedef typename BaseProductList::Head AbstractProduct;
ConcreteProduct* DoCreate(Type2Type<AbstractProduct>)
{
return new ConcreteProduct;
@ -156,4 +156,9 @@ namespace Loki
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // ABSTRACTFACTORY_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef ASSOCVECTOR_INC_
#define ASSOCVECTOR_INC_
@ -22,7 +22,6 @@
#include <functional>
#include <vector>
#include <utility>
#include <utility>
namespace Loki
{
@ -140,7 +139,7 @@ namespace Loki
}
AssocVector& operator=(const AssocVector& rhs)
{ AssocVector(*this).swap(*this); }
{ AssocVector(rhs).swap(*this); }
// iterators:
// The following are here because MWCW gets 'using' wrong
@ -286,7 +285,7 @@ namespace Loki
const key_type& k) const
{
const MyCompare& me = *this;
return std::equal_range(begin(), end(), k, me));
return std::equal_range(begin(), end(), k, me);
}
friend bool operator==(const AssocVector& lhs, const AssocVector& rhs)
@ -295,10 +294,11 @@ namespace Loki
return me == rhs;
}
friend bool operator<(const AssocVector& lhs, const AssocVector& rhs)
bool operator<(const AssocVector& rhs) const
{
const Base& me = lhs;
return me < rhs;
const Base& me = *this;
const Base& yo = rhs;
return me < yo;
}
friend bool operator!=(const AssocVector& lhs, const AssocVector& rhs)
@ -321,4 +321,11 @@ namespace Loki
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// May 20, 2001: change operator= - credit due to Cristoph Koegl
// June 11, 2001: remove paren in equal_range - credit due to Cristoph Koegl
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // ASSOCVECTOR_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef EMPTYTYPE_INC_
#define EMPTYTYPE_INC_
@ -29,4 +29,9 @@ namespace Loki
class EmptyType {};
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // EMPTYTYPE_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef FACTORY_INC_
#define FACTORY_INC_
@ -134,4 +134,9 @@ namespace Loki
};
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // FACTORY_INC_

125
Functor.h
View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef FUNCTOR_INC_
#define FUNCTOR_INC_
@ -22,6 +22,7 @@
#include "EmptyType.h"
#include "SmallObj.h"
#include "TypeTraits.h"
#include <typeinfo>
#include <memory>
namespace Loki
@ -96,6 +97,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
virtual R operator()() = 0;
};
@ -109,6 +111,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
virtual R operator()(Parm1) = 0;
};
@ -124,6 +127,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
virtual R operator()(Parm1, Parm2) = 0;
@ -140,6 +144,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -157,6 +162,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -176,6 +182,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -196,6 +203,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -217,6 +225,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -241,6 +250,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -266,6 +276,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -293,6 +304,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -322,6 +334,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -352,6 +365,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -383,6 +397,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -416,6 +431,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -450,6 +466,7 @@ namespace Loki
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
@ -482,22 +499,22 @@ namespace Loki
typedef typename ParentFunctor::Impl Base;
public:
using typename Base::ResultType;
using typename Base::Parm1;
using typename Base::Parm2;
using typename Base::Parm3;
using typename Base::Parm4;
using typename Base::Parm5;
using typename Base::Parm6;
using typename Base::Parm7;
using typename Base::Parm8;
using typename Base::Parm9;
using typename Base::Parm10;
using typename Base::Parm11;
using typename Base::Parm12;
using typename Base::Parm13;
using typename Base::Parm14;
using typename Base::Parm15;
typedef typename Base::ResultType ResultType;
typedef typename Base::Parm1 Parm1;
typedef typename Base::Parm2 Parm2;
typedef typename Base::Parm3 Parm3;
typedef typename Base::Parm4 Parm4;
typedef typename Base::Parm5 Parm5;
typedef typename Base::Parm6 Parm6;
typedef typename Base::Parm7 Parm7;
typedef typename Base::Parm8 Parm8;
typedef typename Base::Parm9 Parm9;
typedef typename Base::Parm10 Parm10;
typedef typename Base::Parm11 Parm11;
typedef typename Base::Parm12 Parm12;
typedef typename Base::Parm13 Parm13;
typedef typename Base::Parm14 Parm14;
typedef typename Base::Parm15 Parm15;
FunctorHandler(const Fun& fun) : f_(fun) {}
@ -589,22 +606,22 @@ namespace Loki
typedef typename ParentFunctor::Impl Base;
public:
using typename Base::ResultType;
using typename Base::Parm1;
using typename Base::Parm2;
using typename Base::Parm3;
using typename Base::Parm4;
using typename Base::Parm5;
using typename Base::Parm6;
using typename Base::Parm7;
using typename Base::Parm8;
using typename Base::Parm9;
using typename Base::Parm10;
using typename Base::Parm11;
using typename Base::Parm12;
using typename Base::Parm13;
using typename Base::Parm14;
using typename Base::Parm15;
typedef typename Base::ResultType ResultType;
typedef typename Base::Parm1 Parm1;
typedef typename Base::Parm2 Parm2;
typedef typename Base::Parm3 Parm3;
typedef typename Base::Parm4 Parm4;
typedef typename Base::Parm5 Parm5;
typedef typename Base::Parm6 Parm6;
typedef typename Base::Parm7 Parm7;
typedef typename Base::Parm8 Parm8;
typedef typename Base::Parm9 Parm9;
typedef typename Base::Parm10 Parm10;
typedef typename Base::Parm11 Parm11;
typedef typename Base::Parm12 Parm12;
typedef typename Base::Parm13 Parm13;
typedef typename Base::Parm14 Parm14;
typedef typename Base::Parm15 Parm15;
MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
: pObj_(pObj), pMemFn_(pMemFn)
@ -840,7 +857,8 @@ namespace Loki
template <typename R, class TList, template <class> class ThreadingModel>
struct BinderFirstTraits< Functor<R, TList, ThreadingModel> >
{
typedef TL::Erase<TList, typename TL::TypeAt<TList, 0>::Result>::Result
typedef typename TL::Erase<TList,
typename TL::TypeAt<TList, 0>::Result>::Result
ParmList;
typedef Functor<R, ParmList, ThreadingModel> BoundFunctorType;
typedef typename BoundFunctorType::Impl Impl;
@ -980,22 +998,22 @@ namespace Loki
typedef Fun2 Base;
public:
using typename Base::ResultType;
using typename Base::Parm1;
using typename Base::Parm2;
using typename Base::Parm3;
using typename Base::Parm4;
using typename Base::Parm5;
using typename Base::Parm6;
using typename Base::Parm7;
using typename Base::Parm8;
using typename Base::Parm9;
using typename Base::Parm10;
using typename Base::Parm11;
using typename Base::Parm12;
using typename Base::Parm13;
using typename Base::Parm14;
using typename Base::Parm15;
typedef typename Base::ResultType ResultType;
typedef typename Base::Parm1 Parm1;
typedef typename Base::Parm2 Parm2;
typedef typename Base::Parm3 Parm3;
typedef typename Base::Parm4 Parm4;
typedef typename Base::Parm5 Parm5;
typedef typename Base::Parm6 Parm6;
typedef typename Base::Parm7 Parm7;
typedef typename Base::Parm8 Parm8;
typedef typename Base::Parm9 Parm9;
typedef typename Base::Parm10 Parm10;
typedef typename Base::Parm11 Parm11;
typedef typename Base::Parm12 Parm12;
typedef typename Base::Parm13 Parm13;
typedef typename Base::Parm14 Parm14;
typedef typename Base::Parm15 Parm15;
Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {}
@ -1112,10 +1130,15 @@ namespace Loki
const Fun1& fun1,
const Fun2& fun2)
{
return Fun2(std::auto_ptr<Fun2::Impl>(
return Fun2(std::auto_ptr<typename Fun2::Impl>(
new Chainer<Fun1, Fun2>(fun1, fun2)));
}
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // FUNCTOR_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: March 05, 2001
#ifndef HIERARCHYGENERATORS_INC_
#define HIERARCHYGENERATORS_INC_
@ -45,25 +45,29 @@ namespace Loki
typedef Typelist<T1, T2> TList;
typedef GenScatterHierarchy<T1, Unit> LeftBase;
typedef GenScatterHierarchy<T2, Unit> RightBase;
template <class T> struct Rebind
{ typedef Unit<T> Result; };
template <typename T> struct Rebind
{
typedef Unit<T> Result;
};
};
template <class AtomicType, template <class> class Unit>
class GenScatterHierarchy : public Unit<AtomicType>
{
typedef Unit<AtomicType> LeftBase;
template <class T> struct Rebind
{ typedef Unit<T> Result; };
template <typename T> struct Rebind
{
typedef Unit<T> Result;
};
};
template <template <class> class Unit>
class GenScatterHierarchy<NullType, Unit>
{
template <class T> struct Rebind
{ typedef Unit<T> Result; };
template <typename T> struct Rebind
{
typedef Unit<T> Result;
};
};
////////////////////////////////////////////////////////////////////////////////
@ -81,6 +85,12 @@ namespace Loki
return obj;
}
template <class T, class H>
const typename H::Rebind<T>::Result& Field(const H& obj)
{
return obj;
}
////////////////////////////////////////////////////////////////////////////////
// function template TupleUnit
// The building block of tuples
@ -120,20 +130,20 @@ namespace Loki
enum
{
isTuple =
Conversion<UnitType, TupleUnit<ElementType> >::sameType,
isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
isConst = TypeTraits<H>::isConst
};
typedef Select<isConst, const H::LeftBase,
H::LeftBase>::Result LeftBase;
typedef const typename H::LeftBase ConstLeftBase;
typedef Select<isTuple, ElementType, UnitType>::Result
UnqualifiedResultType;
typedef Select<isConst,
const UnqualifiedResultType,
UnqualifiedResultType>::Result
ResultType;
typedef typename Select<isConst, ConstLeftBase,
typename H::LeftBase>::Result LeftBase;
typedef typename Select<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj)
{
@ -150,25 +160,25 @@ namespace Loki
enum
{
isTuple =
Conversion<UnitType, TupleUnit<ElementType> >::sameType,
isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
isConst = TypeTraits<H>::isConst
};
typedef Select<isConst, const H::RightBase,
H::RightBase>::Result RightBase;
typedef const typename H::RightBase ConstRightBase;
typedef Select<isTuple, ElementType, UnitType>::Result
UnqualifiedResultType;
typedef Select<isConst,
const UnqualifiedResultType,
UnqualifiedResultType>::Result
ResultType;
typedef typename Select<isConst, ConstRightBase,
typename H::RightBase>::Result RightBase;
typedef typename Select<isTuple, ElementType,
UnitType>::Result UnqualifiedResultType;
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj)
{
typename H::RightBase& rightBase = obj;
return FieldHelper<typename H::RightBase, i - 1>::Do(obj);
RightBase& rightBase = obj;
return FieldHelper<RightBase, i - 1>::Do(rightBase);
}
};
@ -189,6 +199,13 @@ namespace Loki
return FieldHelper<H, i>::Do(obj);
}
// template <int i, class H>
// const typename FieldHelper<H, i>::ResultType&
// Field(const H& obj)
// {
// return FieldHelper<H, i>::Do(obj);
// }
////////////////////////////////////////////////////////////////////////////////
// class template GenLinearHierarchy
// Generates a linear hierarchy starting from a typelist and a template
@ -222,12 +239,16 @@ namespace Loki
template <class, class> class Unit,
class Root
>
class GenLinearHierarchy<TYPELIST_1(T), Unit, Root>
class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
: public Unit<T, Root>
{
};
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // HIERARCHYGENERATORS_INC_

View file

@ -1,31 +0,0 @@
#ifndef MAPPINGS_H_
#define MAPPINGS_H_
namespace Loki
{
template <int v>
struct Int2Type
{
enum { value = v };
};
template <typename T>
struct Type2Type
{
typedef T OriginalType;
};
template <bool flag, typename T, typename U>
struct Select
{
typedef T Result;
};
template <typename T, typename U>
struct Select<false, T, U>
{
typedef U Result;
};
}
#endif

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef MULTIMETHODS_INC_
#define MULTIMETHODS_INC_
@ -38,25 +38,21 @@ namespace Loki
namespace Private
{
template <bool swapArgs, class SomeLhs, class SomeRhs, class Executor,
typename ResultType>
template <class SomeLhs, class SomeRhs,
class Executor, typename ResultType>
struct InvocationTraits
{
static ResultType DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec)
static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<false>)
{
return exec.Fire(lhs, rhs);
}
};
template <class SomeLhs, class SomeRhs, class Executor,
typename ResultType>
struct InvocationTraits<true, SomeLhs, SomeRhs, Executor, ResultType>
static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<true>)
{
static ResultType DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec)
{
return exec.Fire(rhs, lhs); // swap arguments
return exec.Fire(rhs, lhs);
}
};
}
@ -69,9 +65,9 @@ namespace Loki
template
<
class Executor,
bool symmetric,
class BaseLhs,
class TypesLhs,
bool symmetric = true,
class BaseRhs = BaseLhs,
class TypesRhs = TypesLhs,
typename ResultType = void
@ -92,14 +88,14 @@ namespace Loki
if (Head* p2 = dynamic_cast<Head*>(&rhs))
{
enum { swapArgs = symmetric &&
TL::IndexOf<TypesRhs, Head>::value <
TL::IndexOf<TypesLhs, SomeLhs>::value };
typedef Private::InvocationTraits<swapArgs,
SomeLhs, Head, Executor, ResultType>
CallTraits;
Int2Type<(symmetric &&
int(TL::IndexOf<TypesRhs, Head>::value) <
int(TL::IndexOf<TypesLhs, SomeLhs>::value))> i2t;
return CallTraits::DoDispatch(lhs, *p2, exec);
typedef Private::InvocationTraits<
SomeLhs, Head, Executor, ResultType> CallTraits;
return CallTraits::DoDispatch(lhs, *p2, exec, i2t);
}
return DispatchRhs(lhs, rhs, exec, Tail());
}
@ -148,17 +144,10 @@ namespace Loki
typedef AssocVector<KeyType, MappedType> MapType;
MapType callbackMap_;
void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun);
bool DoRemove(TypeInfo lhs, TypeInfo rhs);
public:
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;
}
template <class SomeLhs, class SomeRhs>
void Add(CallbackType fun)
{
@ -171,17 +160,39 @@ namespace Loki
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...
template <class BaseLhs, class BaseRhs,
typename ResultType, typename CallbackType>
void BasicDispatcher<BaseLhs,BaseRhs,ResultType,CallbackType>
::DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun)
{
MapType::iterator i = callbackMap_.find(
KeyType(typeid(lhs), typeid(rhs)));
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);
}
};
////////////////////////////////////////////////////////////////////////////////
// class template StaticCaster
@ -211,6 +222,31 @@ struct DynamicCaster
}
};
////////////////////////////////////////////////////////////////////////////////
// class template Private::FnDispatcherHelper
// Implements trampolines and argument swapping used by FnDispatcher
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <class BaseLhs, class BaseRhs,
class SomeLhs, class SomeRhs,
typename ResultType,
class CastLhs, class CastRhs,
ResultType (*Callback)(SomeLhs&, SomeRhs&)>
struct FnDispatcherHelper
{
static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs)
{
return Callback(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
}
static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs)
{
return Trampoline(lhs, rhs);
}
};
}
////////////////////////////////////////////////////////////////////////////////
// class template FnDispatcher
// Implements an automatic logarithmic double dispatcher for functions
@ -228,43 +264,92 @@ struct DynamicCaster
ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_;
public:
template <class ConcreteLhs, class ConcreteRhs>
template <class SomeLhs, class SomeRhs>
void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&))
{
return backEnd_.Add<ConcreteLhs, ConcreteRhs>(pFun);
return backEnd_.Add<SomeLhs, SomeRhs>(pFun);
}
template <class ConcreteLhs, class ConcreteRhs,
ResultType (*callback)(ConcreteLhs&, ConcreteRhs&),
template <class SomeLhs, class SomeRhs,
ResultType (*callback)(SomeLhs&, SomeRhs&)>
void Add()
{
typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>,
callback> Local;
Add<SomeLhs, SomeRhs>(&Local::Trampoline);
}
template <class SomeLhs, class SomeRhs,
ResultType (*callback)(SomeLhs&, SomeRhs&),
bool symmetric>
void Add()
{
struct Local
{
static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs)
{
return callback(
CastingPolicy<ConcreteLhs, BaseLhs>::Cast(lhs),
CastingPolicy<ConcreteRhs, BaseRhs>::Cast(rhs));
}
static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs)
{
return Trampoline(lhs, rhs);
}
};
Add<ConcreteLhs, ConcreteRhs>(&Local::Trampoline);
typedef Private::FnDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<SomeRhs,BaseRhs>,
callback> Local;
Add<SomeLhs, SomeRhs>(&Local::Trampoline);
if (symmetric)
{
Add<ConcreteRhs, ConcreteLhs>(&Local::TrampolineR);
Add<SomeRhs, SomeLhs>(&Local::TrampolineR);
}
}
template <class SomeLhs, class SomeRhs>
void Remove()
{
backEnd_.Remove<SomeLhs, SomeRhs>();
}
ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
{
return backEnd_.Go(lhs, rhs);
}
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorDispatcherAdaptor
// permits use of FunctorDispatcher under gcc.2.95.2/3
///////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <class BaseLhs, class BaseRhs,
class SomeLhs, class SomeRhs,
typename ResultType,
class CastLhs, class CastRhs,
class Fun, bool SwapArgs>
class FunctorDispatcherHelper
{
Fun fun_;
ResultType Fire(BaseLhs& lhs, BaseRhs& rhs,Int2Type<false>)
{
return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
}
ResultType Fire(BaseLhs& rhs, BaseRhs& lhs,Int2Type<true>)
{
return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
}
public:
FunctorDispatcherHelper(const Fun& fun) : fun_(fun) {}
ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
{
return Fire(lhs,rhs,Int2Type<SwapArgs>());
}
};
}
////////////////////////////////////////////////////////////////////////////////
// class template FunctorDispatcher
// Implements a logarithmic double dispatcher for functors
@ -281,32 +366,46 @@ struct DynamicCaster
typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList;
typedef Functor<ResultType, ArgsList, DEFAULT_THREADING> FunctorType;
typedef DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType>
BackEndType;
BackEndType backEnd_;
DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType> backEnd_;
public:
template <class SomeLhs, class SomeRhs, class Fun>
void Add(const Fun& fun)
{
typedef FunctorImpl<ResultType, TYPELIST_2(BaseLhs, BaseRhs)>
FunctorImplType;
class Adapter : public FunctorImplType
{
Fun fun_;
virtual ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
{
return fun_(
CastingPolicy<ConcreteLhs, BaseLhs>::Cast(lhs),
CastingPolicy<ConcreteRhs, BaseRhs>::Cast(rhs));
typedef Private::FunctorDispatcherHelper<
BaseLhs, BaseRhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs, BaseLhs>,
CastingPolicy<SomeRhs, BaseRhs>,
Fun, false> Adapter;
backEnd_.Add<SomeLhs, SomeRhs>(FunctorType(Adapter(fun)));
}
virtual FunctorImplType* DoClone() const
{ return new Adapter(*this); }
public:
Adapter(const Fun& fun) : fun_(fun) {}
};
backEnd_.Add<SomeLhs, SomeRhs>(
Functor<ResultType, ArgsList, DEFAULT_THREADING>(new Adapter(fun)));
template <class SomeLhs, class SomeRhs, bool symmetric, class Fun>
void Add(const Fun& fun)
{
Add<SomeLhs,SomeRhs>(fun);
if (symmetric)
{
// Note: symmetry only makes sense where BaseLhs==BaseRhs
typedef Private::FunctorDispatcherHelper<
BaseLhs, BaseLhs,
SomeLhs, SomeRhs,
ResultType,
CastingPolicy<SomeLhs, BaseLhs>,
CastingPolicy<SomeRhs, BaseLhs>,
Fun, true> AdapterR;
backEnd_.Add<SomeRhs, SomeLhs>(FunctorType(AdapterR(fun)));
}
}
template <class SomeLhs, class SomeRhs>
void Remove()
{
backEnd_.Remove<SomeLhs, SomeRhs>();
}
ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
@ -316,5 +415,9 @@ struct DynamicCaster
};
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef NULLTYPE_INC_
#define NULLTYPE_INC_
@ -29,4 +29,9 @@ namespace Loki
class NullType {};
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // NULLTYPE_INC_

View file

@ -13,14 +13,14 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#include "Singleton.h"
using namespace Loki::Private;
extern TrackerArray Loki::Private::pTrackerArray = 0;
extern unsigned int Loki::Private::elements = 0;
Loki::Private::TrackerArray Loki::Private::pTrackerArray = 0;
unsigned int Loki::Private::elements = 0;
////////////////////////////////////////////////////////////////////////////////
// function AtExitFn
@ -40,3 +40,8 @@ void Loki::Private::AtExitFn()
// Destroy the element
delete pTop;
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////

View file

@ -13,12 +13,14 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef SINGLETON_INC_
#define SINGLETON_INC_
#include "Threads.h"
#include <algorithm>
#include <stdexcept>
#include <cassert>
#include <cstdlib>
#include <new>
@ -40,10 +42,10 @@ namespace Loki
virtual ~LifetimeTracker() = 0;
friend inline bool Compare(unsigned int longevity,
const LifetimeTracker* p)
static bool Compare(const LifetimeTracker* lhs,
const LifetimeTracker* rhs)
{
return p->longevity_ > longevity;
return rhs->longevity_ > lhs->longevity_;
}
private:
@ -113,14 +115,19 @@ namespace Loki
// Insert a pointer to the object into the queue
TrackerArray pos = std::upper_bound(
pTrackerArray, pTrackerArray + elements, longevity, Compare);
std::copy_backward(pos, pTrackerArray + elements,
pTrackerArray,
pTrackerArray + elements,
p,
LifetimeTracker::Compare);
std::copy_backward(
pos,
pTrackerArray + elements,
pTrackerArray + elements + 1);
*pos = p;
++elements;
// Register a call to AtExitFn
std::atexit(AtExitFn);
std::atexit(Private::AtExitFn);
}
////////////////////////////////////////////////////////////////////////////////
@ -251,6 +258,21 @@ namespace Loki
template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false;
#endif
////////////////////////////////////////////////////////////////////////////////
// class template Adapter
// Helper for SingletonWithLongevity below
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <class T>
struct Adapter
{
void operator()(T*) { return pFun_(); }
void (*pFun_)();
};
}
////////////////////////////////////////////////////////////////////////////////
// class template SingletonWithLongevity
// Implementation of the LifetimePolicy used by SingletonHolder
@ -265,13 +287,7 @@ namespace Loki
public:
static void ScheduleDestruction(T* pObj, void (*pFun)())
{
struct Adapter
{
void operator()(T*) { return pFun_(); }
void (*pFun_)();
};
Adapter adapter = { pFun };
Private::Adapter<T> adapter = { pFun };
SetLongevity(pObj, GetLongevity(pObj), adapter);
}
@ -323,8 +339,8 @@ namespace Loki
SingletonHolder();
// Data
typedef ThreadingModel<T>::VolatileType InstanceType;
static InstanceType* pInstance_;
typedef typename ThreadingModel<T*>::VolatileType PtrInstanceType;
static PtrInstanceType pInstance_;
static bool destroyed_;
};
@ -339,7 +355,7 @@ namespace Loki
template <class> class L,
template <class> class M
>
typename SingletonHolder<T, C, L, M>::InstanceType*
typename SingletonHolder<T, C, L, M>::PtrInstanceType
SingletonHolder<T, C, L, M>::pInstance_;
template
@ -387,7 +403,7 @@ namespace Loki
LifetimePolicy, ThreadingModel>::MakeInstance()
{
typename ThreadingModel<T>::Lock guard;
guard;
(void)guard;
if (!pInstance_)
{
@ -418,4 +434,10 @@ namespace Loki
}
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// May 21, 2001: Correct the volatile qualifier - credit due to Darin Adler
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // SINGLETON_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: March 20, 2001
#include "SmallObj.h"
#include <cassert>
@ -119,8 +119,8 @@ void FixedAllocator::Chunk::Deallocate(void* p, std::size_t blockSize)
FixedAllocator::FixedAllocator(std::size_t blockSize)
: blockSize_(blockSize)
, deallocChunk_(0)
, allocChunk_(0)
, deallocChunk_(0)
{
assert(blockSize_ > 0);
@ -217,10 +217,11 @@ void* FixedAllocator::Allocate()
if (i == chunks_.end())
{
// Initialize
chunks_.push_back(Chunk());
Chunk& newChunk = chunks_.back();
chunks_.reserve(chunks_.size() + 1);
Chunk newChunk;
newChunk.Init(blockSize_, numBlocks_);
allocChunk_ = &newChunk;
chunks_.push_back(newChunk);
allocChunk_ = &chunks_.back();
deallocChunk_ = &chunks_.front();
break;
}
@ -406,3 +407,10 @@ void SmallObjAllocator::Deallocate(void* p, std::size_t numBytes)
pLastDealloc_ = &*i;
pLastDealloc_->Deallocate(p);
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20: fix exception safety issue in FixedAllocator::Allocate
// (thanks to Chris Udazvinis for pointing that out)
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef SMALLOBJ_INC_
#define SMALLOBJ_INC_
@ -133,6 +133,9 @@ namespace Loki
class SmallObject : public ThreadingModel<
SmallObject<ThreadingModel, chunkSize, maxSmallObjectSize> >
{
typedef ThreadingModel< SmallObject<ThreadingModel,
chunkSize, maxSmallObjectSize> > MyThreadingModel;
struct MySmallObjAllocator : public SmallObjAllocator
{
MySmallObjAllocator()
@ -148,8 +151,8 @@ namespace Loki
static void* operator new(std::size_t size)
{
#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0)
Lock lock;
lock; // get rid of warning
typename MyThreadingModel::Lock lock;
(void)lock; // get rid of warning
return SingletonHolder<MySmallObjAllocator, CreateStatic,
PhoenixSingleton>::Instance().Allocate(size);
@ -160,8 +163,8 @@ namespace Loki
static void operator delete(void* p, std::size_t size)
{
#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0)
Lock lock;
lock; // get rid of warning
typename MyThreadingModel::Lock lock;
(void)lock; // get rid of warning
SingletonHolder<MySmallObjAllocator, CreateStatic,
PhoenixSingleton>::Instance().Deallocate(p, size);
@ -173,4 +176,9 @@ namespace Loki
};
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // SMALLOBJ_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef SMARTPTR_INC_
#define SMARTPTR_INC_
@ -155,11 +155,11 @@ namespace Loki
// Implementation of the OwnershipPolicy used by SmartPtr
// Implements external reference counting for multithreaded programs
////////////////////////////////////////////////////////////////////////////////
template <class P,
template <class> class ThreadingModel>
class RefCountedMT : public ThreadingModel<RefCountedMT>
class RefCountedMT : public ThreadingModel< RefCountedMT<P, ThreadingModel> >
{
public:
RefCountedMT()
{
pCount_ = static_cast<unsigned int*>(
@ -176,7 +176,7 @@ namespace Loki
// MWCW lacks template friends, hence the following kludge
template <typename P1>
RefCountedMT(const RefCountedMT<P1, ThreadingModel>& rhs)
: pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_)
: pCount_(reinterpret_cast<const RefCounted<P>&>(rhs).pCount_)
{}
P Clone(const P& val)
@ -203,7 +203,7 @@ namespace Loki
private:
// Data
volatile ThreadingModel<RefCountedMT>::IntType* pCount_;
volatile unsigned int* pCount_;
};
////////////////////////////////////////////////////////////////////////////////
@ -564,6 +564,8 @@ namespace Loki
struct NullPointerException : public std::runtime_error
{
NullPointerException() : std::runtime_error("")
{ }
const char* what() const
{ return "Null Pointer Exception"; }
};
@ -598,8 +600,8 @@ namespace Loki
static void OnDefault(const P&)
{
STATIC_CHECK(false,
This_Policy_Does_Not_Allow_Default_Initialization);
CompileTimeError<false>
ERROR_This_Policy_Does_Not_Allow_Default_Initialization;
}
static void OnInit(const P& val)
@ -683,7 +685,8 @@ namespace Loki
public:
ByRef(T& v) : value_(v) {}
operator T&() { return value_; }
operator const T&() const { return value_; }
// gcc doesn't like this:
// operator const T&() const { return value_; }
private:
T& value_;
};
@ -823,7 +826,7 @@ namespace Loki
~SmartPtr()
{
if (OP::Release(GetImpl(*this)))
if (OP::Release(GetImpl(*static_cast<SP*>(this))))
{
SP::Destroy();
}
@ -919,8 +922,10 @@ namespace Loki
private:
// Helper for enabling 'if (sp)'
class Tester
struct Tester
{
Tester() {}
private:
void operator delete(void*);
};
@ -940,7 +945,7 @@ namespace Loki
Insipid(PointerType) {}
};
typedef Select<CP::allow, PointerType, Insipid>::Result
typedef typename Select<CP::allow, PointerType, Insipid>::Result
AutomaticConversionResult;
public:
@ -1180,4 +1185,9 @@ namespace std
};
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // SMARTPTR_INC_

View file

@ -9,6 +9,8 @@
// affects only default template arguments
////////////////////////////////////////////////////////////////////////////////
// Last update: June 20, 2001
#ifndef DEFAULT_THREADING
#define DEFAULT_THREADING /**/ ::Loki::SingleThreaded
#endif
@ -192,4 +194,9 @@ namespace Loki
#endif
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
////////////////////////////////////////////////////////////////////////////////
// This file is intentionally left empty

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef TYPEINFO_INC_
#define TYPEINFO_INC_
@ -98,4 +98,9 @@ namespace Loki
{ return !(lhs < rhs); }
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // TYPEINFO_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef TYPEMANIP_INC_
#define TYPEMANIP_INC_
@ -72,9 +72,16 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <class T, class U>
struct ConversionHelper
{
typedef char Small;
class Big { char dummy[2]; };
struct Big { char dummy[2]; };
static Big Test(...);
static Small Test(U);
static T MakeT();
};
}
////////////////////////////////////////////////////////////////////////////////
@ -94,37 +101,33 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
template <class T, class U>
class Conversion
struct Conversion
{
static Private::Big Test(...);
static Private::Small Test(U);
static T MakeT();
public:
enum { exists = sizeof(Test(MakeT())) == sizeof(Private::Small) };
enum { exists2Way = exists &&
Conversion<U, T>::exists };
typedef Private::ConversionHelper<T, U> H;
#ifndef __MWERKS__
enum { exists = sizeof(typename H::Small) == sizeof(H::Test(H::MakeT())) };
#else
enum { exists = false };
#endif
enum { exists2Way = exists && Conversion<U, T>::exists };
enum { sameType = false };
};
template <class T>
class Conversion<T, T>
struct Conversion<T, T>
{
public:
enum { exists = 1, exists2Way = 1,sameType = 1 };
};
template <class T>
class Conversion<void, T>
struct Conversion<void, T>
{
public:
enum { exists = 1, exists2Way = 0,sameType = 0 };
};
template <class T>
class Conversion<T, void>
struct Conversion<T, void>
{
public:
enum { exists = 1, exists2Way = 0,sameType = 0 };
};
@ -161,5 +164,9 @@ namespace Loki
(SUPERSUBCLASS(T, U) && \
!::Loki::Conversion<const T, const U>::sameType)
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // TYPEMANIP_INC_

View file

@ -190,10 +190,10 @@ namespace Loki
public:
enum { isPointer = PointerTraits<T>::result };
typedef PointerTraits<T>::PointeeType PointeeType;
typedef typename PointerTraits<T>::PointeeType PointeeType;
enum { isReference = ReferenceTraits<T>::result };
typedef ReferenceTraits<T>::ReferredType ReferredType;
typedef typename ReferenceTraits<T>::ReferredType ReferredType;
enum { isMemberPointer = PToMTraits<T>::result };
@ -215,16 +215,22 @@ namespace Loki
enum { isArith = isIntegral || isFloat };
enum { isFundamental = isStdFundamental || isArith || isFloat };
typedef Select<isStdArith || isPointer || isMemberPointer,
typedef typename Select<isStdArith || isPointer || isMemberPointer,
T, ReferredType&>::Result
ParameterType;
enum { isConst = UnConst<T>::isConst };
typedef UnConst<T>::Result NonConstType;
typedef typename UnConst<T>::Result NonConstType;
enum { isVolatile = UnVolatile<T>::isVolatile };
typedef UnVolatile<T>::Result NonVolatileType;
typedef UnVolatile<UnConst<T>::Result>::Result UnqualifiedType;
typedef typename UnVolatile<T>::Result NonVolatileType;
typedef typename UnVolatile<typename UnConst<T>::Result>::Result
UnqualifiedType;
};
}
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // TYPETRAITS_INC_

View file

@ -13,12 +13,12 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef TYPELIST_INC_
#define TYPELIST_INC_
#include "Nulltype.h"
#include "NullType.h"
#include "TypeManip.h"
////////////////////////////////////////////////////////////////////////////////
@ -113,31 +113,31 @@
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) >
#define TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T23) \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \
::Loki::Typelist<T1, TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) >
#define TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T23, T24) \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \
::Loki::Typelist<T1, TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) >
#define TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T23, T24, T25) \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \
::Loki::Typelist<T1, TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T22, T23, T24, T25) >
#define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T23, T24, T25, T26) \
T21, T22, T23, T24, T25, T26) \
::Loki::Typelist<T1, TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T22, T23, T24, T25, T26) >
#define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T23, T24, T25, T26, T27) \
T21, T22, T23, T24, T25, T26, T27) \
::Loki::Typelist<T1, TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T22, T23, T24, T25, T26, T27) >
@ -460,7 +460,7 @@ namespace Loki
enum { value = -1 };
};
template <class Tail, class T>
template <class T, class Tail>
struct IndexOf<Typelist<T, Tail>, T>
{
enum { value = 0 };
@ -472,7 +472,7 @@ namespace Loki
private:
enum { temp = IndexOf<Tail, T>::value };
public:
enum { value = temp == -1 ? -1 : 1 + temp };
enum { value = (temp == -1 ? -1 : 1 + temp) };
};
////////////////////////////////////////////////////////////////////////////////
@ -524,11 +524,13 @@ namespace Loki
{
typedef NullType Result;
};
template <class T, class Tail> // Specialization 2
struct Erase<Typelist<T, Tail>, T>
{
typedef Tail Result;
};
template <class Head, class Tail, class T> // Specialization 3
struct Erase<Typelist<Head, Tail>, T>
{
@ -731,4 +733,12 @@ namespace Loki
} // namespace TL
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 09, 2001: Fix bug in parameter list of macros TYPELIST_23 to TYPELIST_27
// (credit due to Dave Taylor)
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // TYPELIST_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef VISITOR_INC_
#define VISITOR_INC_
@ -66,20 +66,20 @@ namespace Loki
template <class Head, class Tail, typename R>
class Visitor<Typelist<Head, Tail>, R>
: public Visitor<Head>, public Visitor<Tail>
: public Visitor<Head, R>, public Visitor<Tail, R>
{
public:
typedef R ReturnType;
using Visitor<Head>::Visit;
using Visitor<Tail>::Visit;
// using Visitor<Head, R>::Visit;
// using Visitor<Tail, R>::Visit;
};
template <class Head, typename R>
class Visitor<Typelist<Head, NullType>, R> : public Visitor<Head>
class Visitor<Typelist<Head, NullType>, R> : public Visitor<Head, R>
{
public:
typedef R ReturnType;
using Visitor<Head>::Visit;
using Visitor<Head, R>::Visit;
};
////////////////////////////////////////////////////////////////////////////////
@ -96,7 +96,7 @@ namespace Loki
, public BaseVisitorImpl<Tail, R>
{
public:
using BaseVisitorImpl<Tail, R>::Visit;
// using BaseVisitorImpl<Tail, R>::Visit;
virtual R Visit(Head&)
{ return R(); }
@ -126,7 +126,11 @@ struct DefaultCatchAll
// class template BaseVisitable
////////////////////////////////////////////////////////////////////////////////
template <typename R = void, template <typename, class> class CatchAll>
template
<
typename R = void,
template <typename, class> class CatchAll = DefaultCatchAll
>
class BaseVisitable
{
public:
@ -157,23 +161,6 @@ struct DefaultCatchAll
virtual ReturnType Accept(BaseVisitor& guest) \
{ return AcceptImpl(*this, guest); }
////////////////////////////////////////////////////////////////////////////////
// class template VisitorBinder
// Helper for CyclicVisitor below
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <typename R>
struct VisitorBinder
{
template <class T>
struct Result : public Visitor<T, R>
{
};
};
}
////////////////////////////////////////////////////////////////////////////////
// class template CyclicVisitor
// Put it in every class that you want to make visitable (in addition to
@ -181,18 +168,16 @@ struct DefaultCatchAll
////////////////////////////////////////////////////////////////////////////////
template <typename R, class TList>
class CyclicVisitor
: public GenScatterHierarchy<TList, Private::VisitorBinder<R>::Result>
class CyclicVisitor : public Visitor<TList, R>
{
public:
typedef R ReturnType;
// using Visitor<TList, R>::Visit;
// this is GenericVisit and not Visit to avoid the compiler warning
// "Visit hides virtual function in base class"
template <class Visited>
ReturnType GenericVisit(Visited& host)
{
Visitor<Visited>& subObj = *this;
Visitor<Visited, ReturnType>& subObj = *this;
return subObj.Visit(host);
}
};
@ -208,4 +193,11 @@ struct DefaultCatchAll
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20: add default argument DefaultCatchAll to BaseVisitable
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // VISITOR_INC_

301
main.cpp
View file

@ -1,301 +0,0 @@
//#include <windows.h>
//#include "Threads.h"
#include "MultiMethods.h"
#include "Visitor.h"
#include "AbstractFactory.h"
#include "SmartPtr.h"
#include "static_check.h"
#include "TypeManip.h"
#include "TypeInfo.h"
#include "TypeTraits.h"
#include "HierarchyGenerators.h"
#include "SmallObj.h"
#include "Functor.h"
#include "Singleton.h"
#include "Factory.h"
#include "SmallObj.h"
#include "Factory.h"
#include <cassert>
using namespace Loki;
class Base
{
public:
int Fun(const char*)
{
return 0;
}
};
class Derived : public Base {};
class Base1
{
public:
int Fun(const char*)
{
return 0;
}
};
class Derived1 : public Base1 {};
unsigned int GetLongevity(Base*) { return 1; }
template <class T>
struct Holder
{
T value_;
};
template <class T, class Base>
struct Holder2 : public Base
{
};
int Fun(double)
{
return 0;
}
template class SmartPtr< Base >;
template class Factory< Base, int, Base* (*)(), DefaultFactoryError >;
template class CloneFactory< Base, Base* (*)(const Base*), DefaultFactoryError>;
template class AbstractFactory<TYPELIST_2(Base, Derived)>;
class DocElement;
class Paragraph;
class RasterBitmap;
typedef CyclicVisitor
<
void, // return type
TYPELIST_3(DocElement, Paragraph, RasterBitmap)
>
MyVisitor;
class DocElement
{
public:
virtual void Accept(MyVisitor&) = 0;
};
class Paragraph : public DocElement
{
public:
DEFINE_CYCLIC_VISITABLE(MyVisitor)
};
class MyConcreteVisitor : public MyVisitor
{
void Visit(DocElement&)
{}
void Visit(Paragraph&)
{}
void Visit(RasterBitmap&)
{}
};
extern void TestMultiMethods();
extern void TestThreads();
extern void TestAbstractFactory();
extern void TestFactory();
extern void TestFunctor();
extern void TestAssocVector();
int main()
{
TestAbstractFactory();
TestAssocVector();
TestFactory();
TestFunctor();
TestMultiMethods();
TestThreads();
{
MyConcreteVisitor vis;
Paragraph par;
DocElement& docElem = par;
docElem.Accept(vis);
}
{
typedef AbstractFactory<TYPELIST_2(Base, Base1)> Fact;
typedef ConcreteFactory<Fact, OpNewFactoryUnit,
TYPELIST_2(Derived, Derived1)> CFact;
CFact factory;
factory.Create<Base>();
}
STATIC_CHECK(sizeof(int) == 4, Int_Too_Small);
{
Int2Type<3> i2t;
i2t;
}
{
Type2Type<int> t2t;
t2t;
}
{
Select<true, int, char*>::Result test = 9;
}
{
Select<false, int, char*>::Result test = "9";
}
{
//STATIC_CHECK(X<int>::a, zzz);
//STATIC_CHECK((Conversion<Derived, Base>::exists == 4), X);
/*STATIC_CHECK((Conversion<int, char>::exists2Way), X);
STATIC_CHECK((!Conversion<int, char>::sameType), X);
STATIC_CHECK(!Conversion<int, char*>::exists, X);
STATIC_CHECK(Conversion<int, char*>::exists2Way;
Conversion<int, char*>::sameType;
Conversion<char*, char*>::exists;
Conversion<char*, char*>::exists2Way;
Conversion<char*, char*>::sameType;
SUPERSUBCLASS(int, char*);*/
}
{
TypeInfo ti1;
TypeInfo ti2(typeid(int));
TypeInfo ti3(ti1);
ti2 = ti1;
ti1.name();
ti1 == ti2;
ti1 != ti2;
ti1 < ti2;
ti1 > ti2;
ti1.before(ti2);
}
{
STATIC_CHECK(TypeTraits<char*>::isPointer, TypeTraits_Broken);
STATIC_CHECK(!TypeTraits<char>::isPointer, TypeTraits_Broken);
STATIC_CHECK(TypeTraits<char&>::isReference, TypeTraits_Broken);
STATIC_CHECK(!TypeTraits<char*>::isReference, TypeTraits_Broken);
STATIC_CHECK(TypeTraits<int>::isStdSignedInt &&
!TypeTraits<int>::isStdUnsignedInt &&
TypeTraits<int>::isStdIntegral &&
!TypeTraits<int>::isStdFloat &&
TypeTraits<int>::isStdArith &&
TypeTraits<int>::isStdFundamental, TypeTraits_Broken);
}
{
typedef TYPELIST_5(int, long int, char*, char, short int)
TList;
STATIC_CHECK(TL::Length<TList>::value == 5, Typelist_Broken);
TL::TypeAt<TList, 2>::Result x = "oo";
typedef TL::Append<TList, int>::Result TList2;
STATIC_CHECK(TL::Length<TList2>::value == 6, Typelist_Broken);
typedef TL::Erase<TList2, int>::Result TList3;
STATIC_CHECK(TL::Length<TList3>::value == 5, Typelist_Broken);
TL::TypeAt<TList3, 1>::Result y = "d";
typedef TL::EraseAll<TList2, int>::Result TList4;
STATIC_CHECK(TL::Length<TList4>::value == 4, Typelist_Broken);
TL::TypeAt<TList3, 1>::Result z = "f";
typedef TL::Append<TList2, long int>::Result TList5;
STATIC_CHECK(TL::Length<TList5>::value == 7, Typelist_Broken);
typedef TL::NoDuplicates<TList5>::Result TList6;
STATIC_CHECK(TL::Length<TList6>::value == 5, Typelist_Broken);
TL::TypeAt<TList6, 2>::Result c = "d";
typedef TL::Replace<TList, char*, int>::Result TList7;
TL::TypeAt<TList7, 2>::Result d = 44;
typedef TL::ReplaceAll<TList2, int, char*>::Result TList8;
TL::TypeAt<TList8, 5>::Result e = "44";
}
{
//GenScatterHierarchy<TYPELIST_2(char*, int), Holder> obj1;
//obj1;
GenLinearHierarchy<TYPELIST_2(char*, int), Holder2> obj2;
obj2;
//Field<char*>(obj1).value_ = "hello";
//Field<int>(obj1).value_ = 3;
//Field<0>(obj1).value_ = "hello";
//Field<1>(obj1).value_ = 3;
//const GenScatterHierarchy<TYPELIST_2(char*, int), Holder> obj3;
//obj3;
//char*& p1 = Field<0>(obj3).value_;
//char*& p2 = Field<0>(obj1).value_;
}
{
Functor<int, TYPELIST_1(double)> fn(Fun);
fn(4.5);
Base b;
Functor<int, TYPELIST_1(char*)> fn2(&b, &Base::Fun);
fn2("a");
char* ddd = "aaa";
Functor<int> fn3 = BindFirst(fn2, "ddd");
fn3();
Functor<int> fn4 = Chain(fn3, fn3);
fn4();
}
{
typedef SingletonHolder<Base> TheBase;
TheBase::Instance();
}
{
typedef SingletonHolder<Base, CreateUsingNew, SingletonWithLongevity> TheBase;
TheBase::Instance();
}
{
SmartPtr<int> sp1, sp2;
GetImpl(sp1);
sp1 = sp2;
SmartPtr<Base, RefLinked> sp3;
SmartPtr<Derived, RefLinked> sp4(new Derived);
sp3 = sp4;
SmartPtr<Derived, RefCounted, AllowConversion> sp5;
if (!!sp5)
{}
//Derived* p = sp5;
//delete sp5;
}
{
class MyClass : public SmallObject<> {};
MyClass* p1 = new MyClass;
MyClass* p2 = new MyClass;
delete p1;
delete p2;
}
}

View file

@ -1,4 +1,4 @@
Last update: February 19, 2001
Last update: June 20, 2001
Directions:
@ -12,6 +12,9 @@ Compatibility:
Loki has been tested with Metrowerks CodeWarrior Pro 6 under Windows. CodeWarrior has a problem with the Conversion template (see TypeManip.h) and, though it compiles it, it doesn't provide correct results. Consequently, the DerivedToFront algorithm in Typelist.h does not function. This affects the static dispatcher in Multimethods.h. As a fix, you must order the types (putting the most derived ones in the front) when providing the typelist argument to StaticDispatcher.
Also, Loki has been ported to gcc 2.95.3 by Nick Thurn.
More info:
http://moderncppdesign.com

View file

@ -13,7 +13,7 @@
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001
// Last update: June 20, 2001
#ifndef STATIC_CHECK_INC_
#define STATIC_CHECK_INC_
@ -24,12 +24,8 @@ namespace Loki
// Helper structure for the STATIC_CHECK macro
////////////////////////////////////////////////////////////////////////////////
template<bool> struct CompileTimeChecker
{
CompileTimeChecker(...);
};
template<> struct CompileTimeChecker<false> {};
template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
}
////////////////////////////////////////////////////////////////////////////////
@ -42,9 +38,14 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
#define STATIC_CHECK(expr, msg) \
{\
class ERROR_##msg {}; \
(void)sizeof(::Loki::CompileTimeChecker<(expr) != 0>(ERROR_##msg()));\
}
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20, 2001: add extra parens to STATIC_CHECK - it looked like a fun
// definition
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // STATIC_CHECK_INC_