/*
-----------------------------------------------------------------------
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