]>
Commit | Line | Data |
---|---|---|
493bc460 PC |
1 | // TR1 type_traits -*- C++ -*- |
2 | ||
3 | // Copyright (C) 2004 Free Software Foundation, Inc. | |
4 | // | |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
8 | // Free Software Foundation; either version 2, or (at your option) | |
9 | // any later version. | |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // You should have received a copy of the GNU General Public License along | |
17 | // with this library; see the file COPYING. If not, write to the Free | |
18 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
19 | // USA. | |
20 | ||
21 | /** @file | |
22 | * This is a TR1 C++ Library header. | |
23 | */ | |
24 | ||
e21cb773 PC |
25 | #ifndef _TYPE_TRAITS |
26 | #define _TYPE_TRAITS 1 | |
493bc460 PC |
27 | |
28 | #include <bits/c++config.h> | |
821c5063 | 29 | #include <tr1/type_traits_fwd.h> |
493bc460 | 30 | |
cacd0a2c | 31 | // namespace std::tr1 |
493bc460 PC |
32 | namespace std |
33 | { | |
34 | namespace tr1 | |
35 | { | |
a9e7ba81 | 36 | // For use in is_enum, is_function, and elsewhere. |
cacd0a2c PC |
37 | struct __sfinae_types |
38 | { | |
39 | typedef char __one; | |
40 | typedef struct { char __arr[2]; } __two; | |
41 | }; | |
e192ab01 | 42 | |
51687431 PC |
43 | #define _DEFINE_SPEC_BODY(_Value) \ |
44 | : public integral_constant<bool, _Value> { }; | |
45 | ||
46 | #define _DEFINE_SPEC_0_HELPER(_Spec, _Value) \ | |
47 | template<> \ | |
48 | struct _Spec \ | |
49 | _DEFINE_SPEC_BODY(_Value) | |
50 | ||
51 | #define _DEFINE_SPEC_1_HELPER(_Spec, _Value) \ | |
52 | template<typename _Tp> \ | |
53 | struct _Spec \ | |
54 | _DEFINE_SPEC_BODY(_Value) | |
e192ab01 | 55 | |
51687431 PC |
56 | #define _DEFINE_SPEC_2_HELPER(_Spec, _Value) \ |
57 | template<typename _Tp, typename _Cp> \ | |
58 | struct _Spec \ | |
59 | _DEFINE_SPEC_BODY(_Value) | |
186e6683 | 60 | |
51687431 PC |
61 | #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ |
62 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value) \ | |
63 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value) \ | |
64 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value) \ | |
65 | _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value) | |
e192ab01 | 66 | |
cacd0a2c PC |
67 | /// @brief helper classes [4.3]. |
68 | template<typename _Tp, _Tp __v> | |
69 | struct integral_constant | |
70 | { | |
71 | static const _Tp value = __v; | |
72 | typedef _Tp value_type; | |
73 | typedef integral_constant<_Tp, __v> type; | |
74 | }; | |
75 | typedef integral_constant<bool, true> true_type; | |
76 | typedef integral_constant<bool, false> false_type; | |
77 | ||
493bc460 PC |
78 | /// @brief primary type categories [4.5.1]. |
79 | template<typename> | |
80 | struct is_void | |
81 | : public false_type { }; | |
51687431 | 82 | _DEFINE_SPEC(0, is_void, void, true) |
493bc460 PC |
83 | |
84 | template<typename> | |
85 | struct is_integral | |
86 | : public false_type { }; | |
51687431 PC |
87 | _DEFINE_SPEC(0, is_integral, bool, true) |
88 | _DEFINE_SPEC(0, is_integral, char, true) | |
89 | _DEFINE_SPEC(0, is_integral, signed char, true) | |
90 | _DEFINE_SPEC(0, is_integral, unsigned char, true) | |
493bc460 | 91 | #ifdef _GLIBCXX_USE_WCHAR_T |
51687431 | 92 | _DEFINE_SPEC(0, is_integral, wchar_t, true) |
493bc460 | 93 | #endif |
51687431 PC |
94 | _DEFINE_SPEC(0, is_integral, short, true) |
95 | _DEFINE_SPEC(0, is_integral, unsigned short, true) | |
96 | _DEFINE_SPEC(0, is_integral, int, true) | |
97 | _DEFINE_SPEC(0, is_integral, unsigned int, true) | |
98 | _DEFINE_SPEC(0, is_integral, long, true) | |
99 | _DEFINE_SPEC(0, is_integral, unsigned long, true) | |
100 | _DEFINE_SPEC(0, is_integral, long long, true) | |
101 | _DEFINE_SPEC(0, is_integral, unsigned long long, true) | |
493bc460 PC |
102 | |
103 | template<typename> | |
104 | struct is_floating_point | |
105 | : public false_type { }; | |
51687431 PC |
106 | _DEFINE_SPEC(0, is_floating_point, float, true) |
107 | _DEFINE_SPEC(0, is_floating_point, double, true) | |
108 | _DEFINE_SPEC(0, is_floating_point, long double, true) | |
493bc460 PC |
109 | |
110 | template<typename> | |
111 | struct is_array | |
112 | : public false_type { }; | |
113 | ||
114 | template<typename _Tp, std::size_t _Size> | |
115 | struct is_array<_Tp[_Size]> | |
116 | : public true_type { }; | |
117 | ||
118 | template<typename _Tp> | |
119 | struct is_array<_Tp[]> | |
120 | : public true_type { }; | |
186e6683 | 121 | |
e192ab01 PC |
122 | template<typename> |
123 | struct is_pointer | |
124 | : public false_type { }; | |
51687431 | 125 | _DEFINE_SPEC(1, is_pointer, _Tp*, true) |
e192ab01 | 126 | |
e21cb773 PC |
127 | template<typename> |
128 | struct is_reference | |
129 | : public false_type { }; | |
130 | ||
493bc460 | 131 | template<typename _Tp> |
e21cb773 PC |
132 | struct is_reference<_Tp&> |
133 | : public true_type { }; | |
186e6683 | 134 | |
186e6683 PC |
135 | template<typename> |
136 | struct is_member_object_pointer | |
137 | : public false_type { }; | |
51687431 PC |
138 | _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*, |
139 | !is_function<_Tp>::value) | |
186e6683 PC |
140 | |
141 | template<typename> | |
142 | struct is_member_function_pointer | |
143 | : public false_type { }; | |
51687431 PC |
144 | _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*, |
145 | is_function<_Tp>::value) | |
186e6683 | 146 | |
a9e7ba81 PC |
147 | template<typename _Tp, bool = (is_fundamental<_Tp>::value |
148 | || is_array<_Tp>::value | |
149 | || is_pointer<_Tp>::value | |
150 | || is_reference<_Tp>::value | |
151 | || is_member_pointer<_Tp>::value | |
152 | || is_function<_Tp>::value)> | |
153 | struct __is_enum_helper | |
154 | : public __sfinae_types | |
155 | { | |
156 | private: | |
157 | static __one __test(bool); | |
158 | static __one __test(char); | |
159 | static __one __test(signed char); | |
160 | static __one __test(unsigned char); | |
161 | #ifdef _GLIBCXX_USE_WCHAR_T | |
162 | static __one __test(wchar_t); | |
163 | #endif | |
164 | static __one __test(short); | |
165 | static __one __test(unsigned short); | |
166 | static __one __test(int); | |
167 | static __one __test(unsigned int); | |
168 | static __one __test(long); | |
169 | static __one __test(unsigned long); | |
170 | static __one __test(long long); | |
171 | static __one __test(unsigned long long); | |
172 | static __two __test(...); | |
173 | ||
fe9ddfce PC |
174 | struct __convert |
175 | { operator _Tp() const; }; | |
a9e7ba81 PC |
176 | |
177 | public: | |
fe9ddfce | 178 | static const bool __value = sizeof(__test(__convert())) == 1; |
a9e7ba81 PC |
179 | }; |
180 | ||
181 | template<typename _Tp> | |
182 | struct __is_enum_helper<_Tp, true> | |
183 | { static const bool __value = false; }; | |
184 | ||
cacd0a2c | 185 | template<typename _Tp> |
a9e7ba81 | 186 | struct is_enum |
310995ea | 187 | : public integral_constant<bool, __is_enum_helper<_Tp>::__value> { }; |
a9e7ba81 PC |
188 | |
189 | template<typename _Tp, bool = (is_reference<_Tp>::value | |
190 | || is_void<_Tp>::value)> | |
cacd0a2c PC |
191 | struct __is_function_helper |
192 | : public __sfinae_types | |
193 | { | |
194 | private: | |
195 | template<typename> | |
821c5063 | 196 | static __one __test(...); |
cacd0a2c | 197 | template<typename _Up> |
821c5063 | 198 | static __two __test(_Up(*)[1]); |
cacd0a2c PC |
199 | |
200 | public: | |
201 | static const bool __value = sizeof(__test<_Tp>(0)) == 1; | |
202 | }; | |
493bc460 | 203 | |
a9e7ba81 PC |
204 | template<typename _Tp> |
205 | struct __is_function_helper<_Tp, true> | |
206 | { static const bool __value = false; }; | |
207 | ||
493bc460 | 208 | template<typename _Tp> |
cacd0a2c | 209 | struct is_function |
a9e7ba81 | 210 | : public integral_constant<bool, __is_function_helper<_Tp>::__value> { }; |
493bc460 | 211 | |
493bc460 PC |
212 | /// @brief composite type traits [4.5.2]. |
213 | template<typename _Tp> | |
214 | struct is_arithmetic | |
215 | : public integral_constant<bool, (is_integral<_Tp>::value | |
216 | || is_floating_point<_Tp>::value)> | |
217 | { }; | |
218 | ||
219 | template<typename _Tp> | |
220 | struct is_fundamental | |
221 | : public integral_constant<bool, (is_arithmetic<_Tp>::value | |
222 | || is_void<_Tp>::value)> | |
223 | { }; | |
224 | ||
225 | template<typename _Tp> | |
226 | struct is_object | |
227 | : public integral_constant<bool, !(is_function<_Tp>::value | |
228 | || is_reference<_Tp>::value | |
229 | || is_void<_Tp>::value)> | |
230 | { }; | |
231 | ||
493bc460 PC |
232 | template<typename _Tp> |
233 | struct is_scalar | |
234 | : public integral_constant<bool, (is_arithmetic<_Tp>::value | |
235 | || is_enum<_Tp>::value | |
236 | || is_pointer<_Tp>::value | |
237 | || is_member_pointer<_Tp>::value)> | |
238 | { }; | |
821c5063 | 239 | |
493bc460 PC |
240 | template<typename _Tp> |
241 | struct is_compound | |
242 | : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; | |
821c5063 PC |
243 | |
244 | template<typename _Tp> | |
245 | struct is_member_pointer | |
246 | : public integral_constant<bool, | |
247 | (is_member_object_pointer<_Tp>::value | |
248 | || is_member_function_pointer<_Tp>::value)> | |
249 | { }; | |
250 | ||
493bc460 | 251 | /// @brief type properties [4.5.3]. |
0f910b4f PC |
252 | template<typename> |
253 | struct is_const | |
254 | : public false_type { }; | |
255 | ||
493bc460 | 256 | template<typename _Tp> |
0f910b4f PC |
257 | struct is_const<_Tp const> |
258 | : public true_type { }; | |
493bc460 | 259 | |
0f910b4f PC |
260 | template<typename> |
261 | struct is_volatile | |
262 | : public false_type { }; | |
263 | ||
493bc460 | 264 | template<typename _Tp> |
0f910b4f PC |
265 | struct is_volatile<_Tp volatile> |
266 | : public true_type { }; | |
493bc460 | 267 | |
1933b74f PC |
268 | template<typename _Tp> |
269 | struct is_pod | |
270 | : public integral_constant<bool, (is_void<_Tp>::value | |
271 | || is_scalar<typename | |
272 | remove_all_extents<_Tp>::type>::value)> | |
273 | { }; | |
274 | ||
275 | template<typename _Tp> | |
276 | struct has_trivial_constructor | |
277 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
278 | ||
279 | template<typename _Tp> | |
280 | struct has_trivial_destructor | |
281 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
282 | ||
5249b4b0 PC |
283 | template<typename _Tp> |
284 | struct has_nothrow_constructor | |
285 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
286 | ||
821c5063 | 287 | template<typename> |
493bc460 PC |
288 | struct has_virtual_destructor |
289 | : public false_type { }; | |
290 | ||
db5ff236 PC |
291 | template<typename> |
292 | struct rank | |
293 | : public integral_constant<std::size_t, 0> { }; | |
294 | ||
295 | template<typename _Tp, std::size_t _Size> | |
296 | struct rank<_Tp[_Size]> | |
297 | : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; | |
298 | ||
493bc460 | 299 | template<typename _Tp> |
db5ff236 PC |
300 | struct rank<_Tp[]> |
301 | : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; | |
493bc460 | 302 | |
821c5063 | 303 | template<typename, unsigned> |
973cb10b | 304 | struct extent |
273dfd21 | 305 | : public integral_constant<std::size_t, 0> { }; |
973cb10b PC |
306 | |
307 | template<typename _Tp, unsigned _Uint, std::size_t _Size> | |
308 | struct extent<_Tp[_Size], _Uint> | |
273dfd21 PC |
309 | : public integral_constant<std::size_t, |
310 | _Uint == 0 ? _Size : extent<_Tp, | |
311 | _Uint - 1>::value> | |
973cb10b PC |
312 | { }; |
313 | ||
314 | template<typename _Tp, unsigned _Uint> | |
315 | struct extent<_Tp[], _Uint> | |
273dfd21 PC |
316 | : public integral_constant<std::size_t, |
317 | _Uint == 0 ? 0 : extent<_Tp, | |
318 | _Uint - 1>::value> | |
973cb10b | 319 | { }; |
493bc460 PC |
320 | |
321 | /// @brief relationships between types [4.6]. | |
d63a0e22 PC |
322 | template<typename, typename> |
323 | struct is_same | |
324 | : public false_type { }; | |
325 | ||
326 | template<typename _Tp> | |
327 | struct is_same<_Tp, _Tp> | |
328 | : public true_type { }; | |
493bc460 | 329 | |
493bc460 PC |
330 | /// @brief const-volatile modifications [4.7.1]. |
331 | template<typename _Tp> | |
d5f60056 | 332 | struct remove_const |
e192ab01 | 333 | { typedef _Tp type; }; |
d5f60056 PC |
334 | |
335 | template<typename _Tp> | |
336 | struct remove_const<_Tp const> | |
e192ab01 | 337 | { typedef _Tp type; }; |
493bc460 PC |
338 | |
339 | template<typename _Tp> | |
d5f60056 | 340 | struct remove_volatile |
e192ab01 | 341 | { typedef _Tp type; }; |
d5f60056 PC |
342 | |
343 | template<typename _Tp> | |
344 | struct remove_volatile<_Tp volatile> | |
e192ab01 | 345 | { typedef _Tp type; }; |
493bc460 PC |
346 | |
347 | template<typename _Tp> | |
d5f60056 PC |
348 | struct remove_cv |
349 | { | |
350 | typedef typename | |
351 | remove_const<typename remove_volatile<_Tp>::type>::type type; | |
352 | }; | |
493bc460 PC |
353 | |
354 | template<typename _Tp> | |
a02def09 PC |
355 | struct add_const |
356 | { typedef _Tp const type; }; | |
493bc460 PC |
357 | |
358 | template<typename _Tp> | |
a02def09 PC |
359 | struct add_volatile |
360 | { typedef _Tp volatile type; }; | |
493bc460 PC |
361 | |
362 | template<typename _Tp> | |
a02def09 PC |
363 | struct add_cv |
364 | { | |
365 | typedef typename | |
366 | add_const<typename add_volatile<_Tp>::type>::type type; | |
367 | }; | |
493bc460 PC |
368 | |
369 | /// @brief reference modifications [4.7.2]. | |
370 | template<typename _Tp> | |
d63a0e22 | 371 | struct remove_reference |
e192ab01 | 372 | { typedef _Tp type; }; |
d63a0e22 PC |
373 | |
374 | template<typename _Tp> | |
375 | struct remove_reference<_Tp&> | |
e192ab01 | 376 | { typedef _Tp type; }; |
493bc460 PC |
377 | |
378 | template<typename _Tp> | |
d63a0e22 | 379 | struct add_reference |
e192ab01 | 380 | { typedef _Tp& type; }; |
d63a0e22 PC |
381 | |
382 | template<typename _Tp> | |
383 | struct add_reference<_Tp&> | |
e192ab01 | 384 | { typedef _Tp& type; }; |
493bc460 PC |
385 | |
386 | /// @brief array modififications [4.7.3]. | |
387 | template<typename _Tp> | |
366e6bd1 | 388 | struct remove_extent |
e192ab01 | 389 | { typedef _Tp type; }; |
366e6bd1 PC |
390 | |
391 | template<typename _Tp, std::size_t _Size> | |
392 | struct remove_extent<_Tp[_Size]> | |
e192ab01 | 393 | { typedef _Tp type; }; |
366e6bd1 PC |
394 | |
395 | template<typename _Tp> | |
396 | struct remove_extent<_Tp[]> | |
e192ab01 | 397 | { typedef _Tp type; }; |
366e6bd1 | 398 | |
493bc460 | 399 | template<typename _Tp> |
366e6bd1 | 400 | struct remove_all_extents |
e192ab01 | 401 | { typedef _Tp type; }; |
366e6bd1 PC |
402 | |
403 | template<typename _Tp, std::size_t _Size> | |
404 | struct remove_all_extents<_Tp[_Size]> | |
e192ab01 | 405 | { typedef typename remove_all_extents<_Tp>::type type; }; |
366e6bd1 PC |
406 | |
407 | template<typename _Tp> | |
408 | struct remove_all_extents<_Tp[]> | |
e192ab01 | 409 | { typedef typename remove_all_extents<_Tp>::type type; }; |
493bc460 PC |
410 | |
411 | /// @brief pointer modifications [4.7.4]. | |
51687431 PC |
412 | #undef _DEFINE_SPEC_BODY |
413 | #define _DEFINE_SPEC_BODY(_Value) \ | |
e192ab01 PC |
414 | { typedef _Tp type; }; |
415 | ||
493bc460 | 416 | template<typename _Tp> |
e192ab01 PC |
417 | struct remove_pointer |
418 | { typedef _Tp type; }; | |
51687431 | 419 | _DEFINE_SPEC(1, remove_pointer, _Tp*, false) |
493bc460 PC |
420 | |
421 | template<typename _Tp> | |
e192ab01 PC |
422 | struct add_pointer |
423 | { typedef typename remove_reference<_Tp>::type* type; }; | |
493bc460 PC |
424 | |
425 | /// @brief other transformations [4.8]. | |
e192ab01 | 426 | |
186e6683 PC |
427 | #undef _DEFINE_SPEC_0_HELPER |
428 | #undef _DEFINE_SPEC_1_HELPER | |
429 | #undef _DEFINE_SPEC_2_HELPER | |
e2f5c678 | 430 | #undef _DEFINE_SPEC |
51687431 | 431 | #undef _DEFINE_SPEC_BODY |
e192ab01 | 432 | |
493bc460 PC |
433 | } |
434 | } | |
435 | ||
436 | #endif |