Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / libstdc++-v3 / include / bits / cpp_type_traits.h
1 // The  -*- C++ -*- type traits classes for internal use in libstdc++
2
3 // Copyright (C) 2000-2018 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 bits/cpp_type_traits.h
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{ext/type_traits}
28  */
29
30 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
31
32 #ifndef _CPP_TYPE_TRAITS_H
33 #define _CPP_TYPE_TRAITS_H 1
34
35 #pragma GCC system_header
36
37 #include <bits/c++config.h>
38
39 //
40 // This file provides some compile-time information about various types.
41 // These representations were designed, on purpose, to be constant-expressions
42 // and not types as found in <bits/type_traits.h>.  In particular, they
43 // can be used in control structures and the optimizer hopefully will do
44 // the obvious thing.
45 //
46 // Why integral expressions, and not functions nor types?
47 // Firstly, these compile-time entities are used as template-arguments
48 // so function return values won't work:  We need compile-time entities.
49 // We're left with types and constant  integral expressions.
50 // Secondly, from the point of view of ease of use, type-based compile-time
51 // information is -not- *that* convenient.  On has to write lots of
52 // overloaded functions and to hope that the compiler will select the right
53 // one. As a net effect, the overall structure isn't very clear at first
54 // glance.
55 // Thirdly, partial ordering and overload resolution (of function templates)
56 // is highly costly in terms of compiler-resource.  It is a Good Thing to
57 // keep these resource consumption as least as possible.
58 //
59 // See valarray_array.h for a case use.
60 //
61 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
62 //
63 // Update 2005: types are also provided and <bits/type_traits.h> has been
64 // removed.
65 //
66
67 extern "C++" {
68
69 namespace std _GLIBCXX_VISIBILITY(default)
70 {
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
72
73   struct __true_type { };
74   struct __false_type { };
75
76   template<bool>
77     struct __truth_type
78     { typedef __false_type __type; };
79
80   template<>
81     struct __truth_type<true>
82     { typedef __true_type __type; };
83
84   // N.B. The conversions to bool are needed due to the issue
85   // explained in c++/19404.
86   template<class _Sp, class _Tp>
87     struct __traitor
88     {
89       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
90       typedef typename __truth_type<__value>::__type __type;
91     };
92
93   // Compare for equality of types.
94   template<typename, typename>
95     struct __are_same
96     {
97       enum { __value = 0 };
98       typedef __false_type __type;
99     };
100
101   template<typename _Tp>
102     struct __are_same<_Tp, _Tp>
103     {
104       enum { __value = 1 };
105       typedef __true_type __type;
106     };
107
108   // Holds if the template-argument is a void type.
109   template<typename _Tp>
110     struct __is_void
111     {
112       enum { __value = 0 };
113       typedef __false_type __type;
114     };
115
116   template<>
117     struct __is_void<void>
118     {
119       enum { __value = 1 };
120       typedef __true_type __type;
121     };
122
123   //
124   // Integer types
125   //
126   template<typename _Tp>
127     struct __is_integer
128     {
129       enum { __value = 0 };
130       typedef __false_type __type;
131     };
132
133   // Thirteen specializations (yes there are eleven standard integer
134   // types; <em>long long</em> and <em>unsigned long long</em> are
135   // supported as extensions).  Up to four target-specific __int<N>
136   // types are supported as well.
137   template<>
138     struct __is_integer<bool>
139     {
140       enum { __value = 1 };
141       typedef __true_type __type;
142     };
143
144   template<>
145     struct __is_integer<char>
146     {
147       enum { __value = 1 };
148       typedef __true_type __type;
149     };
150
151   template<>
152     struct __is_integer<signed char>
153     {
154       enum { __value = 1 };
155       typedef __true_type __type;
156     };
157
158   template<>
159     struct __is_integer<unsigned char>
160     {
161       enum { __value = 1 };
162       typedef __true_type __type;
163     };
164
165 # ifdef _GLIBCXX_USE_WCHAR_T
166   template<>
167     struct __is_integer<wchar_t>
168     {
169       enum { __value = 1 };
170       typedef __true_type __type;
171     };
172 # endif
173
174 #if __cplusplus >= 201103L
175   template<>
176     struct __is_integer<char16_t>
177     {
178       enum { __value = 1 };
179       typedef __true_type __type;
180     };
181
182   template<>
183     struct __is_integer<char32_t>
184     {
185       enum { __value = 1 };
186       typedef __true_type __type;
187     };
188 #endif
189
190   template<>
191     struct __is_integer<short>
192     {
193       enum { __value = 1 };
194       typedef __true_type __type;
195     };
196
197   template<>
198     struct __is_integer<unsigned short>
199     {
200       enum { __value = 1 };
201       typedef __true_type __type;
202     };
203
204   template<>
205     struct __is_integer<int>
206     {
207       enum { __value = 1 };
208       typedef __true_type __type;
209     };
210
211   template<>
212     struct __is_integer<unsigned int>
213     {
214       enum { __value = 1 };
215       typedef __true_type __type;
216     };
217
218   template<>
219     struct __is_integer<long>
220     {
221       enum { __value = 1 };
222       typedef __true_type __type;
223     };
224
225   template<>
226     struct __is_integer<unsigned long>
227     {
228       enum { __value = 1 };
229       typedef __true_type __type;
230     };
231
232   template<>
233     struct __is_integer<long long>
234     {
235       enum { __value = 1 };
236       typedef __true_type __type;
237     };
238
239   template<>
240     struct __is_integer<unsigned long long>
241     {
242       enum { __value = 1 };
243       typedef __true_type __type;
244     };
245
246 #define __INT_N(TYPE)                   \
247   template<>                            \
248     struct __is_integer<TYPE>           \
249     {                                   \
250       enum { __value = 1 };             \
251       typedef __true_type __type;       \
252     };                                  \
253   template<>                            \
254     struct __is_integer<unsigned TYPE>  \
255     {                                   \
256       enum { __value = 1 };             \
257       typedef __true_type __type;       \
258     };
259
260 #ifdef __GLIBCXX_TYPE_INT_N_0
261 __INT_N(__GLIBCXX_TYPE_INT_N_0)
262 #endif
263 #ifdef __GLIBCXX_TYPE_INT_N_1
264 __INT_N(__GLIBCXX_TYPE_INT_N_1)
265 #endif
266 #ifdef __GLIBCXX_TYPE_INT_N_2
267 __INT_N(__GLIBCXX_TYPE_INT_N_2)
268 #endif
269 #ifdef __GLIBCXX_TYPE_INT_N_3
270 __INT_N(__GLIBCXX_TYPE_INT_N_3)
271 #endif
272
273 #undef __INT_N
274
275   //
276   // Floating point types
277   //
278   template<typename _Tp>
279     struct __is_floating
280     {
281       enum { __value = 0 };
282       typedef __false_type __type;
283     };
284
285   // three specializations (float, double and 'long double')
286   template<>
287     struct __is_floating<float>
288     {
289       enum { __value = 1 };
290       typedef __true_type __type;
291     };
292
293   template<>
294     struct __is_floating<double>
295     {
296       enum { __value = 1 };
297       typedef __true_type __type;
298     };
299
300   template<>
301     struct __is_floating<long double>
302     {
303       enum { __value = 1 };
304       typedef __true_type __type;
305     };
306
307   //
308   // Pointer types
309   //
310   template<typename _Tp>
311     struct __is_pointer
312     {
313       enum { __value = 0 };
314       typedef __false_type __type;
315     };
316
317   template<typename _Tp>
318     struct __is_pointer<_Tp*>
319     {
320       enum { __value = 1 };
321       typedef __true_type __type;
322     };
323
324   //
325   // An arithmetic type is an integer type or a floating point type
326   //
327   template<typename _Tp>
328     struct __is_arithmetic
329     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
330     { };
331
332   //
333   // A scalar type is an arithmetic type or a pointer type
334   // 
335   template<typename _Tp>
336     struct __is_scalar
337     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
338     { };
339
340   //
341   // For use in std::copy and std::find overloads for streambuf iterators.
342   //
343   template<typename _Tp>
344     struct __is_char
345     {
346       enum { __value = 0 };
347       typedef __false_type __type;
348     };
349
350   template<>
351     struct __is_char<char>
352     {
353       enum { __value = 1 };
354       typedef __true_type __type;
355     };
356
357 #ifdef _GLIBCXX_USE_WCHAR_T
358   template<>
359     struct __is_char<wchar_t>
360     {
361       enum { __value = 1 };
362       typedef __true_type __type;
363     };
364 #endif
365
366   template<typename _Tp>
367     struct __is_byte
368     {
369       enum { __value = 0 };
370       typedef __false_type __type;
371     };
372
373   template<>
374     struct __is_byte<char>
375     {
376       enum { __value = 1 };
377       typedef __true_type __type;
378     };
379
380   template<>
381     struct __is_byte<signed char>
382     {
383       enum { __value = 1 };
384       typedef __true_type __type;
385     };
386
387   template<>
388     struct __is_byte<unsigned char>
389     {
390       enum { __value = 1 };
391       typedef __true_type __type;
392     };
393
394   //
395   // Move iterator type
396   //
397   template<typename _Tp>
398     struct __is_move_iterator
399     {
400       enum { __value = 0 };
401       typedef __false_type __type;
402     };
403
404   // Fallback implementation of the function in bits/stl_iterator.h used to
405   // remove the move_iterator wrapper.
406   template<typename _Iterator>
407     inline _Iterator
408     __miter_base(_Iterator __it)
409     { return __it; }
410
411 _GLIBCXX_END_NAMESPACE_VERSION
412 } // namespace
413 } // extern "C++"
414
415 #endif //_CPP_TYPE_TRAITS_H