Line data Source code
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 2254 : __miter_base(_Iterator __it) 420 2254 : { return __it; } 421 : 422 : _GLIBCXX_END_NAMESPACE_VERSION 423 : } // namespace 424 : } // extern "C++" 425 : 426 : #endif //_CPP_TYPE_TRAITS_H