]>
Commit | Line | Data |
---|---|---|
af13a7a6 BK |
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 | ||
7b50cdef BK |
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 | ||
7b50cdef BK |
188 | template<typename _Tp> |
189 | struct __make_unsigned_selector<_Tp, false, false, true> | |
190 | { | |
191 | private: | |
ce2e6349 BK |
192 | // GNU enums start with sizeof short. |
193 | typedef unsigned short __smallest; | |
194 | static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest); | |
195 | static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); | |
196 | typedef conditional<__b2, unsigned int, unsigned long> __cond; | |
7b50cdef | 197 | typedef typename __cond::type __cond_type; |
7b50cdef BK |
198 | |
199 | public: | |
ce2e6349 | 200 | typedef typename conditional<__b1, __smallest, __cond_type>::type __type; |
7b50cdef BK |
201 | }; |
202 | ||
203 | // Primary class template. | |
204 | // Given an integral/enum type, return the corresponding unsigned | |
205 | // integer type. | |
206 | template<typename _Tp> | |
207 | struct make_unsigned | |
208 | { typedef typename __make_unsigned_selector<_Tp>::__type type; }; | |
209 | ||
210 | // Integral, but don't define. | |
211 | template<> | |
212 | struct make_unsigned<bool>; | |
213 | ||
214 | ||
215 | // Utility for finding the signed versions of unsigned integral types. | |
216 | template<typename _Tp> | |
217 | struct __make_signed; | |
218 | ||
219 | template<> | |
220 | struct __make_signed<char> | |
221 | { typedef signed char __type; }; | |
222 | ||
223 | template<> | |
224 | struct __make_signed<unsigned char> | |
225 | { typedef signed char __type; }; | |
226 | ||
227 | template<> | |
228 | struct __make_signed<wchar_t> | |
229 | { typedef signed wchar_t __type; }; | |
230 | ||
231 | template<> | |
232 | struct __make_signed<unsigned short> | |
233 | { typedef signed short __type; }; | |
234 | ||
235 | template<> | |
236 | struct __make_signed<unsigned int> | |
237 | { typedef signed int __type; }; | |
238 | ||
239 | template<> | |
240 | struct __make_signed<unsigned long> | |
241 | { typedef signed long __type; }; | |
242 | ||
243 | template<> | |
244 | struct __make_signed<unsigned long long> | |
245 | { typedef signed long long __type; }; | |
246 | ||
247 | ||
fb8ffd10 | 248 | // Select between integral and enum: not possible to be both. |
7b50cdef BK |
249 | template<typename _Tp, |
250 | bool _IsInt = is_integral<_Tp>::value, | |
251 | bool _IsSigned = is_signed<_Tp>::value, | |
252 | bool _IsEnum = is_enum<_Tp>::value> | |
253 | struct __make_signed_selector; | |
254 | ||
255 | template<typename _Tp> | |
256 | struct __make_signed_selector<_Tp, true, true, false> | |
257 | { typedef _Tp __type; }; | |
258 | ||
259 | template<typename _Tp> | |
260 | struct __make_signed_selector<_Tp, true, false, false> | |
261 | { | |
262 | private: | |
263 | typedef __make_signed<typename remove_cv<_Tp>::type> __signedt; | |
264 | typedef typename __signedt::__type __signed_type; | |
265 | typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; | |
266 | ||
267 | public: | |
268 | typedef typename __cv_signed::__type __type; | |
269 | }; | |
270 | ||
7b50cdef BK |
271 | template<typename _Tp> |
272 | struct __make_signed_selector<_Tp, false, false, true> | |
273 | { | |
274 | private: | |
ce2e6349 BK |
275 | // GNU enums start with sizeof short. |
276 | typedef signed short __smallest; | |
277 | static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest); | |
278 | static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); | |
279 | typedef conditional<__b2, signed int, signed long> __cond; | |
7b50cdef | 280 | typedef typename __cond::type __cond_type; |
7b50cdef BK |
281 | |
282 | public: | |
ce2e6349 | 283 | typedef typename conditional<__b1, __smallest, __cond_type>::type __type; |
7b50cdef BK |
284 | }; |
285 | ||
286 | // Primary class template. | |
287 | // Given an integral/enum type, return the corresponding signed | |
288 | // integer type. | |
289 | template<typename _Tp> | |
290 | struct make_signed | |
291 | { typedef typename __make_signed_selector<_Tp>::__type type; }; | |
292 | ||
293 | // Integral, but don't define. | |
294 | template<> | |
295 | struct make_signed<bool>; | |
296 | ||
297 | ||
298 | template<typename _Tp> | |
299 | struct has_nothrow_default_constructor | |
300 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
301 | ||
302 | template<typename _Tp> | |
303 | struct has_nothrow_copy_constructor | |
304 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
305 | ||
306 | template<typename _Tp> | |
307 | struct has_trivial_default_constructor | |
308 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
309 | ||
310 | template<typename _Tp> | |
311 | struct has_trivial_copy_constructor | |
312 | : public integral_constant<bool, is_pod<_Tp>::value> { }; | |
313 | ||
314 | _GLIBCXX_END_NAMESPACE | |
315 | ||
af13a7a6 BK |
316 | #endif |
317 |