1 // The -*- C++ -*- type traits classes for internal use in libstdc++ 2 3 // Copyright (C) 2000-2013 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 (at) 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 (at) 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 // Forward declaration hack, should really include this from somewhere. 68 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 69 { 70 _GLIBCXX_BEGIN_NAMESPACE_VERSION 71 72 template<typename _Iterator, typename _Container> 73 class __normal_iterator; 74 75 _GLIBCXX_END_NAMESPACE_VERSION 76 } // namespace 77 78 namespace std _GLIBCXX_VISIBILITY(default) 79 { 80 _GLIBCXX_BEGIN_NAMESPACE_VERSION 81 82 struct __true_type { }; 83 struct __false_type { }; 84 85 template<bool> 86 struct __truth_type 87 { typedef __false_type __type; }; 88 89 template<> 90 struct __truth_type<true> 91 { typedef __true_type __type; }; 92 93 // N.B. The conversions to bool are needed due to the issue 94 // explained in c++/19404. 95 template<class _Sp, class _Tp> 96 struct __traitor 97 { 98 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 99 typedef typename __truth_type<__value>::__type __type; 100 }; 101 102 // Compare for equality of types. 103 template<typename, typename> 104 struct __are_same 105 { 106 enum { __value = 0 }; 107 typedef __false_type __type; 108 }; 109 110 template<typename _Tp> 111 struct __are_same<_Tp, _Tp> 112 { 113 enum { __value = 1 }; 114 typedef __true_type __type; 115 }; 116 117 // Holds if the template-argument is a void type. 118 template<typename _Tp> 119 struct __is_void 120 { 121 enum { __value = 0 }; 122 typedef __false_type __type; 123 }; 124 125 template<> 126 struct __is_void<void> 127 { 128 enum { __value = 1 }; 129 typedef __true_type __type; 130 }; 131 132 // 133 // Integer types 134 // 135 template<typename _Tp> 136 struct __is_integer 137 { 138 enum { __value = 0 }; 139 typedef __false_type __type; 140 }; 141 142 // Thirteen specializations (yes there are eleven standard integer 143 // types; <em>long long</em> and <em>unsigned long long</em> are 144 // supported as extensions) 145 template<> 146 struct __is_integer<bool> 147 { 148 enum { __value = 1 }; 149 typedef __true_type __type; 150 }; 151 152 template<> 153 struct __is_integer<char> 154 { 155 enum { __value = 1 }; 156 typedef __true_type __type; 157 }; 158 159 template<> 160 struct __is_integer<signed char> 161 { 162 enum { __value = 1 }; 163 typedef __true_type __type; 164 }; 165 166 template<> 167 struct __is_integer<unsigned char> 168 { 169 enum { __value = 1 }; 170 typedef __true_type __type; 171 }; 172 173 # ifdef _GLIBCXX_USE_WCHAR_T 174 template<> 175 struct __is_integer<wchar_t> 176 { 177 enum { __value = 1 }; 178 typedef __true_type __type; 179 }; 180 # endif 181 182 #if __cplusplus >= 201103L 183 template<> 184 struct __is_integer<char16_t> 185 { 186 enum { __value = 1 }; 187 typedef __true_type __type; 188 }; 189 190 template<> 191 struct __is_integer<char32_t> 192 { 193 enum { __value = 1 }; 194 typedef __true_type __type; 195 }; 196 #endif 197 198 template<> 199 struct __is_integer<short> 200 { 201 enum { __value = 1 }; 202 typedef __true_type __type; 203 }; 204 205 template<> 206 struct __is_integer<unsigned short> 207 { 208 enum { __value = 1 }; 209 typedef __true_type __type; 210 }; 211 212 template<> 213 struct __is_integer<int> 214 { 215 enum { __value = 1 }; 216 typedef __true_type __type; 217 }; 218 219 template<> 220 struct __is_integer<unsigned int> 221 { 222 enum { __value = 1 }; 223 typedef __true_type __type; 224 }; 225 226 template<> 227 struct __is_integer<long> 228 { 229 enum { __value = 1 }; 230 typedef __true_type __type; 231 }; 232 233 template<> 234 struct __is_integer<unsigned long> 235 { 236 enum { __value = 1 }; 237 typedef __true_type __type; 238 }; 239 240 template<> 241 struct __is_integer<long long> 242 { 243 enum { __value = 1 }; 244 typedef __true_type __type; 245 }; 246 247 template<> 248 struct __is_integer<unsigned long long> 249 { 250 enum { __value = 1 }; 251 typedef __true_type __type; 252 }; 253 254 // 255 // Floating point types 256 // 257 template<typename _Tp> 258 struct __is_floating 259 { 260 enum { __value = 0 }; 261 typedef __false_type __type; 262 }; 263 264 // three specializations (float, double and 'long double') 265 template<> 266 struct __is_floating<float> 267 { 268 enum { __value = 1 }; 269 typedef __true_type __type; 270 }; 271 272 template<> 273 struct __is_floating<double> 274 { 275 enum { __value = 1 }; 276 typedef __true_type __type; 277 }; 278 279 template<> 280 struct __is_floating<long double> 281 { 282 enum { __value = 1 }; 283 typedef __true_type __type; 284 }; 285 286 // 287 // Pointer types 288 // 289 template<typename _Tp> 290 struct __is_pointer 291 { 292 enum { __value = 0 }; 293 typedef __false_type __type; 294 }; 295 296 template<typename _Tp> 297 struct __is_pointer<_Tp*> 298 { 299 enum { __value = 1 }; 300 typedef __true_type __type; 301 }; 302 303 // 304 // Normal iterator type 305 // 306 template<typename _Tp> 307 struct __is_normal_iterator 308 { 309 enum { __value = 0 }; 310 typedef __false_type __type; 311 }; 312 313 template<typename _Iterator, typename _Container> 314 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 315 _Container> > 316 { 317 enum { __value = 1 }; 318 typedef __true_type __type; 319 }; 320 321 // 322 // An arithmetic type is an integer type or a floating point type 323 // 324 template<typename _Tp> 325 struct __is_arithmetic 326 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 327 { }; 328 329 // 330 // A fundamental type is `void' or and arithmetic type 331 // 332 template<typename _Tp> 333 struct __is_fundamental 334 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > 335 { }; 336 337 // 338 // A scalar type is an arithmetic type or a pointer type 339 // 340 template<typename _Tp> 341 struct __is_scalar 342 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 343 { }; 344 345 // 346 // For use in std::copy and std::find overloads for streambuf iterators. 347 // 348 template<typename _Tp> 349 struct __is_char 350 { 351 enum { __value = 0 }; 352 typedef __false_type __type; 353 }; 354 355 template<> 356 struct __is_char<char> 357 { 358 enum { __value = 1 }; 359 typedef __true_type __type; 360 }; 361 362 #ifdef _GLIBCXX_USE_WCHAR_T 363 template<> 364 struct __is_char<wchar_t> 365 { 366 enum { __value = 1 }; 367 typedef __true_type __type; 368 }; 369 #endif 370 371 template<typename _Tp> 372 struct __is_byte 373 { 374 enum { __value = 0 }; 375 typedef __false_type __type; 376 }; 377 378 template<> 379 struct __is_byte<char> 380 { 381 enum { __value = 1 }; 382 typedef __true_type __type; 383 }; 384 385 template<> 386 struct __is_byte<signed char> 387 { 388 enum { __value = 1 }; 389 typedef __true_type __type; 390 }; 391 392 template<> 393 struct __is_byte<unsigned char> 394 { 395 enum { __value = 1 }; 396 typedef __true_type __type; 397 }; 398 399 // 400 // Move iterator type 401 // 402 template<typename _Tp> 403 struct __is_move_iterator 404 { 405 enum { __value = 0 }; 406 typedef __false_type __type; 407 }; 408 409 #if __cplusplus >= 201103L 410 template<typename _Iterator> 411 class move_iterator; 412 413 template<typename _Iterator> 414 struct __is_move_iterator< move_iterator<_Iterator> > 415 { 416 enum { __value = 1 }; 417 typedef __true_type __type; 418 }; 419 #endif 420 421 _GLIBCXX_END_NAMESPACE_VERSION 422 } // namespace 423 424 #endif //_CPP_TYPE_TRAITS_H 425