Logo Search packages:      
Sourcecode: poco version File versions  Download package

TypeList.h
//
// TypeList.h
//
// $Id: //poco/1.3/Foundation/include/Poco/TypeList.h#6 $
//
// 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;

      
00058 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> 
00083 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> 
00167 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 <>
00184 struct TypeListType<>
{
      typedef NullTypeList HeadType;
};


template <int n> 
00191 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 <> 
00208 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> 
00229 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> 
00237 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>
00258 struct TypeLocator<NullTypeList, T>
{
      enum { value = -1 };
};


template <class T, class Tail>
00265 struct TypeLocator<TypeList<T, Tail>, T>
{
      enum { value = 0 };
};


template <class Head, class Tail, class T>
00272 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 <>
00298 struct TypeAppender<NullTypeList, NullTypeList>
{
      typedef NullTypeList HeadType;
};


template <class T>
00305 struct TypeAppender<NullTypeList, T>
{
      typedef TypeList<T, NullTypeList> HeadType;
};


template <class Head, class Tail>
00312 struct TypeAppender<NullTypeList, TypeList<Head, Tail> >
{
      typedef TypeList<Head, Tail> HeadType;
};


template <class Head, class Tail, class T>
00319 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>
00337 struct TypeOneEraser<NullTypeList, T>
{
      typedef NullTypeList HeadType;
};


template <class T, class Tail>
00344 struct TypeOneEraser<TypeList<T, Tail>, T>
{
      typedef Tail HeadType;
};


template <class Head, class Tail, class T>
00351 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>
00369 struct TypeAllEraser<NullTypeList, T>
{
      typedef NullTypeList HeadType;
};


template <class T, class Tail>
00376 struct TypeAllEraser<TypeList<T, Tail>, T>
{
      typedef typename TypeAllEraser<Tail, T>::HeadType HeadType;
};


template <class Head, class Tail, class T>
00383 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 <> 
00401 struct TypeDuplicateEraser<NullTypeList>
{
      typedef NullTypeList HeadType;
};


template <class Head, class Tail>
00408 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>
00431 struct TypeOneReplacer<NullTypeList, T, R>
{
      typedef NullTypeList HeadType;
};


template <class T, class Tail, class R>
00438 struct TypeOneReplacer<TypeList<T, Tail>, T, R>
{
      typedef TypeList<R, Tail> HeadType;
};


template <class Head, class Tail, class T, class R>
00445 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>
00464 struct TypeAllReplacer<NullTypeList, T, R>
{
      typedef NullTypeList HeadType;
};


template <class T, class Tail, class R>
00471 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>
00478 struct TypeAllReplacer<TypeList<Head, Tail>, T, R>
{
      typedef TypeList<Head, typename TypeAllReplacer<Tail, T, R>::HeadType> HeadType;
};


} // namespace Poco


#endif

Generated by  Doxygen 1.6.0   Back to index