typetraits.hh

Go to the documentation of this file.
00001 #ifndef DUNE_TYPETRAITS_HH
00002 #define DUNE_TYPETRAITS_HH
00003 
00004 #include <dune/common/deprecated.hh>
00005 
00006 #ifdef HAVE_TR1_TYPE_TRAITS
00007 #include <tr1/type_traits>
00008 #elif defined HAVE_TYPE_TRAITS
00009 #include <type_traits>
00010 #endif
00011 
00012 namespace Dune
00013 {
00014   
00028   struct Empty {};
00029 
00034   template <typename T>
00035   class TypeTraits
00036   {
00037   private:
00038     template <class U> 
00039     struct PointerTraits {
00040       enum { result = false };
00041       typedef Empty PointeeType;
00042     };
00043 
00044     template <class U>
00045     struct PointerTraits<U*> {
00046       enum { result = true };
00047       typedef U PointeeType;
00048     };
00049   
00050     template <class U> struct ReferenceTraits
00051     {
00052       enum { result = false };
00053       typedef U ReferredType;
00054     };
00055     
00056     template <class U> struct ReferenceTraits<U&>
00057     {
00058       enum { result = true };
00059       typedef U ReferredType;
00060     };
00061     
00062   public:
00063     enum { isPointer = PointerTraits<T>::result };
00064     typedef typename PointerTraits<T>::PointeeType PointeeType;
00065 
00066     enum { isReference = ReferenceTraits<T>::result };
00067     typedef typename ReferenceTraits<T>::ReferredType ReferredType;
00068  };
00069 
00074   template<typename T>
00075   struct ConstantVolatileTraits
00076   {
00077     enum{
00079       isVolatile=false,
00081         isConst=false
00082         };
00083     
00085     typedef T UnqualifiedType;
00087     typedef const T ConstType;
00089     typedef const volatile T ConstVolatileType;
00090   };
00091 
00092   template<typename T>
00093   struct ConstantVolatileTraits<const T>
00094   {
00095     enum{
00096       isVolatile=false, isConst=true
00097         };
00098     typedef T UnqualifiedType;
00099     typedef const UnqualifiedType ConstType;
00100     typedef const volatile UnqualifiedType ConstVolatileType;
00101   };
00102 
00103 
00104   template<typename T>
00105   struct ConstantVolatileTraits<volatile T>
00106   {
00107     enum{
00108       isVolatile=true, isConst=false
00109         };
00110     typedef T UnqualifiedType;
00111     typedef const UnqualifiedType ConstType;
00112     typedef const volatile UnqualifiedType ConstVolatileType;
00113   };
00114 
00115   template<typename T>
00116   struct ConstantVolatileTraits<const volatile T>
00117   {
00118     enum{
00119       isVolatile=true, isConst=true
00120         };
00121     typedef T UnqualifiedType;
00122     typedef const UnqualifiedType ConstType;
00123     typedef const volatile UnqualifiedType ConstVolatileType;
00124   };
00125 
00127   template<typename T>
00128   struct IsVolatile
00129   {
00130     enum{
00132       value=ConstantVolatileTraits<T>::isVolatile
00133         };
00134   };
00135 
00137   template<typename T>
00138   struct IsConst
00139   {
00140     enum{
00142       value=ConstantVolatileTraits<T>::isConst
00143         };
00144   };
00145 
00146   template<typename T, bool isVolatile>
00147   struct RemoveConstHelper
00148   {
00149     typedef typename ConstantVolatileTraits<T>::UnqualifiedType Type;
00150   };
00151 
00152   template<typename T>
00153   struct RemoveConstHelper<T,true>
00154   {
00155     typedef volatile typename ConstantVolatileTraits<T>::UnqualifiedType Type;
00156   };
00157 
00158 #ifdef HAVE_TR1_TYPE_TRAITS
00159     using std::tr1::remove_const;
00160 #elif defined HAVE_TYPE_TRAITS
00161   using std::remove_const;
00162 #else
00163 
00167   template<typename T>
00168   struct remove_const
00169   {
00170       typedef typename RemoveConstHelper<T, IsVolatile<T>::value>::Type type;
00171   };
00172 #endif
00173 
00178   template<typename T>
00179   struct RemoveConst
00180   {
00181       typedef typename RemoveConstHelper<T, IsVolatile<T>::value>::Type Type;
00182   } DUNE_DEPRECATED;
00183 
00190   template<class From, class To>
00191   class Conversion
00192   {
00193     typedef char Small;
00194     struct Big{char dummy[2];};
00195     static Small test(To);
00196     static Big test(...);
00197     static From makeFrom();
00198   public:
00199     enum {
00201       exists =  sizeof(test(makeFrom())) == sizeof(Small),
00203       isTwoWay = exists && Conversion<To,From>::exists,
00205       sameType = false
00206     };
00207   };
00208 
00209   template <class From>
00210   class Conversion<From, void>
00211   {
00212   public:
00213     enum {
00214       exists = false,
00215       isTwoWay = false,
00216       sameType = false
00217     };
00218   };
00219 
00220   template <class To>
00221   class Conversion<void, To>
00222   {
00223   public:
00224     enum {
00225       exists = false,
00226       isTwoWay = false,
00227       sameType = false
00228     };
00229   }; 
00230 
00231   template<class T>
00232   class Conversion<T,T>{
00233   public:
00234     enum{ exists=true, isTwoWay=true, sameType=true};
00235   };
00236 
00243   template<class T1, class T2>
00244   struct IsInteroperable
00245   {
00246     enum{
00251       value = Conversion<T1,T2>::exists || Conversion<T2,T1>::exists
00252         };
00253   };
00254 
00260   template<bool b, typename T=void>
00261   struct EnableIf
00262   {
00263     typedef T type;
00264     typedef T Type;
00265   };
00266 
00267   template<typename T>
00268   struct EnableIf<false,T>
00269   {};
00270 
00276   template<class T1, class T2, class Type>
00277   struct EnableIfInterOperable 
00278     : public EnableIf<IsInteroperable<T1,T2>::value, Type>
00279   {};
00280   
00281 #ifdef HAVE_TR1_TYPE_TRAITS
00282     using std::tr1::is_same;
00283 #elif defined HAVE_TYPE_TRAITS
00284   using std::is_same;
00285 #else
00286 
00290   template<typename T1, typename T2>
00291   struct is_same
00292   {
00293     enum{ 
00294       /* @brief Whether T1 is the same type as T2. */
00295       value=false
00296         };
00297   };
00298   
00299   
00300   template<typename T>
00301   struct is_same<T,T>
00302   {
00303     enum{ value=true};
00304   };
00305 #endif
00306 
00311   template<typename T1, typename T2>
00312   struct SameType
00313   {
00314     enum{ 
00315       /* @brief Whether T1 is the same type as T2. */
00316       value=false
00317         };
00318   } DUNE_DEPRECATED;
00319   
00320   
00325   template<typename T>
00326   struct SameType<T,T>
00327   {
00328     enum{ value=true};
00329   } DUNE_DEPRECATED;
00330 
00339   template<bool first, class T1, class T2>
00340   struct SelectType
00341   {
00348     typedef T1 Type;
00349   };
00350 
00351   template<class T1, class T2>
00352   struct SelectType<false,T1,T2>
00353   {
00354     typedef T2 Type;
00355   };
00357 }
00358 #endif

Generated on 9 Apr 2008 with Doxygen (ver 1.5.2) [logfile].