// Semantics Consulting's Tyr Library // http://www.semantics.org // // Copyright (c) 2003 by Stephen C. Dewhurst // // Permission to use, copy, modify, distribute, and sell this software // for any purpose is hereby granted without fee, provided that the above // copyright notice appears in all copies and that both that copyright // notice and this permission notice appear in supporting documentation. // The author makes no representations about the suitability of this // software for any purpose. It is provided "as is" without express // or implied warranty. // // Typelists and utilities. Mostly taken from Andrei Alexandrescu's // Modern C++ Design, so I'll include the following for good measure: //////////////////////////////////////////////////////////////////////////////// // 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. //////////////////////////////////////////////////////////////////////////////// #ifndef TYPELIST_H #define TYPELIST_H #include "utils.h" namespace Tyr { // // type lists // // These basic typelist functions are almost all taken from // Alexandrescu's Modern C++ Design, and their implementations // are almost identical to those. // template struct typelist { typedef H head; typedef T tail; }; class null_typelist {}; template struct IsTypelist { enum { r = false }; }; template struct IsTypelist< typelist > { enum { r = true }; }; template <> struct IsTypelist { enum { r = true }; }; template struct printTL { static void print() { std::cout << typeid(typename TL::head).name() << ", "; printTL::print(); } }; template <> struct printTL { static void print() { std::cout << "[end]" << std::endl; } }; // Length template struct Length; template struct Length< typelist > { enum { r = 1 + Length::r }; }; template <> struct Length { enum { r = 0 }; }; // TypeAt template struct TypeAt; template struct TypeAt,0> { typedef H R; }; template struct TypeAt,i> { typedef typename TypeAt::R R; }; // IndexOf template struct IndexOf; template struct IndexOf { enum { r = -1 }; }; template struct IndexOf,T> { enum {r = 0 }; }; template class IndexOf,T> { enum { temp = IndexOf::r }; public: enum { r = temp == -1 ? -1 : 1 + temp }; }; // Append template struct Append; template <> struct Append { typedef null_typelist R; }; template struct Append { typedef typelist R; }; template struct Append < null_typelist,typelist > { typedef typelist R; }; template struct Append,T> { typedef typelist::R> R; }; // Erase template struct Erase; template struct Erase { typedef null_typelist R; }; template struct Erase,T> { typedef Tail R; }; template struct Erase,T> { typedef typelist::R> R; }; // Erase All template struct EraseAll; template struct EraseAll { typedef null_typelist R; }; template struct EraseAll,T> { typedef typename EraseAll::R R; }; template struct EraseAll,T> { typedef typelist::R> R; }; // Erase Duplicates template struct NoDuplicates; template <> struct NoDuplicates { typedef null_typelist R; }; template class NoDuplicates > { typedef typename NoDuplicates::R L1; typedef typename Erase::R L2; public: typedef typelist R; }; #define MakeTypelist1(T1) Tyr::typelist #define MakeTypelist2(T1,T2) Tyr::typelist #define MakeTypelist3(T1,T2,T3) Tyr::typelist #define MakeTypelist4(T1,T2,T3,T4) Tyr::typelist #define MakeTypelist5(T1,T2,T3,T4,T5) Tyr::typelist #define MakeTypelist6(T1,T2,T3,T4,T5,T6) Tyr::typelist #define MakeTypelist7(T1,T2,T3,T4,T5,T6,T7) Tyr::typelist #define MakeTypelist8(T1,T2,T3,T4,T5,T6,T7,T8) Tyr::typelist #define MakeTypelist9(T1,T2,T3,T4,T5,T6,T7,T8,T9) Tyr::typelist } // namespace Tyr #endif