Fixed problems that emerged in list.
[xlqstl.git] / type_traits
blobd43f897fb0c9c115b0e25d1b6a96b8906bf05137
1 // vi: ft=cpp
2 #ifndef __STL_TYPE_TRAITS
3 #define __STL_TYPE_TRAITS
5 #include "limits"
7 namespace std {
9 template <class T, T v>
10 struct integral_constant {
11     typedef T value_type;
12     typedef integral_constant<T, v> type;
13     static const T value = v;
16 typedef integral_constant<bool, true> true_type;
17 typedef integral_constant<bool, false> false_type;
19 template <bool Cond, class TrueType, class FalseType> struct conditional;
20 template <class TrueType, class FalseType> struct conditional<true, TrueType, FalseType> { typedef TrueType type; };
21 template <class TrueType, class FalseType> struct conditional<false, TrueType, FalseType> { typedef FalseType type; };
23 template <class T> struct is_void: public false_type {};
24 template <> struct is_void<void>: public true_type {};
26 template <class T> struct is_integral: public integral_constant<bool, numeric_limits<T>::is_integer> {};
27 template <class T> struct is_integral<const T>: public integral_constant<bool, is_integral<T>::value> {};
28 template <class T> struct is_integral<volatile T>: public integral_constant<bool, is_integral<T>::value> {};
30 template <class T> struct is_floating_point: public false_type {};
31 template <> struct is_floating_point<float>: public true_type {};
32 template <> struct is_floating_point<double>: public true_type {};
33 template <> struct is_floating_point<long double>: public true_type {};
34 template <class T> struct is_floating_point<const T>: public integral_constant<bool, is_floating_point<T>::value> {};
35 template <class T> struct is_floating_point<volatile T>: public integral_constant<bool, is_floating_point<T>::value> {};
37 template <class T> struct is_array: public false_type {};
38 template <class T> struct is_array<T[]>: public true_type {};
39 template <class T, size_t n> struct is_array<T[n]>: public true_type {};
41 template <class T> struct is_pointer: public false_type {};
42 template <class T> struct is_pointer<T *>: public true_type {};
43 template <class T> struct is_pointer<T *const>: public true_type {};
44 template <class T> struct is_pointer<T *volatile>: public true_type {};
45 template <class T, class... P> struct is_pointer<T (*)(P...)>: public true_type {};
47 template <class T> struct is_lvalue_reference: public false_type {};
48 template <class T> struct is_lvalue_reference<T &>: public true_type {};
50 template <class T> struct is_rvalue_reference: public false_type {};
51 template <class T> struct is_rvalue_reference<T &&>: public true_type {};
53 template <class T> struct is_member_object_pointer: public false_type {};
54 template <class C, class T> struct is_member_object_pointer<T C::*>: public false_type {};
56 template <class T> struct is_member_function_pointer: public false_type {};
57 template <class C, class T, class... P> struct is_member_function_pointer<T (C::*)(P...)>: public true_type {};
59 template <class T> struct is_enum: public integral_constant<bool, __is_enum(T)> {};
60 template <class T> struct is_union: public integral_constant<bool, __is_union(T)> {};
61 template <class T> struct is_class: public integral_constant<bool, __is_class(T)> {};
63 template <class T> struct is_function: public false_type {};
64 template <class T, class... P> struct is_function<T(P...)>: public true_type {};
66 template <class T> struct is_reference: public integral_constant<bool, is_lvalue_reference<T>::value || is_rvalue_reference<T>::value> {};
67 template <class T> struct is_arithmetic: public integral_constant<bool, is_integral<T>::value || is_floating_point<T>::value> {};
68 template <class T> struct is_fundamental: public integral_constant<bool, is_arithmetic<T>::value || is_void<T>::value> {};
69 template <class T> struct is_object: public integral_constant<bool, is_arithmetic<T>::value || is_pointer<T>::value
70                                                              || is_member_object_pointer<T>::value || is_member_function_pointer<T>::value
71                                                              || is_enum<T>::value || is_union<T>::value || is_class<T>::value> {};
73 template <class T> struct is_scalar: public integral_constant<bool, is_arithmetic<T>::value || is_enum<T>::value
74                                                              || is_pointer<T>::value || is_member_object_pointer<T>::value
75                                                              || is_member_function_pointer<T>::value> {};
76 template <class T> struct is_scalar<const T>: public integral_constant<bool, is_scalar<T>::value> {};
77 template <class T> struct is_scalar<volatile T>: public integral_constant<bool, is_scalar<T>::value> {};
79 template <class T> struct is_compound: public integral_constant<bool, is_array<T>::value || is_function<T>::value
80                                                                || is_pointer<T>::value || is_reference<T>::value
81                                                                || is_class<T>::value || is_union<T>::value
82                                                                || is_enum<T>::value || is_member_object_pointer<T>::value
83                                                                || is_member_function_pointer<T>::value> {};
84 template <class T> struct is_member_pointer: public integral_constant<bool, is_member_object_pointer<T>::value || is_member_function_pointer<T>::value> {};
86 template <class T> struct is_const: public false_type {};
87 template <class T> struct is_const<const T>: public true_type {};
89 template <class T> struct is_volatile: public false_type {};
90 template <class T> struct is_volatile<volatile T>: public true_type {};
92 template <class T> struct is_standard_layout: public false_type {};
94 template <class T> struct is_pod: public integral_constant<bool, __is_pod(T)> {};
95 template <class T> struct is_empty: public integral_constant<bool, __is_empty(T)> {};
96 template <class T> struct is_polymorphic: public integral_constant<bool, __is_polymorphic(T)> {};
97 template <class T> struct is_abstract: public integral_constant<bool, __is_abstract(T)> {};
98 template <class T> struct has_trivial_default_constructor: public integral_constant<bool, __has_trivial_constructor(T)> {};
99 template <class T> struct has_trivial_copy_constructor: public integral_constant<bool, __has_trivial_copy(T)> {};
100 template <class T> struct has_trivial_assign: public integral_constant<bool, __has_trivial_assign(T)> {};
101 template <class T> struct has_trivial_destructor: public integral_constant<bool, __has_trivial_destructor(T)> {};
102 template <class T> struct has_nothrow_default_constructor: public integral_constant<bool, __has_nothrow_constructor(T)> {};
103 template <class T> struct has_nothrow_copy_constructor: public integral_constant<bool, __has_nothrow_copy(T)> {};
104 template <class T> struct has_nothrow_assign: public integral_constant<bool, __has_nothrow_assign(T)> {};
105 template <class T> struct has_virtual_destructor: public integral_constant<bool, __has_virtual_destructor(T)> {};
106 template <class T> struct is_signed: public integral_constant<bool, is_arithmetic<T>::value && T(-1) < T(0)> {};
107 template <class T> struct is_unsigned: public integral_constant<bool, is_arithmetic<T>::value && T(0) < T(-1)> {};
108 template <class T> struct alignment_of: public integral_constant<size_t, __alignof__(T)> {};
110 // rank = number of dimensions
111 template <class T> struct rank: public integral_constant<size_t, 0> {};
112 template <class T> struct rank<T[]>: public integral_constant<size_t, 1 + rank<T>::value> {};
113 template <class T, size_t sz> struct rank<T[sz]>: public integral_constant<size_t, 1 + rank<T>::value> {};
115 // extent = size of array in Ith dimension
116 template <class T, unsigned I = 0> struct extent: public integral_constant<size_t, 0> {};
117 template <class T, size_t sz> struct extent<T[sz], 0>: public integral_constant<size_t, sz> {};
118 template <class T, unsigned I, size_t sz> struct extent<T[sz], I>:
119     public integral_constant<
120         size_t,
121         extent<T, I - 1>::value
122     > {};
124 template <class A, class B> struct is_same: public false_type {};
125 template <class T> struct is_same<T, T>: public true_type {};
127 template <class Base, class Derived> struct is_base_of: public integral_constant<bool, __is_base_of(Base, Derived)> {};
129 template <class From, class To> struct is_convertible:
130     public integral_constant<
131         bool,
132         is_same<From, To>::value
133      || (is_arithmetic<From>::value && is_arithmetic<To>::value)
134      || (is_enum<From>::value && is_arithmetic<To>::value)
135     > {};
136 // and, for references
137 // can convert any reference type to a value type
138 template <class From, class To> struct is_convertible<From  &, To   >: public integral_constant<bool, is_convertible<From, To>::value> {};
139 template <class From, class To> struct is_convertible<From &&, To   >: public integral_constant<bool, is_convertible<From, To>::value> {};
140 // ...or an rvalue reference!
141 template <class From, class To> struct is_convertible<From   , To &&>: public integral_constant<bool, is_convertible<From, To>::value> {};
142 template <class From, class To> struct is_convertible<From  &, To &&>: public integral_constant<bool, is_convertible<From, To>::value> {};
143 template <class From, class To> struct is_convertible<From &&, To &&>: public integral_constant<bool, is_convertible<From, To>::value> {};
144 // but you can't make an lvalue reference from a value type if the types don't match
145 template <class From, class To> struct is_convertible<From   , To  &>: public false_type {};
146 template <class From, class To> struct is_convertible<From  &, To  &>: public false_type {};
147 template <class From, class To> struct is_convertible<From &&, To  &>: public false_type {};
149 // and for matching types...
150 template <class T> struct is_convertible<T &&, T  &>: public false_type {};
151 template <class T> struct is_convertible<T  &, T  &>: public true_type {};
152 template <class T> struct is_convertible<T   , T  &>: public false_type {};
154 template <class T> struct remove_const { typedef T type; };
155 template <class T> struct remove_const<const T> { typedef T type; };
157 template <class T> struct remove_volatile { typedef T type; };
158 template <class T> struct remove_volatile<volatile T> { typedef T type; };
159 template <class T> struct remove_cv { typedef typename remove_const<typename remove_volatile<T>::type>::type type; };
161 template <class T> struct add_const { typedef const T type; };
162 template <class T> struct add_volatile { typedef volatile T type; };
163 template <class T> struct add_cv { typedef typename add_const<typename add_volatile<T>::type>::type type; };
165 template <class T> struct remove_reference { typedef T type; };
166 template <class T> struct remove_reference<T &> { typedef T type; };
167 template <class T> struct remove_reference<T &&> { typedef T type; };
168 template <class T> struct add_lvalue_reference { typedef T &type; };
169 template <class T> struct add_rvalue_reference { typedef T &&type; };
171 template <class T> struct make_signed;
172 template <> struct make_signed<unsigned char> { typedef signed char type; };
173 template <> struct make_signed<unsigned short> { typedef signed short type; };
174 template <> struct make_signed<unsigned int> { typedef signed int type; };
175 template <> struct make_signed<unsigned long> { typedef signed long type; };
176 template <> struct make_signed<unsigned long long> { typedef signed long long type; };
177 template <class T> struct make_signed<const T> { typedef const typename make_signed<T>::type type; };
178 template <class T> struct make_signed<volatile T> { typedef volatile typename make_signed<T>::type type; };
179 // TODO: enums
181 template <class T> struct make_unsigned;
182 template <> struct make_unsigned<signed char> { typedef unsigned char type; };
183 template <> struct make_unsigned<signed short> { typedef unsigned short type; };
184 template <> struct make_unsigned<signed int> { typedef unsigned int type; };
185 template <> struct make_unsigned<signed long> { typedef unsigned long type; };
186 template <> struct make_unsigned<signed long long> { typedef unsigned long long type; };
187 template <class T> struct make_unsigned<const T> { typedef const typename make_unsigned<T>::type type; };
188 template <class T> struct make_unsigned<volatile T> { typedef volatile typename make_unsigned<T>::type type; };
189 // TODO: enums
191 template <class T> struct remove_extent { typedef T type; };
192 template <class T> struct remove_extent<T[]> { typedef T type; };
193 template <class T, size_t sz> struct remove_extent<T[sz]> { typedef T type; };
195 template <class T, unsigned Extents> struct __remove_n_extents
196 { typedef typename __remove_n_extents<typename remove_extent<T>::type, Extents - 1>::type type; };
197 template <class T> struct __remove_n_extents<T, 0> { typedef T type; };
199 template <class T> struct remove_all_extents { typedef typename __remove_n_extents<T, rank<T>::value>::type type; };
201 template <class T> struct __remove_pointer { typedef void type; };
202 template <class T> struct __remove_pointer<T *> { typedef T type; };
203 template <class T> struct remove_pointer {
204     typedef typename conditional<
205         is_pointer<T>::value,
206         typename __remove_pointer<typename remove_cv<T>::type>::type,
207         T
208     >::type type;
211 template <class T> struct add_pointer { typedef typename remove_reference<T>::type *type; };
213 template <size_t> struct __most_stringent_alignment;
215 template <size_t Len, size_t Align
216   = alignment_of<
217     typename __most_stringent_alignment<Len>::type
218   >::value>
219 struct aligned_storage {
220     typedef union {
221         unsigned char data[Len];
222         struct __attribute__((aligned(Align))) {} alignment;
223     } type;
226 template <size_t Len> struct __most_stringent_alignment {
227     typedef struct {
228         unsigned char data[Len] __attribute__((aligned));
229     } type;
232 template <class T, bool IsArray, bool IsFunction> struct __decay;
233 template <class T> struct __decay<T, false, false> { typedef typename remove_cv<T>::type type; };
234 template <class T> struct __decay<T, true, false> { typedef typename remove_extent<T>::type *type; };
235 template <class T> struct __decay<T, false, true> { typedef typename add_pointer<T>::type type; };
236 template <class T> struct decay {
237     typedef typename remove_reference<T>::type __U;
238     typedef typename __decay<
239         __U,
240         is_array<__U>::value,
241         is_function<__U>::value
242     >::type type;
244     
245 template <bool B, class T = void> struct enable_if;
246 template <class T> struct enable_if<true, T> { typedef T type; };
247 template <class T> struct enable_if<false, T> {};
249 template <class... T> struct common_type;
250 template <class T> struct common_type<T> { typedef T type; };
251 template <class T, class U> struct common_type<T, U> {
252     // This code, given in the draft spec,
253     // doesn't work.
254     /*static T &&__t();
255     static T &&__u();
256     typedef typename remove_reference<
257         decltype(true ? __t() : __u())
258     >::type type;*/
260     // This appears to.
261     typedef decltype(true ? T() : U()) type;
266 #endif