TypeList.hpp

00001 /*------------------------------------------------------------------------*/
00002 /*      phdMesh : Parallel Heterogneous Dynamic unstructured Mesh         */
00003 /*                Copyright (2007) 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 util_TypeList_h
00025 #define util_TypeList_h
00026 
00027 namespace phdmesh {
00028 
00038 //----------------------------------------------------------------------
00044 template<typename T1, typename T2>
00045 struct SameType
00046 { enum { value = false }; };
00047 
00048 template<typename T>
00049 struct SameType<T,T>
00050 { enum { value = true }; };
00051 
00052 //----------------------------------------------------------------------
00053 
00054 struct TypeListEnd {};
00055 
00064 template< typename Value , class Tail = TypeListEnd > struct TypeList {};
00065 
00066 //----------------------------------------------------------------------
00072 template< class ListType > struct TypeListLength {};
00073 
00074 template<>
00075 struct TypeListLength< TypeListEnd >
00076 { enum { value = 0 }; };
00077 
00078 template< typename Value , class Tail >
00079 struct TypeListLength< TypeList< Value , Tail > >
00080 { enum { value = 1 + TypeListLength< Tail >::value }; };
00081 
00082 //----------------------------------------------------------------------
00089 template< class ListType, unsigned ordinal > struct TypeListAt {};
00090 
00091 template< unsigned ordinal >
00092 struct TypeListAt< TypeListEnd , ordinal >
00093 { typedef TypeListEnd type ; };
00094 
00095 template< typename Value , class Tail >
00096 struct TypeListAt< TypeList< Value , Tail > , 0 >
00097 { typedef Value type ; };
00098 
00099 template< typename Value , class Tail , unsigned ordinal >
00100 struct TypeListAt< TypeList< Value , Tail > , ordinal >
00101 { typedef typename TypeListAt< Tail , ordinal - 1 >::type type ; };
00102 
00103 //----------------------------------------------------------------------
00111 template< class ListType , typename TestValue , unsigned ordinal = 0 >
00112 struct TypeListIndex {};
00113 
00114 template< typename TestValue , unsigned ordinal >
00115 struct TypeListIndex< TypeListEnd , TestValue , ordinal >
00116 {
00117   enum { value = -1 };
00118 };
00119 
00120 template< typename Value , class Tail , typename TestValue , unsigned ordinal >
00121 struct TypeListIndex< TypeList< Value , Tail > , TestValue , ordinal >
00122 {
00123 private:
00124   enum { match = SameType< Value , TestValue >::value };
00125   enum { J = match && 0 < ordinal ? ordinal - 1 : ordinal };
00126   enum { N = TypeListIndex< Tail , TestValue , J >::value };
00127 public:
00128   enum { value = match && 0 == ordinal ? 0 : ( -1 == N ? -1 : N + 1 ) };
00129 };
00130 
00131 //----------------------------------------------------------------------
00138 template< class ListType , typename TestValue >
00139 struct TypeListCount {};
00140 
00141 template< typename TestValue >
00142 struct TypeListCount< TypeListEnd , TestValue >
00143 { enum { value = 0 }; };
00144 
00145 template< typename Value , class Tail , typename TestValue >
00146 struct TypeListCount< TypeList< Value , Tail > , TestValue >
00147 {
00148   enum { value = TypeListCount< Tail , TestValue >::value +
00149                  ( SameType< Value , TestValue >::value ? 1 : 0 ) };
00150 };
00151 
00152 //----------------------------------------------------------------------
00158 template< class ListType , typename TestValue > struct TypeListMember {};
00159 
00160 template< typename TestValue >
00161 struct TypeListMember< TypeListEnd , TestValue >
00162 { enum { value = false }; };
00163 
00164 template< typename Value , class Tail , typename TestValue >
00165 struct TypeListMember< TypeList< Value , Tail > , TestValue >
00166 {
00167   enum { value = SameType< Value , TestValue >::value ||
00168                  TypeListMember< Tail , TestValue >::value };
00169 };
00170 
00171 //----------------------------------------------------------------------
00177 template< class ListType > struct TypeListUnique {};
00178 
00179 template<>
00180 struct TypeListUnique< TypeListEnd >
00181 { enum { value = true }; };
00182 
00183 template< typename Value , class Tail >
00184 struct TypeListUnique< TypeList< Value , Tail > >
00185 {
00186   enum { value = ! TypeListMember< Tail , Value >::value &&
00187                  TypeListUnique< Tail >::value };
00188 };
00189 
00190 //----------------------------------------------------------------------
00197 template< class ListA , class ListB > struct TypeListDisjoint {};
00198 
00199 template< class ListB >
00200 struct TypeListDisjoint< TypeListEnd , ListB >
00201 { enum { value = true }; };
00202 
00203 template< typename Value , class Tail , class ListB >
00204 struct TypeListDisjoint< TypeList< Value , Tail > , ListB >
00205 {
00206   enum { value = ! TypeListMember< ListB , Value >::value &&
00207                  TypeListDisjoint< Tail , ListB >::value };
00208 };
00209 
00210 //----------------------------------------------------------------------
00216 template< class ListType > struct TypeListFirst {};
00217 
00218 template<>
00219 struct TypeListFirst< TypeListEnd >
00220 { typedef TypeListEnd type ; };
00221 
00222 template< typename Value , class Tail >
00223 struct TypeListFirst< TypeList< Value , Tail > >
00224 { typedef Value type ; };
00225 
00226 //----------------------------------------------------------------------
00232 template< class ListType > struct TypeListLast {};
00233 
00234 template<>
00235 struct TypeListLast< TypeListEnd >
00236 { typedef TypeListEnd type ; };
00237 
00238 template< typename Value >
00239 struct TypeListLast< TypeList< Value , TypeListEnd > >
00240 { typedef Value type ; };
00241 
00242 template< typename Value , class Tail >
00243 struct TypeListLast< TypeList< Value , Tail > >
00244 { typedef typename TypeListLast< Tail >::type type ; };
00245 
00246 //----------------------------------------------------------------------
00252 template< class ListA , typename T > struct TypeListAppend {};
00253 
00254 template<>
00255 struct TypeListAppend< TypeListEnd , TypeListEnd >
00256 { typedef TypeListEnd type ; };
00257 
00258 template< typename T >
00259 struct TypeListAppend< TypeListEnd , T >
00260 { typedef TypeList< T > type ; };
00261 
00262 template< typename Value , class Tail , typename T >
00263 struct TypeListAppend< TypeList< Value , Tail > , T >
00264 {
00265   typedef TypeList< Value , typename TypeListAppend< Tail , T >::type > type ;
00266 };
00267 
00268 //----------------------------------------------------------------------
00274 template< class ListA , class ListB > struct TypeListJoin {};
00275 
00276 template<>
00277 struct TypeListJoin< TypeListEnd , TypeListEnd >
00278 { typedef TypeListEnd type ; };
00279 
00280 template< typename Value , class Tail >
00281 struct TypeListJoin< TypeListEnd , TypeList< Value , Tail > >
00282 { typedef TypeList< Value , Tail > type ; };
00283 
00284 template< typename ValueA , class TailA , typename ValueB , class TailB >
00285 struct TypeListJoin< TypeList< ValueA , TailA > ,
00286                      TypeList< ValueB , TailB > >
00287 {
00288 private:
00289   typedef typename
00290     TypeListJoin< TailA , TypeList< ValueB , TailB > >::type Tail ;
00291 public:
00292   typedef TypeList< ValueA , Tail > type ;
00293 };
00294 
00295 //----------------------------------------------------------------------
00301 template< class ListType, unsigned ordinal > struct TypeListEraseAt {};
00302 
00303 template< typename Value , class Tail >
00304 struct TypeListEraseAt< TypeList< Value , Tail > , 0 >
00305 { typedef Tail type ; };
00306 
00307 template< typename Value , class Tail , unsigned ordinal >
00308 struct TypeListEraseAt< TypeList< Value , Tail > , ordinal >
00309 {
00310   typedef TypeList< Value ,
00311                     typename TypeListEraseAt<Tail,ordinal-1>::type > type ;
00312 };
00313 
00314 
00315 //----------------------------------------------------------------------
00322 template< class ListType > struct TypeListClean {};
00323 
00324 template<>
00325 struct TypeListClean< TypeListEnd >
00326 { typedef TypeListEnd type ; };
00327 
00328 template< class Tail >
00329 struct TypeListClean< TypeList< TypeListEnd , Tail > >
00330 { typedef TypeListEnd type ; };
00331 
00332 template< typename Value , class Tail >
00333 struct TypeListClean< TypeList< Value , Tail > >
00334 {
00335   typedef TypeList< Value , typename TypeListClean< Tail >::type > type ;
00336 };
00337 
00338 //----------------------------------------------------------------------
00344 template< typename T00 = TypeListEnd ,
00345           typename T01 = TypeListEnd ,
00346           typename T02 = TypeListEnd ,
00347           typename T03 = TypeListEnd ,
00348           typename T04 = TypeListEnd ,
00349           typename T05 = TypeListEnd ,
00350           typename T06 = TypeListEnd ,
00351           typename T07 = TypeListEnd ,
00352           typename T08 = TypeListEnd ,
00353           typename T09 = TypeListEnd ,
00354           typename T10 = TypeListEnd ,
00355           typename T11 = TypeListEnd ,
00356           typename T12 = TypeListEnd ,
00357           typename T13 = TypeListEnd ,
00358           typename T14 = TypeListEnd ,
00359           typename T15 = TypeListEnd ,
00360           typename T16 = TypeListEnd ,
00361           typename T17 = TypeListEnd ,
00362           typename T18 = TypeListEnd ,
00363           typename T19 = TypeListEnd ,
00364           typename T20 = TypeListEnd ,
00365           typename T21 = TypeListEnd ,
00366           typename T22 = TypeListEnd ,
00367           typename T23 = TypeListEnd ,
00368           typename T24 = TypeListEnd ,
00369           typename T25 = TypeListEnd ,
00370           typename T26 = TypeListEnd ,
00371           typename T27 = TypeListEnd ,
00372           typename T28 = TypeListEnd ,
00373           typename T29 = TypeListEnd ,
00374           typename T30 = TypeListEnd ,
00375           typename T31 = TypeListEnd ,
00376           typename T32 = TypeListEnd ,
00377           typename T33 = TypeListEnd ,
00378           typename T34 = TypeListEnd ,
00379           typename T35 = TypeListEnd ,
00380           typename T36 = TypeListEnd ,
00381           typename T37 = TypeListEnd ,
00382           typename T38 = TypeListEnd ,
00383           typename T39 = TypeListEnd ,
00384           typename T40 = TypeListEnd ,
00385           typename T41 = TypeListEnd ,
00386           typename T42 = TypeListEnd ,
00387           typename T43 = TypeListEnd ,
00388           typename T44 = TypeListEnd ,
00389           typename T45 = TypeListEnd ,
00390           typename T46 = TypeListEnd ,
00391           typename T47 = TypeListEnd ,
00392           typename T48 = TypeListEnd ,
00393           typename T49 = TypeListEnd ,
00394           typename T50 = TypeListEnd ,
00395           typename T51 = TypeListEnd ,
00396           typename T52 = TypeListEnd ,
00397           typename T53 = TypeListEnd ,
00398           typename T54 = TypeListEnd ,
00399           typename T55 = TypeListEnd ,
00400           typename T56 = TypeListEnd ,
00401           typename T57 = TypeListEnd ,
00402           typename T58 = TypeListEnd ,
00403           typename T59 = TypeListEnd ,
00404           typename T60 = TypeListEnd ,
00405           typename T61 = TypeListEnd ,
00406           typename T62 = TypeListEnd ,
00407           typename T63 = TypeListEnd >
00408 struct MakeTypeList
00409 {
00410 private:
00411   typedef  TypeList< T00 ,
00412            TypeList< T01 ,
00413            TypeList< T02 ,
00414            TypeList< T03 ,
00415            TypeList< T04 ,
00416            TypeList< T05 ,
00417            TypeList< T06 ,
00418            TypeList< T07 ,
00419            TypeList< T08 ,
00420            TypeList< T09 ,
00421            TypeList< T10 ,
00422            TypeList< T11 ,
00423            TypeList< T12 ,
00424            TypeList< T13 ,
00425            TypeList< T14 ,
00426            TypeList< T15 ,
00427            TypeList< T16 ,
00428            TypeList< T17 ,
00429            TypeList< T18 ,
00430            TypeList< T19 ,
00431            TypeList< T20 ,
00432            TypeList< T21 ,
00433            TypeList< T22 ,
00434            TypeList< T23 ,
00435            TypeList< T24 ,
00436            TypeList< T25 ,
00437            TypeList< T26 ,
00438            TypeList< T27 ,
00439            TypeList< T28 ,
00440            TypeList< T29 ,
00441            TypeList< T30 ,
00442            TypeList< T31 ,
00443            TypeList< T32 ,
00444            TypeList< T33 ,
00445            TypeList< T34 ,
00446            TypeList< T35 ,
00447            TypeList< T36 ,
00448            TypeList< T37 ,
00449            TypeList< T38 ,
00450            TypeList< T39 ,
00451            TypeList< T40 ,
00452            TypeList< T41 ,
00453            TypeList< T42 ,
00454            TypeList< T43 ,
00455            TypeList< T44 ,
00456            TypeList< T45 ,
00457            TypeList< T46 ,
00458            TypeList< T47 ,
00459            TypeList< T48 ,
00460            TypeList< T49 ,
00461            TypeList< T50 ,
00462            TypeList< T51 ,
00463            TypeList< T52 ,
00464            TypeList< T53 ,
00465            TypeList< T54 ,
00466            TypeList< T55 ,
00467            TypeList< T56 ,
00468            TypeList< T57 ,
00469            TypeList< T58 ,
00470            TypeList< T59 ,
00471            TypeList< T60 ,
00472            TypeList< T61 ,
00473            TypeList< T62 ,
00474            TypeList< T63 ,
00475            TypeListEnd > > > > > > > > > > > > > > > >
00476                        > > > > > > > > > > > > > > > >
00477                        > > > > > > > > > > > > > > > >
00478                        > > > > > > > > > > > > > > > > dirty_type ;
00479 public:
00480 
00481   typedef typename TypeListClean< dirty_type >::type type ;
00482 
00483   enum { length = TypeListLength<type>::value };
00484 
00485   enum { unique = TypeListUnique<type>::value };
00486 };
00487 
00488 } // namespace phdmesh
00489 
00490 #endif /* util_TypeList_h */
00491 

Generated on Tue Jul 13 09:22:43 2010 for phdMesh by  doxygen 1.4.7