| // The -*- C++ -*- type traits classes for internal use in libstdc++ |
| |
| // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 |
| // Free Software Foundation, Inc. |
| // |
| // This file is part of the GNU ISO C++ Library. This library is free |
| // software; you can redistribute it and/or modify it under the |
| // terms of the GNU General Public License as published by the |
| // Free Software Foundation; either version 3, or (at your option) |
| // any later version. |
| |
| // This library is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| |
| // Under Section 7 of GPL version 3, you are granted additional |
| // permissions described in the GCC Runtime Library Exception, version |
| // 3.1, as published by the Free Software Foundation. |
| |
| // You should have received a copy of the GNU General Public License and |
| // a copy of the GCC Runtime Library Exception along with this program; |
| // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
| // <http://www.gnu.org/licenses/>. |
| |
| /** @file cpp_type_traits.h |
| * This is an internal header file, included by other library headers. |
| * You should not attempt to use it directly. |
| */ |
| |
| // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> |
| |
| #ifndef _CPP_TYPE_TRAITS_H |
| #define _CPP_TYPE_TRAITS_H 1 |
| |
| #pragma GCC system_header |
| |
| #include <bits/c++config.h> |
| |
| // |
| // This file provides some compile-time information about various types. |
| // These representations were designed, on purpose, to be constant-expressions |
| // and not types as found in <bits/type_traits.h>. In particular, they |
| // can be used in control structures and the optimizer hopefully will do |
| // the obvious thing. |
| // |
| // Why integral expressions, and not functions nor types? |
| // Firstly, these compile-time entities are used as template-arguments |
| // so function return values won't work: We need compile-time entities. |
| // We're left with types and constant integral expressions. |
| // Secondly, from the point of view of ease of use, type-based compile-time |
| // information is -not- *that* convenient. On has to write lots of |
| // overloaded functions and to hope that the compiler will select the right |
| // one. As a net effect, the overall structure isn't very clear at first |
| // glance. |
| // Thirdly, partial ordering and overload resolution (of function templates) |
| // is highly costly in terms of compiler-resource. It is a Good Thing to |
| // keep these resource consumption as least as possible. |
| // |
| // See valarray_array.h for a case use. |
| // |
| // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. |
| // |
| // Update 2005: types are also provided and <bits/type_traits.h> has been |
| // removed. |
| // |
| |
| // Forward declaration hack, should really include this from somewhere. |
| _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) |
| |
| template<typename _Iterator, typename _Container> |
| class __normal_iterator; |
| |
| _GLIBCXX_END_NAMESPACE |
| |
| _GLIBCXX_BEGIN_NAMESPACE(std) |
| |
| struct __true_type { }; |
| struct __false_type { }; |
| |
| template<bool> |
| struct __truth_type |
| { typedef __false_type __type; }; |
| |
| template<> |
| struct __truth_type<true> |
| { typedef __true_type __type; }; |
| |
| // N.B. The conversions to bool are needed due to the issue |
| // explained in c++/19404. |
| template<class _Sp, class _Tp> |
| struct __traitor |
| { |
| enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; |
| typedef typename __truth_type<__value>::__type __type; |
| }; |
| |
| // Compare for equality of types. |
| template<typename, typename> |
| struct __are_same |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| template<typename _Tp> |
| struct __are_same<_Tp, _Tp> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| // Holds if the template-argument is a void type. |
| template<typename _Tp> |
| struct __is_void |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| template<> |
| struct __is_void<void> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| // |
| // Integer types |
| // |
| template<typename _Tp> |
| struct __is_integer |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| // Thirteen specializations (yes there are eleven standard integer |
| // types; <em>long long</em> and <em>unsigned long long</em> are |
| // supported as extensions) |
| template<> |
| struct __is_integer<bool> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<char> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<signed char> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<unsigned char> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| # ifdef _GLIBCXX_USE_WCHAR_T |
| template<> |
| struct __is_integer<wchar_t> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| # endif |
| |
| #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
| template<> |
| struct __is_integer<char16_t> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<char32_t> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| #endif |
| |
| template<> |
| struct __is_integer<short> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<unsigned short> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<int> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<unsigned int> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<long> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<unsigned long> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<long long> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_integer<unsigned long long> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| // |
| // Floating point types |
| // |
| template<typename _Tp> |
| struct __is_floating |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| // three specializations (float, double and 'long double') |
| template<> |
| struct __is_floating<float> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_floating<double> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_floating<long double> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| // |
| // Pointer types |
| // |
| template<typename _Tp> |
| struct __is_pointer |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| template<typename _Tp> |
| struct __is_pointer<_Tp*> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| // |
| // Normal iterator type |
| // |
| template<typename _Tp> |
| struct __is_normal_iterator |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| template<typename _Iterator, typename _Container> |
| struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, |
| _Container> > |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| // |
| // An arithmetic type is an integer type or a floating point type |
| // |
| template<typename _Tp> |
| struct __is_arithmetic |
| : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > |
| { }; |
| |
| // |
| // A fundamental type is `void' or and arithmetic type |
| // |
| template<typename _Tp> |
| struct __is_fundamental |
| : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > |
| { }; |
| |
| // |
| // A scalar type is an arithmetic type or a pointer type |
| // |
| template<typename _Tp> |
| struct __is_scalar |
| : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > |
| { }; |
| |
| // |
| // For use in std::copy and std::find overloads for streambuf iterators. |
| // |
| template<typename _Tp> |
| struct __is_char |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| template<> |
| struct __is_char<char> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| #ifdef _GLIBCXX_USE_WCHAR_T |
| template<> |
| struct __is_char<wchar_t> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| #endif |
| |
| template<typename _Tp> |
| struct __is_byte |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| template<> |
| struct __is_byte<char> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_byte<signed char> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| template<> |
| struct __is_byte<unsigned char> |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| |
| // |
| // Move iterator type |
| // |
| template<typename _Tp> |
| struct __is_move_iterator |
| { |
| enum { __value = 0 }; |
| typedef __false_type __type; |
| }; |
| |
| #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
| template<typename _Iterator> |
| class move_iterator; |
| |
| template<typename _Iterator> |
| struct __is_move_iterator< move_iterator<_Iterator> > |
| { |
| enum { __value = 1 }; |
| typedef __true_type __type; |
| }; |
| #endif |
| |
| template<typename _Tp> |
| class __is_iterator_helper |
| { |
| typedef char __one; |
| typedef struct { char __arr[2]; } __two; |
| |
| template<typename _Up> |
| struct _Wrap_type |
| { }; |
| |
| template<typename _Up> |
| static __one __test(_Wrap_type<typename _Up::iterator_category>*); |
| |
| template<typename _Up> |
| static __two __test(...); |
| |
| public: |
| static const bool __value = (sizeof(__test<_Tp>(0)) == 1 |
| || __is_pointer<_Tp>::__value); |
| }; |
| |
| template<typename _Tp> |
| struct __is_iterator |
| { |
| enum { __value = __is_iterator_helper<_Tp>::__value }; |
| typedef typename __truth_type<__value>::__type __type; |
| }; |
| |
| _GLIBCXX_END_NAMESPACE |
| |
| #endif //_CPP_TYPE_TRAITS_H |