TypeList.hpp

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 
Generated on Wed Apr 13 10:05:49 2011 for Sierra Toolkit by  doxygen 1.6.3