]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/type_traits
re PR fortran/44044 ([OOP] SELECT TYPE with class-valued function)
[thirdparty/gcc.git] / libstdc++-v3 / include / std / type_traits
CommitLineData
5b9daa7e 1// C++0x type_traits -*- C++ -*-
af13a7a6 2
ab65a4c7 3// Copyright (C) 2007, 2008, 2009, 2010 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__
ab65a4c7 35# include <bits/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{
8e32aa11
BK
60 /**
61 * @addtogroup metaprogramming
5b9daa7e
BK
62 * @{
63 */
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,
58366b08 110 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
4a27a739
PC
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,
58366b08 130 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
4a27a739
PC
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>
8e32aa11 158 : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))>
e133ace8
PC
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 175
b0302c68
PC
176 /// is_trivial
177 template<typename _Tp>
178 struct is_trivial
179 : public integral_constant<bool, __is_trivial(_Tp)>
180 { };
181
182 /// is_standard_layout
183 template<typename _Tp>
184 struct is_standard_layout
185 : public integral_constant<bool, __is_standard_layout(_Tp)>
186 { };
187
939759fc 188 /// is_pod
c32097d8 189 // Could use is_standard_layout && is_trivial instead of the builtin.
e133ace8
PC
190 template<typename _Tp>
191 struct is_pod
192 : public integral_constant<bool, __is_pod(_Tp)>
193 { };
194
c32097d8 195 template<typename _Tp>
b0302c68
PC
196 typename add_rvalue_reference<_Tp>::type declval();
197
198 template<typename _Tp, typename... _Args>
199 class __is_constructible_helper
200 : public __sfinae_types
201 {
4b3d7a7e
PC
202 template<typename _Tp1, typename... _Args1>
203 static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
b0302c68
PC
204
205 template<typename, typename...>
206 static __two __test(...);
207
208 public:
209 static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
210 };
211
212 template<typename _Tp, typename _Arg>
213 class __is_constructible_helper<_Tp, _Arg>
214 : public __sfinae_types
215 {
216 template<typename _Tp1, typename _Arg1>
217 static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
218 __test(int);
219
220 template<typename, typename>
221 static __two __test(...);
222
223 public:
224 static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
225 };
226
227 /// is_constructible
228 // XXX FIXME
229 // The C++0x specifications require front-end support, see N2255.
230 template<typename _Tp, typename... _Args>
231 struct is_constructible
232 : public integral_constant<bool,
233 __is_constructible_helper<_Tp,
234 _Args...>::__value>
c32097d8
JM
235 { };
236
939759fc 237 /// has_trivial_default_constructor
e133ace8
PC
238 template<typename _Tp>
239 struct has_trivial_default_constructor
240 : public integral_constant<bool, __has_trivial_constructor(_Tp)>
241 { };
242
939759fc 243 /// has_trivial_copy_constructor
e133ace8
PC
244 template<typename _Tp>
245 struct has_trivial_copy_constructor
246 : public integral_constant<bool, __has_trivial_copy(_Tp)>
247 { };
248
939759fc 249 /// has_trivial_assign
e133ace8
PC
250 template<typename _Tp>
251 struct has_trivial_assign
252 : public integral_constant<bool, __has_trivial_assign(_Tp)>
253 { };
254
939759fc 255 /// has_trivial_destructor
e133ace8
PC
256 template<typename _Tp>
257 struct has_trivial_destructor
258 : public integral_constant<bool, __has_trivial_destructor(_Tp)>
259 { };
260
a7543cfd 261 /// has_nothrow_default_constructor
e133ace8
PC
262 template<typename _Tp>
263 struct has_nothrow_default_constructor
264 : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
265 { };
266
a7543cfd 267 /// has_nothrow_copy_constructor
e133ace8
PC
268 template<typename _Tp>
269 struct has_nothrow_copy_constructor
270 : public integral_constant<bool, __has_nothrow_copy(_Tp)>
271 { };
272
939759fc 273 /// has_nothrow_assign
e133ace8
PC
274 template<typename _Tp>
275 struct has_nothrow_assign
276 : public integral_constant<bool, __has_nothrow_assign(_Tp)>
277 { };
278
b0302c68
PC
279 // Relationships between types.
280
939759fc 281 /// is_base_of
e133ace8
PC
282 template<typename _Base, typename _Derived>
283 struct is_base_of
284 : public integral_constant<bool, __is_base_of(_Base, _Derived)>
285 { };
286
297f34d7
PC
287 template<typename _From, typename _To,
288 bool = (is_void<_From>::value || is_void<_To>::value
289 || is_function<_To>::value || is_array<_To>::value)>
290 struct __is_convertible_helper
291 { static const bool __value = (is_void<_From>::value
292 && is_void<_To>::value); };
293
e133ace8 294 template<typename _From, typename _To>
b0302c68 295 class __is_convertible_helper<_From, _To, false>
e133ace8
PC
296 : public __sfinae_types
297 {
e133ace8
PC
298 static __one __test(_To);
299 static __two __test(...);
297f34d7 300
e133ace8 301 public:
7274deff 302 static const bool __value = sizeof(__test(declval<_From>())) == 1;
e133ace8
PC
303 };
304
b0302c68 305 /// is_convertible
4a27a739 306 // XXX FIXME
2d0269f6 307 // The C++0x specifications require front-end support, see N2255.
e133ace8
PC
308 template<typename _From, typename _To>
309 struct is_convertible
310 : public integral_constant<bool,
311 __is_convertible_helper<_From, _To>::__value>
312 { };
313
b0302c68 314 /// is_explicitly_convertible
75995f37
PC
315 template<typename _From, typename _To>
316 struct is_explicitly_convertible
317 : public is_constructible<_To, _From>
318 { };
319
fd735b6a
PC
320 template<std::size_t _Len>
321 struct __aligned_storage_msa
322 {
323 union __type
324 {
325 unsigned char __data[_Len];
326 struct __attribute__((__aligned__)) { } __align;
327 };
328 };
329
939759fc
BK
330 /**
331 * @brief Alignment type.
332 *
333 * The value of _Align is a default-alignment which shall be the
334 * most stringent alignment requirement for any C++ object type
335 * whose size is no greater than _Len (3.9). The member typedef
336 * type shall be a POD type suitable for use as uninitialized
337 * storage for any object whose size is at most _Len and whose
338 * alignment is a divisor of _Align.
339 */
fd735b6a
PC
340 template<std::size_t _Len, std::size_t _Align =
341 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
342 struct aligned_storage
343 {
344 union type
345 {
346 unsigned char __data[_Len];
347 struct __attribute__((__aligned__((_Align)))) { } __align;
348 };
349 };
350
7b50cdef
BK
351
352 // Define a nested type if some predicate holds.
5b9daa7e
BK
353 // Primary template.
354 /// enable_if
7b50cdef
BK
355 template<bool, typename _Tp = void>
356 struct enable_if
357 { };
358
5b9daa7e 359 // Partial specialization for true.
7b50cdef
BK
360 template<typename _Tp>
361 struct enable_if<true, _Tp>
362 { typedef _Tp type; };
363
364
5b9daa7e
BK
365 // A conditional expression, but for types. If true, first, if false, second.
366 // Primary template.
367 /// conditional
7b50cdef
BK
368 template<bool _Cond, typename _Iftrue, typename _Iffalse>
369 struct conditional
370 { typedef _Iftrue type; };
371
5b9daa7e 372 // Partial specialization for false.
7b50cdef
BK
373 template<typename _Iftrue, typename _Iffalse>
374 struct conditional<false, _Iftrue, _Iffalse>
375 { typedef _Iffalse type; };
376
377
378 // Decay trait for arrays and functions, used for perfect forwarding
379 // in make_pair, make_tuple, etc.
380 template<typename _Up,
381 bool _IsArray = is_array<_Up>::value,
382 bool _IsFunction = is_function<_Up>::value>
383 struct __decay_selector;
384
ce796131 385 // NB: DR 705.
7b50cdef
BK
386 template<typename _Up>
387 struct __decay_selector<_Up, false, false>
ce796131 388 { typedef typename remove_cv<_Up>::type __type; };
7b50cdef
BK
389
390 template<typename _Up>
391 struct __decay_selector<_Up, true, false>
392 { typedef typename remove_extent<_Up>::type* __type; };
393
7b50cdef
BK
394 template<typename _Up>
395 struct __decay_selector<_Up, false, true>
396 { typedef typename add_pointer<_Up>::type __type; };
397
939759fc 398 /// decay
7b50cdef 399 template<typename _Tp>
b0302c68 400 class decay
7b50cdef 401 {
7b50cdef
BK
402 typedef typename remove_reference<_Tp>::type __remove_type;
403
404 public:
405 typedef typename __decay_selector<__remove_type>::__type type;
406 };
407
5e108459
PC
408 template<typename _Tp>
409 class reference_wrapper;
410
411 // Helper which adds a reference to a type when given a reference_wrapper
412 template<typename _Tp>
413 struct __strip_reference_wrapper
414 {
415 typedef _Tp __type;
416 };
417
418 template<typename _Tp>
419 struct __strip_reference_wrapper<reference_wrapper<_Tp> >
420 {
421 typedef _Tp& __type;
422 };
423
424 template<typename _Tp>
425 struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
426 {
427 typedef _Tp& __type;
428 };
429
430 template<typename _Tp>
431 struct __decay_and_strip
432 {
433 typedef typename __strip_reference_wrapper<
434 typename decay<_Tp>::type>::__type __type;
435 };
436
7b50cdef
BK
437
438 // Utility for constructing identically cv-qualified types.
439 template<typename _Unqualified, bool _IsConst, bool _IsVol>
440 struct __cv_selector;
441
442 template<typename _Unqualified>
443 struct __cv_selector<_Unqualified, false, false>
444 { typedef _Unqualified __type; };
445
446 template<typename _Unqualified>
447 struct __cv_selector<_Unqualified, false, true>
448 { typedef volatile _Unqualified __type; };
449
450 template<typename _Unqualified>
451 struct __cv_selector<_Unqualified, true, false>
452 { typedef const _Unqualified __type; };
453
454 template<typename _Unqualified>
455 struct __cv_selector<_Unqualified, true, true>
456 { typedef const volatile _Unqualified __type; };
457
458 template<typename _Qualified, typename _Unqualified,
459 bool _IsConst = is_const<_Qualified>::value,
460 bool _IsVol = is_volatile<_Qualified>::value>
b0302c68 461 class __match_cv_qualifiers
7b50cdef 462 {
7b50cdef
BK
463 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
464
465 public:
466 typedef typename __match::__type __type;
467 };
468
469
470 // Utility for finding the unsigned versions of signed integral types.
471 template<typename _Tp>
e133ace8
PC
472 struct __make_unsigned
473 { typedef _Tp __type; };
7b50cdef
BK
474
475 template<>
476 struct __make_unsigned<char>
477 { typedef unsigned char __type; };
478
479 template<>
480 struct __make_unsigned<signed char>
481 { typedef unsigned char __type; };
482
7b50cdef
BK
483 template<>
484 struct __make_unsigned<short>
485 { typedef unsigned short __type; };
486
487 template<>
488 struct __make_unsigned<int>
489 { typedef unsigned int __type; };
490
491 template<>
492 struct __make_unsigned<long>
493 { typedef unsigned long __type; };
494
495 template<>
496 struct __make_unsigned<long long>
497 { typedef unsigned long long __type; };
498
499
500 // Select between integral and enum: not possible to be both.
501 template<typename _Tp,
502 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 503 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
504 class __make_unsigned_selector;
505
7b50cdef 506 template<typename _Tp>
b0302c68 507 class __make_unsigned_selector<_Tp, true, false>
7b50cdef 508 {
7b50cdef
BK
509 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
510 typedef typename __unsignedt::__type __unsigned_type;
511 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
512
513 public:
514 typedef typename __cv_unsigned::__type __type;
515 };
516
7b50cdef 517 template<typename _Tp>
b0302c68 518 class __make_unsigned_selector<_Tp, false, true>
7b50cdef 519 {
a0230468
MM
520 // With -fshort-enums, an enum may be as small as a char.
521 typedef unsigned char __smallest;
522 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
523 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
ce2e6349 524 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
a0230468
MM
525 typedef conditional<__b2, unsigned int, unsigned long> __cond2;
526 typedef typename __cond2::type __cond2_type;
527 typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
528 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
529
530 public:
a0230468 531 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
532 };
533
7b50cdef
BK
534 // Given an integral/enum type, return the corresponding unsigned
535 // integer type.
5b9daa7e
BK
536 // Primary template.
537 /// make_unsigned
7b50cdef
BK
538 template<typename _Tp>
539 struct make_unsigned
540 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
541
542 // Integral, but don't define.
543 template<>
544 struct make_unsigned<bool>;
545
546
547 // Utility for finding the signed versions of unsigned integral types.
548 template<typename _Tp>
e133ace8
PC
549 struct __make_signed
550 { typedef _Tp __type; };
7b50cdef
BK
551
552 template<>
553 struct __make_signed<char>
554 { typedef signed char __type; };
555
556 template<>
557 struct __make_signed<unsigned char>
558 { typedef signed char __type; };
559
7b50cdef
BK
560 template<>
561 struct __make_signed<unsigned short>
562 { typedef signed short __type; };
563
564 template<>
565 struct __make_signed<unsigned int>
566 { typedef signed int __type; };
567
568 template<>
569 struct __make_signed<unsigned long>
570 { typedef signed long __type; };
571
572 template<>
573 struct __make_signed<unsigned long long>
574 { typedef signed long long __type; };
575
576
fb8ffd10 577 // Select between integral and enum: not possible to be both.
7b50cdef
BK
578 template<typename _Tp,
579 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 580 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
581 class __make_signed_selector;
582
7b50cdef 583 template<typename _Tp>
b0302c68 584 class __make_signed_selector<_Tp, true, false>
7b50cdef 585 {
7b50cdef
BK
586 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
587 typedef typename __signedt::__type __signed_type;
588 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
589
590 public:
591 typedef typename __cv_signed::__type __type;
592 };
593
7b50cdef 594 template<typename _Tp>
b0302c68 595 class __make_signed_selector<_Tp, false, true>
7b50cdef 596 {
a0230468
MM
597 // With -fshort-enums, an enum may be as small as a char.
598 typedef signed char __smallest;
599 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
600 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
ce2e6349 601 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
a0230468
MM
602 typedef conditional<__b2, signed int, signed long> __cond2;
603 typedef typename __cond2::type __cond2_type;
604 typedef conditional<__b1, signed short, __cond2_type> __cond1;
605 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
606
607 public:
a0230468 608 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
609 };
610
7b50cdef
BK
611 // Given an integral/enum type, return the corresponding signed
612 // integer type.
5b9daa7e
BK
613 // Primary template.
614 /// make_signed
7b50cdef
BK
615 template<typename _Tp>
616 struct make_signed
617 { typedef typename __make_signed_selector<_Tp>::__type type; };
618
619 // Integral, but don't define.
620 template<>
621 struct make_signed<bool>;
cfa9a96b 622
5b9daa7e 623 /// common_type
cfa9a96b
CF
624 template<typename... _Tp>
625 struct common_type;
626
627 template<typename _Tp>
628 struct common_type<_Tp>
7274deff 629 { typedef _Tp type; };
cfa9a96b
CF
630
631 template<typename _Tp, typename _Up>
7274deff
PC
632 struct common_type<_Tp, _Up>
633 { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
cfa9a96b
CF
634
635 template<typename _Tp, typename _Up, typename... _Vp>
636 struct common_type<_Tp, _Up, _Vp...>
637 {
638 typedef typename
639 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
640 };
5b9daa7e 641 // @} group metaprogramming
7274deff
PC
642
643 /// declval
644 template<typename _Tp>
645 struct __declval_protector
646 {
647 static const bool __stop = false;
648 static typename add_rvalue_reference<_Tp>::type __delegate();
649 };
650
651 template<typename _Tp>
652 inline typename add_rvalue_reference<_Tp>::type
653 declval()
654 {
655 static_assert(__declval_protector<_Tp>::__stop,
656 "declval() must not be used!");
657 return __declval_protector<_Tp>::__delegate();
658 }
e133ace8 659}
7b50cdef 660
57317d2a
PC
661#endif // __GXX_EXPERIMENTAL_CXX0X__
662
7274deff 663#endif // _GLIBCXX_TYPE_TRAITS