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:
parent
2ffd6b016f
commit
1fadda9836
24 changed files with 612 additions and 686 deletions
|
@ -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_
|
|
@ -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_
|
|
@ -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_
|
|
@ -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
125
Functor.h
|
@ -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_
|
|
@ -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_
|
31
Mappings.h
31
Mappings.h
|
@ -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
|
253
MultiMethods.h
253
MultiMethods.h
|
@ -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
|
|
@ -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_
|
|
@ -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!!!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
58
Singleton.h
58
Singleton.h
|
@ -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_
|
18
SmallObj.cpp
18
SmallObj.cpp
|
@ -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!!!
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
18
SmallObj.h
18
SmallObj.h
|
@ -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_
|
32
SmartPtr.h
32
SmartPtr.h
|
@ -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_
|
|
@ -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
|
2
Tuple.h
2
Tuple.h
|
@ -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
|
||||
|
|
|
@ -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_
|
41
TypeManip.h
41
TypeManip.h
|
@ -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_
|
18
TypeTraits.h
18
TypeTraits.h
|
@ -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_
|
28
Typelist.h
28
Typelist.h
|
@ -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_
|
||||
|
||||
|
|
52
Visitor.h
52
Visitor.h
|
@ -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
301
main.cpp
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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_
|
Loading…
Add table
Add a link
Reference in a new issue