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