233 lines
7.8 KiB
C
233 lines
7.8 KiB
C
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// The Loki Library
|
||
|
// Copyright (c) 2001 by Andrei Alexandrescu
|
||
|
// This code accompanies the book:
|
||
|
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
|
||
|
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
||
|
// Permission to use, copy, modify, distribute and sell this software for any
|
||
|
// purpose is hereby granted without fee, provided that the above copyright
|
||
|
// notice appear in all copies and that both that copyright notice and this
|
||
|
// permission notice appear in supporting documentation.
|
||
|
// The author or Addison-Welsey Longman make no representations about the
|
||
|
// suitability of this software for any purpose. It is provided "as is"
|
||
|
// without express or implied warranty.
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
// Last update: February 19, 2001
|
||
|
|
||
|
#ifndef HIERARCHYGENERATORS_INC_
|
||
|
#define HIERARCHYGENERATORS_INC_
|
||
|
|
||
|
#include "Typelist.h"
|
||
|
#include "TypeTraits.h"
|
||
|
#include "EmptyType.h"
|
||
|
|
||
|
namespace Loki
|
||
|
{
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// class template GenScatterHierarchy
|
||
|
// Generates a scattered hierarchy starting from a typelist and a template
|
||
|
// Invocation (TList is a typelist, Model is a template of one arg):
|
||
|
// GenScatterHierarchy<TList, Model>
|
||
|
// The generated class inherits all classes generated by instantiating the
|
||
|
// template 'Model' with the types contained in TList
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template <class TList, template <class> class Unit>
|
||
|
class GenScatterHierarchy;
|
||
|
|
||
|
template <class T1, class T2, template <class> class Unit>
|
||
|
class GenScatterHierarchy<Typelist<T1, T2>, Unit>
|
||
|
: public GenScatterHierarchy<T1, Unit>
|
||
|
, public GenScatterHierarchy<T2, Unit>
|
||
|
{
|
||
|
public:
|
||
|
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 <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 <template <class> class Unit>
|
||
|
class GenScatterHierarchy<NullType, Unit>
|
||
|
{
|
||
|
template <class T> struct Rebind
|
||
|
{ typedef Unit<T> Result; };
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// function template Field
|
||
|
// Accesses a field in an object of a type generated with GenScatterHierarchy
|
||
|
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
|
||
|
// T is a type in the typelist used to generate H):
|
||
|
// Field<T>(obj)
|
||
|
// returns a reference to Unit<T>, where Unit is the template used to generate H
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template <class T, class H>
|
||
|
typename H::Rebind<T>::Result& Field(H& obj)
|
||
|
{
|
||
|
return obj;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// function template TupleUnit
|
||
|
// The building block of tuples
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template <class T>
|
||
|
struct TupleUnit
|
||
|
{
|
||
|
T value_;
|
||
|
operator T&() { return value_; }
|
||
|
operator const T&() const { return value_; }
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// class template Tuple
|
||
|
// Implements a tuple class that holds a number of values and provides field
|
||
|
// access to them via the Field function (below)
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template <class TList>
|
||
|
struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
|
||
|
{
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// helper class template FieldHelper
|
||
|
// See Field below
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template <class H, unsigned int i> struct FieldHelper;
|
||
|
|
||
|
template <class H>
|
||
|
struct FieldHelper<H, 0>
|
||
|
{
|
||
|
typedef typename H::TList::Head ElementType;
|
||
|
typedef typename H::Rebind<ElementType>::Result UnitType;
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
isTuple =
|
||
|
Conversion<UnitType, TupleUnit<ElementType> >::sameType,
|
||
|
isConst = TypeTraits<H>::isConst
|
||
|
};
|
||
|
|
||
|
typedef Select<isConst, const H::LeftBase,
|
||
|
H::LeftBase>::Result LeftBase;
|
||
|
|
||
|
typedef Select<isTuple, ElementType, UnitType>::Result
|
||
|
UnqualifiedResultType;
|
||
|
typedef Select<isConst,
|
||
|
const UnqualifiedResultType,
|
||
|
UnqualifiedResultType>::Result
|
||
|
ResultType;
|
||
|
|
||
|
static ResultType& Do(H& obj)
|
||
|
{
|
||
|
LeftBase& leftBase = obj;
|
||
|
return leftBase;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <class H, unsigned int i>
|
||
|
struct FieldHelper
|
||
|
{
|
||
|
typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
|
||
|
typedef typename H::Rebind<ElementType>::Result UnitType;
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
isTuple =
|
||
|
Conversion<UnitType, TupleUnit<ElementType> >::sameType,
|
||
|
isConst = TypeTraits<H>::isConst
|
||
|
};
|
||
|
|
||
|
typedef Select<isConst, const H::RightBase,
|
||
|
H::RightBase>::Result RightBase;
|
||
|
|
||
|
typedef Select<isTuple, ElementType, UnitType>::Result
|
||
|
UnqualifiedResultType;
|
||
|
typedef 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);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// function template Field
|
||
|
// Accesses a field in an object of a type generated with GenScatterHierarchy
|
||
|
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
|
||
|
// i is the index of a type in the typelist used to generate H):
|
||
|
// Field<i>(obj)
|
||
|
// returns a reference to Unit<T>, where Unit is the template used to generate H
|
||
|
// and T is the i-th type in the typelist
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template <int i, class H>
|
||
|
typename FieldHelper<H, i>::ResultType&
|
||
|
Field(H& obj)
|
||
|
{
|
||
|
return FieldHelper<H, i>::Do(obj);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// class template GenLinearHierarchy
|
||
|
// Generates a linear hierarchy starting from a typelist and a template
|
||
|
// Invocation (TList is a typelist, Model is a template of two args):
|
||
|
// GenScatterHierarchy<TList, Model>
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
template
|
||
|
<
|
||
|
class TList,
|
||
|
template <class AtomicType, class Base> class Unit,
|
||
|
class Root = EmptyType
|
||
|
>
|
||
|
class GenLinearHierarchy;
|
||
|
|
||
|
template
|
||
|
<
|
||
|
class T1,
|
||
|
class T2,
|
||
|
template <class, class> class Unit,
|
||
|
class Root
|
||
|
>
|
||
|
class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
|
||
|
: public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >
|
||
|
{
|
||
|
};
|
||
|
|
||
|
template
|
||
|
<
|
||
|
class T,
|
||
|
template <class, class> class Unit,
|
||
|
class Root
|
||
|
>
|
||
|
class GenLinearHierarchy<TYPELIST_1(T), Unit, Root>
|
||
|
: public Unit<T, Root>
|
||
|
{
|
||
|
};
|
||
|
|
||
|
} // namespace Loki
|
||
|
|
||
|
|
||
|
#endif // HIERARCHYGENERATORS_INC_
|