typetraits.hh

Go to the documentation of this file.
00001 #ifndef DUNE_TYPETRAITS_HH
00002 #define DUNE_TYPETRAITS_HH
00003 
00004 #if defined HAVE_TYPE_TRAITS
00005 #include <type_traits>
00006 #elif defined HAVE_TR1_TYPE_TRAITS
00007 #include <tr1/type_traits>
00008 #endif
00009 
00010 namespace Dune
00011 {
00012   
00026   struct Empty {};
00027 
00032   template <typename T>
00033   class TypeTraits
00034   {
00035   private:
00036     template <class U> 
00037     struct PointerTraits {
00038       enum { result = false };
00039       typedef Empty PointeeType;
00040     };
00041 
00042     template <class U>
00043     struct PointerTraits<U*> {
00044       enum { result = true };
00045       typedef U PointeeType;
00046     };
00047   
00048     template <class U> struct ReferenceTraits
00049     {
00050       enum { result = false };
00051       typedef U ReferredType;
00052     };
00053     
00054     template <class U> struct ReferenceTraits<U&>
00055     {
00056       enum { result = true };
00057       typedef U ReferredType;
00058     };
00059     
00060   public:
00061     enum { isPointer = PointerTraits<T>::result };
00062     typedef typename PointerTraits<T>::PointeeType PointeeType;
00063 
00064     enum { isReference = ReferenceTraits<T>::result };
00065     typedef typename ReferenceTraits<T>::ReferredType ReferredType;
00066  };
00067 
00072   template<typename T>
00073   struct ConstantVolatileTraits
00074   {
00075     enum{
00077       isVolatile=false,
00079         isConst=false
00080         };
00081     
00083     typedef T UnqualifiedType;
00085     typedef const T ConstType;
00087     typedef const volatile T ConstVolatileType;
00088   };
00089 
00090   template<typename T>
00091   struct ConstantVolatileTraits<const T>
00092   {
00093     enum{
00094       isVolatile=false, isConst=true
00095         };
00096     typedef T UnqualifiedType;
00097     typedef const UnqualifiedType ConstType;
00098     typedef const volatile UnqualifiedType ConstVolatileType;
00099   };
00100 
00101 
00102   template<typename T>
00103   struct ConstantVolatileTraits<volatile T>
00104   {
00105     enum{
00106       isVolatile=true, isConst=false
00107         };
00108     typedef T UnqualifiedType;
00109     typedef const UnqualifiedType ConstType;
00110     typedef const volatile UnqualifiedType ConstVolatileType;
00111   };
00112 
00113   template<typename T>
00114   struct ConstantVolatileTraits<const volatile T>
00115   {
00116     enum{
00117       isVolatile=true, isConst=true
00118         };
00119     typedef T UnqualifiedType;
00120     typedef const UnqualifiedType ConstType;
00121     typedef const volatile UnqualifiedType ConstVolatileType;
00122   };
00123 
00125   template<typename T>
00126   struct IsVolatile
00127   {
00128     enum{
00130       value=ConstantVolatileTraits<T>::isVolatile
00131         };
00132   };
00133 
00135   template<typename T>
00136   struct IsConst
00137   {
00138     enum{
00140       value=ConstantVolatileTraits<T>::isConst
00141         };
00142   };
00143 
00144   template<typename T, bool isVolatile>
00145   struct RemoveConstHelper
00146   {
00147     typedef typename ConstantVolatileTraits<T>::UnqualifiedType Type;
00148   };
00149 
00150   template<typename T>
00151   struct RemoveConstHelper<T,true>
00152   {
00153     typedef volatile typename ConstantVolatileTraits<T>::UnqualifiedType Type;
00154   };
00155 
00156 #if defined HAVE_TYPE_TRAITS
00157   using std::remove_const;
00158 #elif defined HAVE_TR1_TYPE_TRAITS
00159     using std::tr1::remove_const;
00160 #else
00161 
00164   template<typename T>
00165   struct remove_const
00166   {
00167       typedef typename RemoveConstHelper<T, IsVolatile<T>::value>::Type type;
00168   };
00169 #endif
00170 
00180   template<class From, class To>
00181   class Conversion
00182   {
00183     typedef char Small;
00184     struct Big{char dummy[2];};
00185     static Small test(To);
00186     static Big test(...);
00187     static typename TypeTraits< From >::ReferredType &makeFrom ();
00188 
00189   public:
00190     enum {
00192       exists =  sizeof(test(makeFrom())) == sizeof(Small),
00194       isTwoWay = exists && Conversion<To,From>::exists,
00196       sameType = false
00197     };
00198     Conversion(){}
00199     
00200   };
00201 
00202   template <class From>
00203   class Conversion<From, void>
00204   {
00205   public:
00206     enum {
00207       exists = false,
00208       isTwoWay = false,
00209       sameType = false
00210     };
00211   };
00212 
00213   template <class To>
00214   class Conversion<void, To>
00215   {
00216   public:
00217     enum {
00218       exists = false,
00219       isTwoWay = false,
00220       sameType = false
00221     };
00222   };
00223 
00224   template<>
00225   class Conversion< int, double >
00226   {
00227   public:
00228     enum {
00229       exists = true,
00230       isTwoWay = false,
00231       sameType = false
00232     };
00233   };
00234 
00235   template<class T>
00236   class Conversion<T,T>{
00237   public:
00238     enum{ exists=true, isTwoWay=true, sameType=true};
00239   };
00240 
00250   template <class Base, class Derived>
00251   class IsBaseOf
00252   {
00253     typedef typename ConstantVolatileTraits< typename TypeTraits< Base >::ReferredType >::UnqualifiedType RawBase;
00254     typedef typename ConstantVolatileTraits< typename TypeTraits< Derived >::ReferredType >::UnqualifiedType RawDerived;
00255     typedef char Small;
00256     struct Big{char dummy[2];};
00257     static Small test(RawBase*);
00258     static Big test(...);
00259     static RawDerived* &makePtr ();
00260   public:
00261     enum {
00263       value = sizeof(test(makePtr())) == sizeof(Small)
00264     };
00265     IsBaseOf(){}
00266     
00267   };
00268 
00275   template<class T1, class T2>
00276   struct IsInteroperable
00277   {
00278     enum{
00283       value = Conversion<T1,T2>::exists || Conversion<T2,T1>::exists
00284         };
00285   };
00286 
00287 #ifdef HAVE_TYPE_TRAITS
00288   using std::enable_if;
00289 #else
00290 
00296   template<bool b, typename T=void>
00297   struct enable_if
00298   {
00299     typedef T type;
00300   };
00301 
00302   template<typename T>
00303   struct enable_if<false,T>
00304   {};
00305 #endif
00306 
00307 
00313   template<class T1, class T2, class Type>
00314   struct EnableIfInterOperable 
00315     : public enable_if<IsInteroperable<T1,T2>::value, Type>
00316   {};
00317   
00318 #if defined HAVE_TYPE_TRAITS
00319   using std::is_same;
00320 #elif defined HAVE_TR1_TYPE_TRAITS
00321   using std::tr1::is_same;
00322 #else
00323 
00327   template<typename T1, typename T2>
00328   struct is_same
00329   {
00331     enum{ 
00332       /* @brief Whether T1 is the same type as T2. */
00333       value=false
00334         };
00335   };
00336   
00337   
00338   template<typename T>
00339   struct is_same<T,T>
00340   {
00341     enum{ value=true};
00342   };
00343 #endif
00344 
00353   template<bool first, class T1, class T2>
00354   struct SelectType
00355   {
00362     typedef T1 Type;
00363   };
00364 
00365   template<class T1, class T2>
00366   struct SelectType<false,T1,T2>
00367   {
00368     typedef T2 Type;
00369   };
00371 }
00372 #endif
Generated on Mon Apr 26 10:45:22 2010 for dune-common by  doxygen 1.6.3