// // 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 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 struct TypeList /// Compile Time List of Types { typedef Head HeadType; typedef Tail TailType; typedef typename TypeWrapper::CONSTTYPE ConstHeadType; typedef typename TypeWrapper::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 struct TypeListType /// TypeListType takes 1 - 20 typename arguments. /// Usage: /// /// TypeListType::HeadType typeList; /// /// typeList is a TypeList of T0, T1, ... , Tn { private: typedef typename TypeListType::HeadType TailType; public: typedef TypeList HeadType; }; template <> struct TypeListType<> { typedef NullTypeList HeadType; }; template struct Getter { template inline static Ret& get(TypeList& val) { return Getter::template get(val.tail); } template inline static const Ret& get(const TypeList& val) { return Getter::template get(val.tail); } }; template <> struct Getter<0> { template inline static Ret& get(TypeList& val) { return val.head; } template inline static const Ret& get(const TypeList& val) { return val.head; } }; template struct TypeGetter; template struct TypeGetter > { typedef typename TypeGetter::HeadType HeadType; typedef typename TypeWrapper::CONSTTYPE ConstHeadType; }; template struct TypeGetter<0, TypeList > { typedef typename TypeList::HeadType HeadType; typedef typename TypeWrapper::CONSTTYPE ConstHeadType; }; template struct TypeLocator; /// TypeLocator returns the first occurrence of the type T in Head /// or -1 if the type is not found. /// /// Usage example: /// /// TypeLocator::HeadType TypeLoc; /// /// if (2 == TypeLoc.value) ... /// template struct TypeLocator { enum { value = -1 }; }; template struct TypeLocator, T> { enum { value = 0 }; }; template struct TypeLocator, T> { private: enum { tmp = TypeLocator::value }; public: enum { value = tmp == -1 ? -1 : 1 + tmp }; }; template struct TypeAppender; /// TypeAppender appends T (type or a TypeList) to Head. /// /// Usage: /// /// typedef TypeListType::HeadType Type1; /// typedef TypeAppender::HeadType Type2; /// (Type2 is a TypeList of char,int) /// /// typedef TypeListType::HeadType Type3; /// typedef TypeAppender::HeadType Type4; /// (Type4 is a TypeList of char,int,float,double) /// template <> struct TypeAppender { typedef NullTypeList HeadType; }; template struct TypeAppender { typedef TypeList HeadType; }; template struct TypeAppender > { typedef TypeList HeadType; }; template struct TypeAppender, T> { typedef TypeList::HeadType> HeadType; }; template struct TypeOneEraser; /// TypeOneEraser erases the first occurence of the type T in Head. /// Usage: /// /// typedef TypeListType::HeadType Type3; /// typedef TypeOneEraser::HeadType Type2; /// (Type2 is a TypeList of char,float) /// template struct TypeOneEraser { typedef NullTypeList HeadType; }; template struct TypeOneEraser, T> { typedef Tail HeadType; }; template struct TypeOneEraser, T> { typedef TypeList ::HeadType> HeadType; }; template struct TypeAllEraser; /// TypeAllEraser erases all the occurences of the type T in Head. /// Usage: /// /// typedef TypeListType::HeadType Type4; /// typedef TypeAllEraser::HeadType Type2; /// (Type2 is a TypeList of char,float) /// template struct TypeAllEraser { typedef NullTypeList HeadType; }; template struct TypeAllEraser, T> { typedef typename TypeAllEraser::HeadType HeadType; }; template struct TypeAllEraser, T> { typedef TypeList ::HeadType> HeadType; }; template struct TypeDuplicateEraser; /// TypeDuplicateEraser erases all but the first occurence of the type T in Head. /// Usage: /// /// typedef TypeListType::HeadType Type4; /// typedef TypeDuplicateEraser::HeadType Type3; /// (Type3 is a TypeList of char,int,float) /// template <> struct TypeDuplicateEraser { typedef NullTypeList HeadType; }; template struct TypeDuplicateEraser > { private: typedef typename TypeDuplicateEraser::HeadType L1; typedef typename TypeOneEraser::HeadType L2; public: typedef TypeList HeadType; }; template struct TypeOneReplacer; /// TypeOneReplacer replaces the first occurence /// of the type T in Head with type R. /// Usage: /// /// typedef TypeListType::HeadType Type4; /// typedef TypeOneReplacer::HeadType TypeR; /// (TypeR is a TypeList of char,double,float,int) /// template struct TypeOneReplacer { typedef NullTypeList HeadType; }; template struct TypeOneReplacer, T, R> { typedef TypeList HeadType; }; template struct TypeOneReplacer, T, R> { typedef TypeList::HeadType> HeadType; }; template struct TypeAllReplacer; /// TypeAllReplacer replaces all the occurences /// of the type T in Head with type R. /// Usage: /// /// typedef TypeListType::HeadType Type4; /// typedef TypeAllReplacer::HeadType TypeR; /// (TypeR is a TypeList of char,double,float,double) /// template struct TypeAllReplacer { typedef NullTypeList HeadType; }; template struct TypeAllReplacer, T, R> { typedef TypeList::HeadType> HeadType; }; template struct TypeAllReplacer, T, R> { typedef TypeList::HeadType> HeadType; }; } // namespace Poco #endif