OSDN Git Service

2007-05-07 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / type_traits
1 // <type_traits> -*- C++ -*-
2
3 // Copyright (C) 2007 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
40 # include <tr1/type_traits>
41 #else
42 # include <c++0x_warning.h>
43 #endif
44
45 _GLIBCXX_BEGIN_NAMESPACE(std)
46
47   // Define a nested type if some predicate holds.
48   template<bool, typename _Tp = void>
49     struct enable_if 
50     { };
51
52   template<typename _Tp>
53     struct enable_if<true, _Tp>
54     { typedef _Tp type; };
55
56
57   // Like a conditional expression, but for types. If true, first, if
58   // false, second.
59   template<bool _Cond, typename _Iftrue, typename _Iffalse>
60     struct conditional
61     { typedef _Iftrue type; };
62
63   template<typename _Iftrue, typename _Iffalse>
64     struct conditional<false, _Iftrue, _Iffalse>
65     { typedef _Iffalse type; };
66
67
68   // Decay trait for arrays and functions, used for perfect forwarding
69   // in make_pair, make_tuple, etc.
70   template<typename _Up, 
71            bool _IsArray = is_array<_Up>::value,
72            bool _IsFunction = is_function<_Up>::value> 
73     struct __decay_selector;
74
75   template<typename _Up> 
76     struct __decay_selector<_Up, false, false>
77     { typedef _Up __type; };
78
79   template<typename _Up> 
80     struct __decay_selector<_Up, true, false>
81     { typedef typename remove_extent<_Up>::type* __type; };
82
83
84   template<typename _Up> 
85     struct __decay_selector<_Up, false, true>
86     { typedef typename add_pointer<_Up>::type __type; };
87
88   template<typename _Tp> 
89   struct decay 
90     { 
91     private:
92       typedef typename remove_reference<_Tp>::type __remove_type;
93
94     public:
95       typedef typename __decay_selector<__remove_type>::__type type;
96     };
97
98
99   // Utility for constructing identically cv-qualified types.
100   template<typename _Unqualified, bool _IsConst, bool _IsVol>
101     struct __cv_selector;
102
103   template<typename _Unqualified>
104     struct __cv_selector<_Unqualified, false, false>
105     { typedef _Unqualified __type; };
106
107   template<typename _Unqualified>
108     struct __cv_selector<_Unqualified, false, true>
109     { typedef volatile _Unqualified __type; };
110
111   template<typename _Unqualified>
112     struct __cv_selector<_Unqualified, true, false>
113     { typedef const _Unqualified __type; };
114
115   template<typename _Unqualified>
116     struct __cv_selector<_Unqualified, true, true>
117     { typedef const volatile _Unqualified __type; };
118
119   template<typename _Qualified, typename _Unqualified,
120            bool _IsConst = is_const<_Qualified>::value,
121            bool _IsVol = is_volatile<_Qualified>::value>
122     struct __match_cv_qualifiers
123     {
124     private:
125       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
126
127     public:
128       typedef typename __match::__type __type; 
129     };
130
131
132   // Utility for finding the unsigned versions of signed integral types.
133   template<typename _Tp>
134     struct __make_unsigned;
135
136   template<>
137     struct __make_unsigned<char>
138     { typedef unsigned char __type; };
139
140   template<>
141     struct __make_unsigned<signed char>
142     { typedef unsigned char __type; };
143
144   template<>
145     struct __make_unsigned<wchar_t>
146     { typedef unsigned wchar_t __type; };
147
148   template<>
149     struct __make_unsigned<short>
150     { typedef unsigned short __type; };
151
152   template<>
153     struct __make_unsigned<int>
154     { typedef unsigned int __type; };
155
156   template<>
157     struct __make_unsigned<long>
158     { typedef unsigned long __type; };
159
160   template<>
161     struct __make_unsigned<long long>
162     { typedef unsigned long long __type; };
163
164
165   // Select between integral and enum: not possible to be both.
166   template<typename _Tp, 
167            bool _IsInt = is_integral<_Tp>::value,
168            bool _IsUnsigned = is_unsigned<_Tp>::value,
169            bool _IsEnum = is_enum<_Tp>::value>
170     struct __make_unsigned_selector;
171   
172   template<typename _Tp>
173     struct __make_unsigned_selector<_Tp, true, true, false>
174     { typedef _Tp __type; };
175
176   template<typename _Tp>
177     struct __make_unsigned_selector<_Tp, true, false, false>
178     {
179     private:
180       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
181       typedef typename __unsignedt::__type __unsigned_type;
182       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
183
184     public:
185       typedef typename __cv_unsigned::__type __type;
186     };
187
188   template<typename _Tp>
189     struct __make_unsigned_selector<_Tp, false, true, false>
190     {
191     private:
192       // GNU floating point types start with sizeof int.
193       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned int);
194       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned long);
195       typedef conditional<__b2, unsigned long, unsigned long long> __cond;
196       typedef typename __cond::type __cond_type;
197       typedef unsigned int __ui_type;
198
199     public:
200       typedef typename conditional<__b1, __ui_type, __cond_type>::type __type;
201     };
202
203   template<typename _Tp>
204     struct __make_unsigned_selector<_Tp, false, false, true>
205     {
206     private:
207       // GNU enums start with sizeof short.
208       typedef unsigned short __smallest;
209       static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
210       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
211       typedef conditional<__b2, unsigned int, unsigned long> __cond;
212       typedef typename __cond::type __cond_type;
213
214     public:
215       typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
216     };
217
218   // Primary class template.
219   // Given an integral/enum type, return the corresponding unsigned
220   // integer type.
221   template<typename _Tp>
222     struct make_unsigned 
223     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
224
225   // Integral, but don't define.
226   template<>
227     struct make_unsigned<bool>;
228
229
230   // Utility for finding the signed versions of unsigned integral types.
231   template<typename _Tp>
232     struct __make_signed;
233
234   template<>
235     struct __make_signed<char>
236     { typedef signed char __type; };
237
238   template<>
239     struct __make_signed<unsigned char>
240     { typedef signed char __type; };
241
242   template<>
243     struct __make_signed<wchar_t>
244     { typedef signed wchar_t __type; };
245
246   template<>
247     struct __make_signed<unsigned short>
248     { typedef signed short __type; };
249
250   template<>
251     struct __make_signed<unsigned int>
252     { typedef signed int __type; };
253
254   template<>
255     struct __make_signed<unsigned long>
256     { typedef signed long __type; };
257
258   template<>
259     struct __make_signed<unsigned long long>
260     { typedef signed long long __type; };
261
262
263   // Select between arithmetic and enum: not possible to be both.
264   template<typename _Tp, 
265            bool _IsInt = is_integral<_Tp>::value,
266            bool _IsSigned = is_signed<_Tp>::value,
267            bool _IsEnum = is_enum<_Tp>::value>
268     struct __make_signed_selector;
269   
270   template<typename _Tp>
271     struct __make_signed_selector<_Tp, true, true, false>
272     { typedef _Tp __type; };
273
274   template<typename _Tp>
275     struct __make_signed_selector<_Tp, true, false, false>
276     {
277     private:
278       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
279       typedef typename __signedt::__type __signed_type;
280       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
281
282     public:
283       typedef typename __cv_signed::__type __type;
284     };
285
286   template<typename _Tp>
287     struct __make_signed_selector<_Tp, false, true, false>
288     {
289       // GNU floating point types start with sizeof int.
290       static const bool __b1 = sizeof(_Tp) <= sizeof(signed int);
291       static const bool __b2 = sizeof(_Tp) <= sizeof(signed long);
292       typedef conditional<__b2, signed long, signed long long> __cond;
293       typedef typename __cond::type __cond_type;
294       typedef unsigned int __i_type;
295
296     public:
297       typedef typename conditional<__b1, __i_type, __cond_type>::type __type;
298     };
299
300   template<typename _Tp>
301     struct __make_signed_selector<_Tp, false, false, true>
302     {
303     private:
304       // GNU enums start with sizeof short.
305       typedef signed short __smallest;
306       static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
307       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
308       typedef conditional<__b2, signed int, signed long> __cond;
309       typedef typename __cond::type __cond_type;
310
311     public:
312       typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
313     };
314
315   // Primary class template.
316   // Given an integral/enum type, return the corresponding signed
317   // integer type.
318   template<typename _Tp>
319     struct make_signed 
320     { typedef typename __make_signed_selector<_Tp>::__type type; };
321
322   // Integral, but don't define.
323   template<>
324     struct make_signed<bool>;
325
326
327   template<typename _Tp>
328     struct has_nothrow_default_constructor
329     : public integral_constant<bool, is_pod<_Tp>::value> { };
330
331   template<typename _Tp>
332     struct has_nothrow_copy_constructor
333     : public integral_constant<bool, is_pod<_Tp>::value> { };
334
335   template<typename _Tp>
336     struct has_trivial_default_constructor
337     : public integral_constant<bool, is_pod<_Tp>::value> { };
338
339   template<typename _Tp>
340     struct has_trivial_copy_constructor
341     : public integral_constant<bool, is_pod<_Tp>::value> { };
342
343 _GLIBCXX_END_NAMESPACE
344
345 #endif 
346