| Index: src/third_party/loki/TypeManip.h
|
| diff --git a/src/third_party/loki/TypeManip.h b/src/third_party/loki/TypeManip.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6551e162f919f14417ee375b10695b66a94fa3e9
|
| --- /dev/null
|
| +++ b/src/third_party/loki/TypeManip.h
|
| @@ -0,0 +1,283 @@
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// The Loki Library
|
| +// Copyright (c) 2001 by Andrei Alexandrescu
|
| +// This code accompanies the book:
|
| +// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
|
| +// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
| +// Permission to use, copy, modify, distribute and sell this software for any
|
| +// purpose is hereby granted without fee, provided that the above copyright
|
| +// notice appear in all copies and that both that copyright notice and this
|
| +// permission notice appear in supporting documentation.
|
| +// The author or Addison-Welsey Longman make no representations about the
|
| +// suitability of this software for any purpose. It is provided "as is"
|
| +// without express or implied warranty.
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +#ifndef LOKI_TYPEMANIP_INC_
|
| +#define LOKI_TYPEMANIP_INC_
|
| +
|
| +// $Id: TypeManip.h 749 2006-10-17 19:49:26Z syntheticpp $
|
| +
|
| +
|
| +namespace Loki
|
| +{
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// class template Int2Type
|
| +// Converts each integral constant into a unique type
|
| +// Invocation: Int2Type<v> where v is a compile-time constant integral
|
| +// Defines 'value', an enum that evaluates to v
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| + template <int v>
|
| + struct Int2Type
|
| + {
|
| + enum { value = v };
|
| + };
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// class template Type2Type
|
| +// Converts each type into a unique, insipid type
|
| +// Invocation Type2Type<T> where T is a type
|
| +// Defines the type OriginalType which maps back to T
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| + template <typename T>
|
| + struct Type2Type
|
| + {
|
| + typedef T OriginalType;
|
| + };
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// class template Select
|
| +// Selects one of two types based upon a boolean constant
|
| +// Invocation: Select<flag, T, U>::Result
|
| +// where:
|
| +// flag is a compile-time boolean constant
|
| +// T and U are types
|
| +// Result evaluates to T if flag is true, and to U otherwise.
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| + template <bool flag, typename T, typename U>
|
| + struct Select
|
| + {
|
| + typedef T Result;
|
| + };
|
| + template <typename T, typename U>
|
| + struct Select<false, T, U>
|
| + {
|
| + typedef U Result;
|
| + };
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// class template IsSameType
|
| +// Return true iff two given types are the same
|
| +// Invocation: SameType<T, U>::value
|
| +// where:
|
| +// T and U are types
|
| +// Result evaluates to true iff U == T (types equal)
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| + template <typename T, typename U>
|
| + struct IsSameType
|
| + {
|
| + enum { value = false };
|
| + };
|
| +
|
| + template <typename T>
|
| + struct IsSameType<T,T>
|
| + {
|
| + enum { value = true };
|
| + };
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| + namespace Private
|
| + {
|
| + template <class T, class U>
|
| + struct ConversionHelper
|
| + {
|
| + typedef char Small;
|
| + struct Big { char dummy[2]; };
|
| + static Big Test(...);
|
| + static Small Test(U);
|
| + static T MakeT();
|
| + };
|
| + }
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// class template Conversion
|
| +// Figures out the conversion relationships between two types
|
| +// Invocations (T and U are types):
|
| +// a) Conversion<T, U>::exists
|
| +// returns (at compile time) true if there is an implicit conversion from T
|
| +// to U (example: Derived to Base)
|
| +// b) Conversion<T, U>::exists2Way
|
| +// returns (at compile time) true if there are both conversions from T
|
| +// to U and from U to T (example: int to char and back)
|
| +// c) Conversion<T, U>::sameType
|
| +// returns (at compile time) true if T and U represent the same type
|
| +//
|
| +// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| + template <class T, class U>
|
| + struct Conversion
|
| + {
|
| + typedef Private::ConversionHelper<T, U> H;
|
| +#ifndef __MWERKS__
|
| + enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
|
| +#else
|
| + enum { exists = false };
|
| +#endif
|
| + enum { exists2Way = exists && Conversion<U, T>::exists };
|
| + enum { sameType = false };
|
| + };
|
| +
|
| + template <class T>
|
| + struct Conversion<T, T>
|
| + {
|
| + enum { exists = 1, exists2Way = 1, sameType = 1 };
|
| + };
|
| +
|
| + template <class T>
|
| + struct Conversion<void, T>
|
| + {
|
| + enum { exists = 0, exists2Way = 0, sameType = 0 };
|
| + };
|
| +
|
| + template <class T>
|
| + struct Conversion<T, void>
|
| + {
|
| + enum { exists = 0, exists2Way = 0, sameType = 0 };
|
| + };
|
| +
|
| + template <>
|
| + struct Conversion<void, void>
|
| + {
|
| + public:
|
| + enum { exists = 1, exists2Way = 1, sameType = 1 };
|
| + };
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// class template SuperSubclass
|
| +// Invocation: SuperSubclass<B, D>::value where B and D are types.
|
| +// Returns true if B is a public base of D, or if B and D are aliases of the
|
| +// same type.
|
| +//
|
| +// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +template <class T, class U>
|
| +struct SuperSubclass
|
| +{
|
| + enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
|
| + !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
|
| +
|
| + // Dummy enum to make sure that both classes are fully defined.
|
| + enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
|
| +};
|
| +
|
| +template <>
|
| +struct SuperSubclass<void, void>
|
| +{
|
| + enum { value = false };
|
| +};
|
| +
|
| +template <class U>
|
| +struct SuperSubclass<void, U>
|
| +{
|
| + enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
|
| + !::Loki::Conversion<const volatile void*, const volatile void*>::sameType) };
|
| +
|
| + // Dummy enum to make sure that both classes are fully defined.
|
| + enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
|
| +};
|
| +
|
| +template <class T>
|
| +struct SuperSubclass<T, void>
|
| +{
|
| + enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
|
| + !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
|
| +
|
| + // Dummy enum to make sure that both classes are fully defined.
|
| + enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
|
| +};
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// class template SuperSubclassStrict
|
| +// Invocation: SuperSubclassStrict<B, D>::value where B and D are types.
|
| +// Returns true if B is a public base of D.
|
| +//
|
| +// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +template<class T,class U>
|
| +struct SuperSubclassStrict
|
| +{
|
| + enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
|
| + !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
|
| + !::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
|
| +
|
| + // Dummy enum to make sure that both classes are fully defined.
|
| + enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
|
| +};
|
| +
|
| +template<>
|
| +struct SuperSubclassStrict<void, void>
|
| +{
|
| + enum { value = false };
|
| +};
|
| +
|
| +template<class U>
|
| +struct SuperSubclassStrict<void, U>
|
| +{
|
| + enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
|
| + !::Loki::Conversion<const volatile void*, const volatile void*>::sameType &&
|
| + !::Loki::Conversion<const volatile void*, const volatile U*>::sameType) };
|
| +
|
| + // Dummy enum to make sure that both classes are fully defined.
|
| + enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
|
| +};
|
| +
|
| +template<class T>
|
| +struct SuperSubclassStrict<T, void>
|
| +{
|
| + enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
|
| + !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
|
| + !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
|
| +
|
| + // Dummy enum to make sure that both classes are fully defined.
|
| + enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
|
| +};
|
| +
|
| +
|
| +} // namespace Loki
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// macro SUPERSUBCLASS
|
| +// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
| +// Returns true if B is a public base of D, or if B and D are aliases of the
|
| +// same type.
|
| +//
|
| +// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
| +// Deprecated: Use SuperSubclass class template instead.
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +#define LOKI_SUPERSUBCLASS(T, U) \
|
| + ::Loki::SuperSubclass<T,U>::value
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// macro SUPERSUBCLASS_STRICT
|
| +// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
| +// Returns true if B is a public base of D.
|
| +//
|
| +// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
| +// Deprecated: Use SuperSubclassStrict class template instead.
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +#define LOKI_SUPERSUBCLASS_STRICT(T, U) \
|
| + ::Loki::SuperSubclassStrict<T,U>::value
|
| +
|
| +
|
| +#endif // end file guardian
|
|
|