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
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