1 // <type_traits> -*- C++ -*-
3 // Copyright (C) 2007 Free Software Foundation, Inc.
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)
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.
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.
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.
30 /** @file include/type_traits
31 * This is a Standard C++ Library header.
34 #ifndef _GLIBCXX_TYPE_TRAITS
35 #define _GLIBCXX_TYPE_TRAITS 1
37 #pragma GCC system_header
39 #ifdef __GXX_EXPERIMENTAL_CXX0X__
40 # include <tr1/type_traits>
42 # include <c++0x_warning.h>
45 _GLIBCXX_BEGIN_NAMESPACE(std)
47 // Define a nested type if some predicate holds.
48 template<bool, typename _Tp = void>
52 template<typename _Tp>
53 struct enable_if<true, _Tp>
54 { typedef _Tp type; };
57 // Like a conditional expression, but for types. If true, first, if
59 template<bool _Cond, typename _Iftrue, typename _Iffalse>
61 { typedef _Iftrue type; };
63 template<typename _Iftrue, typename _Iffalse>
64 struct conditional<false, _Iftrue, _Iffalse>
65 { typedef _Iffalse type; };
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;
75 template<typename _Up>
76 struct __decay_selector<_Up, false, false>
77 { typedef _Up __type; };
79 template<typename _Up>
80 struct __decay_selector<_Up, true, false>
81 { typedef typename remove_extent<_Up>::type* __type; };
84 template<typename _Up>
85 struct __decay_selector<_Up, false, true>
86 { typedef typename add_pointer<_Up>::type __type; };
88 template<typename _Tp>
92 typedef typename remove_reference<_Tp>::type __remove_type;
95 typedef typename __decay_selector<__remove_type>::__type type;
99 // Utility for constructing identically cv-qualified types.
100 template<typename _Unqualified, bool _IsConst, bool _IsVol>
101 struct __cv_selector;
103 template<typename _Unqualified>
104 struct __cv_selector<_Unqualified, false, false>
105 { typedef _Unqualified __type; };
107 template<typename _Unqualified>
108 struct __cv_selector<_Unqualified, false, true>
109 { typedef volatile _Unqualified __type; };
111 template<typename _Unqualified>
112 struct __cv_selector<_Unqualified, true, false>
113 { typedef const _Unqualified __type; };
115 template<typename _Unqualified>
116 struct __cv_selector<_Unqualified, true, true>
117 { typedef const volatile _Unqualified __type; };
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
125 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
128 typedef typename __match::__type __type;
132 // Utility for finding the unsigned versions of signed integral types.
133 template<typename _Tp>
134 struct __make_unsigned;
137 struct __make_unsigned<char>
138 { typedef unsigned char __type; };
141 struct __make_unsigned<signed char>
142 { typedef unsigned char __type; };
145 struct __make_unsigned<wchar_t>
146 { typedef unsigned wchar_t __type; };
149 struct __make_unsigned<short>
150 { typedef unsigned short __type; };
153 struct __make_unsigned<int>
154 { typedef unsigned int __type; };
157 struct __make_unsigned<long>
158 { typedef unsigned long __type; };
161 struct __make_unsigned<long long>
162 { typedef unsigned long long __type; };
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;
172 template<typename _Tp>
173 struct __make_unsigned_selector<_Tp, true, true, false>
174 { typedef _Tp __type; };
176 template<typename _Tp>
177 struct __make_unsigned_selector<_Tp, true, false, false>
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;
185 typedef typename __cv_unsigned::__type __type;
188 template<typename _Tp>
189 struct __make_unsigned_selector<_Tp, false, true, false>
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;
200 typedef typename conditional<__b1, __ui_type, __cond_type>::type __type;
203 template<typename _Tp>
204 struct __make_unsigned_selector<_Tp, false, false, true>
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;
215 typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
218 // Primary class template.
219 // Given an integral/enum type, return the corresponding unsigned
221 template<typename _Tp>
223 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
225 // Integral, but don't define.
227 struct make_unsigned<bool>;
230 // Utility for finding the signed versions of unsigned integral types.
231 template<typename _Tp>
232 struct __make_signed;
235 struct __make_signed<char>
236 { typedef signed char __type; };
239 struct __make_signed<unsigned char>
240 { typedef signed char __type; };
243 struct __make_signed<wchar_t>
244 { typedef signed wchar_t __type; };
247 struct __make_signed<unsigned short>
248 { typedef signed short __type; };
251 struct __make_signed<unsigned int>
252 { typedef signed int __type; };
255 struct __make_signed<unsigned long>
256 { typedef signed long __type; };
259 struct __make_signed<unsigned long long>
260 { typedef signed long long __type; };
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;
270 template<typename _Tp>
271 struct __make_signed_selector<_Tp, true, true, false>
272 { typedef _Tp __type; };
274 template<typename _Tp>
275 struct __make_signed_selector<_Tp, true, false, false>
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;
283 typedef typename __cv_signed::__type __type;
286 template<typename _Tp>
287 struct __make_signed_selector<_Tp, false, true, false>
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;
297 typedef typename conditional<__b1, __i_type, __cond_type>::type __type;
300 template<typename _Tp>
301 struct __make_signed_selector<_Tp, false, false, true>
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;
312 typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
315 // Primary class template.
316 // Given an integral/enum type, return the corresponding signed
318 template<typename _Tp>
320 { typedef typename __make_signed_selector<_Tp>::__type type; };
322 // Integral, but don't define.
324 struct make_signed<bool>;
327 template<typename _Tp>
328 struct has_nothrow_default_constructor
329 : public integral_constant<bool, is_pod<_Tp>::value> { };
331 template<typename _Tp>
332 struct has_nothrow_copy_constructor
333 : public integral_constant<bool, is_pod<_Tp>::value> { };
335 template<typename _Tp>
336 struct has_trivial_default_constructor
337 : public integral_constant<bool, is_pod<_Tp>::value> { };
339 template<typename _Tp>
340 struct has_trivial_copy_constructor
341 : public integral_constant<bool, is_pod<_Tp>::value> { };
343 _GLIBCXX_END_NAMESPACE