]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/libstdc++/include/bits/cpp_type_traits.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / libstdc++ / include / bits / cpp_type_traits.h
1 // The  -*- C++ -*- type traits classes for internal use in libstdc++
2
3 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 /** @file cpp_type_traits.h
32  *  This is an internal header file, included by other library headers.
33  *  You should not attempt to use it directly.
34  */
35
36 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
37
38 #ifndef _CPP_TYPE_TRAITS_H
39 #define _CPP_TYPE_TRAITS_H 1
40
41 #pragma GCC system_header
42
43 #include <bits/c++config.h>
44
45 //
46 // This file provides some compile-time information about various types.
47 // These representations were designed, on purpose, to be constant-expressions
48 // and not types as found in <bits/type_traits.h>.  In particular, they
49 // can be used in control structures and the optimizer hopefully will do
50 // the obvious thing.
51 //
52 // Why integral expressions, and not functions nor types?
53 // Firstly, these compile-time entities are used as template-arguments
54 // so function return values won't work:  We need compile-time entities.
55 // We're left with types and constant  integral expressions.
56 // Secondly, from the point of view of ease of use, type-based compile-time
57 // information is -not- *that* convenient.  On has to write lots of
58 // overloaded functions and to hope that the compiler will select the right
59 // one. As a net effect, the overall structure isn't very clear at first
60 // glance.
61 // Thirdly, partial ordering and overload resolution (of function templates)
62 // is highly costly in terms of compiler-resource.  It is a Good Thing to
63 // keep these resource consumption as least as possible.
64 //
65 // See valarray_array.h for a case use.
66 //
67 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
68 //
69 // Update 2005: types are also provided and <bits/type_traits.h> has been
70 // removed.
71 //
72
73 // Forward declaration hack, should really include this from somewhere.
74 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
75
76   template<typename _Iterator, typename _Container>
77     class __normal_iterator;
78
79 _GLIBCXX_END_NAMESPACE
80
81 _GLIBCXX_BEGIN_NAMESPACE(std)
82
83 #ifdef __clang__
84 // When using clang, suppress warnings about possible keywords (such as
85 // __is_void, __is_pod, etc) being used as identifiers.
86 #pragma clang diagnostic push
87 #pragma clang diagnostic ignored "-Wkeyword-compat"
88 #endif
89
90 namespace __detail
91 {
92   // NB: g++ can not compile these if declared within the class
93   // __is_pod itself.
94   typedef char __one;
95   typedef char __two[2];
96
97   template<typename _Tp>
98   __one __test_type(int _Tp::*);
99   template<typename _Tp>
100   __two& __test_type(...);
101 } // namespace __detail
102
103
104   struct __true_type { };
105   struct __false_type { };
106
107   template<bool>
108     struct __truth_type
109     { typedef __false_type __type; };
110
111   template<>
112     struct __truth_type<true>
113     { typedef __true_type __type; };
114
115   // N.B. The conversions to bool are needed due to the issue
116   // explained in c++/19404.
117   template<class _Sp, class _Tp>
118     struct __traitor
119     {
120       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
121       typedef typename __truth_type<__value>::__type __type;
122     };
123
124   // Compare for equality of types.
125   template<typename, typename>
126     struct __are_same
127     {
128       enum { __value = 0 };
129       typedef __false_type __type;
130     };
131
132   template<typename _Tp>
133     struct __are_same<_Tp, _Tp>
134     {
135       enum { __value = 1 };
136       typedef __true_type __type;
137     };
138
139   // Holds if the template-argument is a void type.
140   template<typename _Tp>
141     struct __is_void
142     {
143       enum { __value = 0 };
144       typedef __false_type __type;
145     };
146
147   template<>
148     struct __is_void<void>
149     {
150       enum { __value = 1 };
151       typedef __true_type __type;
152     };
153
154   //
155   // Integer types
156   //
157   template<typename _Tp>
158     struct __is_integer
159     {
160       enum { __value = 0 };
161       typedef __false_type __type;
162     };
163
164   // Thirteen specializations (yes there are eleven standard integer
165   // types; 'long long' and 'unsigned long long' are supported as
166   // extensions)
167   template<>
168     struct __is_integer<bool>
169     {
170       enum { __value = 1 };
171       typedef __true_type __type;
172     };
173
174   template<>
175     struct __is_integer<char>
176     {
177       enum { __value = 1 };
178       typedef __true_type __type;
179     };
180
181   template<>
182     struct __is_integer<signed char>
183     {
184       enum { __value = 1 };
185       typedef __true_type __type;
186     };
187
188   template<>
189     struct __is_integer<unsigned char>
190     {
191       enum { __value = 1 };
192       typedef __true_type __type;
193     };
194
195 # ifdef _GLIBCXX_USE_WCHAR_T
196   template<>
197     struct __is_integer<wchar_t>
198     {
199       enum { __value = 1 };
200       typedef __true_type __type;
201     };
202 # endif
203
204   template<>
205     struct __is_integer<short>
206     {
207       enum { __value = 1 };
208       typedef __true_type __type;
209     };
210
211   template<>
212     struct __is_integer<unsigned short>
213     {
214       enum { __value = 1 };
215       typedef __true_type __type;
216     };
217
218   template<>
219     struct __is_integer<int>
220     {
221       enum { __value = 1 };
222       typedef __true_type __type;
223     };
224
225   template<>
226     struct __is_integer<unsigned int>
227     {
228       enum { __value = 1 };
229       typedef __true_type __type;
230     };
231
232   template<>
233     struct __is_integer<long>
234     {
235       enum { __value = 1 };
236       typedef __true_type __type;
237     };
238
239   template<>
240     struct __is_integer<unsigned long>
241     {
242       enum { __value = 1 };
243       typedef __true_type __type;
244     };
245
246   template<>
247     struct __is_integer<long long>
248     {
249       enum { __value = 1 };
250       typedef __true_type __type;
251     };
252
253   template<>
254     struct __is_integer<unsigned long long>
255     {
256       enum { __value = 1 };
257       typedef __true_type __type;
258     };
259
260   //
261   // Floating point types
262   //
263   template<typename _Tp>
264     struct __is_floating
265     {
266       enum { __value = 0 };
267       typedef __false_type __type;
268     };
269
270   // three specializations (float, double and 'long double')
271   template<>
272     struct __is_floating<float>
273     {
274       enum { __value = 1 };
275       typedef __true_type __type;
276     };
277
278   template<>
279     struct __is_floating<double>
280     {
281       enum { __value = 1 };
282       typedef __true_type __type;
283     };
284
285   template<>
286     struct __is_floating<long double>
287     {
288       enum { __value = 1 };
289       typedef __true_type __type;
290     };
291
292   //
293   // Pointer types
294   //
295   template<typename _Tp>
296     struct __is_pointer
297     {
298       enum { __value = 0 };
299       typedef __false_type __type;
300     };
301
302   template<typename _Tp>
303     struct __is_pointer<_Tp*>
304     {
305       enum { __value = 1 };
306       typedef __true_type __type;
307     };
308
309   //
310   // Normal iterator type
311   //
312   template<typename _Tp>
313     struct __is_normal_iterator
314     {
315       enum { __value = 0 };
316       typedef __false_type __type;
317     };
318
319   template<typename _Iterator, typename _Container>
320     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
321                                                               _Container> >
322     {
323       enum { __value = 1 };
324       typedef __true_type __type;
325     };
326
327   //
328   // An arithmetic type is an integer type or a floating point type
329   //
330   template<typename _Tp>
331     struct __is_arithmetic
332     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
333     { };
334
335   //
336   // A fundamental type is `void' or and arithmetic type
337   //
338   template<typename _Tp>
339     struct __is_fundamental
340     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
341     { };
342
343   //
344   // A scalar type is an arithmetic type or a pointer type
345   // 
346   template<typename _Tp>
347     struct __is_scalar
348     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
349     { };
350
351   // For the immediate use, the following is a good approximation.
352   template<typename _Tp>
353     struct __is_pod
354     {
355       enum
356         {
357           __value = (sizeof(__detail::__test_type<_Tp>(0))
358                      != sizeof(__detail::__one))
359         };
360     };
361
362   //
363   // A stripped-down version of std::tr1::is_empty
364   //
365   template<typename _Tp>
366     struct __is_empty
367     { 
368     private:
369       template<typename>
370         struct __first { };
371       template<typename _Up>
372         struct __second
373         : public _Up { };
374            
375     public:
376       enum
377         {
378           __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
379         };
380     };
381
382   //
383   // For use in std::copy and std::find overloads for streambuf iterators.
384   //
385   template<typename _Tp>
386     struct __is_char
387     {
388       enum { __value = 0 };
389       typedef __false_type __type;
390     };
391
392   template<>
393     struct __is_char<char>
394     {
395       enum { __value = 1 };
396       typedef __true_type __type;
397     };
398
399 #ifdef _GLIBCXX_USE_WCHAR_T
400   template<>
401     struct __is_char<wchar_t>
402     {
403       enum { __value = 1 };
404       typedef __true_type __type;
405     };
406 #endif
407
408 #ifdef __clang__
409 #pragma clang diagnostic pop
410 #endif
411
412 _GLIBCXX_END_NAMESPACE
413
414 #endif //_CPP_TYPE_TRAITS_H