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