Shards_TypeList.hpp

00001 /*------------------------------------------------------------------------*/
00002 /*                  shards : Shared Discretization Tools                  */
00003 /*                Copyright (2008) Sandia Corporation                     */
00004 /*                                                                        */
00005 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00006 /*  license for use of this work by or on behalf of the U.S. Government.  */
00007 /*                                                                        */
00008 /*  This library is free software; you can redistribute it and/or modify  */
00009 /*  it under the terms of the GNU Lesser General Public License as        */
00010 /*  published by the Free Software Foundation; either version 2.1 of the  */
00011 /*  License, or (at your option) any later version.                       */
00012 /*                                                                        */
00013 /*  This library is distributed in the hope that it will be useful,       */
00014 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
00015 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     */
00016 /*  Lesser General Public License for more details.                       */
00017 /*                                                                        */
00018 /*  You should have received a copy of the GNU Lesser General Public      */
00019 /*  License along with this library; if not, write to the Free Software   */
00020 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   */
00021 /*  USA                                                                   */
00022 /*------------------------------------------------------------------------*/
00023 
00024 #ifndef Shards_TypeList_hpp
00025 #define Shards_TypeList_hpp
00026 
00027 namespace shards {
00028 
00041 //----------------------------------------------------------------------
00046 template<typename T1, typename T2>
00047 struct SameType { enum { value = false }; };
00048 
00049 template<typename T>
00050 struct SameType<T,T> { enum { value = true }; };
00051 
00052 //----------------------------------------------------------------------
00053 
00054 struct TypeListEnd {};
00055 
00063 template< typename Value , class Tail = TypeListEnd > struct TypeList {};
00064 
00065 //----------------------------------------------------------------------
00070 template< class ListType > struct TypeListLength {};
00071 
00072 template<>
00073 struct TypeListLength< TypeListEnd >
00074 { enum { value = 0 }; };
00075 
00076 template< typename Value , class Tail >
00077 struct TypeListLength< TypeList< Value , Tail > >
00078 { enum { value = 1 + TypeListLength< Tail >::value }; };
00079 
00080 //----------------------------------------------------------------------
00086 template< class ListType, unsigned ordinal > struct TypeListAt {};
00087 
00088 template< unsigned ordinal >
00089 struct TypeListAt< TypeListEnd , ordinal >
00090 { typedef TypeListEnd type ; };
00091 
00092 template< typename Value , class Tail >
00093 struct TypeListAt< TypeList< Value , Tail > , 0 >
00094 { typedef Value type ; };
00095 
00096 template< typename Value , class Tail , unsigned ordinal >
00097 struct TypeListAt< TypeList< Value , Tail > , ordinal >
00098 { typedef typename TypeListAt< Tail , ordinal - 1 >::type type ; };
00099 
00100 //----------------------------------------------------------------------
00107 template< class ListType , typename TestValue , unsigned ordinal = 0 >
00108 struct TypeListIndex {};
00109 
00110 template< typename TestValue , unsigned ordinal >
00111 struct TypeListIndex< TypeListEnd , TestValue , ordinal >
00112 {
00113   enum { value = -1 };
00114 };
00115 
00116 template< typename Value , class Tail , typename TestValue , unsigned ordinal >
00117 struct TypeListIndex< TypeList< Value , Tail > , TestValue , ordinal >
00118 {
00119 private:
00120   enum { match = SameType< Value , TestValue >::value };
00121   enum { J = match && 0 < ordinal ? ordinal - 1 : ordinal };
00122   enum { N = TypeListIndex< Tail , TestValue , J >::value };
00123 public:
00124   enum { value = match && 0 == ordinal ? 0 : ( -1 == N ? -1 : N + 1 ) };
00125 };
00126 
00127 //----------------------------------------------------------------------
00133 template< class ListType , typename TestValue >
00134 struct TypeListCount {};
00135 
00136 template< typename TestValue >
00137 struct TypeListCount< TypeListEnd , TestValue >
00138 { enum { value = 0 }; };
00139 
00140 template< typename Value , class Tail , typename TestValue >
00141 struct TypeListCount< TypeList< Value , Tail > , TestValue >
00142 {
00143   enum { value = TypeListCount< Tail , TestValue >::value +
00144                  ( SameType< Value , TestValue >::value ? 1 : 0 ) };
00145 };
00146 
00147 //----------------------------------------------------------------------
00152 template< class ListType , typename TestValue > struct TypeListMember {};
00153 
00154 template< typename TestValue >
00155 struct TypeListMember< TypeListEnd , TestValue >
00156 { enum { value = false }; };
00157 
00158 template< typename Value , class Tail , typename TestValue >
00159 struct TypeListMember< TypeList< Value , Tail > , TestValue >
00160 {
00161   enum { value = SameType< Value , TestValue >::value ||
00162                  TypeListMember< Tail , TestValue >::value };
00163 };
00164 
00165 //----------------------------------------------------------------------
00170 template< class ListType > struct TypeListUnique {};
00171 
00172 template<>
00173 struct TypeListUnique< TypeListEnd >
00174 { enum { value = true }; };
00175 
00176 template< typename Value , class Tail >
00177 struct TypeListUnique< TypeList< Value , Tail > >
00178 {
00179   enum { value = ! TypeListMember< Tail , Value >::value &&
00180                  TypeListUnique< Tail >::value };
00181 };
00182 
00183 //----------------------------------------------------------------------
00189 template< class ListA , class ListB > struct TypeListDisjoint {};
00190 
00191 template< class ListB >
00192 struct TypeListDisjoint< TypeListEnd , ListB >
00193 { enum { value = true }; };
00194 
00195 template< typename Value , class Tail , class ListB >
00196 struct TypeListDisjoint< TypeList< Value , Tail > , ListB >
00197 {
00198   enum { value = ! TypeListMember< ListB , Value >::value &&
00199                  TypeListDisjoint< Tail , ListB >::value };
00200 };
00201 
00202 //----------------------------------------------------------------------
00207 template< class ListType > struct TypeListFirst {};
00208 
00209 template<>
00210 struct TypeListFirst< TypeListEnd >
00211 { typedef TypeListEnd type ; };
00212 
00213 template< typename Value , class Tail >
00214 struct TypeListFirst< TypeList< Value , Tail > >
00215 { typedef Value type ; };
00216 
00217 //----------------------------------------------------------------------
00222 template< class ListType > struct TypeListLast {};
00223 
00224 template<>
00225 struct TypeListLast< TypeListEnd >
00226 { typedef TypeListEnd type ; };
00227 
00228 template< typename Value >
00229 struct TypeListLast< TypeList< Value , TypeListEnd > >
00230 { typedef Value type ; };
00231 
00232 template< typename Value , class Tail >
00233 struct TypeListLast< TypeList< Value , Tail > >
00234 { typedef typename TypeListLast< Tail >::type type ; };
00235 
00236 //----------------------------------------------------------------------
00241 template< class ListA , typename T > struct TypeListAppend {};
00242 
00243 template<>
00244 struct TypeListAppend< TypeListEnd , TypeListEnd >
00245 { typedef TypeListEnd type ; };
00246 
00247 template< typename T >
00248 struct TypeListAppend< TypeListEnd , T >
00249 { typedef TypeList< T > type ; };
00250 
00251 template< typename Value , class Tail , typename T >
00252 struct TypeListAppend< TypeList< Value , Tail > , T >
00253 {
00254   typedef TypeList< Value , typename TypeListAppend< Tail , T >::type > type ;
00255 };
00256 
00257 //----------------------------------------------------------------------
00262 template< class ListA , class ListB > struct TypeListJoin {};
00263 
00264 template<>
00265 struct TypeListJoin< TypeListEnd , TypeListEnd >
00266 { typedef TypeListEnd type ; };
00267 
00268 template< typename Value , class Tail >
00269 struct TypeListJoin< TypeListEnd , TypeList< Value , Tail > >
00270 { typedef TypeList< Value , Tail > type ; };
00271 
00272 template< typename ValueA , class TailA , typename ValueB , class TailB >
00273 struct TypeListJoin< TypeList< ValueA , TailA > ,
00274                      TypeList< ValueB , TailB > >
00275 {
00276 private:
00277   typedef typename
00278     TypeListJoin< TailA , TypeList< ValueB , TailB > >::type Tail ;
00279 public:
00280   typedef TypeList< ValueA , Tail > type ;
00281 };
00282 
00283 //----------------------------------------------------------------------
00288 template< class ListType, unsigned ordinal > struct TypeListEraseAt {};
00289 
00290 template< typename Value , class Tail >
00291 struct TypeListEraseAt< TypeList< Value , Tail > , 0 >
00292 { typedef Tail type ; };
00293 
00294 template< typename Value , class Tail , unsigned ordinal >
00295 struct TypeListEraseAt< TypeList< Value , Tail > , ordinal >
00296 {
00297   typedef TypeList< Value ,
00298                     typename TypeListEraseAt<Tail,ordinal-1>::type > type ;
00299 };
00300 
00301 //----------------------------------------------------------------------
00308 template< class ListType > struct TypeListClean {};
00309 
00310 template<>
00311 struct TypeListClean< TypeListEnd >
00312 { typedef TypeListEnd type ; };
00313 
00314 template< class Tail >
00315 struct TypeListClean< TypeList< TypeListEnd , Tail > >
00316 { typedef TypeListEnd type ; };
00317 
00318 template< typename Value , class Tail >
00319 struct TypeListClean< TypeList< Value , Tail > >
00320 {
00321   typedef TypeList< Value , typename TypeListClean< Tail >::type > type ;
00322 };
00323 
00324 //----------------------------------------------------------------------
00329 template< typename T00 = TypeListEnd ,
00330           typename T01 = TypeListEnd ,
00331           typename T02 = TypeListEnd ,
00332           typename T03 = TypeListEnd ,
00333           typename T04 = TypeListEnd ,
00334           typename T05 = TypeListEnd ,
00335           typename T06 = TypeListEnd ,
00336           typename T07 = TypeListEnd ,
00337           typename T08 = TypeListEnd ,
00338           typename T09 = TypeListEnd ,
00339           typename T10 = TypeListEnd ,
00340           typename T11 = TypeListEnd ,
00341           typename T12 = TypeListEnd ,
00342           typename T13 = TypeListEnd ,
00343           typename T14 = TypeListEnd ,
00344           typename T15 = TypeListEnd ,
00345           typename T16 = TypeListEnd ,
00346           typename T17 = TypeListEnd ,
00347           typename T18 = TypeListEnd ,
00348           typename T19 = TypeListEnd ,
00349           typename T20 = TypeListEnd ,
00350           typename T21 = TypeListEnd ,
00351           typename T22 = TypeListEnd ,
00352           typename T23 = TypeListEnd ,
00353           typename T24 = TypeListEnd ,
00354           typename T25 = TypeListEnd ,
00355           typename T26 = TypeListEnd ,
00356           typename T27 = TypeListEnd ,
00357           typename T28 = TypeListEnd ,
00358           typename T29 = TypeListEnd ,
00359           typename T30 = TypeListEnd ,
00360           typename T31 = TypeListEnd ,
00361           typename T32 = TypeListEnd ,
00362           typename T33 = TypeListEnd ,
00363           typename T34 = TypeListEnd ,
00364           typename T35 = TypeListEnd ,
00365           typename T36 = TypeListEnd ,
00366           typename T37 = TypeListEnd ,
00367           typename T38 = TypeListEnd ,
00368           typename T39 = TypeListEnd ,
00369           typename T40 = TypeListEnd ,
00370           typename T41 = TypeListEnd ,
00371           typename T42 = TypeListEnd ,
00372           typename T43 = TypeListEnd ,
00373           typename T44 = TypeListEnd ,
00374           typename T45 = TypeListEnd ,
00375           typename T46 = TypeListEnd ,
00376           typename T47 = TypeListEnd ,
00377           typename T48 = TypeListEnd ,
00378           typename T49 = TypeListEnd ,
00379           typename T50 = TypeListEnd ,
00380           typename T51 = TypeListEnd ,
00381           typename T52 = TypeListEnd ,
00382           typename T53 = TypeListEnd ,
00383           typename T54 = TypeListEnd ,
00384           typename T55 = TypeListEnd ,
00385           typename T56 = TypeListEnd ,
00386           typename T57 = TypeListEnd ,
00387           typename T58 = TypeListEnd ,
00388           typename T59 = TypeListEnd ,
00389           typename T60 = TypeListEnd ,
00390           typename T61 = TypeListEnd ,
00391           typename T62 = TypeListEnd ,
00392           typename T63 = TypeListEnd >
00393 struct MakeTypeList
00394 {
00395 #ifndef DOXYGEN_COMPILE
00396 private:
00397   typedef  TypeList< T00 ,
00398            TypeList< T01 ,
00399            TypeList< T02 ,
00400            TypeList< T03 ,
00401            TypeList< T04 ,
00402            TypeList< T05 ,
00403            TypeList< T06 ,
00404            TypeList< T07 ,
00405            TypeList< T08 ,
00406            TypeList< T09 ,
00407            TypeList< T10 ,
00408            TypeList< T11 ,
00409            TypeList< T12 ,
00410            TypeList< T13 ,
00411            TypeList< T14 ,
00412            TypeList< T15 ,
00413            TypeList< T16 ,
00414            TypeList< T17 ,
00415            TypeList< T18 ,
00416            TypeList< T19 ,
00417            TypeList< T20 ,
00418            TypeList< T21 ,
00419            TypeList< T22 ,
00420            TypeList< T23 ,
00421            TypeList< T24 ,
00422            TypeList< T25 ,
00423            TypeList< T26 ,
00424            TypeList< T27 ,
00425            TypeList< T28 ,
00426            TypeList< T29 ,
00427            TypeList< T30 ,
00428            TypeList< T31 ,
00429            TypeList< T32 ,
00430            TypeList< T33 ,
00431            TypeList< T34 ,
00432            TypeList< T35 ,
00433            TypeList< T36 ,
00434            TypeList< T37 ,
00435            TypeList< T38 ,
00436            TypeList< T39 ,
00437            TypeList< T40 ,
00438            TypeList< T41 ,
00439            TypeList< T42 ,
00440            TypeList< T43 ,
00441            TypeList< T44 ,
00442            TypeList< T45 ,
00443            TypeList< T46 ,
00444            TypeList< T47 ,
00445            TypeList< T48 ,
00446            TypeList< T49 ,
00447            TypeList< T50 ,
00448            TypeList< T51 ,
00449            TypeList< T52 ,
00450            TypeList< T53 ,
00451            TypeList< T54 ,
00452            TypeList< T55 ,
00453            TypeList< T56 ,
00454            TypeList< T57 ,
00455            TypeList< T58 ,
00456            TypeList< T59 ,
00457            TypeList< T60 ,
00458            TypeList< T61 ,
00459            TypeList< T62 ,
00460            TypeList< T63 ,
00461            TypeListEnd > > > > > > > > > > > > > > > >
00462                        > > > > > > > > > > > > > > > >
00463                        > > > > > > > > > > > > > > > >
00464                        > > > > > > > > > > > > > > > > dirty_type ;
00465 #endif /* DOXYGEN_COMPILE */
00466 public:
00467 
00469   typedef typename TypeListClean< dirty_type >::type type ;
00470 
00472   enum { length = TypeListLength<type>::value };
00473 
00475   enum { unique = TypeListUnique<type>::value };
00476 };
00477 
00479 } // namespace shards
00480 
00481 #endif // Shards_TypeList_hpp
00482 
Generated on Wed Mar 31 15:02:54 2010 for shards by  doxygen 1.6.3