#ifndef TYPETRAITS_INC_ #define TYPETRAITS_INC_ #include "Typelist.h" namespace Loki { //////////////////////////////////////////////////////////////////////////////// // class template IsCustomUnsignedInt // Offers a means to integrate nonstandard built-in unsigned integral types // (such as unsigned __int64 or unsigned long long int) with the TypeTraits // class template defined below. // Invocation: IsCustomUnsignedInt where T is any type // Defines 'value', an enum that is 1 iff T is a custom built-in unsigned // integral type // Specialize this class template for nonstandard unsigned integral types // and define value = 1 in those specializations //////////////////////////////////////////////////////////////////////////////// template struct IsCustomUnsignedInt { enum { value = 0 }; }; //////////////////////////////////////////////////////////////////////////////// // class template IsCustomSignedInt // Offers a means to integrate nonstandard built-in unsigned integral types // (such as unsigned __int64 or unsigned long long int) with the TypeTraits // class template defined below. // Invocation: IsCustomSignedInt where T is any type // Defines 'value', an enum that is 1 iff T is a custom built-in signed // integral type // Specialize this class template for nonstandard unsigned integral types // and define value = 1 in those specializations //////////////////////////////////////////////////////////////////////////////// template struct IsCustomSignedInt { enum { value = 0 }; }; //////////////////////////////////////////////////////////////////////////////// // class template IsCustomFloat // Offers a means to integrate nonstandard floating point types with the // TypeTraits class template defined below. // Invocation: IsCustomFloat where T is any type // Defines 'value', an enum that is 1 iff T is a custom built-in // floating point type // Specialize this class template for nonstandard unsigned integral types // and define value = 1 in those specializations //////////////////////////////////////////////////////////////////////////////// template struct IsCustomFloat { enum { value = 0 }; }; //////////////////////////////////////////////////////////////////////////////// // Helper types for class template TypeTraits defined below //////////////////////////////////////////////////////////////////////////////// namespace Private { typedef TYPELIST_4(unsigned char, unsigned short int, unsigned int, unsigned long int) StdUnsignedInts; typedef TYPELIST_4(signed char, short int, int, long int) StdSignedInts; typedef TYPELIST_3(bool, char, wchar_t) StdOtherInts; typedef TYPELIST_3(float, double, long double) StdFloats; } //////////////////////////////////////////////////////////////////////////////// // class template TypeTraits // Figures out various properties of any given type // Invocations (T is a type): // a) TypeTraits::isPointer // returns (at compile time) true if T is a pointer type // b) TypeTraits::PointeeType // returns the type to which T points is T is a pointer type, NullType otherwise // a) TypeTraits::isReference // returns (at compile time) true if T is a reference type // b) TypeTraits::ReferredType // returns the type to which T refers is T is a reference type, NullType // otherwise // c) TypeTraits::isMemberPointer // returns (at compile time) true if T is a pointer to member type // d) TypeTraits::isStdUnsignedInt // returns (at compile time) true if T is a standard unsigned integral type // e) TypeTraits::isStdSignedInt // returns (at compile time) true if T is a standard signed integral type // f) TypeTraits::isStdIntegral // returns (at compile time) true if T is a standard integral type // g) TypeTraits::isStdFloat // returns (at compile time) true if T is a standard floating-point type // h) TypeTraits::isStdArith // returns (at compile time) true if T is a standard arithmetic type // i) TypeTraits::isStdFundamental // returns (at compile time) true if T is a standard fundamental type // j) TypeTraits::isUnsignedInt // returns (at compile time) true if T is a unsigned integral type // k) TypeTraits::isSignedInt // returns (at compile time) true if T is a signed integral type // l) TypeTraits::isIntegral // returns (at compile time) true if T is a integral type // m) TypeTraits::isFloat // returns (at compile time) true if T is a floating-point type // n) TypeTraits::isArith // returns (at compile time) true if T is a arithmetic type // o) TypeTraits::isFundamental // returns (at compile time) true if T is a fundamental type // p) TypeTraits::ParameterType // returns the optimal type to be used as a parameter for functions that take Ts // q) TypeTraits::isConst // returns (at compile time) true if T is a const-qualified type // r) TypeTraits::NonConstType // removes the 'const' qualifier from T, if any // s) TypeTraits::isVolatile // returns (at compile time) true if T is a volatile-qualified type // t) TypeTraits::NonVolatileType // removes the 'volatile' qualifier from T, if any // u) TypeTraits::UnqualifiedType // removes both the 'const' and 'volatile' qualifiers from T, if any //////////////////////////////////////////////////////////////////////////////// template class TypeTraits { private: template struct PointerTraits { enum { result = false }; typedef NullType PointeeType; }; template struct PointerTraits { enum { result = true }; typedef U PointeeType; }; template struct ReferenceTraits { enum { result = false }; typedef U ReferredType; }; template struct ReferenceTraits { enum { result = true }; typedef U ReferredType; }; template struct PToMTraits { enum { result = false }; }; template struct PToMTraits { enum { result = true }; }; template struct UnConst { typedef U Result; enum { isConst = 0 }; }; template struct UnConst { typedef U Result; enum { isConst = 1 }; }; template struct UnVolatile { typedef U Result; enum { isVolatile = 0 }; }; template struct UnVolatile { typedef U Result; enum { isVolatile = 1 }; }; public: enum { isPointer = PointerTraits::result }; typedef typename PointerTraits::PointeeType PointeeType; enum { isReference = ReferenceTraits::result }; typedef typename ReferenceTraits::ReferredType ReferredType; enum { isMemberPointer = PToMTraits::result }; enum { isStdUnsignedInt = TL::IndexOf::value >= 0 }; enum { isStdSignedInt = TL::IndexOf::value >= 0 }; enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt || TL::IndexOf::value >= 0 }; enum { isStdFloat = TL::IndexOf::value >= 0 }; enum { isStdArith = isStdIntegral || isStdFloat }; enum { isStdFundamental = isStdArith || isStdFloat || Conversion::sameType }; enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt::value }; enum { isSignedInt = isStdSignedInt || IsCustomSignedInt::value }; enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt }; enum { isFloat = isStdFloat || IsCustomFloat::value }; enum { isArith = isIntegral || isFloat }; enum { isFundamental = isStdFundamental || isArith || isFloat }; typedef typename Select::Result ParameterType; enum { isConst = UnConst::isConst }; typedef typename UnConst::Result NonConstType; enum { isVolatile = UnVolatile::isVolatile }; typedef typename UnVolatile::Result NonVolatileType; typedef typename UnVolatile::Result>::Result UnqualifiedType; }; } //////////////////////////////////////////////////////////////////////////////// // Change log: // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! //////////////////////////////////////////////////////////////////////////////// #endif // TYPETRAITS_INC_