]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/type_traits
m32c.c (m32c_compare_redundant): Avoid removing compares that may be indirectly affec...
[thirdparty/gcc.git] / libstdc++-v3 / include / std / type_traits
CommitLineData
5b9daa7e 1// C++0x type_traits -*- C++ -*-
af13a7a6 2
5b9daa7e 3// Copyright (C) 2007, 2008, 2009 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
748086b7 8// Free Software Foundation; either version 3, or (at your option)
af13a7a6
BK
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
748086b7
JJ
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
af13a7a6
BK
24
25/** @file include/type_traits
26 * This is a Standard C++ Library header.
27 */
28
4514bed6
BK
29#ifndef _GLIBCXX_TYPE_TRAITS
30#define _GLIBCXX_TYPE_TRAITS 1
af13a7a6
BK
31
32#pragma GCC system_header
33
57317d2a 34#ifndef __GXX_EXPERIMENTAL_CXX0X__
af13a7a6 35# include <c++0x_warning.h>
57317d2a 36#else
af13a7a6 37
e133ace8
PC
38#if defined(_GLIBCXX_INCLUDE_AS_TR1)
39# error C++0x header cannot be included from TR1 header
40#endif
41
42#include <cstddef>
43
44#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
45# include <tr1_impl/type_traits>
46#else
47# define _GLIBCXX_INCLUDE_AS_CXX0X
48# define _GLIBCXX_BEGIN_NAMESPACE_TR1
49# define _GLIBCXX_END_NAMESPACE_TR1
50# define _GLIBCXX_TR1
51# include <tr1_impl/type_traits>
52# undef _GLIBCXX_TR1
53# undef _GLIBCXX_END_NAMESPACE_TR1
54# undef _GLIBCXX_BEGIN_NAMESPACE_TR1
55# undef _GLIBCXX_INCLUDE_AS_CXX0X
56#endif
57
58namespace std
59{
5b9daa7e
BK
60 /** @addtogroup metaprogramming
61 * @{
62 */
63
4a27a739 64 // Primary classification traits.
939759fc
BK
65
66 /// is_lvalue_reference
4a27a739
PC
67 template<typename>
68 struct is_lvalue_reference
69 : public false_type { };
70
71 template<typename _Tp>
72 struct is_lvalue_reference<_Tp&>
73 : public true_type { };
74
939759fc 75 /// is_rvalue_reference
4a27a739
PC
76 template<typename>
77 struct is_rvalue_reference
78 : public false_type { };
79
80 template<typename _Tp>
81 struct is_rvalue_reference<_Tp&&>
82 : public true_type { };
83
84 // Secondary classification traits.
939759fc
BK
85
86 /// is_reference
4a27a739
PC
87 template<typename _Tp>
88 struct is_reference
89 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
90 || is_rvalue_reference<_Tp>::value)>
91 { };
92
93 // Reference transformations.
939759fc
BK
94
95 /// remove_reference
4a27a739
PC
96 template<typename _Tp>
97 struct remove_reference
98 { typedef _Tp type; };
99
100 template<typename _Tp>
101 struct remove_reference<_Tp&>
102 { typedef _Tp type; };
103
104 template<typename _Tp>
105 struct remove_reference<_Tp&&>
106 { typedef _Tp type; };
107
108 template<typename _Tp,
58366b08 109 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
4a27a739
PC
110 bool = is_rvalue_reference<_Tp>::value>
111 struct __add_lvalue_reference_helper
112 { typedef _Tp type; };
113
114 template<typename _Tp>
115 struct __add_lvalue_reference_helper<_Tp, true, false>
116 { typedef _Tp& type; };
117
118 template<typename _Tp>
119 struct __add_lvalue_reference_helper<_Tp, false, true>
120 { typedef typename remove_reference<_Tp>::type& type; };
121
939759fc 122 /// add_lvalue_reference
4a27a739
PC
123 template<typename _Tp>
124 struct add_lvalue_reference
125 : public __add_lvalue_reference_helper<_Tp>
126 { };
127
128 template<typename _Tp,
58366b08 129 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
4a27a739
PC
130 struct __add_rvalue_reference_helper
131 { typedef _Tp type; };
132
133 template<typename _Tp>
134 struct __add_rvalue_reference_helper<_Tp, true>
135 { typedef _Tp&& type; };
136
939759fc 137 /// add_rvalue_reference
4a27a739
PC
138 template<typename _Tp>
139 struct add_rvalue_reference
140 : public __add_rvalue_reference_helper<_Tp>
141 { };
142
143 // Scalar properties and transformations.
939759fc 144
e133ace8
PC
145 template<typename _Tp,
146 bool = is_integral<_Tp>::value,
147 bool = is_floating_point<_Tp>::value>
148 struct __is_signed_helper
149 : public false_type { };
150
151 template<typename _Tp>
152 struct __is_signed_helper<_Tp, false, true>
153 : public true_type { };
154
155 template<typename _Tp>
156 struct __is_signed_helper<_Tp, true, false>
157 : public integral_constant<bool, _Tp(-1) < _Tp(0)>
158 { };
159
939759fc 160 /// is_signed
e133ace8
PC
161 template<typename _Tp>
162 struct is_signed
163 : public integral_constant<bool, __is_signed_helper<_Tp>::value>
164 { };
165
939759fc 166 /// is_unsigned
e133ace8
PC
167 template<typename _Tp>
168 struct is_unsigned
169 : public integral_constant<bool, (is_arithmetic<_Tp>::value
170 && !is_signed<_Tp>::value)>
171 { };
172
4a27a739 173 // Member introspection.
939759fc
BK
174
175 /// is_pod
e133ace8
PC
176 template<typename _Tp>
177 struct is_pod
178 : public integral_constant<bool, __is_pod(_Tp)>
179 { };
180
939759fc 181 /// has_trivial_default_constructor
e133ace8
PC
182 template<typename _Tp>
183 struct has_trivial_default_constructor
184 : public integral_constant<bool, __has_trivial_constructor(_Tp)>
185 { };
186
939759fc 187 /// has_trivial_copy_constructor
e133ace8
PC
188 template<typename _Tp>
189 struct has_trivial_copy_constructor
190 : public integral_constant<bool, __has_trivial_copy(_Tp)>
191 { };
192
939759fc 193 /// has_trivial_assign
e133ace8
PC
194 template<typename _Tp>
195 struct has_trivial_assign
196 : public integral_constant<bool, __has_trivial_assign(_Tp)>
197 { };
198
939759fc 199 /// has_trivial_destructor
e133ace8
PC
200 template<typename _Tp>
201 struct has_trivial_destructor
202 : public integral_constant<bool, __has_trivial_destructor(_Tp)>
203 { };
204
a7543cfd 205 /// has_nothrow_default_constructor
e133ace8
PC
206 template<typename _Tp>
207 struct has_nothrow_default_constructor
208 : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
209 { };
210
a7543cfd 211 /// has_nothrow_copy_constructor
e133ace8
PC
212 template<typename _Tp>
213 struct has_nothrow_copy_constructor
214 : public integral_constant<bool, __has_nothrow_copy(_Tp)>
215 { };
216
939759fc 217 /// has_nothrow_assign
e133ace8
PC
218 template<typename _Tp>
219 struct has_nothrow_assign
220 : public integral_constant<bool, __has_nothrow_assign(_Tp)>
221 { };
222
939759fc 223 /// is_base_of
e133ace8
PC
224 template<typename _Base, typename _Derived>
225 struct is_base_of
226 : public integral_constant<bool, __is_base_of(_Base, _Derived)>
227 { };
228
4a27a739 229 // Relationships between types.
e133ace8
PC
230 template<typename _From, typename _To>
231 struct __is_convertible_simple
232 : public __sfinae_types
233 {
234 private:
235 static __one __test(_To);
236 static __two __test(...);
237 static _From __makeFrom();
238
239 public:
240 static const bool __value = sizeof(__test(__makeFrom())) == 1;
241 };
242
243 template<typename _Tp>
244 struct __is_int_or_cref
245 {
246 typedef typename remove_reference<_Tp>::type __rr_Tp;
247 static const bool __value = (is_integral<_Tp>::value
248 || (is_integral<__rr_Tp>::value
249 && is_const<__rr_Tp>::value
250 && !is_volatile<__rr_Tp>::value));
251 };
252
253 template<typename _From, typename _To,
254 bool = (is_void<_From>::value || is_void<_To>::value
255 || is_function<_To>::value || is_array<_To>::value
939759fc 256 // This special case is here only to avoid warnings.
e133ace8
PC
257 || (is_floating_point<typename
258 remove_reference<_From>::type>::value
259 && __is_int_or_cref<_To>::__value))>
260 struct __is_convertible_helper
261 {
262 // "An imaginary lvalue of type From...".
263 static const bool __value = (__is_convertible_simple<typename
6c9bfe99
CF
264 add_lvalue_reference<_From>::type,
265 _To>::__value);
e133ace8
PC
266 };
267
268 template<typename _From, typename _To>
269 struct __is_convertible_helper<_From, _To, true>
270 { static const bool __value = (is_void<_To>::value
271 || (__is_int_or_cref<_To>::__value
272 && !is_void<_From>::value)); };
273
4a27a739
PC
274 // XXX FIXME
275 // The C++0x specifications are different, see N2255.
939759fc 276 /// is_convertible
e133ace8
PC
277 template<typename _From, typename _To>
278 struct is_convertible
279 : public integral_constant<bool,
280 __is_convertible_helper<_From, _To>::__value>
281 { };
282
fd735b6a
PC
283 template<std::size_t _Len>
284 struct __aligned_storage_msa
285 {
286 union __type
287 {
288 unsigned char __data[_Len];
289 struct __attribute__((__aligned__)) { } __align;
290 };
291 };
292
939759fc
BK
293 /**
294 * @brief Alignment type.
295 *
296 * The value of _Align is a default-alignment which shall be the
297 * most stringent alignment requirement for any C++ object type
298 * whose size is no greater than _Len (3.9). The member typedef
299 * type shall be a POD type suitable for use as uninitialized
300 * storage for any object whose size is at most _Len and whose
301 * alignment is a divisor of _Align.
302 */
fd735b6a
PC
303 template<std::size_t _Len, std::size_t _Align =
304 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
305 struct aligned_storage
306 {
307 union type
308 {
309 unsigned char __data[_Len];
310 struct __attribute__((__aligned__((_Align)))) { } __align;
311 };
312 };
313
7b50cdef
BK
314
315 // Define a nested type if some predicate holds.
5b9daa7e
BK
316 // Primary template.
317 /// enable_if
7b50cdef
BK
318 template<bool, typename _Tp = void>
319 struct enable_if
320 { };
321
5b9daa7e 322 // Partial specialization for true.
7b50cdef
BK
323 template<typename _Tp>
324 struct enable_if<true, _Tp>
325 { typedef _Tp type; };
326
327
5b9daa7e
BK
328 // A conditional expression, but for types. If true, first, if false, second.
329 // Primary template.
330 /// conditional
7b50cdef
BK
331 template<bool _Cond, typename _Iftrue, typename _Iffalse>
332 struct conditional
333 { typedef _Iftrue type; };
334
5b9daa7e 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:
a0230468
MM
458 // With -fshort-enums, an enum may be as small as a char.
459 typedef unsigned char __smallest;
460 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
461 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
ce2e6349 462 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
a0230468
MM
463 typedef conditional<__b2, unsigned int, unsigned long> __cond2;
464 typedef typename __cond2::type __cond2_type;
465 typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
466 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
467
468 public:
a0230468 469 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
470 };
471
7b50cdef
BK
472 // Given an integral/enum type, return the corresponding unsigned
473 // integer type.
5b9daa7e
BK
474 // Primary template.
475 /// make_unsigned
7b50cdef
BK
476 template<typename _Tp>
477 struct make_unsigned
478 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
479
480 // Integral, but don't define.
481 template<>
482 struct make_unsigned<bool>;
483
484
485 // Utility for finding the signed versions of unsigned integral types.
486 template<typename _Tp>
e133ace8
PC
487 struct __make_signed
488 { typedef _Tp __type; };
7b50cdef
BK
489
490 template<>
491 struct __make_signed<char>
492 { typedef signed char __type; };
493
494 template<>
495 struct __make_signed<unsigned char>
496 { typedef signed char __type; };
497
7b50cdef
BK
498 template<>
499 struct __make_signed<unsigned short>
500 { typedef signed short __type; };
501
502 template<>
503 struct __make_signed<unsigned int>
504 { typedef signed int __type; };
505
506 template<>
507 struct __make_signed<unsigned long>
508 { typedef signed long __type; };
509
510 template<>
511 struct __make_signed<unsigned long long>
512 { typedef signed long long __type; };
513
514
fb8ffd10 515 // Select between integral and enum: not possible to be both.
7b50cdef
BK
516 template<typename _Tp,
517 bool _IsInt = is_integral<_Tp>::value,
7b50cdef
BK
518 bool _IsEnum = is_enum<_Tp>::value>
519 struct __make_signed_selector;
520
521 template<typename _Tp>
e133ace8 522 struct __make_signed_selector<_Tp, true, false>
7b50cdef
BK
523 {
524 private:
525 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
526 typedef typename __signedt::__type __signed_type;
527 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
528
529 public:
530 typedef typename __cv_signed::__type __type;
531 };
532
7b50cdef 533 template<typename _Tp>
e133ace8 534 struct __make_signed_selector<_Tp, false, true>
7b50cdef
BK
535 {
536 private:
a0230468
MM
537 // With -fshort-enums, an enum may be as small as a char.
538 typedef signed char __smallest;
539 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
540 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
ce2e6349 541 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
a0230468
MM
542 typedef conditional<__b2, signed int, signed long> __cond2;
543 typedef typename __cond2::type __cond2_type;
544 typedef conditional<__b1, signed short, __cond2_type> __cond1;
545 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
546
547 public:
a0230468 548 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
549 };
550
7b50cdef
BK
551 // Given an integral/enum type, return the corresponding signed
552 // integer type.
5b9daa7e
BK
553 // Primary template.
554 /// make_signed
7b50cdef
BK
555 template<typename _Tp>
556 struct make_signed
557 { typedef typename __make_signed_selector<_Tp>::__type type; };
558
559 // Integral, but don't define.
560 template<>
561 struct make_signed<bool>;
cfa9a96b 562
5b9daa7e 563 /// common_type
cfa9a96b
CF
564 template<typename... _Tp>
565 struct common_type;
566
567 template<typename _Tp>
568 struct common_type<_Tp>
569 {
570 static_assert(sizeof(_Tp) > 0, "must be complete type");
571 typedef _Tp type;
572 };
573
574 template<typename _Tp, typename _Up>
575 class common_type<_Tp, _Up>
576 {
577 static_assert(sizeof(_Tp) > 0, "must be complete type");
578 static_assert(sizeof(_Up) > 0, "must be complete type");
579
580 static _Tp&& __t();
581 static _Up&& __u();
582
cfa9a96b 583 public:
026ec377 584 typedef decltype(true ? __t() : __u()) type;
cfa9a96b
CF
585 };
586
587 template<typename _Tp, typename _Up, typename... _Vp>
588 struct common_type<_Tp, _Up, _Vp...>
589 {
590 typedef typename
591 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
592 };
5b9daa7e
BK
593
594 // @} group metaprogramming
e133ace8 595}
7b50cdef 596
57317d2a
PC
597#endif // __GXX_EXPERIMENTAL_CXX0X__
598
4514bed6 599#endif // _GLIBCXX_TYPE_TRAITS
af13a7a6 600