00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015 #ifndef LOKI_TYPELIST_INC_
00016 #define LOKI_TYPELIST_INC_
00017
00018
00019
00020
00021 #include "NullType.h"
00022 #include "TypeManip.h"
00023 #include "TypelistMacros.h"
00024
00025
00026 namespace Loki
00027 {
00029
00030
00031
00032
00033
00034
00036
00037 template <class T, class U>
00038 struct Typelist
00039 {
00040 typedef T Head;
00041 typedef U Tail;
00042 };
00043
00044
00045
00046 namespace TL
00047 {
00048
00050
00051
00052
00053
00054
00056
00057 template
00058 <
00059 typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
00060 typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
00061 typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
00062 typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
00063 typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
00064 typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
00065 >
00066 struct MakeTypelist
00067 {
00068 private:
00069 typedef typename MakeTypelist
00070 <
00071 T2 , T3 , T4 ,
00072 T5 , T6 , T7 ,
00073 T8 , T9 , T10,
00074 T11, T12, T13,
00075 T14, T15, T16,
00076 T17, T18
00077 >
00078 ::Result TailResult;
00079
00080 public:
00081 typedef Typelist<T1, TailResult> Result;
00082 };
00083
00084 template<>
00085 struct MakeTypelist<>
00086 {
00087 typedef NullType Result;
00088 };
00089
00091
00092
00093
00094
00095
00096
00098
00099 template <class TList> struct Length;
00100 template <> struct Length<NullType>
00101 {
00102 enum { value = 0 };
00103 };
00104
00105 template <class T, class U>
00106 struct Length< Typelist<T, U> >
00107 {
00108 enum { value = 1 + Length<U>::value };
00109 };
00110
00112
00113
00114
00115
00116
00117
00118
00120
00121 template <class TList, unsigned int index> struct TypeAt;
00122
00123 template <class Head, class Tail>
00124 struct TypeAt<Typelist<Head, Tail>, 0>
00125 {
00126 typedef Head Result;
00127 };
00128
00129 template <class Head, class Tail, unsigned int i>
00130 struct TypeAt<Typelist<Head, Tail>, i>
00131 {
00132 typedef typename TypeAt<Tail, i - 1>::Result Result;
00133 };
00134
00136
00137
00138
00139
00140
00141
00142
00143
00144
00146
00147 template <class TList, unsigned int index,
00148 typename DefaultType = NullType>
00149 struct TypeAtNonStrict
00150 {
00151 typedef DefaultType Result;
00152 };
00153
00154 template <class Head, class Tail, typename DefaultType>
00155 struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
00156 {
00157 typedef Head Result;
00158 };
00159
00160 template <class Head, class Tail, unsigned int i, typename DefaultType>
00161 struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
00162 {
00163 typedef typename
00164 TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
00165 };
00166
00168
00169
00170
00171
00172
00174
00175 template <class TList, class T> struct IndexOf;
00176
00177 template <class T>
00178 struct IndexOf<NullType, T>
00179 {
00180 enum { value = -1 };
00181 };
00182
00183 template <class T, class Tail>
00184 struct IndexOf<Typelist<T, Tail>, T>
00185 {
00186 enum { value = 0 };
00187 };
00188
00189 template <class Head, class Tail, class T>
00190 struct IndexOf<Typelist<Head, Tail>, T>
00191 {
00192 private:
00193 enum { temp = IndexOf<Tail, T>::value };
00194 public:
00195 enum { value = (temp == -1 ? -1 : 1 + temp) };
00196 };
00197
00199
00200
00201
00202
00203
00205
00206 template <class TList, class T> struct Append;
00207
00208 template <> struct Append<NullType, NullType>
00209 {
00210 typedef NullType Result;
00211 };
00212
00213 template <class T> struct Append<NullType, T>
00214 {
00215 typedef Typelist<T,NullType> Result;
00216 };
00217
00218 template <class Head, class Tail>
00219 struct Append<NullType, Typelist<Head, Tail> >
00220 {
00221 typedef Typelist<Head, Tail> Result;
00222 };
00223
00224 template <class Head, class Tail, class T>
00225 struct Append<Typelist<Head, Tail>, T>
00226 {
00227 typedef Typelist<Head,
00228 typename Append<Tail, T>::Result>
00229 Result;
00230 };
00231
00233
00234
00235
00236
00237
00239
00240 template <class TList, class T> struct Erase;
00241
00242 template <class T>
00243 struct Erase<NullType, T>
00244 {
00245 typedef NullType Result;
00246 };
00247
00248 template <class T, class Tail>
00249 struct Erase<Typelist<T, Tail>, T>
00250 {
00251 typedef Tail Result;
00252 };
00253
00254 template <class Head, class Tail, class T>
00255 struct Erase<Typelist<Head, Tail>, T>
00256 {
00257 typedef Typelist<Head,
00258 typename Erase<Tail, T>::Result>
00259 Result;
00260 };
00261
00263
00264
00265
00266
00267
00269
00270 template <class TList, class T> struct EraseAll;
00271 template <class T>
00272 struct EraseAll<NullType, T>
00273 {
00274 typedef NullType Result;
00275 };
00276 template <class T, class Tail>
00277 struct EraseAll<Typelist<T, Tail>, T>
00278 {
00279
00280 typedef typename EraseAll<Tail, T>::Result Result;
00281 };
00282 template <class Head, class Tail, class T>
00283 struct EraseAll<Typelist<Head, Tail>, T>
00284 {
00285
00286 typedef Typelist<Head,
00287 typename EraseAll<Tail, T>::Result>
00288 Result;
00289 };
00290
00292
00293
00294
00295
00297
00298 template <class TList> struct NoDuplicates;
00299
00300 template <> struct NoDuplicates<NullType>
00301 {
00302 typedef NullType Result;
00303 };
00304
00305 template <class Head, class Tail>
00306 struct NoDuplicates< Typelist<Head, Tail> >
00307 {
00308 private:
00309 typedef typename NoDuplicates<Tail>::Result L1;
00310 typedef typename Erase<L1, Head>::Result L2;
00311 public:
00312 typedef Typelist<Head, L2> Result;
00313 };
00314
00316
00317
00318
00319
00320
00322
00323 template <class TList, class T, class U> struct Replace;
00324
00325 template <class T, class U>
00326 struct Replace<NullType, T, U>
00327 {
00328 typedef NullType Result;
00329 };
00330
00331 template <class T, class Tail, class U>
00332 struct Replace<Typelist<T, Tail>, T, U>
00333 {
00334 typedef Typelist<U, Tail> Result;
00335 };
00336
00337 template <class Head, class Tail, class T, class U>
00338 struct Replace<Typelist<Head, Tail>, T, U>
00339 {
00340 typedef Typelist<Head,
00341 typename Replace<Tail, T, U>::Result>
00342 Result;
00343 };
00344
00346
00347
00348
00349
00350
00352
00353 template <class TList, class T, class U> struct ReplaceAll;
00354
00355 template <class T, class U>
00356 struct ReplaceAll<NullType, T, U>
00357 {
00358 typedef NullType Result;
00359 };
00360
00361 template <class T, class Tail, class U>
00362 struct ReplaceAll<Typelist<T, Tail>, T, U>
00363 {
00364 typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
00365 };
00366
00367 template <class Head, class Tail, class T, class U>
00368 struct ReplaceAll<Typelist<Head, Tail>, T, U>
00369 {
00370 typedef Typelist<Head,
00371 typename ReplaceAll<Tail, T, U>::Result>
00372 Result;
00373 };
00374
00376
00377
00378
00379
00380
00382
00383 template <class TList> struct Reverse;
00384
00385 template <>
00386 struct Reverse<NullType>
00387 {
00388 typedef NullType Result;
00389 };
00390
00391 template <class Head, class Tail>
00392 struct Reverse< Typelist<Head, Tail> >
00393 {
00394 typedef typename Append<
00395 typename Reverse<Tail>::Result, Head>::Result Result;
00396 };
00397
00399
00400
00401
00402
00403
00405
00406 template <class TList, class T> struct MostDerived;
00407
00408 template <class T>
00409 struct MostDerived<NullType, T>
00410 {
00411 typedef T Result;
00412 };
00413
00414 template <class Head, class Tail, class T>
00415 struct MostDerived<Typelist<Head, Tail>, T>
00416 {
00417 private:
00418 typedef typename MostDerived<Tail, T>::Result Candidate;
00419 public:
00420 typedef typename Select<
00421 SuperSubclass<Candidate,Head>::value,
00422 Head, Candidate>::Result Result;
00423 };
00424
00426
00427
00428
00429
00430
00432
00433 template <class TList> struct DerivedToFront;
00434
00435 template <>
00436 struct DerivedToFront<NullType>
00437 {
00438 typedef NullType Result;
00439 };
00440
00441 template <class Head, class Tail>
00442 struct DerivedToFront< Typelist<Head, Tail> >
00443 {
00444 private:
00445 typedef typename MostDerived<Tail, Head>::Result
00446 TheMostDerived;
00447 typedef typename Replace<Tail,
00448 TheMostDerived, Head>::Result Temp;
00449 typedef typename DerivedToFront<Temp>::Result L;
00450 public:
00451 typedef Typelist<TheMostDerived, L> Result;
00452 };
00453
00454 }
00455 }
00456
00457
00458 #endif // end file guardian
00459