libstdc++
type_traits
Go to the documentation of this file.
1 // C++0x type_traits -*- C++ -*-
2 
3 // Copyright (C) 2007, 2008, 2009 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 <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 
58 namespace std
59 {
60  /** @addtogroup metaprogramming
61  * @{
62  */
63 
64  // Primary classification traits.
65 
66  /// is_lvalue_reference
67  template<typename>
69  : public false_type { };
70 
71  template<typename _Tp>
72  struct is_lvalue_reference<_Tp&>
73  : public true_type { };
74 
75  /// is_rvalue_reference
76  template<typename>
78  : public false_type { };
79 
80  template<typename _Tp>
81  struct is_rvalue_reference<_Tp&&>
82  : public true_type { };
83 
84  // Secondary classification traits.
85 
86  /// is_reference
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.
94 
95  /// remove_reference
96  template<typename _Tp>
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,
109  bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
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 
122  /// add_lvalue_reference
123  template<typename _Tp>
125  : public __add_lvalue_reference_helper<_Tp>
126  { };
127 
128  template<typename _Tp,
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 
137  /// add_rvalue_reference
138  template<typename _Tp>
140  : public __add_rvalue_reference_helper<_Tp>
141  { };
142 
143  // Scalar properties and transformations.
144 
145  template<typename _Tp,
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 
160  /// is_signed
161  template<typename _Tp>
162  struct is_signed
163  : public integral_constant<bool, __is_signed_helper<_Tp>::value>
164  { };
165 
166  /// is_unsigned
167  template<typename _Tp>
168  struct is_unsigned
169  : public integral_constant<bool, (is_arithmetic<_Tp>::value
170  && !is_signed<_Tp>::value)>
171  { };
172 
173  // Member introspection.
174 
175  /// is_pod
176  template<typename _Tp>
177  struct is_pod
178  : public integral_constant<bool, __is_pod(_Tp)>
179  { };
180 
181  /// has_trivial_default_constructor
182  template<typename _Tp>
183  struct has_trivial_default_constructor
184  : public integral_constant<bool, __has_trivial_constructor(_Tp)>
185  { };
186 
187  /// has_trivial_copy_constructor
188  template<typename _Tp>
189  struct has_trivial_copy_constructor
190  : public integral_constant<bool, __has_trivial_copy(_Tp)>
191  { };
192 
193  /// has_trivial_assign
194  template<typename _Tp>
195  struct has_trivial_assign
196  : public integral_constant<bool, __has_trivial_assign(_Tp)>
197  { };
198 
199  /// has_trivial_destructor
200  template<typename _Tp>
201  struct has_trivial_destructor
202  : public integral_constant<bool, __has_trivial_destructor(_Tp)>
203  { };
204 
205  /// has_nothrow_default_constructor
206  template<typename _Tp>
207  struct has_nothrow_default_constructor
208  : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
209  { };
210 
211  /// has_nothrow_copy_constructor
212  template<typename _Tp>
213  struct has_nothrow_copy_constructor
214  : public integral_constant<bool, __has_nothrow_copy(_Tp)>
215  { };
216 
217  /// has_nothrow_assign
218  template<typename _Tp>
219  struct has_nothrow_assign
220  : public integral_constant<bool, __has_nothrow_assign(_Tp)>
221  { };
222 
223  /// is_base_of
224  template<typename _Base, typename _Derived>
225  struct is_base_of
226  : public integral_constant<bool, __is_base_of(_Base, _Derived)>
227  { };
228 
229  // Relationships between types.
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
256  // This special case is here only to avoid warnings.
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
264  add_lvalue_reference<_From>::type,
265  _To>::__value);
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 
274  // XXX FIXME
275  // The C++0x specifications are different, see N2255.
276  /// is_convertible
277  template<typename _From, typename _To>
278  struct is_convertible
279  : public integral_constant<bool,
280  __is_convertible_helper<_From, _To>::__value>
281  { };
282 
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 
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  */
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 
314 
315  // Define a nested type if some predicate holds.
316  // Primary template.
317  /// enable_if
318  template<bool, typename _Tp = void>
319  struct enable_if
320  { };
321 
322  // Partial specialization for true.
323  template<typename _Tp>
324  struct enable_if<true, _Tp>
325  { typedef _Tp type; };
326 
327 
328  // A conditional expression, but for types. If true, first, if false, second.
329  // Primary template.
330  /// conditional
331  template<bool _Cond, typename _Iftrue, typename _Iffalse>
332  struct conditional
333  { typedef _Iftrue type; };
334 
335  // Partial specialization for false.
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 
348  // NB: DR 705.
349  template<typename _Up>
350  struct __decay_selector<_Up, false, false>
351  { typedef typename remove_cv<_Up>::type __type; };
352 
353  template<typename _Up>
354  struct __decay_selector<_Up, true, false>
355  { typedef typename remove_extent<_Up>::type* __type; };
356 
357  template<typename _Up>
358  struct __decay_selector<_Up, false, true>
359  { typedef typename add_pointer<_Up>::type __type; };
360 
361  /// decay
362  template<typename _Tp>
363  struct decay
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>
408  struct __make_unsigned
409  { typedef _Tp __type; };
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 
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,
439  bool _IsEnum = is_enum<_Tp>::value>
440  struct __make_unsigned_selector;
441 
442  template<typename _Tp>
443  struct __make_unsigned_selector<_Tp, true, false>
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 
454  template<typename _Tp>
455  struct __make_unsigned_selector<_Tp, false, true>
456  {
457  private:
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);
462  static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
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;
467 
468  public:
469  typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
470  };
471 
472  // Given an integral/enum type, return the corresponding unsigned
473  // integer type.
474  // Primary template.
475  /// make_unsigned
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>
487  struct __make_signed
488  { typedef _Tp __type; };
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 
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 
515  // Select between integral and enum: not possible to be both.
516  template<typename _Tp,
517  bool _IsInt = is_integral<_Tp>::value,
518  bool _IsEnum = is_enum<_Tp>::value>
519  struct __make_signed_selector;
520 
521  template<typename _Tp>
522  struct __make_signed_selector<_Tp, true, false>
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 
533  template<typename _Tp>
534  struct __make_signed_selector<_Tp, false, true>
535  {
536  private:
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);
541  static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
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;
546 
547  public:
548  typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
549  };
550 
551  // Given an integral/enum type, return the corresponding signed
552  // integer type.
553  // Primary template.
554  /// make_signed
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>;
562 
563  /// common_type
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 
583  // HACK: Prevents optimization of ?: in the decltype
584  // expression when the condition is the literal, "true".
585  // See, PR36628.
586  static bool __true_or_false();
587 
588  public:
589  typedef decltype(__true_or_false() ? __t() : __u()) type;
590  };
591 
592  template<typename _Tp, typename _Up, typename... _Vp>
593  struct common_type<_Tp, _Up, _Vp...>
594  {
595  typedef typename
596  common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
597  };
598 
599  // @} group metaprogramming
600 }
601 
602 #endif // __GXX_EXPERIMENTAL_CXX0X__
603 
604 #endif // _GLIBCXX_TYPE_TRAITS
605