/* ----------------------------------------------------------------------- Copyright: 2010-2021, imec Vision Lab, University of Antwerp 2014-2021, CWI, Amsterdam Contact: astra@astra-toolbox.com Website: http://www.astra-toolbox.com/ This file is part of the ASTRA Toolbox. The ASTRA Toolbox is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The ASTRA Toolbox is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the ASTRA Toolbox. If not, see . ----------------------------------------------------------------------- */ #ifndef _INC_ASTRA_TYPELIST #define _INC_ASTRA_TYPELIST #include "Globals.h" #include namespace astra { namespace typelist { //----------------------------------------------------------------------------------------- // basic types /** * Type to serve as tail of typelist **/ class NullType { }; struct FalseType { enum { value = false }; }; struct TrueType { enum { value = true }; }; //----------------------------------------------------------------------------------------- // define typelist /** * Typelist definition * \par References * [1] Modern C++ design: generic programming and design patterns applied, Andrei Alexandrescu **/ template struct TypeList { typedef T Head; typedef U Tail; }; //----------------------------------------------------------------------------------------- // linearize typelist #define TYPELIST_0 typelist::NullType #define TYPELIST_1(T1) typelist::TypeList #define TYPELIST_2(T1,T2) typelist::TypeList #define TYPELIST_3(T1,T2,T3) typelist::TypeList #define TYPELIST_4(T1,T2,T3,T4) typelist::TypeList #define TYPELIST_5(T1,T2,T3,T4,T5) typelist::TypeList #define TYPELIST_6(T1,T2,T3,T4,T5,T6) typelist::TypeList #define TYPELIST_7(T1,T2,T3,T4,T5,T6,T7) typelist::TypeList #define TYPELIST_8(T1,T2,T3,T4,T5,T6,T7,T8) typelist::TypeList #define TYPELIST_9(T1,T2,T3,T4,T5,T6,T7,T8,T9) typelist::TypeList #define TYPELIST_10(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10) \ typelist::TypeList #define TYPELIST_11(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11) \ typelist::TypeList #define TYPELIST_12(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12) \ typelist::TypeList #define TYPELIST_13(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13) \ typelist::TypeList #define TYPELIST_14(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14) \ typelist::TypeList #define TYPELIST_15(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15) \ typelist::TypeList #define TYPELIST_16(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16) \ typelist::TypeList #define TYPELIST_17(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17) \ typelist::TypeList #define TYPELIST_18(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18) \ typelist::TypeList #define TYPELIST_19(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19) \ typelist::TypeList #define TYPELIST_20(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20) \ typelist::TypeList #define TYPELIST_21(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21) \ typelist::TypeList #define TYPELIST_22(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22) \ typelist::TypeList #define TYPELIST_23(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23) \ typelist::TypeList #define TYPELIST_24(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24) \ typelist::TypeList #define TYPELIST_25(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25) \ typelist::TypeList #define TYPELIST_26(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26) \ typelist::TypeList #define TYPELIST_27(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27) \ typelist::TypeList #define TYPELIST_28(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28) \ typelist::TypeList #define TYPELIST_29(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29) \ typelist::TypeList #define TYPELIST_30(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30) \ typelist::TypeList #define TYPELIST_31(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31) \ typelist::TypeList #define TYPELIST_32(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32) \ typelist::TypeList #define TYPELIST_33(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33) \ typelist::TypeList #define TYPELIST_34(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34) \ typelist::TypeList #define TYPELIST_35(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35) \ typelist::TypeList #define TYPELIST_36(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36) \ typelist::TypeList #define TYPELIST_37(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37) \ typelist::TypeList #define TYPELIST_38(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38) \ typelist::TypeList #define TYPELIST_39(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39) \ typelist::TypeList #define TYPELIST_40(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,T40) \ typelist::TypeList //----------------------------------------------------------------------------------------- // calculate length of a typelist template struct Length; template <> struct Length { enum { value = 0 }; }; template struct Length< TypeList > { enum { value = 1 + Length::value }; }; //----------------------------------------------------------------------------------------- // indexed access template struct TypeAt; template struct TypeAt , 0> { typedef Head Result; }; template struct TypeAt, i> { typedef typename TypeAt::Result Result; }; //----------------------------------------------------------------------------------------- // append to typelist template struct Append; template <> struct Append { typedef NullType Result; }; template struct Append { typedef TYPELIST_1(T) Result; }; template struct Append > { typedef TypeList Result; }; template struct Append, T> { typedef TypeList::Result> Result; }; //----------------------------------------------------------------------------------------- // create a new object template struct CreateObject { template static void find (U& functor) { if (functor(TList::Head::type)) { functor.res = new typename TList::Head(); } CreateObject::find(functor); } }; template <> struct CreateObject { template static void find(U& functor) {} }; template struct functor_find { functor_find() { res = NULL; } bool operator() (std::string name) { return strcmp(tofind.c_str(), name.c_str()) == 0; } std::string tofind; Base* res; }; } // end namespace typelist } // end namespace astra #endif