Build system improvements
[ustl.git] / typet.h
blob7c16885b15207c96ca2b4bb8aee7f748bdbda066
1 // This file is part of the ustl library, an STL implementation.
2 //
3 // Copyright (c) 2007 by Mike Sharov <msharov@users.sourceforge.net>
4 //
5 // This implementation is adapted from the Loki library, distributed under
6 // the MIT license with Copyright (c) 2001 by Andrei Alexandrescu.
7 //
8 // typet.h
9 //
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
17 namespace ustl {
18 /// Template metaprogramming tools
19 namespace tm {
21 /// An empty type useful as a placeholder.
22 class NullType { };
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 }; };
39 template <typename T>
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>
47 class Conversion {
48 typedef char UT;
49 typedef short TT;
50 static UT Test (U);
51 static TT Test (...);
52 static T MakeT (void);
53 public:
54 enum {
55 exists = sizeof(UT) == sizeof(Test(MakeT())),
56 exists2Way = exists && Conversion<U,T>::exists,
57 sameType = false
60 template <typename T>
61 struct Conversion<T, T> { enum { exists = true, exists2Way = true, sameType = true }; };
62 template <typename T>
63 struct Conversion<void, T> { enum { exists = false, exists2Way = false, sameType = false }; };
64 template <typename T>
65 struct Conversion<T, void> { enum { exists = false, exists2Way = false, sameType = false }; };
66 template <>
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.
76 template <>
77 struct SuperSubclass<void, void> { enum { value = false }; };
78 template <typename U>
79 struct SuperSubclass<void, U> {
80 enum { value = false };
81 enum { dontUseWithIncompleteTypes = 0==sizeof(U) };
83 template <typename T>
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; }
101 } // namespace tm
102 } // namespace ustl
104 #endif