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