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 #include <dune/common/deprecated.hh>
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 #if defined HAVE_TYPE_TRAITS
00159   using std::remove_const;
00160 #elif defined HAVE_TR1_TYPE_TRAITS
00161     using std::tr1::remove_const;
00162 #else
00163 
00166   template<typename T>
00167   struct remove_const
00168   {
00169       typedef typename RemoveConstHelper<T, IsVolatile<T>::value>::Type type;
00170   };
00171 #endif
00172 
00179   template<class From, class To>
00180   class Conversion
00181   {
00182     typedef char Small;
00183     struct Big{char dummy[2];};
00184     static Small test(To);
00185     static Big test(...);
00186     static From makeFrom();
00187   public:
00188     enum {
00190       exists =  sizeof(test(makeFrom())) == sizeof(Small),
00192       isTwoWay = exists && Conversion<To,From>::exists,
00194       sameType = false
00195     };
00196   };
00197 
00198   template <class From>
00199   class Conversion<From, void>
00200   {
00201   public:
00202     enum {
00203       exists = false,
00204       isTwoWay = false,
00205       sameType = false
00206     };
00207   };
00208 
00209   template <class To>
00210   class Conversion<void, To>
00211   {
00212   public:
00213     enum {
00214       exists = false,
00215       isTwoWay = false,
00216       sameType = false
00217     };
00218   };
00219 
00220   template<>
00221   class Conversion< int, double >
00222   {
00223   public:
00224     enum {
00225       exists = true,
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 
00261   template<bool b, typename T=void>
00262   struct EnableIf
00263   {
00264     typedef T type;
00265     typedef T Type;
00266   } DUNE_DEPRECATED;
00267 
00268   template<typename T>
00269   struct EnableIf<false,T>
00270   {} DUNE_DEPRECATED;
00271 
00272 #ifdef HAVE_TYPE_TRAITS
00273   using std::enable_if;
00274 #else
00275 
00281   template<bool b, typename T=void>
00282   struct enable_if
00283   {
00284     typedef T type;
00285   };
00286 
00287   template<typename T>
00288   struct enable_if<false,T>
00289   {};
00290 #endif
00291 
00292 
00298   template<class T1, class T2, class Type>
00299   struct EnableIfInterOperable 
00300     : public EnableIf<IsInteroperable<T1,T2>::value, Type>
00301   {};
00302   
00303 #if defined HAVE_TYPE_TRAITS
00304   using std::is_same;
00305 #elif defined HAVE_TR1_TYPE_TRAITS
00306   using std::tr1::is_same;
00307 #else
00308 
00312   template<typename T1, typename T2>
00313   struct is_same
00314   {
00315     enum{ 
00316       /* @brief Whether T1 is the same type as T2. */
00317       value=false
00318         };
00319   };
00320   
00321   
00322   template<typename T>
00323   struct is_same<T,T>
00324   {
00325     enum{ value=true};
00326   };
00327 #endif
00328 
00337   template<bool first, class T1, class T2>
00338   struct SelectType
00339   {
00346     typedef T1 Type;
00347   };
00348 
00349   template<class T1, class T2>
00350   struct SelectType<false,T1,T2>
00351   {
00352     typedef T2 Type;
00353   };
00355 }
00356 #endif

Generated on Sun Nov 15 22:28:13 2009 for dune-common by  doxygen 1.5.6