1 // This file is part of the ustl library, an STL implementation.
3 // Copyright (c) 2007 by Mike Sharov <msharov@users.sourceforge.net>
5 // This implementation is adapted from the Loki library, distributed under
6 // the MIT license with Copyright (c) 2001 by Andrei Alexandrescu.
10 // This file contains type information templates useful for template
11 // parameter manipulation and deduction.
14 #ifndef TYPET_H_70B4C9693A05E0B405B225F356DE5450
15 #define TYPET_H_70B4C9693A05E0B405B225F356DE5450
18 /// Template metaprogramming tools
21 /// An empty type useful as a placeholder.
24 /// Converts an integer to a type.
25 template <int v
> struct Int2Type
{ enum { value
= v
}; };
27 /// Converts an type to a unique empty type.
28 template <typename T
> struct Type2Type
{ typedef T OriginalType
; };
30 /// Selects type Result = flag ? T : U
31 template <bool flag
, typename T
, typename U
>
32 struct Select
{ typedef T Result
; };
33 template <typename T
, typename U
>
34 struct Select
<false, T
, U
> { typedef U Result
; };
36 /// IsSameType<T,U>::value is true when T=U
37 template <typename T
, typename U
>
38 struct IsSameType
{ enum { value
= false }; };
40 struct IsSameType
<T
,T
> { enum { value
= true }; };
42 /// \brief Checks for conversion possibilities between T and U
43 /// Conversion<T,U>::exists is true if T is convertible to U
44 /// Conversion<T,U>::exists2Way is true if U is also convertible to T
45 /// Conversion<T,U>::sameType is true if U is T
46 template <typename T
, typename U
>
52 static T
MakeT (void);
55 exists
= sizeof(UT
) == sizeof(Test(MakeT())),
56 exists2Way
= exists
&& Conversion
<U
,T
>::exists
,
61 struct Conversion
<T
, T
> { enum { exists
= true, exists2Way
= true, sameType
= true }; };
63 struct Conversion
<void, T
> { enum { exists
= false, exists2Way
= false, sameType
= false }; };
65 struct Conversion
<T
, void> { enum { exists
= false, exists2Way
= false, sameType
= false }; };
67 struct Conversion
<void, void> { enum { exists
= true, exists2Way
= true, sameType
= true }; };
69 /// SuperSubclass<T,U>::value is true when U is derived from T, or when U is T
70 template <typename T
, typename U
>
71 struct SuperSubclass
{
72 enum { value
= (::ustl::tm::Conversion
<const volatile U
*, const volatile T
*>::exists
&&
73 !::ustl::tm::Conversion
<const volatile T
*, const volatile void*>::sameType
) };
74 enum { dontUseWithIncompleteTypes
= sizeof(T
)==sizeof(U
) }; // Dummy enum to make sure that both classes are fully defined.
77 struct SuperSubclass
<void, void> { enum { value
= false }; };
79 struct SuperSubclass
<void, U
> {
80 enum { value
= false };
81 enum { dontUseWithIncompleteTypes
= 0==sizeof(U
) };
84 struct SuperSubclass
<T
, void> {
85 enum { value
= false };
86 enum { dontUseWithIncompleteTypes
= 0==sizeof(T
) };
89 /// SuperSubclassStrict<T,U>::value is true when U is derived from T
90 template <typename T
, typename U
>
91 struct SuperSubclassStrict
{
92 enum { value
= SuperSubclass
<T
,U
>::value
&&
93 !::ustl::tm::Conversion
<const volatile T
*, const volatile U
*>::sameType
};
96 // static assert support
97 template <bool> struct CompileTimeError
;
98 template <> struct CompileTimeError
<true> {};
99 #define static_assert(cond,msg) { ::ustl::tm::CompileTimeError<!!(cond)> ERROR_##msg; (void) ERROR_##msg; }