shards Version of the Day
Shards_TypeList.hpp
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //                Shards : Shared Discretization Tools
00006 //                 Copyright 2008 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Carter Edwards (hcedwar@sandia.gov),
00039 //                    Pavel Bochev (pbboche@sandia.gov), or
00040 //                    Denis Ridzal (dridzal@sandia.gov).
00041 //
00042 // ************************************************************************
00043 //@HEADER
00044 */
00045 
00046 #ifndef Shards_TypeList_hpp
00047 #define Shards_TypeList_hpp
00048 
00049 namespace shards {
00050 
00063 //----------------------------------------------------------------------
00068 template<typename T1, typename T2>
00069 struct SameType { enum { value = false }; };
00070 
00071 template<typename T>
00072 struct SameType<T,T> { enum { value = true }; };
00073 
00074 //----------------------------------------------------------------------
00075 
00076 struct TypeListEnd {};
00077 
00085 template< typename Value , class Tail = TypeListEnd > struct TypeList {};
00086 
00087 //----------------------------------------------------------------------
00092 template< class ListType > struct TypeListLength {};
00093 
00094 template<>
00095 struct TypeListLength< TypeListEnd >
00096 { enum { value = 0 }; };
00097 
00098 template< typename Value , class Tail >
00099 struct TypeListLength< TypeList< Value , Tail > >
00100 { enum { value = 1 + TypeListLength< Tail >::value }; };
00101 
00102 //----------------------------------------------------------------------
00108 template< class ListType, unsigned ordinal > struct TypeListAt {};
00109 
00110 template< unsigned ordinal >
00111 struct TypeListAt< TypeListEnd , ordinal >
00112 { typedef TypeListEnd type ; };
00113 
00114 template< typename Value , class Tail >
00115 struct TypeListAt< TypeList< Value , Tail > , 0 >
00116 { typedef Value type ; };
00117 
00118 template< typename Value , class Tail , unsigned ordinal >
00119 struct TypeListAt< TypeList< Value , Tail > , ordinal >
00120 { typedef typename TypeListAt< Tail , ordinal - 1 >::type type ; };
00121 
00122 //----------------------------------------------------------------------
00129 template< class ListType , typename TestValue , unsigned ordinal = 0 >
00130 struct TypeListIndex {};
00131 
00132 template< typename TestValue , unsigned ordinal >
00133 struct TypeListIndex< TypeListEnd , TestValue , ordinal >
00134 {
00135   enum { value = -1 };
00136 };
00137 
00138 template< typename Value , class Tail , typename TestValue , unsigned ordinal >
00139 struct TypeListIndex< TypeList< Value , Tail > , TestValue , ordinal >
00140 {
00141 private:
00142   enum { match = SameType< Value , TestValue >::value };
00143   enum { J = match && 0 < ordinal ? ordinal - 1 : ordinal };
00144   enum { N = TypeListIndex< Tail , TestValue , J >::value };
00145 public:
00146   enum { value = match && 0 == ordinal ? 0 : ( -1 == N ? -1 : N + 1 ) };
00147 };
00148 
00149 //----------------------------------------------------------------------
00155 template< class ListType , typename TestValue >
00156 struct TypeListCount {};
00157 
00158 template< typename TestValue >
00159 struct TypeListCount< TypeListEnd , TestValue >
00160 { enum { value = 0 }; };
00161 
00162 template< typename Value , class Tail , typename TestValue >
00163 struct TypeListCount< TypeList< Value , Tail > , TestValue >
00164 {
00165   enum { value = TypeListCount< Tail , TestValue >::value +
00166                  ( SameType< Value , TestValue >::value ? 1 : 0 ) };
00167 };
00168 
00169 //----------------------------------------------------------------------
00174 template< class ListType , typename TestValue > struct TypeListMember {};
00175 
00176 template< typename TestValue >
00177 struct TypeListMember< TypeListEnd , TestValue >
00178 { enum { value = false }; };
00179 
00180 template< typename Value , class Tail , typename TestValue >
00181 struct TypeListMember< TypeList< Value , Tail > , TestValue >
00182 {
00183   enum { value = SameType< Value , TestValue >::value ||
00184                  TypeListMember< Tail , TestValue >::value };
00185 };
00186 
00187 //----------------------------------------------------------------------
00192 template< class ListType > struct TypeListUnique {};
00193 
00194 template<>
00195 struct TypeListUnique< TypeListEnd >
00196 { enum { value = true }; };
00197 
00198 template< typename Value , class Tail >
00199 struct TypeListUnique< TypeList< Value , Tail > >
00200 {
00201   enum { value = ! TypeListMember< Tail , Value >::value &&
00202                  TypeListUnique< Tail >::value };
00203 };
00204 
00205 //----------------------------------------------------------------------
00211 template< class ListA , class ListB > struct TypeListDisjoint {};
00212 
00213 template< class ListB >
00214 struct TypeListDisjoint< TypeListEnd , ListB >
00215 { enum { value = true }; };
00216 
00217 template< typename Value , class Tail , class ListB >
00218 struct TypeListDisjoint< TypeList< Value , Tail > , ListB >
00219 {
00220   enum { value = ! TypeListMember< ListB , Value >::value &&
00221                  TypeListDisjoint< Tail , ListB >::value };
00222 };
00223 
00224 //----------------------------------------------------------------------
00229 template< class ListType > struct TypeListFirst {};
00230 
00231 template<>
00232 struct TypeListFirst< TypeListEnd >
00233 { typedef TypeListEnd type ; };
00234 
00235 template< typename Value , class Tail >
00236 struct TypeListFirst< TypeList< Value , Tail > >
00237 { typedef Value type ; };
00238 
00239 //----------------------------------------------------------------------
00244 template< class ListType > struct TypeListLast {};
00245 
00246 template<>
00247 struct TypeListLast< TypeListEnd >
00248 { typedef TypeListEnd type ; };
00249 
00250 template< typename Value >
00251 struct TypeListLast< TypeList< Value , TypeListEnd > >
00252 { typedef Value type ; };
00253 
00254 template< typename Value , class Tail >
00255 struct TypeListLast< TypeList< Value , Tail > >
00256 { typedef typename TypeListLast< Tail >::type type ; };
00257 
00258 //----------------------------------------------------------------------
00263 template< class ListA , typename T > struct TypeListAppend {};
00264 
00265 template<>
00266 struct TypeListAppend< TypeListEnd , TypeListEnd >
00267 { typedef TypeListEnd type ; };
00268 
00269 template< typename T >
00270 struct TypeListAppend< TypeListEnd , T >
00271 { typedef TypeList< T > type ; };
00272 
00273 template< typename Value , class Tail , typename T >
00274 struct TypeListAppend< TypeList< Value , Tail > , T >
00275 {
00276   typedef TypeList< Value , typename TypeListAppend< Tail , T >::type > type ;
00277 };
00278 
00279 //----------------------------------------------------------------------
00284 template< class ListA , class ListB > struct TypeListJoin {};
00285 
00286 template<>
00287 struct TypeListJoin< TypeListEnd , TypeListEnd >
00288 { typedef TypeListEnd type ; };
00289 
00290 template< typename Value , class Tail >
00291 struct TypeListJoin< TypeListEnd , TypeList< Value , Tail > >
00292 { typedef TypeList< Value , Tail > type ; };
00293 
00294 template< typename ValueA , class TailA , typename ValueB , class TailB >
00295 struct TypeListJoin< TypeList< ValueA , TailA > ,
00296                      TypeList< ValueB , TailB > >
00297 {
00298 private:
00299   typedef typename
00300     TypeListJoin< TailA , TypeList< ValueB , TailB > >::type Tail ;
00301 public:
00302   typedef TypeList< ValueA , Tail > type ;
00303 };
00304 
00305 //----------------------------------------------------------------------
00310 template< class ListType, unsigned ordinal > struct TypeListEraseAt {};
00311 
00312 template< typename Value , class Tail >
00313 struct TypeListEraseAt< TypeList< Value , Tail > , 0 >
00314 { typedef Tail type ; };
00315 
00316 template< typename Value , class Tail , unsigned ordinal >
00317 struct TypeListEraseAt< TypeList< Value , Tail > , ordinal >
00318 {
00319   typedef TypeList< Value ,
00320                     typename TypeListEraseAt<Tail,ordinal-1>::type > type ;
00321 };
00322 
00323 //----------------------------------------------------------------------
00330 template< class ListType > struct TypeListClean {};
00331 
00332 template<>
00333 struct TypeListClean< TypeListEnd >
00334 { typedef TypeListEnd type ; };
00335 
00336 template< class Tail >
00337 struct TypeListClean< TypeList< TypeListEnd , Tail > >
00338 { typedef TypeListEnd type ; };
00339 
00340 template< typename Value , class Tail >
00341 struct TypeListClean< TypeList< Value , Tail > >
00342 {
00343   typedef TypeList< Value , typename TypeListClean< Tail >::type > type ;
00344 };
00345 
00346 //----------------------------------------------------------------------
00351 template< typename T00 = TypeListEnd ,
00352           typename T01 = TypeListEnd ,
00353           typename T02 = TypeListEnd ,
00354           typename T03 = TypeListEnd ,
00355           typename T04 = TypeListEnd ,
00356           typename T05 = TypeListEnd ,
00357           typename T06 = TypeListEnd ,
00358           typename T07 = TypeListEnd ,
00359           typename T08 = TypeListEnd ,
00360           typename T09 = TypeListEnd ,
00361           typename T10 = TypeListEnd ,
00362           typename T11 = TypeListEnd ,
00363           typename T12 = TypeListEnd ,
00364           typename T13 = TypeListEnd ,
00365           typename T14 = TypeListEnd ,
00366           typename T15 = TypeListEnd ,
00367           typename T16 = TypeListEnd ,
00368           typename T17 = TypeListEnd ,
00369           typename T18 = TypeListEnd ,
00370           typename T19 = TypeListEnd ,
00371           typename T20 = TypeListEnd ,
00372           typename T21 = TypeListEnd ,
00373           typename T22 = TypeListEnd ,
00374           typename T23 = TypeListEnd ,
00375           typename T24 = TypeListEnd ,
00376           typename T25 = TypeListEnd ,
00377           typename T26 = TypeListEnd ,
00378           typename T27 = TypeListEnd ,
00379           typename T28 = TypeListEnd ,
00380           typename T29 = TypeListEnd ,
00381           typename T30 = TypeListEnd ,
00382           typename T31 = TypeListEnd ,
00383           typename T32 = TypeListEnd ,
00384           typename T33 = TypeListEnd ,
00385           typename T34 = TypeListEnd ,
00386           typename T35 = TypeListEnd ,
00387           typename T36 = TypeListEnd ,
00388           typename T37 = TypeListEnd ,
00389           typename T38 = TypeListEnd ,
00390           typename T39 = TypeListEnd ,
00391           typename T40 = TypeListEnd ,
00392           typename T41 = TypeListEnd ,
00393           typename T42 = TypeListEnd ,
00394           typename T43 = TypeListEnd ,
00395           typename T44 = TypeListEnd ,
00396           typename T45 = TypeListEnd ,
00397           typename T46 = TypeListEnd ,
00398           typename T47 = TypeListEnd ,
00399           typename T48 = TypeListEnd ,
00400           typename T49 = TypeListEnd ,
00401           typename T50 = TypeListEnd ,
00402           typename T51 = TypeListEnd ,
00403           typename T52 = TypeListEnd ,
00404           typename T53 = TypeListEnd ,
00405           typename T54 = TypeListEnd ,
00406           typename T55 = TypeListEnd ,
00407           typename T56 = TypeListEnd ,
00408           typename T57 = TypeListEnd ,
00409           typename T58 = TypeListEnd ,
00410           typename T59 = TypeListEnd ,
00411           typename T60 = TypeListEnd ,
00412           typename T61 = TypeListEnd ,
00413           typename T62 = TypeListEnd ,
00414           typename T63 = TypeListEnd >
00415 struct MakeTypeList
00416 {
00417 #ifndef DOXYGEN_COMPILE
00418 private:
00419   typedef  TypeList< T00 ,
00420            TypeList< T01 ,
00421            TypeList< T02 ,
00422            TypeList< T03 ,
00423            TypeList< T04 ,
00424            TypeList< T05 ,
00425            TypeList< T06 ,
00426            TypeList< T07 ,
00427            TypeList< T08 ,
00428            TypeList< T09 ,
00429            TypeList< T10 ,
00430            TypeList< T11 ,
00431            TypeList< T12 ,
00432            TypeList< T13 ,
00433            TypeList< T14 ,
00434            TypeList< T15 ,
00435            TypeList< T16 ,
00436            TypeList< T17 ,
00437            TypeList< T18 ,
00438            TypeList< T19 ,
00439            TypeList< T20 ,
00440            TypeList< T21 ,
00441            TypeList< T22 ,
00442            TypeList< T23 ,
00443            TypeList< T24 ,
00444            TypeList< T25 ,
00445            TypeList< T26 ,
00446            TypeList< T27 ,
00447            TypeList< T28 ,
00448            TypeList< T29 ,
00449            TypeList< T30 ,
00450            TypeList< T31 ,
00451            TypeList< T32 ,
00452            TypeList< T33 ,
00453            TypeList< T34 ,
00454            TypeList< T35 ,
00455            TypeList< T36 ,
00456            TypeList< T37 ,
00457            TypeList< T38 ,
00458            TypeList< T39 ,
00459            TypeList< T40 ,
00460            TypeList< T41 ,
00461            TypeList< T42 ,
00462            TypeList< T43 ,
00463            TypeList< T44 ,
00464            TypeList< T45 ,
00465            TypeList< T46 ,
00466            TypeList< T47 ,
00467            TypeList< T48 ,
00468            TypeList< T49 ,
00469            TypeList< T50 ,
00470            TypeList< T51 ,
00471            TypeList< T52 ,
00472            TypeList< T53 ,
00473            TypeList< T54 ,
00474            TypeList< T55 ,
00475            TypeList< T56 ,
00476            TypeList< T57 ,
00477            TypeList< T58 ,
00478            TypeList< T59 ,
00479            TypeList< T60 ,
00480            TypeList< T61 ,
00481            TypeList< T62 ,
00482            TypeList< T63 ,
00483            TypeListEnd > > > > > > > > > > > > > > > >
00484                        > > > > > > > > > > > > > > > >
00485                        > > > > > > > > > > > > > > > >
00486                        > > > > > > > > > > > > > > > > dirty_type ;
00487 #endif /* DOXYGEN_COMPILE */
00488 public:
00489 
00491   typedef typename TypeListClean< dirty_type >::type type ;
00492 
00494   enum { length = TypeListLength<type>::value };
00495 
00497   enum { unique = TypeListUnique<type>::value };
00498 };
00499 
00501 } // namespace shards
00502 
00503 #endif // Shards_TypeList_hpp
00504 
 All Classes Functions Variables Typedefs Enumerator