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   	
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
416