1// TR1 type_traits -*- C++ -*-
2
3// Copyright (C) 2004-2022 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 3, 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// 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/>.
24
25/** @file tr1/type_traits
26 *  This is a TR1 C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TR1_TYPE_TRAITS
30#define _GLIBCXX_TR1_TYPE_TRAITS 1
31
32#pragma GCC system_header
33
34#include <bits/c++config.h>
35
36namespace std _GLIBCXX_VISIBILITY(default)
37{
38_GLIBCXX_BEGIN_NAMESPACE_VERSION
39
40namespace tr1
41{
42  /**
43   * @addtogroup metaprogramming
44   * @{
45   */
46
47  struct __sfinae_types
48  {
49    typedef char __one;
50    typedef struct { char __arr[2]; } __two;
51  };
52
53#define _DEFINE_SPEC_0_HELPER                          \
54  template<>
55
56#define _DEFINE_SPEC_1_HELPER                          \
57  template<typename _Tp>
58
59#define _DEFINE_SPEC_2_HELPER                          \
60  template<typename _Tp, typename _Cp>
61
62#define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)    \
63  _DEFINE_SPEC_##_Order##_HELPER                       \
64    struct _Trait<_Type>                               \
65    : public integral_constant<bool, _Value> { };
66
67  // helper classes [4.3].
68
69  /// integral_constant
70  template<typename _Tp, _Tp __v>
71    struct integral_constant
72    {
73      static const _Tp                      value = __v;
74      typedef _Tp                           value_type;
75      typedef integral_constant<_Tp, __v>   type;
76    };
77
78  /// typedef for true_type
79  typedef integral_constant<bool, true>     true_type;
80
81  /// typedef for false_type
82  typedef integral_constant<bool, false>    false_type;
83
84  template<typename _Tp, _Tp __v>
85    const _Tp integral_constant<_Tp, __v>::value;
86
87  /// remove_cv
88  template<typename>
89    struct remove_cv;
90
91  template<typename>
92    struct __is_void_helper
93    : public false_type { };
94  _DEFINE_SPEC(0, __is_void_helper, void, true)
95
96  // primary type categories [4.5.1].
97
98  /// is_void
99  template<typename _Tp>
100    struct is_void
101    : public integral_constant<bool, (__is_void_helper<typename
102				      remove_cv<_Tp>::type>::value)>
103    { };
104
105  template<typename>
106    struct __is_integral_helper
107    : public false_type { };
108  _DEFINE_SPEC(0, __is_integral_helper, bool, true)
109  _DEFINE_SPEC(0, __is_integral_helper, char, true)
110  _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
111  _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
112  _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
113  _DEFINE_SPEC(0, __is_integral_helper, short, true)
114  _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
115  _DEFINE_SPEC(0, __is_integral_helper, int, true)
116  _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
117  _DEFINE_SPEC(0, __is_integral_helper, long, true)
118  _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
119  _DEFINE_SPEC(0, __is_integral_helper, long long, true)
120  _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
121
122  /// is_integral
123  template<typename _Tp>
124    struct is_integral
125    : public integral_constant<bool, (__is_integral_helper<typename
126				      remove_cv<_Tp>::type>::value)>
127    { };
128
129  template<typename>
130    struct __is_floating_point_helper
131    : public false_type { };
132  _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
133  _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
134  _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
135
136  /// is_floating_point
137  template<typename _Tp>
138    struct is_floating_point
139    : public integral_constant<bool, (__is_floating_point_helper<typename
140				      remove_cv<_Tp>::type>::value)>
141    { };
142
143  /// is_array
144  template<typename>
145    struct is_array
146    : public false_type { };
147
148  template<typename _Tp, std::size_t _Size>
149    struct is_array<_Tp[_Size]>
150    : public true_type { };
151
152  template<typename _Tp>
153    struct is_array<_Tp[]>
154    : public true_type { };
155
156  template<typename>
157    struct __is_pointer_helper
158    : public false_type { };
159  _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
160
161  /// is_pointer
162  template<typename _Tp>
163    struct is_pointer
164    : public integral_constant<bool, (__is_pointer_helper<typename
165				      remove_cv<_Tp>::type>::value)>
166    { };
167
168  /// is_reference
169  template<typename _Tp>
170    struct is_reference;
171
172  /// is_function
173  template<typename _Tp>
174    struct is_function;
175
176  template<typename>
177    struct __is_member_object_pointer_helper
178    : public false_type { };
179  _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
180	       !is_function<_Tp>::value)
181
182  /// is_member_object_pointer
183  template<typename _Tp>
184    struct is_member_object_pointer
185    : public integral_constant<bool, (__is_member_object_pointer_helper<
186				      typename remove_cv<_Tp>::type>::value)>
187    { };
188
189  template<typename>
190    struct __is_member_function_pointer_helper
191    : public false_type { };
192  _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
193	       is_function<_Tp>::value)
194
195  /// is_member_function_pointer
196  template<typename _Tp>
197    struct is_member_function_pointer
198    : public integral_constant<bool, (__is_member_function_pointer_helper<
199				      typename remove_cv<_Tp>::type>::value)>
200    { };
201
202  /// is_enum
203  template<typename _Tp>
204    struct is_enum
205    : public integral_constant<bool, __is_enum(_Tp)>
206    { };
207
208  /// is_union
209  template<typename _Tp>
210    struct is_union
211    : public integral_constant<bool, __is_union(_Tp)>
212    { };
213
214  /// is_class
215  template<typename _Tp>
216    struct is_class
217    : public integral_constant<bool, __is_class(_Tp)>
218    { };
219
220  /// is_function
221  template<typename>
222    struct is_function
223    : public false_type { };
224  template<typename _Res, typename... _ArgTypes>
225    struct is_function<_Res(_ArgTypes...)>
226    : public true_type { };
227  template<typename _Res, typename... _ArgTypes>
228    struct is_function<_Res(_ArgTypes......)>
229    : public true_type { };
230  template<typename _Res, typename... _ArgTypes>
231    struct is_function<_Res(_ArgTypes...) const>
232    : public true_type { };
233  template<typename _Res, typename... _ArgTypes>
234    struct is_function<_Res(_ArgTypes......) const>
235    : public true_type { };
236  template<typename _Res, typename... _ArgTypes>
237    struct is_function<_Res(_ArgTypes...) volatile>
238    : public true_type { };
239  template<typename _Res, typename... _ArgTypes>
240    struct is_function<_Res(_ArgTypes......) volatile>
241    : public true_type { };
242  template<typename _Res, typename... _ArgTypes>
243    struct is_function<_Res(_ArgTypes...) const volatile>
244    : public true_type { };
245  template<typename _Res, typename... _ArgTypes>
246    struct is_function<_Res(_ArgTypes......) const volatile>
247    : public true_type { };
248
249  // composite type traits [4.5.2].
250
251  /// is_arithmetic
252  template<typename _Tp>
253    struct is_arithmetic
254    : public integral_constant<bool, (is_integral<_Tp>::value
255				      || is_floating_point<_Tp>::value)>
256    { };
257
258  /// is_fundamental
259  template<typename _Tp>
260    struct is_fundamental
261    : public integral_constant<bool, (is_arithmetic<_Tp>::value
262				      || is_void<_Tp>::value)>
263    { };
264
265  /// is_object
266  template<typename _Tp>
267    struct is_object
268    : public integral_constant<bool, !(is_function<_Tp>::value
269				       || is_reference<_Tp>::value
270				       || is_void<_Tp>::value)>
271    { };
272
273  /// is_member_pointer
274  template<typename _Tp>
275    struct is_member_pointer;
276
277  /// is_scalar
278  template<typename _Tp>
279    struct is_scalar
280    : public integral_constant<bool, (is_arithmetic<_Tp>::value
281				      || is_enum<_Tp>::value
282				      || is_pointer<_Tp>::value
283				      || is_member_pointer<_Tp>::value)>
284    { };
285
286  /// is_compound
287  template<typename _Tp>
288    struct is_compound
289    : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
290
291  /// is_member_pointer
292  template<typename _Tp>
293    struct __is_member_pointer_helper
294    : public false_type { };
295  _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
296
297  template<typename _Tp>
298  struct is_member_pointer
299    : public integral_constant<bool, (__is_member_pointer_helper<
300				      typename remove_cv<_Tp>::type>::value)>
301    { };
302
303  // type properties [4.5.3].
304  /// is_const
305  template<typename>
306    struct is_const
307    : public false_type { };
308
309  template<typename _Tp>
310    struct is_const<_Tp const>
311    : public true_type { };
312
313  /// is_volatile
314  template<typename>
315    struct is_volatile
316    : public false_type { };
317
318  template<typename _Tp>
319    struct is_volatile<_Tp volatile>
320    : public true_type { };
321
322  /// is_empty
323  template<typename _Tp>
324    struct is_empty
325    : public integral_constant<bool, __is_empty(_Tp)>
326    { };
327
328  /// is_polymorphic
329  template<typename _Tp>
330    struct is_polymorphic
331    : public integral_constant<bool, __is_polymorphic(_Tp)>
332    { };
333
334  /// is_abstract
335  template<typename _Tp>
336    struct is_abstract
337    : public integral_constant<bool, __is_abstract(_Tp)>
338    { };
339
340  /// has_virtual_destructor
341  template<typename _Tp>
342    struct has_virtual_destructor
343    : public integral_constant<bool, __has_virtual_destructor(_Tp)>
344    { };
345
346  /// alignment_of
347  template<typename _Tp>
348    struct alignment_of
349    : public integral_constant<std::size_t, __alignof__(_Tp)> { };
350
351  /// rank
352  template<typename>
353    struct rank
354    : public integral_constant<std::size_t, 0> { };
355
356  template<typename _Tp, std::size_t _Size>
357    struct rank<_Tp[_Size]>
358    : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
359
360  template<typename _Tp>
361    struct rank<_Tp[]>
362    : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
363
364  /// extent
365  template<typename, unsigned _Uint = 0>
366    struct extent
367    : public integral_constant<std::size_t, 0> { };
368
369  template<typename _Tp, unsigned _Uint, std::size_t _Size>
370    struct extent<_Tp[_Size], _Uint>
371    : public integral_constant<std::size_t,
372			       _Uint == 0 ? _Size : extent<_Tp,
373							   _Uint - 1>::value>
374    { };
375
376  template<typename _Tp, unsigned _Uint>
377    struct extent<_Tp[], _Uint>
378    : public integral_constant<std::size_t,
379			       _Uint == 0 ? 0 : extent<_Tp,
380						       _Uint - 1>::value>
381    { };
382
383  // relationships between types [4.6].
384
385  /// is_same
386  template<typename, typename>
387    struct is_same
388    : public false_type { };
389
390  template<typename _Tp>
391    struct is_same<_Tp, _Tp>
392    : public true_type { };
393
394  // const-volatile modifications [4.7.1].
395
396  /// remove_const
397  template<typename _Tp>
398    struct remove_const
399    { typedef _Tp     type; };
400
401  template<typename _Tp>
402    struct remove_const<_Tp const>
403    { typedef _Tp     type; };
404
405  /// remove_volatile
406  template<typename _Tp>
407    struct remove_volatile
408    { typedef _Tp     type; };
409
410  template<typename _Tp>
411    struct remove_volatile<_Tp volatile>
412    { typedef _Tp     type; };
413
414  /// remove_cv
415  template<typename _Tp>
416    struct remove_cv
417    {
418      typedef typename
419      remove_const<typename remove_volatile<_Tp>::type>::type     type;
420    };
421
422  /// add_const
423  template<typename _Tp>
424    struct add_const
425    { typedef _Tp const     type; };
426
427  /// add_volatile
428  template<typename _Tp>
429    struct add_volatile
430    { typedef _Tp volatile     type; };
431
432  /// add_cv
433  template<typename _Tp>
434    struct add_cv
435    {
436      typedef typename
437      add_const<typename add_volatile<_Tp>::type>::type     type;
438    };
439
440  // array modifications [4.7.3].
441
442  /// remove_extent
443  template<typename _Tp>
444    struct remove_extent
445    { typedef _Tp     type; };
446
447  template<typename _Tp, std::size_t _Size>
448    struct remove_extent<_Tp[_Size]>
449    { typedef _Tp     type; };
450
451  template<typename _Tp>
452    struct remove_extent<_Tp[]>
453    { typedef _Tp     type; };
454
455  /// remove_all_extents
456  template<typename _Tp>
457    struct remove_all_extents
458    { typedef _Tp     type; };
459
460  template<typename _Tp, std::size_t _Size>
461    struct remove_all_extents<_Tp[_Size]>
462    { typedef typename remove_all_extents<_Tp>::type     type; };
463
464  template<typename _Tp>
465    struct remove_all_extents<_Tp[]>
466    { typedef typename remove_all_extents<_Tp>::type     type; };
467
468  // pointer modifications [4.7.4].
469
470  template<typename _Tp, typename>
471    struct __remove_pointer_helper
472    { typedef _Tp     type; };
473
474  template<typename _Tp, typename _Up>
475    struct __remove_pointer_helper<_Tp, _Up*>
476    { typedef _Up     type; };
477
478  /// remove_pointer
479  template<typename _Tp>
480    struct remove_pointer
481    : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
482    { };
483
484  template<typename>
485    struct remove_reference;
486
487  /// add_pointer
488  template<typename _Tp>
489    struct add_pointer
490    { typedef typename remove_reference<_Tp>::type*     type; };
491
492  template<typename>
493    struct is_reference
494    : public false_type { };
495
496  template<typename _Tp>
497    struct is_reference<_Tp&>
498    : public true_type { };
499
500  template<typename _Tp>
501    struct is_pod
502    : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
503    { };
504
505  template<typename _Tp>
506    struct has_trivial_constructor
507    : public integral_constant<bool, is_pod<_Tp>::value>
508    { };
509
510  template<typename _Tp>
511    struct has_trivial_copy
512    : public integral_constant<bool, is_pod<_Tp>::value>
513    { };
514
515  template<typename _Tp>
516    struct has_trivial_assign
517    : public integral_constant<bool, is_pod<_Tp>::value>
518    { };
519
520  template<typename _Tp>
521    struct has_trivial_destructor
522    : public integral_constant<bool, is_pod<_Tp>::value>
523    { };
524
525  template<typename _Tp>
526    struct has_nothrow_constructor
527    : public integral_constant<bool, is_pod<_Tp>::value>
528    { };
529
530  template<typename _Tp>
531    struct has_nothrow_copy
532    : public integral_constant<bool, is_pod<_Tp>::value>
533    { };
534
535  template<typename _Tp>
536    struct has_nothrow_assign
537    : public integral_constant<bool, is_pod<_Tp>::value>
538    { };
539
540  template<typename>
541    struct __is_signed_helper
542    : public false_type { };
543  _DEFINE_SPEC(0, __is_signed_helper, signed char, true)
544  _DEFINE_SPEC(0, __is_signed_helper, short, true)
545  _DEFINE_SPEC(0, __is_signed_helper, int, true)
546  _DEFINE_SPEC(0, __is_signed_helper, long, true)
547  _DEFINE_SPEC(0, __is_signed_helper, long long, true)
548
549  template<typename _Tp>
550    struct is_signed
551    : public integral_constant<bool, (__is_signed_helper<typename
552				      remove_cv<_Tp>::type>::value)>
553    { };
554
555  template<typename>
556    struct __is_unsigned_helper
557    : public false_type { };
558  _DEFINE_SPEC(0, __is_unsigned_helper, unsigned char, true)
559  _DEFINE_SPEC(0, __is_unsigned_helper, unsigned short, true)
560  _DEFINE_SPEC(0, __is_unsigned_helper, unsigned int, true)
561  _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long, true)
562  _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long long, true)
563
564  template<typename _Tp>
565    struct is_unsigned
566    : public integral_constant<bool, (__is_unsigned_helper<typename
567				      remove_cv<_Tp>::type>::value)>
568    { };
569
570  template<typename _Base, typename _Derived>
571    struct __is_base_of_helper
572    {
573      typedef typename remove_cv<_Base>::type    _NoCv_Base;
574      typedef typename remove_cv<_Derived>::type _NoCv_Derived;
575      static const bool __value = (is_same<_Base, _Derived>::value
576				   || (__is_base_of(_Base, _Derived)
577				       && !is_same<_NoCv_Base,
578				                   _NoCv_Derived>::value));
579    };
580
581  template<typename _Base, typename _Derived>
582    struct is_base_of
583    : public integral_constant<bool,
584			       __is_base_of_helper<_Base, _Derived>::__value>
585    { };
586
587  template<typename _From, typename _To>
588    struct __is_convertible_simple
589    : public __sfinae_types
590    {
591    private:
592      static __one __test(_To);
593      static __two __test(...);
594      static _From __makeFrom();
595
596    public:
597      static const bool __value = sizeof(__test(__makeFrom())) == 1;
598    };
599
600  template<typename _Tp>
601    struct add_reference;
602
603  template<typename _Tp>
604    struct __is_int_or_cref
605    {
606      typedef typename remove_reference<_Tp>::type __rr_Tp;
607      static const bool __value = (is_integral<_Tp>::value
608				   || (is_integral<__rr_Tp>::value
609				       && is_const<__rr_Tp>::value
610				       && !is_volatile<__rr_Tp>::value));
611    };
612
613  template<typename _From, typename _To,
614	   bool = (is_void<_From>::value || is_void<_To>::value
615		   || is_function<_To>::value || is_array<_To>::value
616		   // This special case is here only to avoid warnings.
617		   || (is_floating_point<typename
618		       remove_reference<_From>::type>::value
619		       && __is_int_or_cref<_To>::__value))>
620    struct __is_convertible_helper
621    {
622      // "An imaginary lvalue of type From...".
623      static const bool __value = (__is_convertible_simple<typename
624				   add_reference<_From>::type, _To>::__value);
625    };
626
627  template<typename _From, typename _To>
628    struct __is_convertible_helper<_From, _To, true>
629    { static const bool __value = (is_void<_To>::value
630				   || (__is_int_or_cref<_To>::__value
631				       && !is_void<_From>::value)); };
632
633  template<typename _From, typename _To>
634    struct is_convertible
635    : public integral_constant<bool,
636			       __is_convertible_helper<_From, _To>::__value>
637    { };
638
639  // reference modifications [4.7.2].
640  template<typename _Tp>
641    struct remove_reference
642    { typedef _Tp     type; };
643
644  template<typename _Tp>
645    struct remove_reference<_Tp&>
646    { typedef _Tp     type; };
647
648  // NB: Careful with reference to void.
649  template<typename _Tp, bool = (is_void<_Tp>::value
650				 || is_reference<_Tp>::value)>
651    struct __add_reference_helper
652    { typedef _Tp&    type; };
653
654  template<typename _Tp>
655    struct __add_reference_helper<_Tp, true>
656    { typedef _Tp     type; };
657
658  template<typename _Tp>
659    struct add_reference
660    : public __add_reference_helper<_Tp>
661    { };
662
663  // other transformations [4.8].
664  template<std::size_t _Len, std::size_t _Align>
665    struct aligned_storage
666    {
667      union type
668      {
669	unsigned char __data[_Len];
670	struct __attribute__((__aligned__((_Align)))) { } __align;
671      };
672    };
673
674#undef _DEFINE_SPEC_0_HELPER
675#undef _DEFINE_SPEC_1_HELPER
676#undef _DEFINE_SPEC_2_HELPER
677#undef _DEFINE_SPEC
678
679  /// @} group metaprogramming
680}
681
682_GLIBCXX_END_NAMESPACE_VERSION
683}
684
685#endif // _GLIBCXX_TR1_TYPE_TRAITS
686