1// C++0x type_traits -*- C++ -*-
2
3// Copyright (C) 2007, 2008, 2009, 2010 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 include/type_traits
26 *  This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TYPE_TRAITS
30#define _GLIBCXX_TYPE_TRAITS 1
31
32#pragma GCC system_header
33
34#ifndef __GXX_EXPERIMENTAL_CXX0X__
35# include <bits/c++0x_warning.h>
36#else
37
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{
60  /**
61   * @addtogroup metaprogramming
62   * @{
63   */
64
65  // Primary classification traits.
66
67  /// is_lvalue_reference
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
76  /// is_rvalue_reference
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.
86
87  /// is_reference
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.
95
96  /// remove_reference
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_reference<_Tp>::value && !is_void<_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
123  /// add_lvalue_reference
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_reference<_Tp>::value && !is_void<_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
138  /// add_rvalue_reference
139  template<typename _Tp>
140    struct add_rvalue_reference
141    : public __add_rvalue_reference_helper<_Tp>
142    { };
143
144  // Scalar properties and transformations.
145
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, static_cast<bool>(_Tp(-1) < _Tp(0))>
159    { };
160
161  /// is_signed
162  template<typename _Tp>
163    struct is_signed
164    : public integral_constant<bool, __is_signed_helper<_Tp>::value>
165    { };
166
167  /// is_unsigned
168  template<typename _Tp>
169    struct is_unsigned
170    : public integral_constant<bool, (is_arithmetic<_Tp>::value
171				      && !is_signed<_Tp>::value)>
172    { };
173
174  // Member introspection.
175
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
188  /// is_pod
189  // Could use is_standard_layout && is_trivial instead of the builtin.
190  template<typename _Tp>
191    struct is_pod
192    : public integral_constant<bool, __is_pod(_Tp)>
193    { };
194
195  template<typename _Tp>
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    {
202      template<typename _Tp1, typename... _Args1>
203        static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
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>
235    { };
236
237  /// has_trivial_default_constructor
238  template<typename _Tp>
239    struct has_trivial_default_constructor
240    : public integral_constant<bool, __has_trivial_constructor(_Tp)>
241    { };
242
243  /// has_trivial_copy_constructor
244  template<typename _Tp>
245    struct has_trivial_copy_constructor
246    : public integral_constant<bool, __has_trivial_copy(_Tp)>
247    { };
248
249  /// has_trivial_assign
250  template<typename _Tp>
251    struct has_trivial_assign
252    : public integral_constant<bool, __has_trivial_assign(_Tp)>
253    { };
254
255  /// has_trivial_destructor
256  template<typename _Tp>
257    struct has_trivial_destructor
258    : public integral_constant<bool, __has_trivial_destructor(_Tp)>
259    { };
260
261  /// has_nothrow_default_constructor
262  template<typename _Tp>
263    struct has_nothrow_default_constructor
264    : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
265    { };
266
267  /// has_nothrow_copy_constructor
268  template<typename _Tp>
269    struct has_nothrow_copy_constructor
270    : public integral_constant<bool, __has_nothrow_copy(_Tp)>
271    { };
272
273  /// has_nothrow_assign
274  template<typename _Tp>
275    struct has_nothrow_assign
276    : public integral_constant<bool, __has_nothrow_assign(_Tp)>
277    { };
278
279  // Relationships between types.
280
281  /// is_base_of
282  template<typename _Base, typename _Derived>
283    struct is_base_of
284    : public integral_constant<bool, __is_base_of(_Base, _Derived)>
285    { };
286
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
294  template<typename _From, typename _To>
295    class __is_convertible_helper<_From, _To, false>
296    : public __sfinae_types
297    {
298      static __one __test(_To);
299      static __two __test(...);
300
301    public:
302      static const bool __value = sizeof(__test(declval<_From>())) == 1;
303    };
304
305  /// is_convertible
306  // XXX FIXME
307  // The C++0x specifications require front-end support, see N2255.
308  template<typename _From, typename _To>
309    struct is_convertible
310    : public integral_constant<bool,
311			       __is_convertible_helper<_From, _To>::__value>
312    { };
313
314  /// is_explicitly_convertible
315  template<typename _From, typename _To>
316    struct is_explicitly_convertible
317    : public is_constructible<_To, _From>
318    { };
319
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
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  */
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
351
352  // Define a nested type if some predicate holds.
353  // Primary template.
354  /// enable_if
355  template<bool, typename _Tp = void>
356    struct enable_if 
357    { };
358
359  // Partial specialization for true.
360  template<typename _Tp>
361    struct enable_if<true, _Tp>
362    { typedef _Tp type; };
363
364
365  // A conditional expression, but for types. If true, first, if false, second.
366  // Primary template.
367  /// conditional
368  template<bool _Cond, typename _Iftrue, typename _Iffalse>
369    struct conditional
370    { typedef _Iftrue type; };
371
372  // Partial specialization for false.
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
385  // NB: DR 705.
386  template<typename _Up> 
387    struct __decay_selector<_Up, false, false>
388    { typedef typename remove_cv<_Up>::type __type; };
389
390  template<typename _Up> 
391    struct __decay_selector<_Up, true, false>
392    { typedef typename remove_extent<_Up>::type* __type; };
393
394  template<typename _Up> 
395    struct __decay_selector<_Up, false, true>
396    { typedef typename add_pointer<_Up>::type __type; };
397
398  /// decay
399  template<typename _Tp> 
400    class decay 
401    { 
402      typedef typename remove_reference<_Tp>::type __remove_type;
403
404    public:
405      typedef typename __decay_selector<__remove_type>::__type type;
406    };
407
408
409  // Utility for constructing identically cv-qualified types.
410  template<typename _Unqualified, bool _IsConst, bool _IsVol>
411    struct __cv_selector;
412
413  template<typename _Unqualified>
414    struct __cv_selector<_Unqualified, false, false>
415    { typedef _Unqualified __type; };
416
417  template<typename _Unqualified>
418    struct __cv_selector<_Unqualified, false, true>
419    { typedef volatile _Unqualified __type; };
420
421  template<typename _Unqualified>
422    struct __cv_selector<_Unqualified, true, false>
423    { typedef const _Unqualified __type; };
424
425  template<typename _Unqualified>
426    struct __cv_selector<_Unqualified, true, true>
427    { typedef const volatile _Unqualified __type; };
428
429  template<typename _Qualified, typename _Unqualified,
430	   bool _IsConst = is_const<_Qualified>::value,
431	   bool _IsVol = is_volatile<_Qualified>::value>
432    class __match_cv_qualifiers
433    {
434      typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
435
436    public:
437      typedef typename __match::__type __type; 
438    };
439
440
441  // Utility for finding the unsigned versions of signed integral types.
442  template<typename _Tp>
443    struct __make_unsigned
444    { typedef _Tp __type; };
445
446  template<>
447    struct __make_unsigned<char>
448    { typedef unsigned char __type; };
449
450  template<>
451    struct __make_unsigned<signed char>
452    { typedef unsigned char __type; };
453
454  template<>
455    struct __make_unsigned<short>
456    { typedef unsigned short __type; };
457
458  template<>
459    struct __make_unsigned<int>
460    { typedef unsigned int __type; };
461
462  template<>
463    struct __make_unsigned<long>
464    { typedef unsigned long __type; };
465
466  template<>
467    struct __make_unsigned<long long>
468    { typedef unsigned long long __type; };
469
470
471  // Select between integral and enum: not possible to be both.
472  template<typename _Tp, 
473	   bool _IsInt = is_integral<_Tp>::value,
474	   bool _IsEnum = is_enum<_Tp>::value>
475    class __make_unsigned_selector;
476
477  template<typename _Tp>
478    class __make_unsigned_selector<_Tp, true, false>
479    {
480      typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
481      typedef typename __unsignedt::__type __unsigned_type;
482      typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
483
484    public:
485      typedef typename __cv_unsigned::__type __type;
486    };
487
488  template<typename _Tp>
489    class __make_unsigned_selector<_Tp, false, true>
490    {
491      // With -fshort-enums, an enum may be as small as a char.
492      typedef unsigned char __smallest;
493      static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
494      static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
495      static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
496      typedef conditional<__b2, unsigned int, unsigned long> __cond2;
497      typedef typename __cond2::type __cond2_type;
498      typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
499      typedef typename __cond1::type __cond1_type;
500
501    public:
502      typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
503    };
504
505  // Given an integral/enum type, return the corresponding unsigned
506  // integer type.
507  // Primary template.
508  /// make_unsigned
509  template<typename _Tp>
510    struct make_unsigned 
511    { typedef typename __make_unsigned_selector<_Tp>::__type type; };
512
513  // Integral, but don't define.
514  template<>
515    struct make_unsigned<bool>;
516
517
518  // Utility for finding the signed versions of unsigned integral types.
519  template<typename _Tp>
520    struct __make_signed
521    { typedef _Tp __type; };
522
523  template<>
524    struct __make_signed<char>
525    { typedef signed char __type; };
526
527  template<>
528    struct __make_signed<unsigned char>
529    { typedef signed char __type; };
530
531  template<>
532    struct __make_signed<unsigned short>
533    { typedef signed short __type; };
534
535  template<>
536    struct __make_signed<unsigned int>
537    { typedef signed int __type; };
538
539  template<>
540    struct __make_signed<unsigned long>
541    { typedef signed long __type; };
542
543  template<>
544    struct __make_signed<unsigned long long>
545    { typedef signed long long __type; };
546
547
548  // Select between integral and enum: not possible to be both.
549  template<typename _Tp, 
550	   bool _IsInt = is_integral<_Tp>::value,
551	   bool _IsEnum = is_enum<_Tp>::value>
552    class __make_signed_selector;
553
554  template<typename _Tp>
555    class __make_signed_selector<_Tp, true, false>
556    {
557      typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
558      typedef typename __signedt::__type __signed_type;
559      typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
560
561    public:
562      typedef typename __cv_signed::__type __type;
563    };
564
565  template<typename _Tp>
566    class __make_signed_selector<_Tp, false, true>
567    {
568      // With -fshort-enums, an enum may be as small as a char.
569      typedef signed char __smallest;
570      static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
571      static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
572      static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
573      typedef conditional<__b2, signed int, signed long> __cond2;
574      typedef typename __cond2::type __cond2_type;
575      typedef conditional<__b1, signed short, __cond2_type> __cond1;
576      typedef typename __cond1::type __cond1_type;
577
578    public:
579      typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
580    };
581
582  // Given an integral/enum type, return the corresponding signed
583  // integer type.
584  // Primary template.
585  /// make_signed
586  template<typename _Tp>
587    struct make_signed 
588    { typedef typename __make_signed_selector<_Tp>::__type type; };
589
590  // Integral, but don't define.
591  template<>
592    struct make_signed<bool>;
593
594  /// common_type
595  template<typename... _Tp>
596    struct common_type;
597
598  template<typename _Tp>
599    struct common_type<_Tp>
600    { typedef _Tp type; };
601
602  template<typename _Tp, typename _Up>
603    struct common_type<_Tp, _Up>
604    { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
605
606  template<typename _Tp, typename _Up, typename... _Vp>
607    struct common_type<_Tp, _Up, _Vp...>
608    {
609      typedef typename
610        common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
611    };
612  // @} group metaprogramming
613
614  /// declval
615  template<typename _Tp>
616    struct __declval_protector
617    {
618      static const bool __stop = false;
619      static typename add_rvalue_reference<_Tp>::type __delegate();
620    };
621
622  template<typename _Tp>
623    inline typename add_rvalue_reference<_Tp>::type
624    declval()
625    {
626      static_assert(__declval_protector<_Tp>::__stop,
627		    "declval() must not be used!");
628      return __declval_protector<_Tp>::__delegate();
629    }
630}
631
632#endif  // __GXX_EXPERIMENTAL_CXX0X__
633
634#endif  // _GLIBCXX_TYPE_TRAITS
635