Clang Project

include/c++/7/bits/cpp_type_traits.h
1// The  -*- C++ -*- type traits classes for internal use in libstdc++
2
3// Copyright (C) 2000-2017 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
67extern "C++" {
68
69namespace 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<typenametypename>
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
165ifdef _GLIBCXX_USE_WCHAR_T
166  template<>
167    struct __is_integer<wchar_t>
168    {
169      enum { __value = 1 };
170      typedef __true_type __type;
171    };
172endif
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
416