197403Sobrien// The  -*- C++ -*- type traits classes for internal use in libstdc++
297403Sobrien
3169691Skan// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
4169691Skan// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien/** @file cpp_type_traits.h
3297403Sobrien *  This is an internal header file, included by other library headers.
3397403Sobrien *  You should not attempt to use it directly.
3497403Sobrien */
3597403Sobrien
36169691Skan// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
37169691Skan
38132720Skan#ifndef _CPP_TYPE_TRAITS_H
39132720Skan#define _CPP_TYPE_TRAITS_H 1
4097403Sobrien
4197403Sobrien#pragma GCC system_header
4297403Sobrien
43169691Skan#include <bits/c++config.h>
44169691Skan
4597403Sobrien//
4697403Sobrien// This file provides some compile-time information about various types.
4797403Sobrien// These representations were designed, on purpose, to be constant-expressions
48169691Skan// and not types as found in <bits/type_traits.h>.  In particular, they
4997403Sobrien// can be used in control structures and the optimizer hopefully will do
5097403Sobrien// the obvious thing.
5197403Sobrien//
5297403Sobrien// Why integral expressions, and not functions nor types?
5397403Sobrien// Firstly, these compile-time entities are used as template-arguments
5497403Sobrien// so function return values won't work:  We need compile-time entities.
5597403Sobrien// We're left with types and constant  integral expressions.
5697403Sobrien// Secondly, from the point of view of ease of use, type-based compile-time
5797403Sobrien// information is -not- *that* convenient.  On has to write lots of
5897403Sobrien// overloaded functions and to hope that the compiler will select the right
5997403Sobrien// one. As a net effect, the overall structure isn't very clear at first
6097403Sobrien// glance.
6197403Sobrien// Thirdly, partial ordering and overload resolution (of function templates)
6297403Sobrien// is highly costly in terms of compiler-resource.  It is a Good Thing to
6397403Sobrien// keep these resource consumption as least as possible.
6497403Sobrien//
6597403Sobrien// See valarray_array.h for a case use.
6697403Sobrien//
6797403Sobrien// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
6897403Sobrien//
69169691Skan// Update 2005: types are also provided and <bits/type_traits.h> has been
70169691Skan// removed.
71169691Skan//
7297403Sobrien
73169691Skan// Forward declaration hack, should really include this from somewhere.
74169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
75169691Skan
76169691Skan  template<typename _Iterator, typename _Container>
77169691Skan    class __normal_iterator;
78169691Skan
79169691Skan_GLIBCXX_END_NAMESPACE
80169691Skan
81169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
82169691Skan
83263774Sdim#ifdef __clang__
84263774Sdim// When using clang, suppress warnings about possible keywords (such as
85263774Sdim// __is_void, __is_pod, etc) being used as identifiers.
86263774Sdim#pragma clang diagnostic push
87263774Sdim#pragma clang diagnostic ignored "-Wkeyword-compat"
88263774Sdim#endif
89263774Sdim
90169691Skannamespace __detail
91132720Skan{
92169691Skan  // NB: g++ can not compile these if declared within the class
93169691Skan  // __is_pod itself.
94132720Skan  typedef char __one;
95132720Skan  typedef char __two[2];
96132720Skan
97169691Skan  template<typename _Tp>
98169691Skan  __one __test_type(int _Tp::*);
99169691Skan  template<typename _Tp>
100169691Skan  __two& __test_type(...);
101169691Skan} // namespace __detail
102132720Skan
103169691Skan
104169691Skan  struct __true_type { };
105169691Skan  struct __false_type { };
106169691Skan
107169691Skan  template<bool>
108169691Skan    struct __truth_type
109169691Skan    { typedef __false_type __type; };
110169691Skan
111169691Skan  template<>
112169691Skan    struct __truth_type<true>
113169691Skan    { typedef __true_type __type; };
114169691Skan
115169691Skan  // N.B. The conversions to bool are needed due to the issue
116169691Skan  // explained in c++/19404.
117169691Skan  template<class _Sp, class _Tp>
118169691Skan    struct __traitor
119169691Skan    {
120169691Skan      enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
121169691Skan      typedef typename __truth_type<__value>::__type __type;
122169691Skan    };
123169691Skan
124132720Skan  // Compare for equality of types.
125132720Skan  template<typename, typename>
126132720Skan    struct __are_same
127132720Skan    {
128169691Skan      enum { __value = 0 };
129169691Skan      typedef __false_type __type;
130132720Skan    };
131132720Skan
13297403Sobrien  template<typename _Tp>
133132720Skan    struct __are_same<_Tp, _Tp>
134132720Skan    {
135169691Skan      enum { __value = 1 };
136169691Skan      typedef __true_type __type;
137132720Skan    };
138132720Skan
139132720Skan  // Holds if the template-argument is a void type.
140132720Skan  template<typename _Tp>
14197403Sobrien    struct __is_void
14297403Sobrien    {
143169691Skan      enum { __value = 0 };
144169691Skan      typedef __false_type __type;
14597403Sobrien    };
14697403Sobrien
14797403Sobrien  template<>
14897403Sobrien    struct __is_void<void>
14997403Sobrien    {
150169691Skan      enum { __value = 1 };
151169691Skan      typedef __true_type __type;
15297403Sobrien    };
15397403Sobrien
15497403Sobrien  //
15597403Sobrien  // Integer types
15697403Sobrien  //
15797403Sobrien  template<typename _Tp>
15897403Sobrien    struct __is_integer
15997403Sobrien    {
160169691Skan      enum { __value = 0 };
161169691Skan      typedef __false_type __type;
16297403Sobrien    };
16397403Sobrien
16497403Sobrien  // Thirteen specializations (yes there are eleven standard integer
16597403Sobrien  // types; 'long long' and 'unsigned long long' are supported as
16697403Sobrien  // extensions)
16797403Sobrien  template<>
16897403Sobrien    struct __is_integer<bool>
16997403Sobrien    {
170169691Skan      enum { __value = 1 };
171169691Skan      typedef __true_type __type;
17297403Sobrien    };
173132720Skan
17497403Sobrien  template<>
17597403Sobrien    struct __is_integer<char>
17697403Sobrien    {
177169691Skan      enum { __value = 1 };
178169691Skan      typedef __true_type __type;
17997403Sobrien    };
18097403Sobrien
18197403Sobrien  template<>
18297403Sobrien    struct __is_integer<signed char>
18397403Sobrien    {
184169691Skan      enum { __value = 1 };
185169691Skan      typedef __true_type __type;
18697403Sobrien    };
187132720Skan
18897403Sobrien  template<>
189132720Skan    struct __is_integer<unsigned char>
19097403Sobrien    {
191169691Skan      enum { __value = 1 };
192169691Skan      typedef __true_type __type;
19397403Sobrien    };
19497403Sobrien
195132720Skan# ifdef _GLIBCXX_USE_WCHAR_T
19697403Sobrien  template<>
197132720Skan    struct __is_integer<wchar_t>
19897403Sobrien    {
199169691Skan      enum { __value = 1 };
200169691Skan      typedef __true_type __type;
20197403Sobrien    };
20297403Sobrien# endif
203132720Skan
20497403Sobrien  template<>
205132720Skan    struct __is_integer<short>
20697403Sobrien    {
207169691Skan      enum { __value = 1 };
208169691Skan      typedef __true_type __type;
20997403Sobrien    };
21097403Sobrien
21197403Sobrien  template<>
212132720Skan    struct __is_integer<unsigned short>
21397403Sobrien    {
214169691Skan      enum { __value = 1 };
215169691Skan      typedef __true_type __type;
21697403Sobrien    };
21797403Sobrien
21897403Sobrien  template<>
219132720Skan    struct __is_integer<int>
22097403Sobrien    {
221169691Skan      enum { __value = 1 };
222169691Skan      typedef __true_type __type;
22397403Sobrien    };
22497403Sobrien
22597403Sobrien  template<>
226132720Skan    struct __is_integer<unsigned int>
22797403Sobrien    {
228169691Skan      enum { __value = 1 };
229169691Skan      typedef __true_type __type;
23097403Sobrien    };
23197403Sobrien
23297403Sobrien  template<>
233132720Skan    struct __is_integer<long>
23497403Sobrien    {
235169691Skan      enum { __value = 1 };
236169691Skan      typedef __true_type __type;
23797403Sobrien    };
23897403Sobrien
23997403Sobrien  template<>
240132720Skan    struct __is_integer<unsigned long>
24197403Sobrien    {
242169691Skan      enum { __value = 1 };
243169691Skan      typedef __true_type __type;
24497403Sobrien    };
24597403Sobrien
24697403Sobrien  template<>
247132720Skan    struct __is_integer<long long>
24897403Sobrien    {
249169691Skan      enum { __value = 1 };
250169691Skan      typedef __true_type __type;
25197403Sobrien    };
25297403Sobrien
25397403Sobrien  template<>
254132720Skan    struct __is_integer<unsigned long long>
25597403Sobrien    {
256169691Skan      enum { __value = 1 };
257169691Skan      typedef __true_type __type;
25897403Sobrien    };
25997403Sobrien
26097403Sobrien  //
26197403Sobrien  // Floating point types
26297403Sobrien  //
26397403Sobrien  template<typename _Tp>
264132720Skan    struct __is_floating
26597403Sobrien    {
266169691Skan      enum { __value = 0 };
267169691Skan      typedef __false_type __type;
26897403Sobrien    };
26997403Sobrien
27097403Sobrien  // three specializations (float, double and 'long double')
27197403Sobrien  template<>
272132720Skan    struct __is_floating<float>
27397403Sobrien    {
274169691Skan      enum { __value = 1 };
275169691Skan      typedef __true_type __type;
27697403Sobrien    };
27797403Sobrien
27897403Sobrien  template<>
279132720Skan    struct __is_floating<double>
28097403Sobrien    {
281169691Skan      enum { __value = 1 };
282169691Skan      typedef __true_type __type;
28397403Sobrien    };
28497403Sobrien
28597403Sobrien  template<>
286132720Skan    struct __is_floating<long double>
28797403Sobrien    {
288169691Skan      enum { __value = 1 };
289169691Skan      typedef __true_type __type;
29097403Sobrien    };
29197403Sobrien
29297403Sobrien  //
293169691Skan  // Pointer types
29497403Sobrien  //
29597403Sobrien  template<typename _Tp>
296169691Skan    struct __is_pointer
29797403Sobrien    {
298169691Skan      enum { __value = 0 };
299169691Skan      typedef __false_type __type;
30097403Sobrien    };
301169691Skan
302169691Skan  template<typename _Tp>
303169691Skan    struct __is_pointer<_Tp*>
304169691Skan    {
305169691Skan      enum { __value = 1 };
306169691Skan      typedef __true_type __type;
307169691Skan    };
308169691Skan
30997403Sobrien  //
310169691Skan  // Normal iterator type
311169691Skan  //
312169691Skan  template<typename _Tp>
313169691Skan    struct __is_normal_iterator
314169691Skan    {
315169691Skan      enum { __value = 0 };
316169691Skan      typedef __false_type __type;
317169691Skan    };
318169691Skan
319169691Skan  template<typename _Iterator, typename _Container>
320169691Skan    struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
321169691Skan							      _Container> >
322169691Skan    {
323169691Skan      enum { __value = 1 };
324169691Skan      typedef __true_type __type;
325169691Skan    };
326169691Skan
327169691Skan  //
328169691Skan  // An arithmetic type is an integer type or a floating point type
329169691Skan  //
330169691Skan  template<typename _Tp>
331169691Skan    struct __is_arithmetic
332169691Skan    : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
333169691Skan    { };
334169691Skan
335169691Skan  //
33697403Sobrien  // A fundamental type is `void' or and arithmetic type
33797403Sobrien  //
33897403Sobrien  template<typename _Tp>
339132720Skan    struct __is_fundamental
340169691Skan    : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
341169691Skan    { };
342169691Skan
343169691Skan  //
344169691Skan  // A scalar type is an arithmetic type or a pointer type
345169691Skan  //
346169691Skan  template<typename _Tp>
347169691Skan    struct __is_scalar
348169691Skan    : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
349169691Skan    { };
350169691Skan
351169691Skan  // For the immediate use, the following is a good approximation.
352169691Skan  template<typename _Tp>
353169691Skan    struct __is_pod
35497403Sobrien    {
355132720Skan      enum
356132720Skan	{
357169691Skan	  __value = (sizeof(__detail::__test_type<_Tp>(0))
358169691Skan		     != sizeof(__detail::__one))
359132720Skan	};
36097403Sobrien    };
36197403Sobrien
36297403Sobrien  //
363169691Skan  // A stripped-down version of std::tr1::is_empty
36497403Sobrien  //
36597403Sobrien  template<typename _Tp>
366169691Skan    struct __is_empty
367169691Skan    {
368169691Skan    private:
369169691Skan      template<typename>
370169691Skan        struct __first { };
371169691Skan      template<typename _Up>
372169691Skan        struct __second
373169691Skan        : public _Up { };
374169691Skan
375169691Skan    public:
376132720Skan      enum
377132720Skan	{
378169691Skan	  __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
379132720Skan	};
38097403Sobrien    };
38197403Sobrien
382169691Skan  //
383169691Skan  // For use in std::copy and std::find overloads for streambuf iterators.
384169691Skan  //
385169691Skan  template<typename _Tp>
386169691Skan    struct __is_char
387169691Skan    {
388169691Skan      enum { __value = 0 };
389169691Skan      typedef __false_type __type;
390169691Skan    };
39197403Sobrien
392169691Skan  template<>
393169691Skan    struct __is_char<char>
394169691Skan    {
395169691Skan      enum { __value = 1 };
396169691Skan      typedef __true_type __type;
397169691Skan    };
398169691Skan
399169691Skan#ifdef _GLIBCXX_USE_WCHAR_T
400169691Skan  template<>
401169691Skan    struct __is_char<wchar_t>
402169691Skan    {
403169691Skan      enum { __value = 1 };
404169691Skan      typedef __true_type __type;
405169691Skan    };
406169691Skan#endif
407169691Skan
408263774Sdim#ifdef __clang__
409263774Sdim#pragma clang diagnostic pop
410263774Sdim#endif
411263774Sdim
412169691Skan_GLIBCXX_END_NAMESPACE
413169691Skan
414132720Skan#endif //_CPP_TYPE_TRAITS_H
415