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