libstdc++
type_traits.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2005-2017 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file ext/type_traits.h
00026  *  This file is a GNU extension to the Standard C++ Library.
00027  */
00028 
00029 #ifndef _EXT_TYPE_TRAITS
00030 #define _EXT_TYPE_TRAITS 1
00031 
00032 #pragma GCC system_header
00033 
00034 #include <bits/c++config.h>
00035 #include <bits/cpp_type_traits.h>
00036 
00037 extern "C++" {
00038 
00039 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00040 {
00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00042 
00043   // Define a nested type if some predicate holds.
00044   template<bool, typename>
00045     struct __enable_if 
00046     { };
00047 
00048   template<typename _Tp>
00049     struct __enable_if<true, _Tp>
00050     { typedef _Tp __type; };
00051 
00052 
00053   // Conditional expression for types. If true, first, if false, second.
00054   template<bool _Cond, typename _Iftrue, typename _Iffalse>
00055     struct __conditional_type
00056     { typedef _Iftrue __type; };
00057 
00058   template<typename _Iftrue, typename _Iffalse>
00059     struct __conditional_type<false, _Iftrue, _Iffalse>
00060     { typedef _Iffalse __type; };
00061 
00062 
00063   // Given an integral builtin type, return the corresponding unsigned type.
00064   template<typename _Tp>
00065     struct __add_unsigned
00066     { 
00067     private:
00068       typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
00069       
00070     public:
00071       typedef typename __if_type::__type __type; 
00072     };
00073 
00074   template<>
00075     struct __add_unsigned<char>
00076     { typedef unsigned char __type; };
00077 
00078   template<>
00079     struct __add_unsigned<signed char>
00080     { typedef unsigned char __type; };
00081 
00082   template<>
00083     struct __add_unsigned<short>
00084     { typedef unsigned short __type; };
00085 
00086   template<>
00087     struct __add_unsigned<int>
00088     { typedef unsigned int __type; };
00089 
00090   template<>
00091     struct __add_unsigned<long>
00092     { typedef unsigned long __type; };
00093 
00094   template<>
00095     struct __add_unsigned<long long>
00096     { typedef unsigned long long __type; };
00097 
00098   // Declare but don't define.
00099   template<>
00100     struct __add_unsigned<bool>;
00101 
00102   template<>
00103     struct __add_unsigned<wchar_t>;
00104 
00105 
00106   // Given an integral builtin type, return the corresponding signed type.
00107   template<typename _Tp>
00108     struct __remove_unsigned
00109     { 
00110     private:
00111       typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
00112       
00113     public:
00114       typedef typename __if_type::__type __type; 
00115     };
00116 
00117   template<>
00118     struct __remove_unsigned<char>
00119     { typedef signed char __type; };
00120 
00121   template<>
00122     struct __remove_unsigned<unsigned char>
00123     { typedef signed char __type; };
00124 
00125   template<>
00126     struct __remove_unsigned<unsigned short>
00127     { typedef short __type; };
00128 
00129   template<>
00130     struct __remove_unsigned<unsigned int>
00131     { typedef int __type; };
00132 
00133   template<>
00134     struct __remove_unsigned<unsigned long>
00135     { typedef long __type; };
00136 
00137   template<>
00138     struct __remove_unsigned<unsigned long long>
00139     { typedef long long __type; };
00140 
00141   // Declare but don't define.
00142   template<>
00143     struct __remove_unsigned<bool>;
00144 
00145   template<>
00146     struct __remove_unsigned<wchar_t>;
00147 
00148 
00149   // For use in string and vstring.
00150   template<typename _Type>
00151     inline bool
00152     __is_null_pointer(_Type* __ptr)
00153     { return __ptr == 0; }
00154 
00155   template<typename _Type>
00156     inline bool
00157     __is_null_pointer(_Type)
00158     { return false; }
00159 
00160 #if __cplusplus >= 201103L
00161   inline bool
00162   __is_null_pointer(std::nullptr_t)
00163   { return true; }
00164 #endif
00165 
00166   // For complex and cmath
00167   template<typename _Tp, bool = std::__is_integer<_Tp>::__value>
00168     struct __promote
00169     { typedef double __type; };
00170 
00171   // No nested __type member for non-integer non-floating point types,
00172   // allows this type to be used for SFINAE to constrain overloads in
00173   // <cmath> and <complex> to only the intended types.
00174   template<typename _Tp>
00175     struct __promote<_Tp, false>
00176     { };
00177 
00178   template<>
00179     struct __promote<long double>
00180     { typedef long double __type; };
00181 
00182   template<>
00183     struct __promote<double>
00184     { typedef double __type; };
00185 
00186   template<>
00187     struct __promote<float>
00188     { typedef float __type; };
00189 
00190   template<typename _Tp, typename _Up,
00191            typename _Tp2 = typename __promote<_Tp>::__type,
00192            typename _Up2 = typename __promote<_Up>::__type>
00193     struct __promote_2
00194     {
00195       typedef __typeof__(_Tp2() + _Up2()) __type;
00196     };
00197 
00198   template<typename _Tp, typename _Up, typename _Vp,
00199            typename _Tp2 = typename __promote<_Tp>::__type,
00200            typename _Up2 = typename __promote<_Up>::__type,
00201            typename _Vp2 = typename __promote<_Vp>::__type>
00202     struct __promote_3
00203     {
00204       typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type;
00205     };
00206 
00207   template<typename _Tp, typename _Up, typename _Vp, typename _Wp,
00208            typename _Tp2 = typename __promote<_Tp>::__type,
00209            typename _Up2 = typename __promote<_Up>::__type,
00210            typename _Vp2 = typename __promote<_Vp>::__type,
00211            typename _Wp2 = typename __promote<_Wp>::__type>
00212     struct __promote_4
00213     {
00214       typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type;
00215     };
00216 
00217 _GLIBCXX_END_NAMESPACE_VERSION
00218 } // namespace
00219 } // extern "C++"
00220 
00221 #endif