typetraits.hh

Go to the documentation of this file.
00001 #ifndef DUNE_TYPETRAITS_HH
00002 #define DUNE_TYPETRAITS_HH
00003 
00004 namespace Dune
00005 {
00006   
00020   struct Empty {};
00021 
00026   template <typename T>
00027   class TypeTraits
00028   {
00029   private:
00030     template <class U> 
00031     struct PointerTraits {
00032       enum { result = false };
00033       typedef Empty PointeeType;
00034     };
00035 
00036     template <class U>
00037     struct PointerTraits<U*> {
00038       enum { result = true };
00039       typedef U PointeeType;
00040     };
00041   
00042     template <class U> struct ReferenceTraits
00043     {
00044       enum { result = false };
00045       typedef U ReferredType;
00046     };
00047     
00048     template <class U> struct ReferenceTraits<U&>
00049     {
00050       enum { result = true };
00051       typedef U ReferredType;
00052     };
00053     
00054   public:
00055     enum { isPointer = PointerTraits<T>::result };
00056     typedef typename PointerTraits<T>::PointeeType PointeeType;
00057 
00058     enum { isReference = ReferenceTraits<T>::result };
00059     typedef typename ReferenceTraits<T>::ReferredType ReferredType;
00060  };
00061 
00066   template<typename T>
00067   struct ConstantVolatileTraits
00068   {
00069     enum{
00071       isVolatile=false,
00073         isConst=false
00074         };
00075     
00077     typedef T UnqualifiedType;
00079     typedef const T ConstType;
00081     typedef const volatile T ConstVolatileType;
00082   };
00083 
00084   template<typename T>
00085   struct ConstantVolatileTraits<const T>
00086   {
00087     enum{
00088       isVolatile=false, isConst=true
00089         };
00090     typedef T UnqualifiedType;
00091     typedef const UnqualifiedType ConstType;
00092     typedef const volatile UnqualifiedType ConstVolatileType;
00093   };
00094 
00095 
00096   template<typename T>
00097   struct ConstantVolatileTraits<volatile T>
00098   {
00099     enum{
00100       isVolatile=true, isConst=false
00101         };
00102     typedef T UnqualifiedType;
00103     typedef const UnqualifiedType ConstType;
00104     typedef const volatile UnqualifiedType ConstVolatileType;
00105   };
00106 
00107   template<typename T>
00108   struct ConstantVolatileTraits<const volatile T>
00109   {
00110     enum{
00111       isVolatile=true, isConst=true
00112         };
00113     typedef T UnqualifiedType;
00114     typedef const UnqualifiedType ConstType;
00115     typedef const volatile UnqualifiedType ConstVolatileType;
00116   };
00117 
00119   template<typename T>
00120   struct IsVolatile
00121   {
00122     enum{
00124       value=ConstantVolatileTraits<T>::isVolatile
00125         };
00126   };
00127 
00129   template<typename T>
00130   struct IsConst
00131   {
00132     enum{
00134       value=ConstantVolatileTraits<T>::isConst
00135         };
00136   };
00137 
00138   template<typename T, bool isVolatile>
00139   struct RemoveConstHelper
00140   {
00141     typedef typename ConstantVolatileTraits<T>::UnqualifiedType Type;
00142   };
00143 
00144   template<typename T>
00145   struct RemoveConstHelper<T,true>
00146   {
00147     typedef volatile typename ConstantVolatileTraits<T>::UnqualifiedType Type;
00148   };
00149 
00150 
00154   template<typename T>
00155   struct RemoveConst
00156   {
00157     typedef typename RemoveConstHelper<T, IsVolatile<T>::value>::Type Type;
00158   };
00159 
00166   template<class From, class To>
00167   class Conversion
00168   {
00169     typedef char Small;
00170     struct Big{char dummy[2];};
00171     static Small test(To);
00172     static Big test(...);
00173     static From makeFrom();
00174   public:
00175     enum {
00177       exists =  sizeof(test(makeFrom())) == sizeof(Small),
00179       isTwoWay = exists && Conversion<To,From>::exists,
00181       sameType = false
00182     };
00183   };
00184 
00185   template <class From>
00186   class Conversion<From, void>
00187   {
00188   public:
00189     enum {
00190       exists = false,
00191       isTwoWay = false,
00192       sameType = false
00193     };
00194   };
00195 
00196   template <class To>
00197   class Conversion<void, To>
00198   {
00199   public:
00200     enum {
00201       exists = false,
00202       isTwoWay = false,
00203       sameType = false
00204     };
00205   }; 
00206 
00207   template<class T>
00208   class Conversion<T,T>{
00209   public:
00210     enum{ exists=true, isTwoWay=true, sameType=true};
00211   };
00212 
00219   template<class T1, class T2>
00220   struct IsInteroperable
00221   {
00222     enum{
00227       value = Conversion<T1,T2>::exists || Conversion<T2,T1>::exists
00228         };
00229   };
00230 
00236   template<bool b, typename T=void>
00237   struct EnableIf
00238   {
00239     typedef T type;
00240     typedef T Type;
00241   };
00242 
00243   template<typename T>
00244   struct EnableIf<false,T>
00245   {};
00246 
00252   template<class T1, class T2, class Type>
00253   struct EnableIfInterOperable 
00254     : public EnableIf<IsInteroperable<T1,T2>::value, Type>
00255   {};
00256   
00257 
00262   template<typename T1, typename T2>
00263   struct SameType
00264   {
00265     enum{ 
00266       /* @brief Whether T1 is the same type as T2. */
00267       value=false
00268         };
00269   };
00270   
00271   
00272   template<typename T>
00273   struct SameType<T,T>
00274   {
00275     enum{ value=true};
00276   };
00277 
00286   template<bool first, class T1, class T2>
00287   struct SelectType
00288   {
00295     typedef T1 Type;
00296   };
00297 
00298   template<class T1, class T2>
00299   struct SelectType<false,T1,T2>
00300   {
00301     typedef T2 Type;
00302   };
00304 }
00305 #endif

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)