|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 00010 #ifndef stk_util_util_TypeList_h 00011 #define stk_util_util_TypeList_h 00012 00013 #include <stk_util/util/SameType.hpp> 00014 00015 namespace stk { 00016 00027 //---------------------------------------------------------------------- 00028 00029 struct TypeListEnd {}; 00030 00039 template< typename Value , class Tail = TypeListEnd > struct TypeList {}; 00040 00041 //---------------------------------------------------------------------- 00047 template< class ListType > struct TypeListLength {}; 00048 00049 template<> 00050 struct TypeListLength< TypeListEnd > 00051 { enum { value = 0 }; }; 00052 00053 template< typename Value , class Tail > 00054 struct TypeListLength< TypeList< Value , Tail > > 00055 { enum { value = 1 + TypeListLength< Tail >::value }; }; 00056 00057 //---------------------------------------------------------------------- 00064 template< class ListType, unsigned ordinal > struct TypeListAt {}; 00065 00066 template< unsigned ordinal > 00067 struct TypeListAt< TypeListEnd , ordinal > 00068 { typedef TypeListEnd type ; }; 00069 00070 template< typename Value , class Tail > 00071 struct TypeListAt< TypeList< Value , Tail > , 0 > 00072 { typedef Value type ; }; 00073 00074 template< typename Value , class Tail , unsigned ordinal > 00075 struct TypeListAt< TypeList< Value , Tail > , ordinal > 00076 { typedef typename TypeListAt< Tail , ordinal - 1 >::type type ; }; 00077 00078 //---------------------------------------------------------------------- 00086 template< class ListType , typename TestValue , unsigned ordinal = 0 > 00087 struct TypeListIndex {}; 00088 00089 template< typename TestValue , unsigned ordinal > 00090 struct TypeListIndex< TypeListEnd , TestValue , ordinal > 00091 { 00092 enum { value = -1 }; 00093 }; 00094 00095 template< typename Value , class Tail , typename TestValue , unsigned ordinal > 00096 struct TypeListIndex< TypeList< Value , Tail > , TestValue , ordinal > 00097 { 00098 private: 00099 enum { match = SameType< Value , TestValue >::value }; 00100 enum { J = match && 0 < ordinal ? ordinal - 1 : ordinal }; 00101 enum { N = TypeListIndex< Tail , TestValue , J >::value }; 00102 public: 00103 enum { value = match && 0 == ordinal ? 0 : ( -1 == N ? -1 : N + 1 ) }; 00104 }; 00105 00106 //---------------------------------------------------------------------- 00113 template< class ListType , typename TestValue > 00114 struct TypeListCount {}; 00115 00116 template< typename TestValue > 00117 struct TypeListCount< TypeListEnd , TestValue > 00118 { enum { value = 0 }; }; 00119 00120 template< typename Value , class Tail , typename TestValue > 00121 struct TypeListCount< TypeList< Value , Tail > , TestValue > 00122 { 00123 enum { value = TypeListCount< Tail , TestValue >::value + 00124 ( SameType< Value , TestValue >::value ? 1 : 0 ) }; 00125 }; 00126 00127 //---------------------------------------------------------------------- 00133 template< class ListType , typename TestValue > struct TypeListMember {}; 00134 00135 template< typename TestValue > 00136 struct TypeListMember< TypeListEnd , TestValue > 00137 { enum { value = false }; }; 00138 00139 template< typename Value , class Tail , typename TestValue > 00140 struct TypeListMember< TypeList< Value , Tail > , TestValue > 00141 { 00142 enum { value = SameType< Value , TestValue >::value || 00143 TypeListMember< Tail , TestValue >::value }; 00144 }; 00145 00146 //---------------------------------------------------------------------- 00152 template< class ListType > struct TypeListUnique {}; 00153 00154 template<> 00155 struct TypeListUnique< TypeListEnd > 00156 { enum { value = true }; }; 00157 00158 template< typename Value , class Tail > 00159 struct TypeListUnique< TypeList< Value , Tail > > 00160 { 00161 enum { value = ! TypeListMember< Tail , Value >::value && 00162 TypeListUnique< Tail >::value }; 00163 }; 00164 00165 //---------------------------------------------------------------------- 00172 template< class ListA , class ListB > struct TypeListDisjoint {}; 00173 00174 template< class ListB > 00175 struct TypeListDisjoint< TypeListEnd , ListB > 00176 { enum { value = true }; }; 00177 00178 template< typename Value , class Tail , class ListB > 00179 struct TypeListDisjoint< TypeList< Value , Tail > , ListB > 00180 { 00181 enum { value = ! TypeListMember< ListB , Value >::value && 00182 TypeListDisjoint< Tail , ListB >::value }; 00183 }; 00184 00185 //---------------------------------------------------------------------- 00191 template< class ListType > struct TypeListFirst {}; 00192 00193 template<> 00194 struct TypeListFirst< TypeListEnd > 00195 { typedef TypeListEnd type ; }; 00196 00197 template< typename Value , class Tail > 00198 struct TypeListFirst< TypeList< Value , Tail > > 00199 { typedef Value type ; }; 00200 00201 //---------------------------------------------------------------------- 00207 template< class ListType > struct TypeListLast {}; 00208 00209 template<> 00210 struct TypeListLast< TypeListEnd > 00211 { typedef TypeListEnd type ; }; 00212 00213 template< typename Value > 00214 struct TypeListLast< TypeList< Value , TypeListEnd > > 00215 { typedef Value type ; }; 00216 00217 template< typename Value , class Tail > 00218 struct TypeListLast< TypeList< Value , Tail > > 00219 { typedef typename TypeListLast< Tail >::type type ; }; 00220 00221 //---------------------------------------------------------------------- 00227 template< class ListA , typename T > struct TypeListAppend {}; 00228 00229 template<> 00230 struct TypeListAppend< TypeListEnd , TypeListEnd > 00231 { typedef TypeListEnd type ; }; 00232 00233 template< typename T > 00234 struct TypeListAppend< TypeListEnd , T > 00235 { typedef TypeList< T > type ; }; 00236 00237 template< typename Value , class Tail , typename T > 00238 struct TypeListAppend< TypeList< Value , Tail > , T > 00239 { 00240 typedef TypeList< Value , typename TypeListAppend< Tail , T >::type > type ; 00241 }; 00242 00243 //---------------------------------------------------------------------- 00249 template< class ListA , class ListB > struct TypeListJoin {}; 00250 00251 template<> 00252 struct TypeListJoin< TypeListEnd , TypeListEnd > 00253 { typedef TypeListEnd type ; }; 00254 00255 template< typename Value , class Tail > 00256 struct TypeListJoin< TypeListEnd , TypeList< Value , Tail > > 00257 { typedef TypeList< Value , Tail > type ; }; 00258 00259 template< typename ValueA , class TailA , typename ValueB , class TailB > 00260 struct TypeListJoin< TypeList< ValueA , TailA > , 00261 TypeList< ValueB , TailB > > 00262 { 00263 private: 00264 typedef typename 00265 TypeListJoin< TailA , TypeList< ValueB , TailB > >::type Tail ; 00266 public: 00267 typedef TypeList< ValueA , Tail > type ; 00268 }; 00269 00270 //---------------------------------------------------------------------- 00276 template< class ListType, unsigned ordinal > struct TypeListEraseAt {}; 00277 00278 template< typename Value , class Tail > 00279 struct TypeListEraseAt< TypeList< Value , Tail > , 0 > 00280 { typedef Tail type ; }; 00281 00282 template< typename Value , class Tail , unsigned ordinal > 00283 struct TypeListEraseAt< TypeList< Value , Tail > , ordinal > 00284 { 00285 typedef TypeList< Value , 00286 typename TypeListEraseAt<Tail,ordinal-1>::type > type ; 00287 }; 00288 00289 00290 //---------------------------------------------------------------------- 00297 template< class ListType > struct TypeListClean {}; 00298 00299 template<> 00300 struct TypeListClean< TypeListEnd > 00301 { typedef TypeListEnd type ; }; 00302 00303 template< class Tail > 00304 struct TypeListClean< TypeList< TypeListEnd , Tail > > 00305 { typedef TypeListEnd type ; }; 00306 00307 template< typename Value , class Tail > 00308 struct TypeListClean< TypeList< Value , Tail > > 00309 { 00310 typedef TypeList< Value , typename TypeListClean< Tail >::type > type ; 00311 }; 00312 00313 //---------------------------------------------------------------------- 00319 template< typename T00 = TypeListEnd , 00320 typename T01 = TypeListEnd , 00321 typename T02 = TypeListEnd , 00322 typename T03 = TypeListEnd , 00323 typename T04 = TypeListEnd , 00324 typename T05 = TypeListEnd , 00325 typename T06 = TypeListEnd , 00326 typename T07 = TypeListEnd , 00327 typename T08 = TypeListEnd , 00328 typename T09 = TypeListEnd , 00329 typename T10 = TypeListEnd , 00330 typename T11 = TypeListEnd , 00331 typename T12 = TypeListEnd , 00332 typename T13 = TypeListEnd , 00333 typename T14 = TypeListEnd , 00334 typename T15 = TypeListEnd , 00335 typename T16 = TypeListEnd , 00336 typename T17 = TypeListEnd , 00337 typename T18 = TypeListEnd , 00338 typename T19 = TypeListEnd , 00339 typename T20 = TypeListEnd , 00340 typename T21 = TypeListEnd , 00341 typename T22 = TypeListEnd , 00342 typename T23 = TypeListEnd , 00343 typename T24 = TypeListEnd , 00344 typename T25 = TypeListEnd , 00345 typename T26 = TypeListEnd , 00346 typename T27 = TypeListEnd , 00347 typename T28 = TypeListEnd , 00348 typename T29 = TypeListEnd , 00349 typename T30 = TypeListEnd , 00350 typename T31 = TypeListEnd , 00351 typename T32 = TypeListEnd , 00352 typename T33 = TypeListEnd , 00353 typename T34 = TypeListEnd , 00354 typename T35 = TypeListEnd , 00355 typename T36 = TypeListEnd , 00356 typename T37 = TypeListEnd , 00357 typename T38 = TypeListEnd , 00358 typename T39 = TypeListEnd , 00359 typename T40 = TypeListEnd , 00360 typename T41 = TypeListEnd , 00361 typename T42 = TypeListEnd , 00362 typename T43 = TypeListEnd , 00363 typename T44 = TypeListEnd , 00364 typename T45 = TypeListEnd , 00365 typename T46 = TypeListEnd , 00366 typename T47 = TypeListEnd , 00367 typename T48 = TypeListEnd , 00368 typename T49 = TypeListEnd , 00369 typename T50 = TypeListEnd , 00370 typename T51 = TypeListEnd , 00371 typename T52 = TypeListEnd , 00372 typename T53 = TypeListEnd , 00373 typename T54 = TypeListEnd , 00374 typename T55 = TypeListEnd , 00375 typename T56 = TypeListEnd , 00376 typename T57 = TypeListEnd , 00377 typename T58 = TypeListEnd , 00378 typename T59 = TypeListEnd , 00379 typename T60 = TypeListEnd , 00380 typename T61 = TypeListEnd , 00381 typename T62 = TypeListEnd , 00382 typename T63 = TypeListEnd > 00383 struct MakeTypeList 00384 { 00385 #ifndef DOXYGEN_COMPILE 00386 private: 00387 typedef TypeList< T00 , 00388 TypeList< T01 , 00389 TypeList< T02 , 00390 TypeList< T03 , 00391 TypeList< T04 , 00392 TypeList< T05 , 00393 TypeList< T06 , 00394 TypeList< T07 , 00395 TypeList< T08 , 00396 TypeList< T09 , 00397 TypeList< T10 , 00398 TypeList< T11 , 00399 TypeList< T12 , 00400 TypeList< T13 , 00401 TypeList< T14 , 00402 TypeList< T15 , 00403 TypeList< T16 , 00404 TypeList< T17 , 00405 TypeList< T18 , 00406 TypeList< T19 , 00407 TypeList< T20 , 00408 TypeList< T21 , 00409 TypeList< T22 , 00410 TypeList< T23 , 00411 TypeList< T24 , 00412 TypeList< T25 , 00413 TypeList< T26 , 00414 TypeList< T27 , 00415 TypeList< T28 , 00416 TypeList< T29 , 00417 TypeList< T30 , 00418 TypeList< T31 , 00419 TypeList< T32 , 00420 TypeList< T33 , 00421 TypeList< T34 , 00422 TypeList< T35 , 00423 TypeList< T36 , 00424 TypeList< T37 , 00425 TypeList< T38 , 00426 TypeList< T39 , 00427 TypeList< T40 , 00428 TypeList< T41 , 00429 TypeList< T42 , 00430 TypeList< T43 , 00431 TypeList< T44 , 00432 TypeList< T45 , 00433 TypeList< T46 , 00434 TypeList< T47 , 00435 TypeList< T48 , 00436 TypeList< T49 , 00437 TypeList< T50 , 00438 TypeList< T51 , 00439 TypeList< T52 , 00440 TypeList< T53 , 00441 TypeList< T54 , 00442 TypeList< T55 , 00443 TypeList< T56 , 00444 TypeList< T57 , 00445 TypeList< T58 , 00446 TypeList< T59 , 00447 TypeList< T60 , 00448 TypeList< T61 , 00449 TypeList< T62 , 00450 TypeList< T63 , 00451 TypeListEnd > > > > > > > > > > > > > > > > 00452 > > > > > > > > > > > > > > > > 00453 > > > > > > > > > > > > > > > > 00454 > > > > > > > > > > > > > > > > dirty_type ; 00455 #endif /* DOXYGEN_COMPILE */ 00456 public: 00457 00459 typedef typename TypeListClean< dirty_type >::type type ; 00460 00462 enum { length = TypeListLength<type>::value }; 00463 00465 enum { unique = TypeListUnique<type>::value }; 00466 }; 00467 00468 } // namespace stk 00469 00470 #endif // stk_util_util_TypeList_h 00471