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

View file

@ -13,7 +13,7 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef ASSOCVECTOR_INC_ #ifndef ASSOCVECTOR_INC_
#define ASSOCVECTOR_INC_ #define ASSOCVECTOR_INC_
@ -22,7 +22,6 @@
#include <functional> #include <functional>
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <utility>
namespace Loki namespace Loki
{ {
@ -140,7 +139,7 @@ namespace Loki
} }
AssocVector& operator=(const AssocVector& rhs) AssocVector& operator=(const AssocVector& rhs)
{ AssocVector(*this).swap(*this); } { AssocVector(rhs).swap(*this); }
// iterators: // iterators:
// The following are here because MWCW gets 'using' wrong // The following are here because MWCW gets 'using' wrong
@ -286,7 +285,7 @@ namespace Loki
const key_type& k) const const key_type& k) const
{ {
const MyCompare& me = *this; 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) friend bool operator==(const AssocVector& lhs, const AssocVector& rhs)
@ -295,10 +294,11 @@ namespace Loki
return me == rhs; return me == rhs;
} }
friend bool operator<(const AssocVector& lhs, const AssocVector& rhs) bool operator<(const AssocVector& rhs) const
{ {
const Base& me = lhs; const Base& me = *this;
return me < rhs; const Base& yo = rhs;
return me < yo;
} }
friend bool operator!=(const AssocVector& lhs, const AssocVector& rhs) friend bool operator!=(const AssocVector& lhs, const AssocVector& rhs)
@ -321,4 +321,11 @@ namespace Loki
} // 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_ #endif // ASSOCVECTOR_INC_

View file

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

View file

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

125
Functor.h
View file

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

View file

