]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/type_traits
mips.md (GPR2): New mode iterator.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / type_traits
CommitLineData
af13a7a6
BK
1// <type_traits> -*- C++ -*-
2
939759fc 3// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
af13a7a6
BK
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
17// along with this library; see the file COPYING. If not, write to
18// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19// Boston, MA 02110-1301, USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction. Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License. This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30/** @file include/type_traits
31 * This is a Standard C++ Library header.
32 */
33
e133ace8
PC
34#ifndef _GLIBCXX_CXX0X_TYPE_TRAITS
35#define _GLIBCXX_CXX0X_TYPE_TRAITS 1
af13a7a6
BK
36
37#pragma GCC system_header
38
e133ace8 39#ifndef __GXX_EXPERIMENTAL_CXX0X__
af13a7a6
BK
40# include <c++0x_warning.h>
41#endif
42
e133ace8
PC
43#if defined(_GLIBCXX_INCLUDE_AS_TR1)
44# error C++0x header cannot be included from TR1 header
45#endif
46
47#include <cstddef>
48
49#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
50# include <tr1_impl/type_traits>
51#else
52# define _GLIBCXX_INCLUDE_AS_CXX0X
53# define _GLIBCXX_BEGIN_NAMESPACE_TR1
54# define _GLIBCXX_END_NAMESPACE_TR1
55# define _GLIBCXX_TR1
56# include <tr1_impl/type_traits>
57# undef _GLIBCXX_TR1
58# undef _GLIBCXX_END_NAMESPACE_TR1
59# undef _GLIBCXX_BEGIN_NAMESPACE_TR1
60# undef _GLIBCXX_INCLUDE_AS_CXX0X
61#endif
62
63namespace std
64{
4a27a739 65 // Primary classification traits.
939759fc
BK
66
67 /// is_lvalue_reference
4a27a739
PC
68 template<typename>
69 struct is_lvalue_reference
70 : public false_type { };
71
72 template<typename _Tp>
73 struct is_lvalue_reference<_Tp&>
74 : public true_type { };
75
939759fc 76 /// is_rvalue_reference
4a27a739
PC
77 template<typename>
78 struct is_rvalue_reference
79 : public false_type { };
80
81 template<typename _Tp>
82 struct is_rvalue_reference<_Tp&&>
83 : public true_type { };
84
85 // Secondary classification traits.
939759fc
BK
86
87 /// is_reference
4a27a739
PC
88 template<typename _Tp>
89 struct is_reference
90 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
91 || is_rvalue_reference<_Tp>::value)>
92 { };
93
94 // Reference transformations.
939759fc
BK
95
96 /// remove_reference
4a27a739
PC
97 template<typename _Tp>
98 struct remove_reference
99 { typedef _Tp type; };
100
101 template<typename _Tp>
102 struct remove_reference<_Tp&>
103 { typedef _Tp type; };
104
105 template<typename _Tp>
106 struct remove_reference<_Tp&&>
107 { typedef _Tp type; };
108
109 template<typename _Tp,
110 bool = is_object<_Tp>::value || is_function<_Tp>::value,
111 bool = is_rvalue_reference<_Tp>::value>
112 struct __add_lvalue_reference_helper
113 { typedef _Tp type; };
114
115 template<typename _Tp>
116 struct __add_lvalue_reference_helper<_Tp, true, false>
117 { typedef _Tp& type; };
118
119 template<typename _Tp>
120 struct __add_lvalue_reference_helper<_Tp, false, true>
121 { typedef typename remove_reference<_Tp>::type& type; };
122
939759fc 123 /// add_lvalue_reference
4a27a739
PC
124 template<typename _Tp>
125 struct add_lvalue_reference
126 : public __add_lvalue_reference_helper<_Tp>
127 { };
128
129 template<typename _Tp,
130 bool = is_object<_Tp>::value || is_function<_Tp>::value>
131 struct __add_rvalue_reference_helper
132 { typedef _Tp type; };
133
134 template<typename _Tp>
135 struct __add_rvalue_reference_helper<_Tp, true>
136 { typedef _Tp&& type; };
137
939759fc 138 /// add_rvalue_reference
4a27a739
PC
139 template<typename _Tp>
140 struct add_rvalue_reference
141 : public __add_rvalue_reference_helper<_Tp>
142 { };
143
144 // Scalar properties and transformations.
939759fc 145
e133ace8
PC
146 template<typename _Tp,
147 bool = is_integral<_Tp>::value,
148 bool = is_floating_point<_Tp>::value>
149 struct __is_signed_helper
150 : public false_type { };
151
152 template<typename _Tp>
153 struct __is_signed_helper<_Tp, false, true>
154 : public true_type { };
155
156 template<typename _Tp>
157 struct __is_signed_helper<_Tp, true, false>
158 : public integral_constant<bool, _Tp(-1) < _Tp(0)>
159 { };
160
939759fc 161 /// is_signed
e133ace8
PC
162 template<typename _Tp>
163 struct is_signed
164 : public integral_constant<bool, __is_signed_helper<_Tp>::value>
165 { };
166
939759fc 167 /// is_unsigned
e133ace8
PC
168 template<typename _Tp>
169 struct is_unsigned
170 : public integral_constant<bool, (is_arithmetic<_Tp>::value
171 && !is_signed<_Tp>::value)>
172 { };
173
4a27a739 174 // Member introspection.
939759fc
BK
175
176 /// is_pod
e133ace8
PC
177 template<typename _Tp>
178 struct is_pod
179 : public integral_constant<bool, __is_pod(_Tp)>
180 { };
181
939759fc 182 /// has_trivial_default_constructor
e133ace8
PC
183 template<typename _Tp>
184 struct has_trivial_default_constructor
185 : public integral_constant<bool, __has_trivial_constructor(_Tp)>
186 { };
187
939759fc 188 /// has_trivial_copy_constructor
e133ace8
PC
189 template<typename _Tp>
190 struct has_trivial_copy_constructor
191 : public integral_constant<bool, __has_trivial_copy(_Tp)>
192 { };
193
939759fc 194 /// has_trivial_assign
e133ace8
PC
195 template<typename _Tp>
196 struct has_trivial_assign
197 : public integral_constant<bool, __has_trivial_assign(_Tp)>
198 { };
199
939759fc 200 /// has_trivial_destructor
e133ace8
PC
201 template<typename _Tp>
202 struct has_trivial_destructor
203 : public integral_constant<bool, __has_trivial_destructor(_Tp)>
204 { };
205
939759fc 206 /// has_nothrow_default_destructor
e133ace8
PC
207 template<typename _Tp>
208 struct has_nothrow_default_constructor
209 : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
210 { };
211
939759fc 212 /// has_nothrow_copy_destructor
e133ace8
PC
213 template<typename _Tp>
214 struct has_nothrow_copy_constructor
215 : public integral_constant<bool, __has_nothrow_copy(_Tp)>
216 { };
217
939759fc 218 /// has_nothrow_assign
e133ace8
PC
219 template<typename _Tp>
220 struct has_nothrow_assign
221 : public integral_constant<bool, __has_nothrow_assign(_Tp)>
222 { };
223
939759fc 224 /// is_base_of
e133ace8
PC
225 template<typename _Base, typename _Derived>
226 struct is_base_of
227 : public integral_constant<bool, __is_base_of(_Base, _Derived)>
228 { };
229
4a27a739 230 // Relationships between types.
e133ace8
PC
231 template<typename _From, typename _To>
232 struct __is_convertible_simple
233 : public __sfinae_types
234 {
235 private:
236 static __one __test(_To);
237 static __two __test(...);
238 static _From __makeFrom();
239
240 public:
241 static const bool __value = sizeof(__test(__makeFrom())) == 1;
242 };
243
244 template<typename _Tp>
245 struct __is_int_or_cref
246 {
247 typedef typename remove_reference<_Tp>::type __rr_Tp;
248 static const bool __value = (is_integral<_Tp>::value
249 || (is_integral<__rr_Tp>::value
250 && is_const<__rr_Tp>::value
251 && !is_volatile<__rr_Tp>::value));
252 };
253
254 template<typename _From, typename _To,
255 bool = (is_void<_From>::value || is_void<_To>::value
256 || is_function<_To>::value || is_array<_To>::value
939759fc 257 // This special case is here only to avoid warnings.
e133ace8
PC
258 || (is_floating_point<typename
259 remove_reference<_From>::type>::value
260 && __is_int_or_cref<_To>::__value))>
261 struct __is_convertible_helper
262 {
263 // "An imaginary lvalue of type From...".
264 static const bool __value = (__is_convertible_simple<typename
6c9bfe99
CF
265 add_lvalue_reference<_From>::type,
266 _To>::__value);
e133ace8
PC
267 };
268
269 template<typename _From, typename _To>
270 struct __is_convertible_helper<_From, _To, true>
271 { static const bool __value = (is_void<_To>::value
272 || (__is_int_or_cref<_To>::__value
273 && !is_void<_From>::value)); };
274
4a27a739
PC
275 // XXX FIXME
276 // The C++0x specifications are different, see N2255.
939759fc 277 /// is_convertible
e133ace8
PC
278 template<typename _From, typename _To>
279 struct is_convertible
280 : public integral_constant<bool,
281 __is_convertible_helper<_From, _To>::__value>
282 { };
283
fd735b6a
PC
284 template<std::size_t _Len>
285 struct __aligned_storage_msa
286 {
287 union __type
288 {
289 unsigned char __data[_Len];
290 struct __attribute__((__aligned__)) { } __align;
291 };
292 };
293
939759fc
BK
294 /**
295 * @brief Alignment type.
296 *
297 * The value of _Align is a default-alignment which shall be the
298 * most stringent alignment requirement for any C++ object type
299 * whose size is no greater than _Len (3.9). The member typedef
300 * type shall be a POD type suitable for use as uninitialized
301 * storage for any object whose size is at most _Len and whose
302 * alignment is a divisor of _Align.
303 */
fd735b6a
PC
304 template<std::size_t _Len, std::size_t _Align =
305 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
306 struct aligned_storage
307 {
308 union type
309 {
310 unsigned char __data[_Len];
311 struct __attribute__((__aligned__((_Align)))) { } __align;
312 };
313 };
314
7b50cdef
BK
315
316 // Define a nested type if some predicate holds.
939759fc 317 /// Primary template.
7b50cdef
BK
318 template<bool, typename _Tp = void>
319 struct enable_if
320 { };
321
939759fc 322 /// Partial specialization for true.
7b50cdef
BK
323 template<typename _Tp>
324 struct enable_if<true, _Tp>
325 { typedef _Tp type; };
326
327
939759fc
BK
328 // A conditional expression, but for types.
329 // If true, first, if false, second.
330 /// Primary template.
7b50cdef
BK
331 template<bool _Cond, typename _Iftrue, typename _Iffalse>
332 struct conditional
333 { typedef _Iftrue type; };
334
939759fc 335 /// Partial specialization for false.
7b50cdef
BK
336 template<typename _Iftrue, typename _Iffalse>
337 struct conditional<false, _Iftrue, _Iffalse>
338 { typedef _Iffalse type; };
339
340
341 // Decay trait for arrays and functions, used for perfect forwarding
342 // in make_pair, make_tuple, etc.
343 template<typename _Up,
344 bool _IsArray = is_array<_Up>::value,
345 bool _IsFunction = is_function<_Up>::value>
346 struct __decay_selector;
347
ce796131 348 // NB: DR 705.
7b50cdef
BK
349 template<typename _Up>
350 struct __decay_selector<_Up, false, false>
ce796131 351 { typedef typename remove_cv<_Up>::type __type; };
7b50cdef
BK
352
353 template<typename _Up>
354 struct __decay_selector<_Up, true, false>
355 { typedef typename remove_extent<_Up>::type* __type; };
356
7b50cdef
BK
357 template<typename _Up>
358 struct __decay_selector<_Up, false, true>
359 { typedef typename add_pointer<_Up>::type __type; };
360
939759fc 361 /// decay
7b50cdef 362 template<typename _Tp>
ce796131 363 struct decay
7b50cdef
BK
364 {
365 private:
366 typedef typename remove_reference<_Tp>::type __remove_type;
367
368 public:
369 typedef typename __decay_selector<__remove_type>::__type type;
370 };
371
372
373 // Utility for constructing identically cv-qualified types.
374 template<typename _Unqualified, bool _IsConst, bool _IsVol>
375 struct __cv_selector;
376
377 template<typename _Unqualified>
378 struct __cv_selector<_Unqualified, false, false>
379 { typedef _Unqualified __type; };
380
381 template<typename _Unqualified>
382 struct __cv_selector<_Unqualified, false, true>
383 { typedef volatile _Unqualified __type; };
384
385 template<typename _Unqualified>
386 struct __cv_selector<_Unqualified, true, false>
387 { typedef const _Unqualified __type; };
388
389 template<typename _Unqualified>
390 struct __cv_selector<_Unqualified, true, true>
391 { typedef const volatile _Unqualified __type; };
392
393 template<typename _Qualified, typename _Unqualified,
394 bool _IsConst = is_const<_Qualified>::value,
395 bool _IsVol = is_volatile<_Qualified>::value>
396 struct __match_cv_qualifiers
397 {
398 private:
399 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
400
401 public:
402 typedef typename __match::__type __type;
403 };
404
405
406 // Utility for finding the unsigned versions of signed integral types.
407 template<typename _Tp>
e133ace8
PC
408 struct __make_unsigned
409 { typedef _Tp __type; };
7b50cdef
BK
410
411 template<>
412 struct __make_unsigned<char>
413 { typedef unsigned char __type; };
414
415 template<>
416 struct __make_unsigned<signed char>
417 { typedef unsigned char __type; };
418
7b50cdef
BK
419 template<>
420 struct __make_unsigned<short>
421 { typedef unsigned short __type; };
422
423 template<>
424 struct __make_unsigned<int>
425 { typedef unsigned int __type; };
426
427 template<>
428 struct __make_unsigned<long>
429 { typedef unsigned long __type; };
430
431 template<>
432 struct __make_unsigned<long long>
433 { typedef unsigned long long __type; };
434
435
436 // Select between integral and enum: not possible to be both.
437 template<typename _Tp,
438 bool _IsInt = is_integral<_Tp>::value,
7b50cdef
BK
439 bool _IsEnum = is_enum<_Tp>::value>
440 struct __make_unsigned_selector;
441
442 template<typename _Tp>
e133ace8 443 struct __make_unsigned_selector<_Tp, true, false>
7b50cdef
BK
444 {
445 private:
446 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
447 typedef typename __unsignedt::__type __unsigned_type;
448 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
449
450 public:
451 typedef typename __cv_unsigned::__type __type;
452 };
453
7b50cdef 454 template<typename _Tp>
e133ace8 455 struct __make_unsigned_selector<_Tp, false, true>
7b50cdef
BK
456 {
457 private:
ce2e6349
BK
458 // GNU enums start with sizeof short.
459 typedef unsigned short __smallest;
460 static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
461 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
462 typedef conditional<__b2, unsigned int, unsigned long> __cond;
7b50cdef 463 typedef typename __cond::type __cond_type;
7b50cdef
BK
464
465 public:
ce2e6349 466 typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
7b50cdef
BK
467 };
468
7b50cdef
BK
469 // Given an integral/enum type, return the corresponding unsigned
470 // integer type.
939759fc 471 /// Primary template.
7b50cdef
BK
472 template<typename _Tp>
473 struct make_unsigned
474 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
475
476 // Integral, but don't define.
477 template<>
478 struct make_unsigned<bool>;
479
480
481 // Utility for finding the signed versions of unsigned integral types.
482 template<typename _Tp>
e133ace8
PC
483 struct __make_signed
484 { typedef _Tp __type; };
7b50cdef
BK
485
486 template<>
487 struct __make_signed<char>
488 { typedef signed char __type; };
489
490 template<>
491 struct __make_signed<unsigned char>
492 { typedef signed char __type; };
493
7b50cdef
BK
494 template<>
495 struct __make_signed<unsigned short>
496 { typedef signed short __type; };
497
498 template<>
499 struct __make_signed<unsigned int>
500 { typedef signed int __type; };
501
502 template<>
503 struct __make_signed<unsigned long>
504 { typedef signed long __type; };
505
506 template<>
507 struct __make_signed<unsigned long long>
508 { typedef signed long long __type; };
509
510
fb8ffd10 511 // Select between integral and enum: not possible to be both.
7b50cdef
BK
512 template<typename _Tp,
513 bool _IsInt = is_integral<_Tp>::value,
7b50cdef
BK
514 bool _IsEnum = is_enum<_Tp>::value>
515 struct __make_signed_selector;
516
517 template<typename _Tp>
e133ace8 518 struct __make_signed_selector<_Tp, true, false>
7b50cdef
BK
519 {
520 private:
521 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
522 typedef typename __signedt::__type __signed_type;
523 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
524
525 public:
526 typedef typename __cv_signed::__type __type;
527 };
528
7b50cdef 529 template<typename _Tp>
e133ace8 530 struct __make_signed_selector<_Tp, false, true>
7b50cdef
BK
531 {
532 private:
ce2e6349
BK
533 // GNU enums start with sizeof short.
534 typedef signed short __smallest;
535 static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
536 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
537 typedef conditional<__b2, signed int, signed long> __cond;
7b50cdef 538 typedef typename __cond::type __cond_type;
7b50cdef
BK
539
540 public:
ce2e6349 541 typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
7b50cdef
BK
542 };
543
7b50cdef
BK
544 // Given an integral/enum type, return the corresponding signed
545 // integer type.
939759fc 546 /// Primary template.
7b50cdef
BK
547 template<typename _Tp>
548 struct make_signed
549 { typedef typename __make_signed_selector<_Tp>::__type type; };
550
551 // Integral, but don't define.
552 template<>
553 struct make_signed<bool>;
e133ace8 554}
7b50cdef 555
e133ace8 556#endif // _GLIBCXX_CXX0X_TYPE_TRAITS
af13a7a6 557