2001-11-21 07:28:56 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2001-11-23 08:06:43 +00:00
|
|
|
// Last update: November 22, 2001
|
2001-11-21 07:28:56 +00:00
|
|
|
|
|
|
|
#ifndef TYPEMANIP_INC_
|
|
|
|
#define TYPEMANIP_INC_
|
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
namespace Private
|
|
|
|
{
|
2001-11-21 09:31:45 +00:00
|
|
|
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();
|
|
|
|
};
|
2001-11-21 07:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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>
|
2001-11-21 09:31:45 +00:00
|
|
|
struct Conversion
|
2001-11-21 07:28:56 +00:00
|
|
|
{
|
2001-11-21 09:31:45 +00:00
|
|
|
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 };
|
2001-11-21 07:28:56 +00:00
|
|
|
enum { sameType = false };
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
2001-11-21 09:31:45 +00:00
|
|
|
struct Conversion<T, T>
|
2001-11-21 07:28:56 +00:00
|
|
|
{
|
2001-11-23 08:06:43 +00:00
|
|
|
enum { exists = 1, exists2Way = 1, sameType = 1 };
|
2001-11-21 07:28:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
2001-11-21 09:31:45 +00:00
|
|
|
struct Conversion<void, T>
|
2001-11-21 07:28:56 +00:00
|
|
|
{
|
2001-11-23 08:06:43 +00:00
|
|
|
enum { exists = 0, exists2Way = 0, sameType = 0 };
|
2001-11-21 07:28:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
2001-11-21 09:31:45 +00:00
|
|
|
struct Conversion<T, void>
|
2001-11-21 07:28:56 +00:00
|
|
|
{
|
2001-11-23 08:06:43 +00:00
|
|
|
enum { exists = 1, exists2Way = 0, sameType = 0 };
|
2001-11-21 07:28:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
class Conversion<void, void>
|
|
|
|
{
|
|
|
|
public:
|
2001-11-23 08:06:43 +00:00
|
|
|
enum { exists = 1, exists2Way = 1, sameType = 1 };
|
|
|
|
};
|
|
|
|
} // namespace Loki
|
2001-11-21 07:28:56 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#define SUPERSUBCLASS(T, U) \
|
2001-11-23 08:06:43 +00:00
|
|
|
(::Loki::Conversion<const volatile U*, const volatile T*>::exists && \
|
|
|
|
!::Loki::Conversion<const volatile T*, const volatile void*>::sameType)
|
2001-11-21 07:28:56 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// macro SUPERSUBCLASS
|
|
|
|
// 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.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#define SUPERSUBCLASS_STRICT(T, U) \
|
|
|
|
(SUPERSUBCLASS(T, U) && \
|
2001-11-23 08:06:43 +00:00
|
|
|
!::Loki::Conversion<const volatile T, const volatile U>::sameType)
|
2001-11-21 07:28:56 +00:00
|
|
|
|
2001-11-21 09:31:45 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Change log:
|
|
|
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
2001-11-23 08:06:43 +00:00
|
|
|
// November 22, 2001: minor change to support porting to boost
|
|
|
|
// November 22, 2001: fixed bug in Conversion<void, T>
|
|
|
|
// (credit due to Brad Town)
|
|
|
|
// November 23, 2001: (well it's 12:01 am) fixed bug in SUPERSUBCLASS - added
|
|
|
|
// the volatile qualifier to be 100% politically correct
|
2001-11-21 09:31:45 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2001-11-21 07:28:56 +00:00
|
|
|
|
2001-11-21 09:31:45 +00:00
|
|
|
#endif // TYPEMANIP_INC_
|