@ -13,7 +13,7 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: March 05, 2001
#ifndef HIERARCHYGENERATORS_INC_ #ifndef HIERARCHYGENERATORS_INC_
#define HIERARCHYGENERATORS_INC_ #define HIERARCHYGENERATORS_INC_
@ -45,25 +45,29 @@ namespace Loki
typedef Typelist<T1, T2> TList; typedef Typelist<T1, T2> TList;
typedef GenScatterHierarchy<T1, Unit> LeftBase; typedef GenScatterHierarchy<T1, Unit> LeftBase;
typedef GenScatterHierarchy<T2, Unit> RightBase; typedef GenScatterHierarchy<T2, Unit> RightBase;
template <typename T> struct Rebind
template <class T> struct Rebind {
{ typedef Unit<T> Result; }; typedef Unit<T> Result;
};
}; };
template <class AtomicType, template <class> class Unit> template <class AtomicType, template <class> class Unit>
class GenScatterHierarchy : public Unit<AtomicType> class GenScatterHierarchy : public Unit<AtomicType>
{ {
typedef Unit<AtomicType> LeftBase; typedef Unit<AtomicType> LeftBase;
template <typename T> struct Rebind
template <class T> struct Rebind {
{ typedef Unit<T> Result; }; typedef Unit<T> Result;
};
}; };
template <template <class> class Unit> template <template <class> class Unit>
class GenScatterHierarchy<NullType, Unit> class GenScatterHierarchy<NullType, Unit>
{ {
template <class T> struct Rebind template <typename T> struct Rebind
{ typedef Unit<T> Result; }; {
typedef Unit<T> Result;
};
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -81,6 +85,12 @@ namespace Loki
return obj; return obj;
} }
template <class T, class H>
const typename H::Rebind<T>::Result& Field(const H& obj)
{
return obj;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// function template TupleUnit // function template TupleUnit
// The building block of tuples // The building block of tuples
@ -120,20 +130,20 @@ namespace Loki
enum enum
{ {
isTuple = isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
Conversion<UnitType, TupleUnit<ElementType> >::sameType,
isConst = TypeTraits<H>::isConst isConst = TypeTraits<H>::isConst
}; };
typedef Select<isConst, const H::LeftBase, typedef const typename H::LeftBase ConstLeftBase;
H::LeftBase>::Result LeftBase;
typedef Select<isTuple, ElementType, UnitType>::Result typedef typename Select<isConst, ConstLeftBase,
UnqualifiedResultType; typename H::LeftBase>::Result LeftBase;
typedef Select<isConst,
const UnqualifiedResultType, typedef typename Select<isTuple, ElementType,
UnqualifiedResultType>::Result UnitType>::Result UnqualifiedResultType;
ResultType;
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj) static ResultType& Do(H& obj)
{ {
@ -150,25 +160,25 @@ namespace Loki
enum enum
{ {
isTuple = isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
Conversion<UnitType, TupleUnit<ElementType> >::sameType,
isConst = TypeTraits<H>::isConst isConst = TypeTraits<H>::isConst
}; };
typedef Select<isConst, const H::RightBase, typedef const typename H::RightBase ConstRightBase;
H::RightBase>::Result RightBase;
typedef Select<isTuple, ElementType, UnitType>::Result typedef typename Select<isConst, ConstRightBase,
UnqualifiedResultType; typename H::RightBase>::Result RightBase;
typedef Select<isConst,
const UnqualifiedResultType, typedef typename Select<isTuple, ElementType,
UnqualifiedResultType>::Result UnitType>::Result UnqualifiedResultType;
ResultType;
typedef typename Select<isConst, const UnqualifiedResultType,
UnqualifiedResultType>::Result ResultType;
static ResultType& Do(H& obj) static ResultType& Do(H& obj)
{ {
typename H::RightBase& rightBase = obj; RightBase& rightBase = obj;
return FieldHelper<typename H::RightBase, i - 1>::Do(obj); return FieldHelper<RightBase, i - 1>::Do(rightBase);
} }
}; };
@ -189,6 +199,13 @@ namespace Loki
return FieldHelper<H, i>::Do(obj); 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 // class template GenLinearHierarchy
// Generates a linear hierarchy starting from a typelist and a template // Generates a linear hierarchy starting from a typelist and a template
@ -222,12 +239,16 @@ namespace Loki
template <class, class> class Unit, template <class, class> class Unit,
class Root class Root
> >
class GenLinearHierarchy<TYPELIST_1(T), Unit, Root> class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
: public Unit<T, Root> : public Unit<T, Root>
{ {
}; };
} // namespace Loki } // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // HIERARCHYGENERATORS_INC_ #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. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef MULTIMETHODS_INC_ #ifndef MULTIMETHODS_INC_
#define MULTIMETHODS_INC_ #define MULTIMETHODS_INC_
@ -38,25 +38,21 @@ namespace Loki
namespace Private namespace Private
{ {
template <bool swapArgs, class SomeLhs, class SomeRhs, class Executor, template <class SomeLhs, class SomeRhs,
typename ResultType> class Executor, typename ResultType>
struct InvocationTraits struct InvocationTraits
{ {
static ResultType DoDispatch(SomeLhs& lhs, SomeRhs& rhs, static ResultType
Executor& exec) DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
Executor& exec, Int2Type<false>)
{ {
return exec.Fire(lhs, rhs); return exec.Fire(lhs, rhs);
} }
}; static ResultType
DoDispatch(SomeLhs& lhs, SomeRhs& rhs,
template <class SomeLhs, class SomeRhs, class Executor, Executor& exec, Int2Type<true>)
typename ResultType>
struct InvocationTraits<true, SomeLhs, SomeRhs, Executor, ResultType>
{ {
static ResultType DoDispatch(SomeLhs& lhs, SomeRhs& rhs, return exec.Fire(rhs, lhs);
Executor& exec)
{
return exec.Fire(rhs, lhs); // swap arguments
} }
}; };
} }
@ -69,9 +65,9 @@ namespace Loki
template template
< <
class Executor, class Executor,
bool symmetric,
class BaseLhs, class BaseLhs,
class TypesLhs, class TypesLhs,
bool symmetric = true,
class BaseRhs = BaseLhs, class BaseRhs = BaseLhs,
class TypesRhs = TypesLhs, class TypesRhs = TypesLhs,
typename ResultType = void typename ResultType = void
@ -92,14 +88,14 @@ namespace Loki
if (Head* p2 = dynamic_cast<Head*>(&rhs)) if (Head* p2 = dynamic_cast<Head*>(&rhs))
{ {
enum { swapArgs = symmetric && Int2Type<(symmetric &&
TL::IndexOf<TypesRhs, Head>::value < int(TL::IndexOf<TypesRhs, Head>::value) <
TL::IndexOf<TypesLhs, SomeLhs>::value }; int(TL::IndexOf<TypesLhs, SomeLhs>::value))> i2t;
typedef Private::InvocationTraits<swapArgs,
SomeLhs, Head, Executor, ResultType>
CallTraits;
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()); return DispatchRhs(lhs, rhs, exec, Tail());
} }
@ -148,17 +144,10 @@ namespace Loki
typedef AssocVector<KeyType, MappedType> MapType; typedef AssocVector<KeyType, MappedType> MapType;
MapType callbackMap_; MapType callbackMap_;
void DoAdd(TypeInfo lhs, TypeInfo rhs, CallbackType fun);
bool DoRemove(TypeInfo lhs, TypeInfo rhs);
public: 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> template <class SomeLhs, class SomeRhs>
void Add(CallbackType fun) void Add(CallbackType fun)
{ {
@ -171,17 +160,39 @@ namespace Loki
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...
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( callbackMap_[KeyType(lhs, rhs)] = fun;
KeyType(typeid(lhs), typeid(rhs))); }
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()) if (i == callbackMap_.end())
{ {
throw std::runtime_error("Function not found"); throw std::runtime_error("Function not found");
} }
return (i->second)(lhs, rhs); return (i->second)(lhs, rhs);
} }
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// class template StaticCaster // 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 // class template FnDispatcher
// Implements an automatic logarithmic double dispatcher for functions // Implements an automatic logarithmic double dispatcher for functions
@ -228,43 +264,92 @@ struct DynamicCaster
ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_; ResultType (*)(BaseLhs&, BaseRhs&)> backEnd_;
public: public:
template <class ConcreteLhs, class ConcreteRhs> template <class SomeLhs, class SomeRhs>
void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&)) void Add(ResultType (*pFun)(BaseLhs&, BaseRhs&))
{ {
return backEnd_.Add<ConcreteLhs, ConcreteRhs>(pFun); return backEnd_.Add<SomeLhs, SomeRhs>(pFun);
} }
template <class ConcreteLhs, class ConcreteRhs, template <class SomeLhs, class SomeRhs,
ResultType (*callback)(ConcreteLhs&, ConcreteRhs&), 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> bool symmetric>
void Add() void Add()
{ {
struct Local typedef Private::FnDispatcherHelper<
{ BaseLhs, BaseRhs,
static ResultType Trampoline(BaseLhs& lhs, BaseRhs& rhs) SomeLhs, SomeRhs,
{ ResultType,
return callback( CastingPolicy<SomeLhs,BaseLhs>,
CastingPolicy<ConcreteLhs, BaseLhs>::Cast(lhs), CastingPolicy<SomeRhs,BaseRhs>,
CastingPolicy<ConcreteRhs, BaseRhs>::Cast(rhs)); callback> Local;
}
static ResultType TrampolineR(BaseRhs& rhs, BaseLhs& lhs) Add<SomeLhs, SomeRhs>(&Local::Trampoline);
{
return Trampoline(lhs, rhs);
}
};
Add<ConcreteLhs, ConcreteRhs>(&Local::Trampoline);
if (symmetric) 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) ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
{ {
return backEnd_.Go(lhs, 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 // class template FunctorDispatcher
// Implements a logarithmic double dispatcher for functors // Implements a logarithmic double dispatcher for functors
@ -281,32 +366,46 @@ struct DynamicCaster
typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList; typedef TYPELIST_2(BaseLhs&, BaseRhs&) ArgsList;
typedef Functor<ResultType, ArgsList, DEFAULT_THREADING> FunctorType; typedef Functor<ResultType, ArgsList, DEFAULT_THREADING> FunctorType;
typedef DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType> DispatcherBackend<BaseLhs, BaseRhs, ResultType, FunctorType> backEnd_;
BackEndType;
BackEndType backEnd_;
public: public:
template <class SomeLhs, class SomeRhs, class Fun> template <class SomeLhs, class SomeRhs, class Fun>
void Add(const Fun& fun) void Add(const Fun& fun)
{ {
typedef FunctorImpl<ResultType, TYPELIST_2(BaseLhs, BaseRhs)> typedef Private::FunctorDispatcherHelper<
FunctorImplType; BaseLhs, BaseRhs,
class Adapter : public FunctorImplType SomeLhs, SomeRhs,
{ ResultType,
Fun fun_; CastingPolicy<SomeLhs, BaseLhs>,
virtual ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) CastingPolicy<SomeRhs, BaseRhs>,
{ Fun, false> Adapter;
return fun_(
CastingPolicy<ConcreteLhs, BaseLhs>::Cast(lhs), backEnd_.Add<SomeLhs, SomeRhs>(FunctorType(Adapter(fun)));
CastingPolicy<ConcreteRhs, BaseRhs>::Cast(rhs));
} }
virtual FunctorImplType* DoClone() const template <class SomeLhs, class SomeRhs, bool symmetric, class Fun>
{ return new Adapter(*this); } void Add(const Fun& fun)
public: {
Adapter(const Fun& fun) : fun_(fun) {} Add<SomeLhs,SomeRhs>(fun);
};
backEnd_.Add<SomeLhs, SomeRhs>( if (symmetric)
Functor<ResultType, ArgsList, DEFAULT_THREADING>(new Adapter(fun))); {
// 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) ResultType Go(BaseLhs& lhs, BaseRhs& rhs)
@ -316,5 +415,9 @@ struct DynamicCaster
}; };
} // namespace Loki } // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif #endif

View file

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

View file

@ -13,14 +13,14 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#include "Singleton.h" #include "Singleton.h"
using namespace Loki::Private; using namespace Loki::Private;
extern TrackerArray Loki::Private::pTrackerArray = 0; Loki::Private::TrackerArray Loki::Private::pTrackerArray = 0;
extern unsigned int Loki::Private::elements = 0; unsigned int Loki::Private::elements = 0;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// function AtExitFn // function AtExitFn
@ -40,3 +40,8 @@ void Loki::Private::AtExitFn()
// Destroy the element // Destroy the element
delete pTop; 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. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef SINGLETON_INC_ #ifndef SINGLETON_INC_
#define SINGLETON_INC_ #define SINGLETON_INC_
#include "Threads.h" #include "Threads.h"
#include <algorithm>
#include <stdexcept>
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
#include <new> #include <new>
@ -40,10 +42,10 @@ namespace Loki
virtual ~LifetimeTracker() = 0; virtual ~LifetimeTracker() = 0;
friend inline bool Compare(unsigned int longevity, static bool Compare(const LifetimeTracker* lhs,
const LifetimeTracker* p) const LifetimeTracker* rhs)
{ {
return p->longevity_ > longevity; return rhs->longevity_ > lhs->longevity_;
} }
private: private:
@ -113,14 +115,19 @@ namespace Loki
// Insert a pointer to the object into the queue // Insert a pointer to the object into the queue
TrackerArray pos = std::upper_bound( TrackerArray pos = std::upper_bound(
pTrackerArray, pTrackerArray + elements, longevity, Compare); pTrackerArray,
std::copy_backward(pos, pTrackerArray + elements, pTrackerArray + elements,
p,
LifetimeTracker::Compare);
std::copy_backward(
pos,
pTrackerArray + elements,
pTrackerArray + elements + 1); pTrackerArray + elements + 1);
*pos = p; *pos = p;
++elements; ++elements;
// Register a call to AtExitFn // 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; template <class T> bool PhoenixSingleton<T>::destroyedOnce_ = false;
#endif #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 // class template SingletonWithLongevity
// Implementation of the LifetimePolicy used by SingletonHolder // Implementation of the LifetimePolicy used by SingletonHolder
@ -265,13 +287,7 @@ namespace Loki
public: public:
static void ScheduleDestruction(T* pObj, void (*pFun)()) static void ScheduleDestruction(T* pObj, void (*pFun)())
{ {
struct Adapter Private::Adapter<T> adapter = { pFun };
{
void operator()(T*) { return pFun_(); }
void (*pFun_)();
};
Adapter adapter = { pFun };
SetLongevity(pObj, GetLongevity(pObj), adapter); SetLongevity(pObj, GetLongevity(pObj), adapter);
} }
@ -323,8 +339,8 @@ namespace Loki
SingletonHolder(); SingletonHolder();
// Data // Data
typedef ThreadingModel<T>::VolatileType InstanceType; typedef typename ThreadingModel<T*>::VolatileType PtrInstanceType;
static InstanceType* pInstance_; static PtrInstanceType pInstance_;
static bool destroyed_; static bool destroyed_;
}; };
@ -339,7 +355,7 @@ namespace Loki
template <class> class L, template <class> class L,
template <class> class M template <class> class M
> >
typename SingletonHolder<T, C, L, M>::InstanceType* typename SingletonHolder<T, C, L, M>::PtrInstanceType
SingletonHolder<T, C, L, M>::pInstance_; SingletonHolder<T, C, L, M>::pInstance_;
template template
@ -387,7 +403,7 @@ namespace Loki
LifetimePolicy, ThreadingModel>::MakeInstance() LifetimePolicy, ThreadingModel>::MakeInstance()
{ {
typename ThreadingModel<T>::Lock guard; typename ThreadingModel<T>::Lock guard;
guard; (void)guard;
if (!pInstance_) if (!pInstance_)
{ {
@ -418,4 +434,10 @@ namespace Loki
} }
} // 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_ #endif // SINGLETON_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: March 20, 2001
#include "SmallObj.h" #include "SmallObj.h"
#include <cassert> #include <cassert>
@ -119,8 +119,8 @@ void FixedAllocator::Chunk::Deallocate(void* p, std::size_t blockSize)
FixedAllocator::FixedAllocator(std::size_t blockSize) FixedAllocator::FixedAllocator(std::size_t blockSize)
: blockSize_(blockSize) : blockSize_(blockSize)
, deallocChunk_(0)
, allocChunk_(0) , allocChunk_(0)
, deallocChunk_(0)
{ {
assert(blockSize_ > 0); assert(blockSize_ > 0);
@ -217,10 +217,11 @@ void* FixedAllocator::Allocate()
if (i == chunks_.end()) if (i == chunks_.end())
{ {
// Initialize // Initialize
chunks_.push_back(Chunk()); chunks_.reserve(chunks_.size() + 1);
Chunk& newChunk = chunks_.back(); Chunk newChunk;
newChunk.Init(blockSize_, numBlocks_); newChunk.Init(blockSize_, numBlocks_);
allocChunk_ = &newChunk; chunks_.push_back(newChunk);
allocChunk_ = &chunks_.back();
deallocChunk_ = &chunks_.front(); deallocChunk_ = &chunks_.front();
break; break;
} }
@ -406,3 +407,10 @@ void SmallObjAllocator::Deallocate(void* p, std::size_t numBytes)
pLastDealloc_ = &*i; pLastDealloc_ = &*i;
pLastDealloc_->Deallocate(p); 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. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef SMALLOBJ_INC_ #ifndef SMALLOBJ_INC_
#define SMALLOBJ_INC_ #define SMALLOBJ_INC_
@ -133,6 +133,9 @@ namespace Loki
class SmallObject : public ThreadingModel< class SmallObject : public ThreadingModel<
SmallObject<ThreadingModel, chunkSize, maxSmallObjectSize> > SmallObject<ThreadingModel, chunkSize, maxSmallObjectSize> >
{ {
typedef ThreadingModel< SmallObject<ThreadingModel,
chunkSize, maxSmallObjectSize> > MyThreadingModel;
struct MySmallObjAllocator : public SmallObjAllocator struct MySmallObjAllocator : public SmallObjAllocator
{ {
MySmallObjAllocator() MySmallObjAllocator()
@ -148,8 +151,8 @@ namespace Loki
static void* operator new(std::size_t size) static void* operator new(std::size_t size)
{ {
#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) #if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0)
Lock lock; typename MyThreadingModel::Lock lock;
lock; // get rid of warning (void)lock; // get rid of warning
return SingletonHolder<MySmallObjAllocator, CreateStatic, return SingletonHolder<MySmallObjAllocator, CreateStatic,
PhoenixSingleton>::Instance().Allocate(size); PhoenixSingleton>::Instance().Allocate(size);
@ -160,8 +163,8 @@ namespace Loki
static void operator delete(void* p, std::size_t size) static void operator delete(void* p, std::size_t size)
{ {
#if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0) #if (MAX_SMALL_OBJECT_SIZE != 0) && (DEFAULT_CHUNK_SIZE != 0)
Lock lock; typename MyThreadingModel::Lock lock;
lock; // get rid of warning (void)lock; // get rid of warning
SingletonHolder<MySmallObjAllocator, CreateStatic, SingletonHolder<MySmallObjAllocator, CreateStatic,
PhoenixSingleton>::Instance().Deallocate(p, size); PhoenixSingleton>::Instance().Deallocate(p, size);
@ -173,4 +176,9 @@ namespace Loki
}; };
} // namespace Loki } // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////
#endif // SMALLOBJ_INC_ #endif // SMALLOBJ_INC_

View file

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

View file

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

View file

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

View file

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

View file

@ -13,7 +13,7 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef TYPEMANIP_INC_ #ifndef TYPEMANIP_INC_
#define TYPEMANIP_INC_ #define TYPEMANIP_INC_
@ -72,9 +72,16 @@ namespace Loki
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
namespace Private namespace Private
{
template <class T, class U>
struct ConversionHelper
{ {
typedef char Small; 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> template <class T, class U>
class Conversion struct Conversion
{ {
static Private::Big Test(...); typedef Private::ConversionHelper<T, U> H;
static Private::Small Test(U); #ifndef __MWERKS__
static T MakeT(); enum { exists = sizeof(typename H::Small) == sizeof(H::Test(H::MakeT())) };
#else
public: enum { exists = false };
enum { exists = sizeof(Test(MakeT())) == sizeof(Private::Small) }; #endif
enum { exists2Way = exists && enum { exists2Way = exists && Conversion<U, T>::exists };
Conversion<U, T>::exists };
enum { sameType = false }; enum { sameType = false };
}; };
template <class T> template <class T>
class Conversion<T, T> struct Conversion<T, T>
{ {
public:
enum { exists = 1, exists2Way = 1,sameType = 1 }; enum { exists = 1, exists2Way = 1,sameType = 1 };
}; };
template <class T> template <class T>
class Conversion<void, T> struct Conversion<void, T>
{ {
public:
enum { exists = 1, exists2Way = 0,sameType = 0 }; enum { exists = 1, exists2Way = 0,sameType = 0 };
}; };
template <class T> template <class T>
class Conversion<T, void> struct Conversion<T, void>
{ {
public:
enum { exists = 1, exists2Way = 0,sameType = 0 }; enum { exists = 1, exists2Way = 0,sameType = 0 };
}; };
@ -161,5 +164,9 @@ namespace Loki
(SUPERSUBCLASS(T, U) && \ (SUPERSUBCLASS(T, U) && \
!::Loki::Conversion<const T, const U>::sameType) !::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_ #endif // TYPEMANIP_INC_

View file

@ -190,10 +190,10 @@ namespace Loki
public: public:
enum { isPointer = PointerTraits<T>::result }; enum { isPointer = PointerTraits<T>::result };
typedef PointerTraits<T>::PointeeType PointeeType; typedef typename PointerTraits<T>::PointeeType PointeeType;
enum { isReference = ReferenceTraits<T>::result }; enum { isReference = ReferenceTraits<T>::result };
typedef ReferenceTraits<T>::ReferredType ReferredType; typedef typename ReferenceTraits<T>::ReferredType ReferredType;
enum { isMemberPointer = PToMTraits<T>::result }; enum { isMemberPointer = PToMTraits<T>::result };
@ -215,16 +215,22 @@ namespace Loki
enum { isArith = isIntegral || isFloat }; enum { isArith = isIntegral || isFloat };
enum { isFundamental = isStdFundamental || isArith || isFloat }; enum { isFundamental = isStdFundamental || isArith || isFloat };
typedef Select<isStdArith || isPointer || isMemberPointer, typedef typename Select<isStdArith || isPointer || isMemberPointer,
T, ReferredType&>::Result T, ReferredType&>::Result
ParameterType; ParameterType;
enum { isConst = UnConst<T>::isConst }; enum { isConst = UnConst<T>::isConst };
typedef UnConst<T>::Result NonConstType; typedef typename UnConst<T>::Result NonConstType;
enum { isVolatile = UnVolatile<T>::isVolatile }; enum { isVolatile = UnVolatile<T>::isVolatile };
typedef UnVolatile<T>::Result NonVolatileType; typedef typename UnVolatile<T>::Result NonVolatileType;
typedef UnVolatile<UnConst<T>::Result>::Result UnqualifiedType; 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_ #endif // TYPETRAITS_INC_

View file

@ -13,12 +13,12 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef TYPELIST_INC_ #ifndef TYPELIST_INC_
#define TYPELIST_INC_ #define TYPELIST_INC_
#include "Nulltype.h" #include "NullType.h"
#include "TypeManip.h" #include "TypeManip.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -113,31 +113,31 @@
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) > 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, \ #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, \ ::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) > 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, \ #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, \ ::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) > 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, \ #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, \ ::Loki::Typelist<T1, TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T22, T23, T24, T25) > T21, T22, T23, T24, T25) >
#define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ #define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ 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, \ ::Loki::Typelist<T1, TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T22, T23, T24, T25, T26) > T21, T22, T23, T24, T25, T26) >
#define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ #define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ 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, \ ::Loki::Typelist<T1, TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
T21, T22, T23, T24, T25, T26, T27) > T21, T22, T23, T24, T25, T26, T27) >
@ -460,7 +460,7 @@ namespace Loki
enum { value = -1 }; enum { value = -1 };
}; };
template <class Tail, class T> template <class T, class Tail>
struct IndexOf<Typelist<T, Tail>, T> struct IndexOf<Typelist<T, Tail>, T>
{ {
enum { value = 0 }; enum { value = 0 };
@ -472,7 +472,7 @@ namespace Loki
private: private:
enum { temp = IndexOf<Tail, T>::value }; enum { temp = IndexOf<Tail, T>::value };
public: public:
enum { value = temp == -1 ? -1 : 1 + temp }; enum { value = (temp == -1 ? -1 : 1 + temp) };
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -524,11 +524,13 @@ namespace Loki
{ {
typedef NullType Result; typedef NullType Result;
}; };
template <class T, class Tail> // Specialization 2 template <class T, class Tail> // Specialization 2
struct Erase<Typelist<T, Tail>, T> struct Erase<Typelist<T, Tail>, T>
{ {
typedef Tail Result; typedef Tail Result;
}; };
template <class Head, class Tail, class T> // Specialization 3 template <class Head, class Tail, class T> // Specialization 3
struct Erase<Typelist<Head, Tail>, T> struct Erase<Typelist<Head, Tail>, T>
{ {
@ -731,4 +733,12 @@ namespace Loki
} // namespace TL } // namespace TL
} // namespace Loki } // 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_ #endif // TYPELIST_INC_

View file

@ -13,7 +13,7 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef VISITOR_INC_ #ifndef VISITOR_INC_
#define VISITOR_INC_ #define VISITOR_INC_
@ -66,20 +66,20 @@ namespace Loki
template <class Head, class Tail, typename R> template <class Head, class Tail, typename R>
class Visitor<Typelist<Head, Tail>, R> class Visitor<Typelist<Head, Tail>, R>
: public Visitor<Head>, public Visitor<Tail> : public Visitor<Head, R>, public Visitor<Tail, R>
{ {
public: public:
typedef R ReturnType; typedef R ReturnType;
using Visitor<Head>::Visit; // using Visitor<Head, R>::Visit;
using Visitor<Tail>::Visit; // using Visitor<Tail, R>::Visit;
}; };
template <class Head, typename R> 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: public:
typedef R ReturnType; typedef R ReturnType;
using Visitor<Head>::Visit; using Visitor<Head, R>::Visit;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -96,7 +96,7 @@ namespace Loki
, public BaseVisitorImpl<Tail, R> , public BaseVisitorImpl<Tail, R>
{ {
public: public:
using BaseVisitorImpl<Tail, R>::Visit; // using BaseVisitorImpl<Tail, R>::Visit;
virtual R Visit(Head&) virtual R Visit(Head&)
{ return R(); } { return R(); }
@ -126,7 +126,11 @@ struct DefaultCatchAll
// class template BaseVisitable // class template BaseVisitable
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <typename R = void, template <typename, class> class CatchAll> template
<
typename R = void,
template <typename, class> class CatchAll = DefaultCatchAll
>
class BaseVisitable class BaseVisitable
{ {
public: public:
@ -157,23 +161,6 @@ struct DefaultCatchAll
virtual ReturnType Accept(BaseVisitor& guest) \ virtual ReturnType Accept(BaseVisitor& guest) \
{ return AcceptImpl(*this, 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 // class template CyclicVisitor
// Put it in every class that you want to make visitable (in addition to // 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> template <typename R, class TList>
class CyclicVisitor class CyclicVisitor : public Visitor<TList, R>
: public GenScatterHierarchy<TList, Private::VisitorBinder<R>::Result>
{ {
public: public:
typedef R ReturnType; 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> template <class Visited>
ReturnType GenericVisit(Visited& host) ReturnType GenericVisit(Visited& host)
{ {
Visitor<Visited>& subObj = *this; Visitor<Visited, ReturnType>& subObj = *this;
return subObj.Visit(host); return subObj.Visit(host);
} }
}; };
@ -208,4 +193,11 @@ struct DefaultCatchAll
} // namespace Loki } // 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_ #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: 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. 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: More info:
http://moderncppdesign.com http://moderncppdesign.com

View file

@ -13,7 +13,7 @@
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Last update: February 19, 2001 // Last update: June 20, 2001
#ifndef STATIC_CHECK_INC_ #ifndef STATIC_CHECK_INC_
#define STATIC_CHECK_INC_ #define STATIC_CHECK_INC_
@ -24,12 +24,8 @@ namespace Loki
// Helper structure for the STATIC_CHECK macro // Helper structure for the STATIC_CHECK macro
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template<bool> struct CompileTimeChecker template<int> struct CompileTimeError;
{ template<> struct CompileTimeError<true> {};
CompileTimeChecker(...);
};
template<> struct CompileTimeChecker<false> {};
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -42,9 +38,14 @@ namespace Loki
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define STATIC_CHECK(expr, msg) \ #define STATIC_CHECK(expr, msg) \
{\ { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
class ERROR_##msg {}; \
(void)sizeof(::Loki::CompileTimeChecker<(expr) != 0>(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_ #endif // STATIC_CHECK_INC_