topical media & game development
lib-of-vs-libs-Poco-include-Poco-TypeList.h / h
//
// TypeList.h
//
//
//
// Library: Foundation
// Package: Core
// Module: TypeList
//
// Implementation of the TypeList template.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Portions extracted and adapted from
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
ifndef Foundation_TypeList_INCLUDED
define Foundation_TypeList_INCLUDED
include "Poco/Foundation.h"
include "Poco/MetaProgramming.h"
namespace Poco {
template <class Head, class Tail>
struct TypeList;
struct NullTypeList
{
enum
{
length = 0
};
bool operator == (const NullTypeList&) const
{
return true;
}
bool operator != (const NullTypeList&) const
{
return false;
}
bool operator < (const NullTypeList&) const
{
return false;
}
};
template <class Head, class Tail>
struct TypeList
Compile Time List of Types
{
typedef Head HeadType;
typedef Tail TailType;
typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
typedef typename TypeWrapper<TailType>::CONSTTYPE ConstTailType;
enum
{
length = TailType::length+1
};
TypeList():head(), tail()
{
}
TypeList(ConstHeadType& h, ConstTailType& t):head(h), tail(t)
{
}
TypeList(const TypeList& tl): head(tl.head), tail(tl.tail)
{
}
TypeList& operator = (const TypeList& tl)
{
if (this != &tl)
{
TypeList tmp(tl);
swap(tmp);
}
return *this;
}
bool operator == (const TypeList& tl) const
{
return tl.head == head && tl.tail == tail;
}
bool operator != (const TypeList& tl) const
{
return !(*this == tl);
}
bool operator < (const TypeList& tl) const
{
if (head < tl.head)
return true;
else if (head == tl.head)
return tail < tl.tail;
return false;
}
void swap(TypeList& tl)
{
std::swap(head, tl.head);
std::swap(tail, tl.tail);
}
HeadType head;
TailType tail;
};
template <typename T0 = NullTypeList,
typename T1 = NullTypeList,
typename T2 = NullTypeList,
typename T3 = NullTypeList,
typename T4 = NullTypeList,
typename T5 = NullTypeList,
typename T6 = NullTypeList,
typename T7 = NullTypeList,
typename T8 = NullTypeList,
typename T9 = NullTypeList,
typename T10 = NullTypeList,
typename T11 = NullTypeList,
typename T12 = NullTypeList,
typename T13 = NullTypeList,
typename T14 = NullTypeList,
typename T15 = NullTypeList,
typename T16 = NullTypeList,
typename T17 = NullTypeList,
typename T18 = NullTypeList,
typename T19 = NullTypeList>
struct TypeListType
TypeListType takes 1 - 20 typename arguments.
Usage:
TypeListType<T0, T1, ... , Tn>::HeadType typeList;
typeList is a TypeList of T0, T1, ... , Tn
{
private:
typedef typename TypeListType<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19>::HeadType TailType;
public:
typedef TypeList<T0, TailType> HeadType;
};
template <>
struct TypeListType<>
{
typedef NullTypeList HeadType;
};
template <int n>
struct Getter
{
template <class Ret, class Head, class Tail>
inline static Ret& get(TypeList<Head, Tail>& val)
{
return Getter<n-1>::template get<Ret, typename Tail::HeadType, typename Tail::TailType>(val.tail);
}
template <class Ret, class Head, class Tail>
inline static const Ret& get(const TypeList<Head, Tail>& val)
{
return Getter<n-1>::template get<Ret, typename Tail::HeadType, typename Tail::TailType>(val.tail);
}
};
template <>
struct Getter<0>
{
template <class Ret, class Head, class Tail>
inline static Ret& get(TypeList<Head, Tail>& val)
{
return val.head;
}
template <class Ret, class Head, class Tail>
inline static const Ret& get(const TypeList<Head, Tail>& val)
{
return val.head;
}
};
template <int N, class Head>
struct TypeGetter;
template <int N, class Head, class Tail>
struct TypeGetter<N, TypeList<Head, Tail> >
{
typedef typename TypeGetter<N-1, Tail>::HeadType HeadType;
typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
};
template <class Head, class Tail>
struct TypeGetter<0, TypeList<Head, Tail> >
{
typedef typename TypeList<Head, Tail>::HeadType HeadType;
typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
};
template <class Head, class T>
struct TypeLocator;
TypeLocator returns the first occurrence of the type T in Head
or -1 if the type is not found.
Usage example:
TypeLocator<Head, int>::HeadType TypeLoc;
if (2 == TypeLoc.value) ...
template <class T>
struct TypeLocator<NullTypeList, T>
{
enum { value = -1 };
};
template <class T, class Tail>
struct TypeLocator<TypeList<T, Tail>, T>
{
enum { value = 0 };
};
template <class Head, class Tail, class T>
struct TypeLocator<TypeList<Head, Tail>, T>
{
private:
enum { tmp = TypeLocator<Tail, T>::value };
public:
enum { value = tmp == -1 ? -1 : 1 + tmp };
};
template <class Head, class T>
struct TypeAppender;
TypeAppender appends T (type or a TypeList) to Head.
Usage:
typedef TypeListType
<char>::HeadType Type1;
typedef TypeAppender<Type1, int>::HeadType Type2;
(Type2 is a TypeList of char,int)
typedef TypeListType
<float, double>::HeadType Type3;
typedef TypeAppender<Type2, Type3>::HeadType Type4;
(Type4 is a TypeList of char,int,float,double)
template <>
struct TypeAppender<NullTypeList, NullTypeList>
{
typedef NullTypeList HeadType;
};
template <class T>
struct TypeAppender<NullTypeList, T>
{
typedef TypeList<T, NullTypeList> HeadType;
};
template <class Head, class Tail>
struct TypeAppender<NullTypeList, TypeList<Head, Tail> >
{
typedef TypeList<Head, Tail> HeadType;
};
template <class Head, class Tail, class T>
struct TypeAppender<TypeList<Head, Tail>, T>
{
typedef TypeList<Head, typename TypeAppender<Tail, T>::HeadType> HeadType;
};
template <class Head, class T>
struct TypeOneEraser;
TypeOneEraser erases the first occurence of the type T in Head.
Usage:
typedef TypeListType
<char, int, float>::HeadType Type3;
typedef TypeOneEraser<Type3, int>::HeadType Type2;
(Type2 is a TypeList of char,float)
template <class T>
struct TypeOneEraser<NullTypeList, T>
{
typedef NullTypeList HeadType;
};
template <class T, class Tail>
struct TypeOneEraser<TypeList<T, Tail>, T>
{
typedef Tail HeadType;
};
template <class Head, class Tail, class T>
struct TypeOneEraser<TypeList<Head, Tail>, T>
{
typedef TypeList <Head, typename TypeOneEraser<Tail, T>::HeadType> HeadType;
};
template <class Head, class T>
struct TypeAllEraser;
TypeAllEraser erases all the occurences of the type T in Head.
Usage:
typedef TypeListType
<char, int, float, int>::HeadType Type4;
typedef TypeAllEraser<Type4, int>::HeadType Type2;
(Type2 is a TypeList of char,float)
template <class T>
struct TypeAllEraser<NullTypeList, T>
{
typedef NullTypeList HeadType;
};
template <class T, class Tail>
struct TypeAllEraser<TypeList<T, Tail>, T>
{
typedef typename TypeAllEraser<Tail, T>::HeadType HeadType;
};
template <class Head, class Tail, class T>
struct TypeAllEraser<TypeList<Head, Tail>, T>
{
typedef TypeList <Head, typename TypeAllEraser<Tail, T>::HeadType> HeadType;
};
template <class Head>
struct TypeDuplicateEraser;
TypeDuplicateEraser erases all but the first occurence of the type T in Head.
Usage:
typedef TypeListType
<char, int, float, int>::HeadType Type4;
typedef TypeDuplicateEraser<Type4, int>::HeadType Type3;
(Type3 is a TypeList of char,int,float)
template <>
struct TypeDuplicateEraser<NullTypeList>
{
typedef NullTypeList HeadType;
};
template <class Head, class Tail>
struct TypeDuplicateEraser<TypeList<Head, Tail> >
{
private:
typedef typename TypeDuplicateEraser<Tail>::HeadType L1;
typedef typename TypeOneEraser<L1, Head>::HeadType L2;
public:
typedef TypeList<Head, L2> HeadType;
};
template <class Head, class T, class R>
struct TypeOneReplacer;
TypeOneReplacer replaces the first occurence
of the type T in Head with type R.
Usage:
typedef TypeListType
<char, int, float, int>::HeadType Type4;
typedef TypeOneReplacer<Type4, int, double>::HeadType TypeR;
(TypeR is a TypeList of char,double,float,int)
template <class T, class R>
struct TypeOneReplacer<NullTypeList, T, R>
{
typedef NullTypeList HeadType;
};
template <class T, class Tail, class R>
struct TypeOneReplacer<TypeList<T, Tail>, T, R>
{
typedef TypeList<R, Tail> HeadType;
};
template <class Head, class Tail, class T, class R>
struct TypeOneReplacer<TypeList<Head, Tail>, T, R>
{
typedef TypeList<Head, typename TypeOneReplacer<Tail, T, R>::HeadType> HeadType;
};
template <class Head, class T, class R>
struct TypeAllReplacer;
TypeAllReplacer replaces all the occurences
of the type T in Head with type R.
Usage:
typedef TypeListType
<char, int, float, int>::HeadType Type4;
typedef TypeAllReplacer<Type4, int, double>::HeadType TypeR;
(TypeR is a TypeList of char,double,float,double)
template <class T, class R>
struct TypeAllReplacer<NullTypeList, T, R>
{
typedef NullTypeList HeadType;
};
template <class T, class Tail, class R>
struct TypeAllReplacer<TypeList<T, Tail>, T, R>
{
typedef TypeList<R, typename TypeAllReplacer<Tail, T, R>::HeadType> HeadType;
};
template <class Head, class Tail, class T, class R>
struct TypeAllReplacer<TypeList<Head, Tail>, T, R>
{
typedef TypeList<Head, typename TypeAllReplacer<Tail, T, R>::HeadType> HeadType;
};
} // namespace Poco
endif
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.