1 // The -*- C++ -*- type traits classes for internal use in libstdc++ 2 3 // Copyright (C) 2000-2018 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 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU 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 bits/cpp_type_traits.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{ext/type_traits} 28 */ 29 30 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 31 32 #ifndef _CPP_TYPE_TRAITS_H 33 #define _CPP_TYPE_TRAITS_H 1 34 35 #pragma GCC system_header 36 37 #include <bits/c++config.h> 38 39 // 40 // This file provides some compile-time information about various types. 41 // These representations were designed, on purpose, to be constant-expressions 42 // and not types as found in <bits/type_traits.h>. In particular, they 43 // can be used in control structures and the optimizer hopefully will do 44 // the obvious thing. 45 // 46 // Why integral expressions, and not functions nor types? 47 // Firstly, these compile-time entities are used as template-arguments 48 // so function return values won't work: We need compile-time entities. 49 // We're left with types and constant integral expressions. 50 // Secondly, from the point of view of ease of use, type-based compile-time 51 // information is -not- *that* convenient. On has to write lots of 52 // overloaded functions and to hope that the compiler will select the right 53 // one. As a net effect, the overall structure isn't very clear at first 54 // glance. 55 // Thirdly, partial ordering and overload resolution (of function templates) 56 // is highly costly in terms of compiler-resource. It is a Good Thing to 57 // keep these resource consumption as least as possible. 58 // 59 // See valarray_array.h for a case use. 60 // 61 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. 62 // 63 // Update 2005: types are also provided and <bits/type_traits.h> has been 64 // removed. 65 // 66 67 extern "C++" { 68 69 namespace std _GLIBCXX_VISIBILITY(default) 70 { 71 _GLIBCXX_BEGIN_NAMESPACE_VERSION 72 73 struct __true_type { }; 74 struct __false_type { }; 75 76 template<bool> 77 struct __truth_type 78 { typedef __false_type __type; }; 79 80 template<> 81 struct __truth_type<true> 82 { typedef __true_type __type; }; 83 84 // N.B. The conversions to bool are needed due to the issue 85 // explained in c++/19404. 86 template<class _Sp, class _Tp> 87 struct __traitor 88 { 89 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 90 typedef typename __truth_type<__value>::__type __type; 91 }; 92 93 // Compare for equality of types. 94 template<typename, typename> 95 struct __are_same 96 { 97 enum { __value = 0 }; 98 typedef __false_type __type; 99 }; 100 101 template<typename _Tp> 102 struct __are_same<_Tp, _Tp> 103 { 104 enum { __value = 1 }; 105 typedef __true_type __type; 106 }; 107 108 // Holds if the template-argument is a void type. 109 template<typename _Tp> 110 struct __is_void 111 { 112 enum { __value = 0 }; 113 typedef __false_type __type; 114 }; 115 116 template<> 117 struct __is_void<void> 118 { 119 enum { __value = 1 }; 120 typedef __true_type __type; 121 }; 122 123 // 124 // Integer types 125 // 126 template<typename _Tp> 127 struct __is_integer 128 { 129 enum { __value = 0 }; 130 typedef __false_type __type; 131 }; 132 133 // Thirteen specializations (yes there are eleven standard integer 134 // types; <em>long long</em> and <em>unsigned long long</em> are 135 // supported as extensions). Up to four target-specific __int<N> 136 // types are supported as well. 137 template<> 138 struct __is_integer<bool> 139 { 140 enum { __value = 1 }; 141 typedef __true_type __type; 142 }; 143 144 template<> 145 struct __is_integer<char> 146 { 147 enum { __value = 1 }; 148 typedef __true_type __type; 149 }; 150 151 template<> 152 struct __is_integer<signed char> 153 { 154 enum { __value = 1 }; 155 typedef __true_type __type; 156 }; 157 158 template<> 159 struct __is_integer<unsigned char> 160 { 161 enum { __value = 1 }; 162 typedef __true_type __type; 163 }; 164 165 # ifdef _GLIBCXX_USE_WCHAR_T 166 template<> 167 struct __is_integer<wchar_t> 168 { 169 enum { __value = 1 }; 170 typedef __true_type __type; 171 }; 172 # endif 173 174 #if __cplusplus >= 201103L 175 template<> 176 struct __is_integer<char16_t> 177 { 178 enum { __value = 1 }; 179 typedef __true_type __type; 180 }; 181 182 template<> 183 struct __is_integer<char32_t> 184 { 185 enum { __value = 1 }; 186 typedef __true_type __type; 187 }; 188 #endif 189 190 template<> 191 struct __is_integer<short> 192 { 193 enum { __value = 1 }; 194 typedef __true_type __type; 195 }; 196 197 template<> 198 struct __is_integer<unsigned short> 199 { 200 enum { __value = 1 }; 201 typedef __true_type __type; 202 }; 203 204 template<> 205 struct __is_integer<int> 206 { 207 enum { __value = 1 }; 208 typedef __true_type __type; 209 }; 210 211 template<> 212 struct __is_integer<unsigned int> 213 { 214 enum { __value = 1 }; 215 typedef __true_type __type; 216 }; 217 218 template<> 219 struct __is_integer<long> 220 { 221 enum { __value = 1 }; 222 typedef __true_type __type; 223 }; 224 225 template<> 226 struct __is_integer<unsigned long> 227 { 228 enum { __value = 1 }; 229 typedef __true_type __type; 230 }; 231 232 template<> 233 struct __is_integer<long long> 234 { 235 enum { __value = 1 }; 236 typedef __true_type __type; 237 }; 238 239 template<> 240 struct __is_integer<unsigned long long> 241 { 242 enum { __value = 1 }; 243 typedef __true_type __type; 244 }; 245 246 #define __INT_N(TYPE) \ 247 template<> \ 248 struct __is_integer<TYPE> \ 249 { \ 250 enum { __value = 1 }; \ 251 typedef __true_type __type; \ 252 }; \ 253 template<> \ 254 struct __is_integer<unsigned TYPE> \ 255 { \ 256 enum { __value = 1 }; \ 257 typedef __true_type __type; \ 258 }; 259 260 #ifdef __GLIBCXX_TYPE_INT_N_0 261 __INT_N(__GLIBCXX_TYPE_INT_N_0) 262 #endif 263 #ifdef __GLIBCXX_TYPE_INT_N_1 264 __INT_N(__GLIBCXX_TYPE_INT_N_1) 265 #endif 266 #ifdef __GLIBCXX_TYPE_INT_N_2 267 __INT_N(__GLIBCXX_TYPE_INT_N_2) 268 #endif 269 #ifdef __GLIBCXX_TYPE_INT_N_3 270 __INT_N(__GLIBCXX_TYPE_INT_N_3) 271 #endif 272 273 #undef __INT_N 274 275 // 276 // Floating point types 277 // 278 template<typename _Tp> 279 struct __is_floating 280 { 281 enum { __value = 0 }; 282 typedef __false_type __type; 283 }; 284 285 // three specializations (float, double and 'long double') 286 template<> 287 struct __is_floating<float> 288 { 289 enum { __value = 1 }; 290 typedef __true_type __type; 291 }; 292 293 template<> 294 struct __is_floating<double> 295 { 296 enum { __value = 1 }; 297 typedef __true_type __type; 298 }; 299 300 template<> 301 struct __is_floating<long double> 302 { 303 enum { __value = 1 }; 304 typedef __true_type __type; 305 }; 306 307 // 308 // Pointer types 309 // 310 template<typename _Tp> 311 struct __is_pointer 312 { 313 enum { __value = 0 }; 314 typedef __false_type __type; 315 }; 316 317 template<typename _Tp> 318 struct __is_pointer<_Tp*> 319 { 320 enum { __value = 1 }; 321 typedef __true_type __type; 322 }; 323 324 // 325 // An arithmetic type is an integer type or a floating point type 326 // 327 template<typename _Tp> 328 struct __is_arithmetic 329 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 330 { }; 331 332 // 333 // A scalar type is an arithmetic type or a pointer type 334 // 335 template<typename _Tp> 336 struct __is_scalar 337 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 338 { }; 339 340 // 341 // For use in std::copy and std::find overloads for streambuf iterators. 342 // 343 template<typename _Tp> 344 struct __is_char 345 { 346 enum { __value = 0 }; 347 typedef __false_type __type; 348 }; 349 350 template<> 351 struct __is_char<char> 352 { 353 enum { __value = 1 }; 354 typedef __true_type __type; 355 }; 356 357 #ifdef _GLIBCXX_USE_WCHAR_T 358 template<> 359 struct __is_char<wchar_t> 360 { 361 enum { __value = 1 }; 362 typedef __true_type __type; 363 }; 364 #endif 365 366 template<typename _Tp> 367 struct __is_byte 368 { 369 enum { __value = 0 }; 370 typedef __false_type __type; 371 }; 372 373 template<> 374 struct __is_byte<char> 375 { 376 enum { __value = 1 }; 377 typedef __true_type __type; 378 }; 379 380 template<> 381 struct __is_byte<signed char> 382 { 383 enum { __value = 1 }; 384 typedef __true_type __type; 385 }; 386 387 template<> 388 struct __is_byte<unsigned char> 389 { 390 enum { __value = 1 }; 391 typedef __true_type __type; 392 }; 393 394 #if __cplusplus >= 201703L 395 enum class byte : unsigned char; 396 397 template<> 398 struct __is_byte<byte> 399 { 400 enum { __value = 1 }; 401 typedef __true_type __type; 402 }; 403 #endif // C++17 404 405 // 406 // Move iterator type 407 // 408 template<typename _Tp> 409 struct __is_move_iterator 410 { 411 enum { __value = 0 }; 412 typedef __false_type __type; 413 }; 414 415 // Fallback implementation of the function in bits/stl_iterator.h used to 416 // remove the move_iterator wrapper. 417 template<typename _Iterator> 418 inline _Iterator 419 __miter_base(_Iterator __it) 420 { return __it; } 421 422 _GLIBCXX_END_NAMESPACE_VERSION 423 } // namespace 424 } // extern "C++" 425 426 #endif //_CPP_TYPE_TRAITS_H 427