| 1 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 2 | // The Loki Library | 
|---|
| 3 | // Copyright (c) 2001 by Andrei Alexandrescu | 
|---|
| 4 | // This code accompanies the book: | 
|---|
| 5 | // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design  | 
|---|
| 6 | //     Patterns Applied". Copyright (c) 2001. Addison-Wesley. | 
|---|
| 7 | // Permission to use, copy, modify, distribute and sell this software for any  | 
|---|
| 8 | //     purpose is hereby granted without fee, provided that the above copyright  | 
|---|
| 9 | //     notice appear in all copies and that both that copyright notice and this  | 
|---|
| 10 | //     permission notice appear in supporting documentation. | 
|---|
| 11 | // The author or Addison-Wesley Longman make no representations about the  | 
|---|
| 12 | //     suitability of this software for any purpose. It is provided "as is"  | 
|---|
| 13 | //     without express or implied warranty. | 
|---|
| 14 | // | 
|---|
| 15 | // Changes by Orxonox (Reto) | 
|---|
| 16 | //     Removed all stdInt, etc. type traits and function pointer traits | 
|---|
| 17 | //     and added UnqualifiedReferredType. | 
|---|
| 18 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 19 | #ifndef LOKI_TYPETRAITS_INC_ | 
|---|
| 20 | #define LOKI_TYPETRAITS_INC_ | 
|---|
| 21 |  | 
|---|
| 22 | // $Id: TypeTraits.h 835 2007-08-02 19:39:02Z syntheticpp $ | 
|---|
| 23 |  | 
|---|
| 24 |  | 
|---|
| 25 | #if (defined _MSC_VER) && (_MSC_VER < 1400) | 
|---|
| 26 | #include <string> | 
|---|
| 27 | #endif | 
|---|
| 28 |  | 
|---|
| 29 |  | 
|---|
| 30 | #ifdef _MSC_VER | 
|---|
| 31 | #pragma warning( push )  | 
|---|
| 32 | #pragma warning( disable : 4180 ) //qualifier applied to function type has no meaning; ignored | 
|---|
| 33 | #endif | 
|---|
| 34 |  | 
|---|
| 35 | namespace Loki | 
|---|
| 36 | { | 
|---|
| 37 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 38 | // class NullType | 
|---|
| 39 | // Used as a placeholder for "no type here" | 
|---|
| 40 | // Useful as an end marker in typelists  | 
|---|
| 41 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 42 |  | 
|---|
| 43 |     class NullType {}; | 
|---|
| 44 |  | 
|---|
| 45 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 46 | // class template IsCustomUnsignedInt | 
|---|
| 47 | // Offers a means to integrate nonstandard built-in unsigned integral types | 
|---|
| 48 | // (such as unsigned __int64 or unsigned long long int) with the TypeTraits  | 
|---|
| 49 | //     class template defined below. | 
|---|
| 50 | // Invocation: IsCustomUnsignedInt<T> where T is any type | 
|---|
| 51 | // Defines 'value', an enum that is 1 iff T is a custom built-in unsigned | 
|---|
| 52 | //     integral type | 
|---|
| 53 | // Specialize this class template for nonstandard unsigned integral types | 
|---|
| 54 | //     and define value = 1 in those specializations | 
|---|
| 55 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 56 |  | 
|---|
| 57 |     template <typename T> | 
|---|
| 58 |     struct IsCustomUnsignedInt | 
|---|
| 59 |     { | 
|---|
| 60 |         enum { value = 0 }; | 
|---|
| 61 |     };         | 
|---|
| 62 |  | 
|---|
| 63 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 64 | // class template IsCustomSignedInt | 
|---|
| 65 | // Offers a means to integrate nonstandard built-in unsigned integral types | 
|---|
| 66 | // (such as unsigned __int64 or unsigned long long int) with the TypeTraits  | 
|---|
| 67 | //     class template defined below. | 
|---|
| 68 | // Invocation: IsCustomSignedInt<T> where T is any type | 
|---|
| 69 | // Defines 'value', an enum that is 1 iff T is a custom built-in signed | 
|---|
| 70 | //     integral type | 
|---|
| 71 | // Specialize this class template for nonstandard unsigned integral types | 
|---|
| 72 | //     and define value = 1 in those specializations | 
|---|
| 73 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 74 |  | 
|---|
| 75 |     template <typename T> | 
|---|
| 76 |     struct IsCustomSignedInt | 
|---|
| 77 |     { | 
|---|
| 78 |         enum { value = 0 }; | 
|---|
| 79 |     };         | 
|---|
| 80 |  | 
|---|
| 81 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 82 | // class template IsCustomFloat | 
|---|
| 83 | // Offers a means to integrate nonstandard floating point types with the | 
|---|
| 84 | //     TypeTraits class template defined below. | 
|---|
| 85 | // Invocation: IsCustomFloat<T> where T is any type | 
|---|
| 86 | // Defines 'value', an enum that is 1 iff T is a custom built-in | 
|---|
| 87 | //     floating point type | 
|---|
| 88 | // Specialize this class template for nonstandard unsigned integral types | 
|---|
| 89 | //     and define value = 1 in those specializations | 
|---|
| 90 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 91 |  | 
|---|
| 92 |     template <typename T> | 
|---|
| 93 |     struct IsCustomFloat | 
|---|
| 94 |     { | 
|---|
| 95 |         enum { value = 0 }; | 
|---|
| 96 |     };         | 
|---|
| 97 |  | 
|---|
| 98 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 99 | // Helper types for class template TypeTraits defined below | 
|---|
| 100 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 101 |  | 
|---|
| 102 |     namespace Private | 
|---|
| 103 |     { | 
|---|
| 104 |         template <typename U> struct AddPointer | 
|---|
| 105 |         { | 
|---|
| 106 |             typedef U* Result; | 
|---|
| 107 |         }; | 
|---|
| 108 |  | 
|---|
| 109 |         template <typename U> struct AddPointer<U&> | 
|---|
| 110 |         { | 
|---|
| 111 |             typedef U* Result; | 
|---|
| 112 |         }; | 
|---|
| 113 |  | 
|---|
| 114 |         template <class U> struct AddReference | 
|---|
| 115 |         { | 
|---|
| 116 |             typedef U & Result; | 
|---|
| 117 |         }; | 
|---|
| 118 |  | 
|---|
| 119 |         template <class U> struct AddReference<U &> | 
|---|
| 120 |         { | 
|---|
| 121 |             typedef U & Result; | 
|---|
| 122 |         }; | 
|---|
| 123 |  | 
|---|
| 124 |         template <> struct AddReference<void> | 
|---|
| 125 |         { | 
|---|
| 126 |             typedef NullType Result; | 
|---|
| 127 |         }; | 
|---|
| 128 |  | 
|---|
| 129 |         template <class U> struct AddParameterType | 
|---|
| 130 |         { | 
|---|
| 131 |             typedef const U & Result; | 
|---|
| 132 |         }; | 
|---|
| 133 |  | 
|---|
| 134 |         template <class U> struct AddParameterType<U &> | 
|---|
| 135 |         { | 
|---|
| 136 |             typedef U & Result; | 
|---|
| 137 |         }; | 
|---|
| 138 |  | 
|---|
| 139 |         template <> struct AddParameterType<void> | 
|---|
| 140 |         { | 
|---|
| 141 |             typedef NullType Result; | 
|---|
| 142 |         }; | 
|---|
| 143 |     }// namespace Private | 
|---|
| 144 |          | 
|---|
| 145 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 146 | // class template TypeTraits | 
|---|
| 147 | // | 
|---|
| 148 | // Figures out at compile time various properties of any given type | 
|---|
| 149 | // Invocations (T is a type, TypeTraits<T>::Property): | 
|---|
| 150 | // | 
|---|
| 151 | // - isPointer       : returns true if T is a pointer type | 
|---|
| 152 | // - PointeeType     : returns the type to which T points if T is a pointer  | 
|---|
| 153 | //                     type, NullType otherwise | 
|---|
| 154 | // - isReference     : returns true if T is a reference type | 
|---|
| 155 | // - ReferredType    : returns the type to which T refers if T is a reference  | 
|---|
| 156 | //                     type, NullType otherwise | 
|---|
| 157 | // - ParameterType   : returns the optimal type to be used as a parameter for  | 
|---|
| 158 | //                     functions that take Ts | 
|---|
| 159 | // - isConst         : returns true if T is a const-qualified type | 
|---|
| 160 | // - NonConstType    : Type with removed 'const' qualifier from T, if any | 
|---|
| 161 | // - isVolatile      : returns true if T is a volatile-qualified type | 
|---|
| 162 | // - NonVolatileType : Type with removed 'volatile' qualifier from T, if any | 
|---|
| 163 | // - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from  | 
|---|
| 164 | //                     T, if any | 
|---|
| 165 | // - ParameterType   : returns the optimal type to be used as a parameter  | 
|---|
| 166 | //                       for functions that take 'const T's | 
|---|
| 167 | // | 
|---|
| 168 | //////////////////////////////////////////////////////////////////////////////// | 
|---|
| 169 |  | 
|---|
| 170 |     template <typename T> | 
|---|
| 171 |     class TypeTraits | 
|---|
| 172 |     { | 
|---|
| 173 |     private: | 
|---|
| 174 |      | 
|---|
| 175 |         template <class U> struct ReferenceTraits | 
|---|
| 176 |         { | 
|---|
| 177 |             enum { result = false }; | 
|---|
| 178 |             typedef U ReferredType; | 
|---|
| 179 |         }; | 
|---|
| 180 |          | 
|---|
| 181 |         template <class U> struct ReferenceTraits<U&> | 
|---|
| 182 |         { | 
|---|
| 183 |             enum { result = true }; | 
|---|
| 184 |             typedef U ReferredType; | 
|---|
| 185 |         }; | 
|---|
| 186 |                 | 
|---|
| 187 |         template <class U> struct PointerTraits | 
|---|
| 188 |         { | 
|---|
| 189 |             enum { result = false }; | 
|---|
| 190 |             typedef NullType PointeeType; | 
|---|
| 191 |         }; | 
|---|
| 192 |          | 
|---|
| 193 |         template <class U> struct PointerTraits<U*> | 
|---|
| 194 |         { | 
|---|
| 195 |             enum { result = true }; | 
|---|
| 196 |             typedef U PointeeType; | 
|---|
| 197 |         }; | 
|---|
| 198 |          | 
|---|
| 199 |         template <class U> struct PointerTraits<U*&> | 
|---|
| 200 |         { | 
|---|
| 201 |             enum { result = true }; | 
|---|
| 202 |             typedef U PointeeType; | 
|---|
| 203 |         }; | 
|---|
| 204 |            | 
|---|
| 205 |         template <class U> struct PToMTraits | 
|---|
| 206 |         { | 
|---|
| 207 |             enum { result = false }; | 
|---|
| 208 |         }; | 
|---|
| 209 |          | 
|---|
| 210 |         template <class U, class V> struct PToMTraits<U V::*> | 
|---|
| 211 |         { | 
|---|
| 212 |             enum { result = true }; | 
|---|
| 213 |         }; | 
|---|
| 214 |          | 
|---|
| 215 |         template <class U, class V> struct PToMTraits<U V::*&> | 
|---|
| 216 |         { | 
|---|
| 217 |             enum { result = true }; | 
|---|
| 218 |         }; | 
|---|
| 219 |          | 
|---|
| 220 |         template <class U> struct UnConst | 
|---|
| 221 |         { | 
|---|
| 222 |             typedef U Result; | 
|---|
| 223 |             enum { isConst = 0 }; | 
|---|
| 224 |         }; | 
|---|
| 225 |          | 
|---|
| 226 |         template <class U> struct UnConst<const U> | 
|---|
| 227 |         { | 
|---|
| 228 |             typedef U Result; | 
|---|
| 229 |             enum { isConst = 1 }; | 
|---|
| 230 |         }; | 
|---|
| 231 |  | 
|---|
| 232 |         template <class U> struct UnConst<const U&> | 
|---|
| 233 |         { | 
|---|
| 234 |             typedef U& Result; | 
|---|
| 235 |             enum { isConst = 1 }; | 
|---|
| 236 |         }; | 
|---|
| 237 |    | 
|---|
| 238 |         template <class U> struct UnVolatile | 
|---|
| 239 |         { | 
|---|
| 240 |             typedef U Result; | 
|---|
| 241 |             enum { isVolatile = 0 }; | 
|---|
| 242 |         }; | 
|---|
| 243 |         | 
|---|
| 244 |         template <class U> struct UnVolatile<volatile U> | 
|---|
| 245 |         { | 
|---|
| 246 |             typedef U Result; | 
|---|
| 247 |             enum { isVolatile = 1 }; | 
|---|
| 248 |         }; | 
|---|
| 249 |  | 
|---|
| 250 |         template <class U> struct UnVolatile<volatile U&> | 
|---|
| 251 |         { | 
|---|
| 252 |             typedef U& Result; | 
|---|
| 253 |             enum { isVolatile = 1 }; | 
|---|
| 254 |         }; | 
|---|
| 255 |          | 
|---|
| 256 |     public: | 
|---|
| 257 |         typedef typename UnConst<T>::Result  | 
|---|
| 258 |             NonConstType; | 
|---|
| 259 |         typedef typename UnVolatile<T>::Result  | 
|---|
| 260 |             NonVolatileType; | 
|---|
| 261 |         typedef typename UnVolatile<typename UnConst<T>::Result>::Result  | 
|---|
| 262 |             UnqualifiedType; | 
|---|
| 263 |         typedef typename PointerTraits<UnqualifiedType>::PointeeType  | 
|---|
| 264 |             PointeeType; | 
|---|
| 265 |         typedef typename ReferenceTraits<T>::ReferredType  | 
|---|
| 266 |             ReferredType; | 
|---|
| 267 |         typedef typename ReferenceTraits<typename UnVolatile<typename UnConst<T>::Result>::Result>::ReferredType | 
|---|
| 268 |             UnqualifiedReferredType; | 
|---|
| 269 |  | 
|---|
| 270 |         enum { isConst          = UnConst<T>::isConst }; | 
|---|
| 271 |         enum { isVolatile       = UnVolatile<T>::isVolatile }; | 
|---|
| 272 |         enum { isReference      = ReferenceTraits<UnqualifiedType>::result }; | 
|---|
| 273 |         enum { isPointer        = PointerTraits< | 
|---|
| 274 |                                         typename ReferenceTraits<UnqualifiedType>::ReferredType >::result}; | 
|---|
| 275 |                  | 
|---|
| 276 |     }; | 
|---|
| 277 | } | 
|---|
| 278 |  | 
|---|
| 279 | #ifdef _MSC_VER | 
|---|
| 280 | #pragma warning( pop ) | 
|---|
| 281 | #endif // _MSC_VER | 
|---|
| 282 |  | 
|---|
| 283 |  | 
|---|
| 284 | #endif // end file guardian | 
|---|
| 285 |  | 
|---|