OSDN Git Service

2008-05-25 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / type_traits
1 // <type_traits> -*- C++ -*-
2
3 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING.  If not, write to
18 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 // Boston, MA 02110-1301, USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /** @file include/type_traits
31  *  This is a Standard C++ Library header.
32  */
33
34 #ifndef _GLIBCXX_TYPE_TRAITS
35 #define _GLIBCXX_TYPE_TRAITS 1
36
37 #pragma GCC system_header
38
39 #ifndef __GXX_EXPERIMENTAL_CXX0X__
40 # include <c++0x_warning.h>
41 #else
42
43 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
44 #  error C++0x header cannot be included from TR1 header
45 #endif
46
47 #include <cstddef>
48
49 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
50 #  include <tr1_impl/type_traits>
51 #else
52 #  define _GLIBCXX_INCLUDE_AS_CXX0X
53 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1
54 #  define _GLIBCXX_END_NAMESPACE_TR1
55 #  define _GLIBCXX_TR1
56 #  include <tr1_impl/type_traits>
57 #  undef _GLIBCXX_TR1
58 #  undef _GLIBCXX_END_NAMESPACE_TR1
59 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
60 #  undef _GLIBCXX_INCLUDE_AS_CXX0X
61 #endif
62
63 namespace std
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_object<_Tp>::value || is_function<_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_object<_Tp>::value || is_function<_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, _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_pod
177   template<typename _Tp>
178     struct is_pod
179     : public integral_constant<bool, __is_pod(_Tp)>
180     { };
181
182   /// has_trivial_default_constructor
183   template<typename _Tp>
184     struct has_trivial_default_constructor
185     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
186     { };
187
188   /// has_trivial_copy_constructor
189   template<typename _Tp>
190     struct has_trivial_copy_constructor
191     : public integral_constant<bool, __has_trivial_copy(_Tp)>
192     { };
193
194   /// has_trivial_assign
195   template<typename _Tp>
196     struct has_trivial_assign
197     : public integral_constant<bool, __has_trivial_assign(_Tp)>
198     { };
199
200   /// has_trivial_destructor
201   template<typename _Tp>
202     struct has_trivial_destructor
203     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
204     { };
205
206   /// has_nothrow_default_destructor
207   template<typename _Tp>
208     struct has_nothrow_default_constructor
209     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
210     { };
211
212   /// has_nothrow_copy_destructor
213   template<typename _Tp>
214     struct has_nothrow_copy_constructor
215     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
216     { };
217
218   /// has_nothrow_assign
219   template<typename _Tp>
220     struct has_nothrow_assign
221     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
222     { };
223
224   /// is_base_of
225   template<typename _Base, typename _Derived>
226     struct is_base_of
227     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
228     { };
229
230   // Relationships between types.
231   template<typename _From, typename _To>
232     struct __is_convertible_simple
233     : public __sfinae_types
234     {
235     private:
236       static __one __test(_To);
237       static __two __test(...);
238       static _From __makeFrom();
239     
240     public:
241       static const bool __value = sizeof(__test(__makeFrom())) == 1;
242     };
243
244   template<typename _Tp>
245     struct __is_int_or_cref
246     {
247       typedef typename remove_reference<_Tp>::type __rr_Tp;
248       static const bool __value = (is_integral<_Tp>::value
249                                    || (is_integral<__rr_Tp>::value
250                                        && is_const<__rr_Tp>::value
251                                        && !is_volatile<__rr_Tp>::value));
252     };
253
254   template<typename _From, typename _To,
255            bool = (is_void<_From>::value || is_void<_To>::value
256                    || is_function<_To>::value || is_array<_To>::value
257                    // This special case is here only to avoid warnings.
258                    || (is_floating_point<typename
259                        remove_reference<_From>::type>::value
260                        && __is_int_or_cref<_To>::__value))>
261     struct __is_convertible_helper
262     {
263       // "An imaginary lvalue of type From...".
264       static const bool __value = (__is_convertible_simple<typename
265                                    add_lvalue_reference<_From>::type,
266                                    _To>::__value);
267     };
268
269   template<typename _From, typename _To>
270     struct __is_convertible_helper<_From, _To, true>
271     { static const bool __value = (is_void<_To>::value
272                                    || (__is_int_or_cref<_To>::__value
273                                        && !is_void<_From>::value)); };
274
275   // XXX FIXME
276   // The C++0x specifications are different, see N2255.
277   /// is_convertible
278   template<typename _From, typename _To>
279     struct is_convertible
280     : public integral_constant<bool,
281                                __is_convertible_helper<_From, _To>::__value>
282     { };
283
284   template<std::size_t _Len>
285     struct __aligned_storage_msa
286     { 
287       union __type
288       {
289         unsigned char __data[_Len];
290         struct __attribute__((__aligned__)) { } __align; 
291       };
292     };
293
294   /**
295    *  @brief Alignment type.
296    *
297    *  The value of _Align is a default-alignment which shall be the
298    *  most stringent alignment requirement for any C++ object type
299    *  whose size is no greater than _Len (3.9). The member typedef
300    *  type shall be a POD type suitable for use as uninitialized
301    *  storage for any object whose size is at most _Len and whose
302    *  alignment is a divisor of _Align.
303   */
304   template<std::size_t _Len, std::size_t _Align =
305            __alignof__(typename __aligned_storage_msa<_Len>::__type)>
306     struct aligned_storage
307     { 
308       union type
309       {
310         unsigned char __data[_Len];
311         struct __attribute__((__aligned__((_Align)))) { } __align; 
312       };
313     };
314
315
316   // Define a nested type if some predicate holds.
317   /// Primary template.
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. 
329   // If true, first, if false, second.
330   /// Primary template.
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       // GNU enums start with sizeof short.
459       typedef unsigned short __smallest;
460       static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
461       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
462       typedef conditional<__b2, unsigned int, unsigned long> __cond;
463       typedef typename __cond::type __cond_type;
464
465     public:
466       typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
467     };
468
469   // Given an integral/enum type, return the corresponding unsigned
470   // integer type.
471   /// Primary template.
472   template<typename _Tp>
473     struct make_unsigned 
474     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
475
476   // Integral, but don't define.
477   template<>
478     struct make_unsigned<bool>;
479
480
481   // Utility for finding the signed versions of unsigned integral types.
482   template<typename _Tp>
483     struct __make_signed
484     { typedef _Tp __type; };
485
486   template<>
487     struct __make_signed<char>
488     { typedef signed char __type; };
489
490   template<>
491     struct __make_signed<unsigned char>
492     { typedef signed char __type; };
493
494   template<>
495     struct __make_signed<unsigned short>
496     { typedef signed short __type; };
497
498   template<>
499     struct __make_signed<unsigned int>
500     { typedef signed int __type; };
501
502   template<>
503     struct __make_signed<unsigned long>
504     { typedef signed long __type; };
505
506   template<>
507     struct __make_signed<unsigned long long>
508     { typedef signed long long __type; };
509
510
511   // Select between integral and enum: not possible to be both.
512   template<typename _Tp, 
513            bool _IsInt = is_integral<_Tp>::value,
514            bool _IsEnum = is_enum<_Tp>::value>
515     struct __make_signed_selector;
516   
517   template<typename _Tp>
518     struct __make_signed_selector<_Tp, true, false>
519     {
520     private:
521       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
522       typedef typename __signedt::__type __signed_type;
523       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
524
525     public:
526       typedef typename __cv_signed::__type __type;
527     };
528
529   template<typename _Tp>
530     struct __make_signed_selector<_Tp, false, true>
531     {
532     private:
533       // GNU enums start with sizeof short.
534       typedef signed short __smallest;
535       static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
536       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
537       typedef conditional<__b2, signed int, signed long> __cond;
538       typedef typename __cond::type __cond_type;
539
540     public:
541       typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
542     };
543
544   // Given an integral/enum type, return the corresponding signed
545   // integer type.
546   /// Primary template.
547   template<typename _Tp>
548     struct make_signed 
549     { typedef typename __make_signed_selector<_Tp>::__type type; };
550
551   // Integral, but don't define.
552   template<>
553     struct make_signed<bool>;
554 }
555
556 #endif  // __GXX_EXPERIMENTAL_CXX0X__
557
558 #endif  // _GLIBCXX_TYPE_TRAITS 
559