1// -*- C++ -*- 2 3// Copyright (C) 2005-2015 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the terms 7// of the GNU General Public License as published by the Free Software 8// Foundation; either version 3, or (at your option) any later 9// version. 10 11// This library is distributed in the hope that it will be useful, but 12// WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14// General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file ext/type_traits.h 26 * This file is a GNU extension to the Standard C++ Library. 27 */ 28 29#ifndef _EXT_TYPE_TRAITS 30#define _EXT_TYPE_TRAITS 1 31 32#pragma GCC system_header 33 34#include <bits/c++config.h> 35#include <bits/cpp_type_traits.h> 36 37namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 38{ 39_GLIBCXX_BEGIN_NAMESPACE_VERSION 40 41 // Define a nested type if some predicate holds. 42 template<bool, typename> 43 struct __enable_if 44 { }; 45 46 template<typename _Tp> 47 struct __enable_if<true, _Tp> 48 { typedef _Tp __type; }; 49 50 51 // Conditional expression for types. If true, first, if false, second. 52 template<bool _Cond, typename _Iftrue, typename _Iffalse> 53 struct __conditional_type 54 { typedef _Iftrue __type; }; 55 56 template<typename _Iftrue, typename _Iffalse> 57 struct __conditional_type<false, _Iftrue, _Iffalse> 58 { typedef _Iffalse __type; }; 59 60 61 // Given an integral builtin type, return the corresponding unsigned type. 62 template<typename _Tp> 63 struct __add_unsigned 64 { 65 private: 66 typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; 67 68 public: 69 typedef typename __if_type::__type __type; 70 }; 71 72 template<> 73 struct __add_unsigned<char> 74 { typedef unsigned char __type; }; 75 76 template<> 77 struct __add_unsigned<signed char> 78 { typedef unsigned char __type; }; 79 80 template<> 81 struct __add_unsigned<short> 82 { typedef unsigned short __type; }; 83 84 template<> 85 struct __add_unsigned<int> 86 { typedef unsigned int __type; }; 87 88 template<> 89 struct __add_unsigned<long> 90 { typedef unsigned long __type; }; 91 92 template<> 93 struct __add_unsigned<long long> 94 { typedef unsigned long long __type; }; 95 96 // Declare but don't define. 97 template<> 98 struct __add_unsigned<bool>; 99 100 template<> 101 struct __add_unsigned<wchar_t>; 102 103 104 // Given an integral builtin type, return the corresponding signed type. 105 template<typename _Tp> 106 struct __remove_unsigned 107 { 108 private: 109 typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; 110 111 public: 112 typedef typename __if_type::__type __type; 113 }; 114 115 template<> 116 struct __remove_unsigned<char> 117 { typedef signed char __type; }; 118 119 template<> 120 struct __remove_unsigned<unsigned char> 121 { typedef signed char __type; }; 122 123 template<> 124 struct __remove_unsigned<unsigned short> 125 { typedef short __type; }; 126 127 template<> 128 struct __remove_unsigned<unsigned int> 129 { typedef int __type; }; 130 131 template<> 132 struct __remove_unsigned<unsigned long> 133 { typedef long __type; }; 134 135 template<> 136 struct __remove_unsigned<unsigned long long> 137 { typedef long long __type; }; 138 139 // Declare but don't define. 140 template<> 141 struct __remove_unsigned<bool>; 142 143 template<> 144 struct __remove_unsigned<wchar_t>; 145 146 147 // For use in string and vstring. 148 template<typename _Type> 149 inline bool 150 __is_null_pointer(_Type* __ptr) 151 { return __ptr == 0; } 152 153 template<typename _Type> 154 inline bool 155 __is_null_pointer(_Type) 156 { return false; } 157 158#if __cplusplus >= 201103L 159 inline bool 160 __is_null_pointer(std::nullptr_t) 161 { return true; } 162#endif 163 164 // For complex and cmath 165 template<typename _Tp, bool = std::__is_integer<_Tp>::__value> 166 struct __promote 167 { typedef double __type; }; 168 169 // No nested __type member for non-integer non-floating point types, 170 // allows this type to be used for SFINAE to constrain overloads in 171 // <cmath> and <complex> to only the intended types. 172 template<typename _Tp> 173 struct __promote<_Tp, false> 174 { }; 175 176 template<> 177 struct __promote<long double> 178 { typedef long double __type; }; 179 180 template<> 181 struct __promote<double> 182 { typedef double __type; }; 183 184 template<> 185 struct __promote<float> 186 { typedef float __type; }; 187 188 template<typename _Tp, typename _Up, 189 typename _Tp2 = typename __promote<_Tp>::__type, 190 typename _Up2 = typename __promote<_Up>::__type> 191 struct __promote_2 192 { 193 typedef __typeof__(_Tp2() + _Up2()) __type; 194 }; 195 196 template<typename _Tp, typename _Up, typename _Vp, 197 typename _Tp2 = typename __promote<_Tp>::__type, 198 typename _Up2 = typename __promote<_Up>::__type, 199 typename _Vp2 = typename __promote<_Vp>::__type> 200 struct __promote_3 201 { 202 typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type; 203 }; 204 205 template<typename _Tp, typename _Up, typename _Vp, typename _Wp, 206 typename _Tp2 = typename __promote<_Tp>::__type, 207 typename _Up2 = typename __promote<_Up>::__type, 208 typename _Vp2 = typename __promote<_Vp>::__type, 209 typename _Wp2 = typename __promote<_Wp>::__type> 210 struct __promote_4 211 { 212 typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type; 213 }; 214 215_GLIBCXX_END_NAMESPACE_VERSION 216} // namespace 217 218#endif 219