📄 typetraits.h
字号:
struct AdjReference
{
template<typename U>
struct In { typedef U const & Result; };
};
template<>
struct AdjReference<true>
{
template<typename U>
struct In { typedef U Result; };
};
struct PointerHelper
{
PointerHelper(const volatile void*);
};
template <class T>
NO EnumDetection(T);
template <class T>
YES EnumDetection(...);
YES IsPointer(PointerHelper);
NO IsPointer(...);
// With the VC 6. Rani Sharoni's approach to detect references unfortunately
// results in an error C1001: INTERNAL COMPILER-ERROR
//
// this reference-detection approach is based on boost's
// Type-Traits. See: boost::composite_traits.h
//
// is_reference_helper1 is a function taking a Type2Type<T> returning
// a pointer to a function taking a Type2Type<T> returning a T&.
// This function can only be used if T is not a reference-Type.
// If T is a reference Type the return type would be
// a function taking a Type2Type<T> returning a reference to a T-reference.
// That is illegal, therefore is_reference_helper1(...) is used for
// references.
// In order to detect a reference, use the return-type of is_reference_helper1
// with is_reference_helper2.
//
template <class U>
U&(* IsReferenceHelper1(::Loki::Type2Type<U>) )(::Loki::Type2Type<U>);
NO IsReferenceHelper1(...);
template <class U>
NO IsReferenceHelper2(U&(*)(::Loki::Type2Type<U>));
YES IsReferenceHelper2(...);
template <class U, class Z>
YES IsPointer2Member(Z U::*);
NO IsPointer2Member(...);
// this array-detection approach is based on boost's
// Type-Traits. See: boost::array_traits.hpp
// This function can only be used for non-array-types, because
// functions can't return arrays.
template<class U>
U(* IsArrayTester1(::Loki::Type2Type<U>) )(::Loki::Type2Type<U>);
char IsArrayTester1(...);
template<class U>
NO IsArrayTester2(U(*)(::Loki::Type2Type<U>));
YES IsArrayTester2(...);
// Helper functions for function-pointer detection.
// The code uses the fact, that arrays of functions are not allowed.
// Of course TypeTraits first makes sure that U is neither void
// nor a reference.type.
// The idea for this code is from D Vandevoorde's & N. Josuttis'
// book "C++ Templates".
template<class U>
NO IsFunctionPtrTester1(U*, U(*)[1] = 0);
YES IsFunctionPtrTester1(...);
}
template <typename T>
class TypeTraits
{
public:
enum { isVoid = Private::IsVoid<T>::value};
enum { isStdUnsignedInt =
TL::IndexOf<Private::StdUnsignedInts, T>::value >= 0 };
enum { isStdSignedInt =
TL::IndexOf<Private::StdSignedInts, T>::value >= 0 };
enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
TL::IndexOf<Private::StdOtherInts, T>::value >= 0 };
enum { isStdFloat = TL::IndexOf<Private::StdFloats, T>::value >= 0 };
enum { isStdArith = isStdIntegral || isStdFloat };
enum { isStdFundamental = isStdArith || isStdFloat || isVoid };
enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<T>::value };
enum { isSignedInt = isStdSignedInt || IsCustomSignedInt<T>::value };
enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt };
enum { isFloat = isStdFloat || IsCustomFloat<T>::value };
enum { isArith = isIntegral || isFloat };
enum { isFundamental = isStdFundamental || isArith || isFloat };
enum { isArray = sizeof(Private::YES)
== sizeof(Private::IsArrayTester2(
Private::IsArrayTester1(::Loki::Type2Type<T>()))
)
};
enum { isReference = sizeof(Private::YES)
== sizeof(Private::IsReferenceHelper2(
Private::IsReferenceHelper1(::Loki::Type2Type<T>()))
) && !isVoid
};
enum { isConst = Private::IsConstImpl
<isReference, isArray>::template In<T>::value
};
enum { isVolatile = Private::IsVolatileImpl
<isReference, isArray>::template In<T>::value
};
private:
typedef typename Private::AdjReference<isReference || isVoid>::
template In<T>::Result AdjType;
struct is_scalar
{
private:
struct BoolConvert { BoolConvert(bool); };
static Private::YES check(BoolConvert);
static Private::NO check(...);
struct NotScalar {};
typedef typename Select
<
isVoid || isReference || isArray,
NotScalar, T
>
::Result RetType;
// changed to RetType& to allow testing of abstract classes
static RetType& get();
public:
enum { value = sizeof(check(get())) == sizeof(Private::YES) };
}; // is_scalar
public:
enum { isScalar = is_scalar::value};
typedef typename Select
<
isScalar || isArray, T, AdjType
>
::Result ParameterType;
private:
typedef typename Loki::Select
<
isScalar,
T,
int
>::Result TestType;
static TestType MakeT();
enum { isMemberPointerTemp = sizeof(Private::YES)
== sizeof(Private::IsPointer2Member(MakeT()))
};
public:
enum {isPointer = sizeof(Private::YES)
== sizeof(Private::IsPointer(MakeT()))};
private:
typedef typename Loki::Select
<
isVoid || isReference || !isPointer,
int*,
T
>::Result MayBeFuncPtr;
public:
// enum types are the only scalar types that can't be initialized
// with 0.
// Because we replace all non scalars with int,
// template <class T>
// YES EnumDetection(...);
// will only be selected for enums.
enum { isEnum = sizeof(Private::YES)
== sizeof (Private::EnumDetection<TestType>(0))
};
enum { isMemberFunctionPointer = isScalar && !isArith && !isPointer &&
!isMemberPointerTemp && !isEnum
};
enum { isMemberPointer = isMemberPointerTemp || isMemberFunctionPointer};
enum { isFunctionPointer = sizeof(Private::YES)
== sizeof(
Private::IsFunctionPtrTester1(MayBeFuncPtr(0))
) && !isMemberPointer
};
//
// We get is_class for free
// BUG - fails with functions types (ICE) and unknown size array
// (but works for other incomplete types)
// (the boost one (Paul Mensonides) is better)
//
enum { isClass =
!isScalar &&
!isArray &&
!isReference &&
!isVoid &&
!isEnum
};
};
}
#ifdef _MSC_VER
#pragma warning (default: 4800)
#endif
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466)
// Oct 05, 2002: ported by Benjamin Kaufmann to MSVC 6
// Jan 31, 2003: fixed bugs in scalar and array detection.
// Added isMemberFuncPointer and isEnum. B.K.
//
// Feb 16, 2003: fixed bug in reference-Detection. Renamed isMemberFuncPointer
// to isMemberFunctionPointer. Added isFunctionPointer, replaced
// all occurrences of Private::Wrap with Loki::Type2Type and
// cleaned up the TypeTraits-class. B.K.
////////////////////////////////////////////////////////////////////////////////
#endif // TYPETRAITS_INC_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -