libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005-2015 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 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00038 { 00039 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00040 00041 // Define a nested type if some predicate holds. 00042 template<bool, typename> 00043 struct __enable_if 00044 { }; 00045 00046 template<typename _Tp> 00047 struct __enable_if<true, _Tp> 00048 { typedef _Tp __type; }; 00049 00050 00051 // Conditional expression for types. If true, first, if false, second. 00052 template<bool _Cond, typename _Iftrue, typename _Iffalse> 00053 struct __conditional_type 00054 { typedef _Iftrue __type; }; 00055 00056 template<typename _Iftrue, typename _Iffalse> 00057 struct __conditional_type<false, _Iftrue, _Iffalse> 00058 { typedef _Iffalse __type; }; 00059 00060 00061 // Given an integral builtin type, return the corresponding unsigned type. 00062 template<typename _Tp> 00063 struct __add_unsigned 00064 { 00065 private: 00066 typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; 00067 00068 public: 00069 typedef typename __if_type::__type __type; 00070 }; 00071 00072 template<> 00073 struct __add_unsigned<char> 00074 { typedef unsigned char __type; }; 00075 00076 template<> 00077 struct __add_unsigned<signed char> 00078 { typedef unsigned char __type; }; 00079 00080 template<> 00081 struct __add_unsigned<short> 00082 { typedef unsigned short __type; }; 00083 00084 template<> 00085 struct __add_unsigned<int> 00086 { typedef unsigned int __type; }; 00087 00088 template<> 00089 struct __add_unsigned<long> 00090 { typedef unsigned long __type; }; 00091 00092 template<> 00093 struct __add_unsigned<long long> 00094 { typedef unsigned long long __type; }; 00095 00096 // Declare but don't define. 00097 template<> 00098 struct __add_unsigned<bool>; 00099 00100 template<> 00101 struct __add_unsigned<wchar_t>; 00102 00103 00104 // Given an integral builtin type, return the corresponding signed type. 00105 template<typename _Tp> 00106 struct __remove_unsigned 00107 { 00108 private: 00109 typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; 00110 00111 public: 00112 typedef typename __if_type::__type __type; 00113 }; 00114 00115 template<> 00116 struct __remove_unsigned<char> 00117 { typedef signed char __type; }; 00118 00119 template<> 00120 struct __remove_unsigned<unsigned char> 00121 { typedef signed char __type; }; 00122 00123 template<> 00124 struct __remove_unsigned<unsigned short> 00125 { typedef short __type; }; 00126 00127 template<> 00128 struct __remove_unsigned<unsigned int> 00129 { typedef int __type; }; 00130 00131 template<> 00132 struct __remove_unsigned<unsigned long> 00133 { typedef long __type; }; 00134 00135 template<> 00136 struct __remove_unsigned<unsigned long long> 00137 { typedef long long __type; }; 00138 00139 // Declare but don't define. 00140 template<> 00141 struct __remove_unsigned<bool>; 00142 00143 template<> 00144 struct __remove_unsigned<wchar_t>; 00145 00146 00147 // For use in string and vstring. 00148 template<typename _Type> 00149 inline bool 00150 __is_null_pointer(_Type* __ptr) 00151 { return __ptr == 0; } 00152 00153 template<typename _Type> 00154 inline bool 00155 __is_null_pointer(_Type) 00156 { return false; } 00157 00158 #if __cplusplus >= 201103L 00159 inline bool 00160 __is_null_pointer(std::nullptr_t) 00161 { return true; } 00162 #endif 00163 00164 // For complex and cmath 00165 template<typename _Tp, bool = std::__is_integer<_Tp>::__value> 00166 struct __promote 00167 { typedef double __type; }; 00168 00169 // No nested __type member for non-integer non-floating point types, 00170 // allows this type to be used for SFINAE to constrain overloads in 00171 // <cmath> and <complex> to only the intended types. 00172 template<typename _Tp> 00173 struct __promote<_Tp, false> 00174 { }; 00175 00176 template<> 00177 struct __promote<long double> 00178 { typedef long double __type; }; 00179 00180 template<> 00181 struct __promote<double> 00182 { typedef double __type; }; 00183 00184 template<> 00185 struct __promote<float> 00186 { typedef float __type; }; 00187 00188 template<typename _Tp, typename _Up, 00189 typename _Tp2 = typename __promote<_Tp>::__type, 00190 typename _Up2 = typename __promote<_Up>::__type> 00191 struct __promote_2 00192 { 00193 typedef __typeof__(_Tp2() + _Up2()) __type; 00194 }; 00195 00196 template<typename _Tp, typename _Up, typename _Vp, 00197 typename _Tp2 = typename __promote<_Tp>::__type, 00198 typename _Up2 = typename __promote<_Up>::__type, 00199 typename _Vp2 = typename __promote<_Vp>::__type> 00200 struct __promote_3 00201 { 00202 typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type; 00203 }; 00204 00205 template<typename _Tp, typename _Up, typename _Vp, typename _Wp, 00206 typename _Tp2 = typename __promote<_Tp>::__type, 00207 typename _Up2 = typename __promote<_Up>::__type, 00208 typename _Vp2 = typename __promote<_Vp>::__type, 00209 typename _Wp2 = typename __promote<_Wp>::__type> 00210 struct __promote_4 00211 { 00212 typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type; 00213 }; 00214 00215 _GLIBCXX_END_NAMESPACE_VERSION 00216 } // namespace 00217 00218 #endif