cpp_type_traits.h revision 169691
197403Sobrien// The -*- C++ -*- type traits classes for internal use in libstdc++ 297403Sobrien 3169691Skan// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 4169691Skan// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien/** @file cpp_type_traits.h 3297403Sobrien * This is an internal header file, included by other library headers. 3397403Sobrien * You should not attempt to use it directly. 3497403Sobrien */ 3597403Sobrien 36169691Skan// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 37169691Skan 38132720Skan#ifndef _CPP_TYPE_TRAITS_H 39132720Skan#define _CPP_TYPE_TRAITS_H 1 4097403Sobrien 4197403Sobrien#pragma GCC system_header 4297403Sobrien 43169691Skan#include <bits/c++config.h> 44169691Skan 4597403Sobrien// 4697403Sobrien// This file provides some compile-time information about various types. 4797403Sobrien// These representations were designed, on purpose, to be constant-expressions 48169691Skan// and not types as found in <bits/type_traits.h>. In particular, they 4997403Sobrien// can be used in control structures and the optimizer hopefully will do 5097403Sobrien// the obvious thing. 5197403Sobrien// 5297403Sobrien// Why integral expressions, and not functions nor types? 5397403Sobrien// Firstly, these compile-time entities are used as template-arguments 5497403Sobrien// so function return values won't work: We need compile-time entities. 5597403Sobrien// We're left with types and constant integral expressions. 5697403Sobrien// Secondly, from the point of view of ease of use, type-based compile-time 5797403Sobrien// information is -not- *that* convenient. On has to write lots of 5897403Sobrien// overloaded functions and to hope that the compiler will select the right 5997403Sobrien// one. As a net effect, the overall structure isn't very clear at first 6097403Sobrien// glance. 6197403Sobrien// Thirdly, partial ordering and overload resolution (of function templates) 6297403Sobrien// is highly costly in terms of compiler-resource. It is a Good Thing to 6397403Sobrien// keep these resource consumption as least as possible. 6497403Sobrien// 6597403Sobrien// See valarray_array.h for a case use. 6697403Sobrien// 6797403Sobrien// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. 6897403Sobrien// 69169691Skan// Update 2005: types are also provided and <bits/type_traits.h> has been 70169691Skan// removed. 71169691Skan// 7297403Sobrien 73169691Skan// Forward declaration hack, should really include this from somewhere. 74169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 75169691Skan 76169691Skan template<typename _Iterator, typename _Container> 77169691Skan class __normal_iterator; 78169691Skan 79169691Skan_GLIBCXX_END_NAMESPACE 80169691Skan 81169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 82169691Skan 83169691Skannamespace __detail 84132720Skan{ 85169691Skan // NB: g++ can not compile these if declared within the class 86169691Skan // __is_pod itself. 87132720Skan typedef char __one; 88132720Skan typedef char __two[2]; 89132720Skan 90169691Skan template<typename _Tp> 91169691Skan __one __test_type(int _Tp::*); 92169691Skan template<typename _Tp> 93169691Skan __two& __test_type(...); 94169691Skan} // namespace __detail 95132720Skan 96169691Skan 97169691Skan struct __true_type { }; 98169691Skan struct __false_type { }; 99169691Skan 100169691Skan template<bool> 101169691Skan struct __truth_type 102169691Skan { typedef __false_type __type; }; 103169691Skan 104169691Skan template<> 105169691Skan struct __truth_type<true> 106169691Skan { typedef __true_type __type; }; 107169691Skan 108169691Skan // N.B. The conversions to bool are needed due to the issue 109169691Skan // explained in c++/19404. 110169691Skan template<class _Sp, class _Tp> 111169691Skan struct __traitor 112169691Skan { 113169691Skan enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 114169691Skan typedef typename __truth_type<__value>::__type __type; 115169691Skan }; 116169691Skan 117132720Skan // Compare for equality of types. 118132720Skan template<typename, typename> 119132720Skan struct __are_same 120132720Skan { 121169691Skan enum { __value = 0 }; 122169691Skan typedef __false_type __type; 123132720Skan }; 124132720Skan 12597403Sobrien template<typename _Tp> 126132720Skan struct __are_same<_Tp, _Tp> 127132720Skan { 128169691Skan enum { __value = 1 }; 129169691Skan typedef __true_type __type; 130132720Skan }; 131132720Skan 132132720Skan // Holds if the template-argument is a void type. 133132720Skan template<typename _Tp> 13497403Sobrien struct __is_void 13597403Sobrien { 136169691Skan enum { __value = 0 }; 137169691Skan typedef __false_type __type; 13897403Sobrien }; 13997403Sobrien 14097403Sobrien template<> 14197403Sobrien struct __is_void<void> 14297403Sobrien { 143169691Skan enum { __value = 1 }; 144169691Skan typedef __true_type __type; 14597403Sobrien }; 14697403Sobrien 14797403Sobrien // 14897403Sobrien // Integer types 14997403Sobrien // 15097403Sobrien template<typename _Tp> 15197403Sobrien struct __is_integer 15297403Sobrien { 153169691Skan enum { __value = 0 }; 154169691Skan typedef __false_type __type; 15597403Sobrien }; 15697403Sobrien 15797403Sobrien // Thirteen specializations (yes there are eleven standard integer 15897403Sobrien // types; 'long long' and 'unsigned long long' are supported as 15997403Sobrien // extensions) 16097403Sobrien template<> 16197403Sobrien struct __is_integer<bool> 16297403Sobrien { 163169691Skan enum { __value = 1 }; 164169691Skan typedef __true_type __type; 16597403Sobrien }; 166132720Skan 16797403Sobrien template<> 16897403Sobrien struct __is_integer<char> 16997403Sobrien { 170169691Skan enum { __value = 1 }; 171169691Skan typedef __true_type __type; 17297403Sobrien }; 17397403Sobrien 17497403Sobrien template<> 17597403Sobrien struct __is_integer<signed char> 17697403Sobrien { 177169691Skan enum { __value = 1 }; 178169691Skan typedef __true_type __type; 17997403Sobrien }; 180132720Skan 18197403Sobrien template<> 182132720Skan struct __is_integer<unsigned char> 18397403Sobrien { 184169691Skan enum { __value = 1 }; 185169691Skan typedef __true_type __type; 18697403Sobrien }; 18797403Sobrien 188132720Skan# ifdef _GLIBCXX_USE_WCHAR_T 18997403Sobrien template<> 190132720Skan struct __is_integer<wchar_t> 19197403Sobrien { 192169691Skan enum { __value = 1 }; 193169691Skan typedef __true_type __type; 19497403Sobrien }; 19597403Sobrien# endif 196132720Skan 19797403Sobrien template<> 198132720Skan struct __is_integer<short> 19997403Sobrien { 200169691Skan enum { __value = 1 }; 201169691Skan typedef __true_type __type; 20297403Sobrien }; 20397403Sobrien 20497403Sobrien template<> 205132720Skan struct __is_integer<unsigned short> 20697403Sobrien { 207169691Skan enum { __value = 1 }; 208169691Skan typedef __true_type __type; 20997403Sobrien }; 21097403Sobrien 21197403Sobrien template<> 212132720Skan struct __is_integer<int> 21397403Sobrien { 214169691Skan enum { __value = 1 }; 215169691Skan typedef __true_type __type; 21697403Sobrien }; 21797403Sobrien 21897403Sobrien template<> 219132720Skan struct __is_integer<unsigned int> 22097403Sobrien { 221169691Skan enum { __value = 1 }; 222169691Skan typedef __true_type __type; 22397403Sobrien }; 22497403Sobrien 22597403Sobrien template<> 226132720Skan struct __is_integer<long> 22797403Sobrien { 228169691Skan enum { __value = 1 }; 229169691Skan typedef __true_type __type; 23097403Sobrien }; 23197403Sobrien 23297403Sobrien template<> 233132720Skan struct __is_integer<unsigned long> 23497403Sobrien { 235169691Skan enum { __value = 1 }; 236169691Skan typedef __true_type __type; 23797403Sobrien }; 23897403Sobrien 23997403Sobrien template<> 240132720Skan struct __is_integer<long long> 24197403Sobrien { 242169691Skan enum { __value = 1 }; 243169691Skan typedef __true_type __type; 24497403Sobrien }; 24597403Sobrien 24697403Sobrien template<> 247132720Skan struct __is_integer<unsigned long long> 24897403Sobrien { 249169691Skan enum { __value = 1 }; 250169691Skan typedef __true_type __type; 25197403Sobrien }; 25297403Sobrien 25397403Sobrien // 25497403Sobrien // Floating point types 25597403Sobrien // 25697403Sobrien template<typename _Tp> 257132720Skan struct __is_floating 25897403Sobrien { 259169691Skan enum { __value = 0 }; 260169691Skan typedef __false_type __type; 26197403Sobrien }; 26297403Sobrien 26397403Sobrien // three specializations (float, double and 'long double') 26497403Sobrien template<> 265132720Skan struct __is_floating<float> 26697403Sobrien { 267169691Skan enum { __value = 1 }; 268169691Skan typedef __true_type __type; 26997403Sobrien }; 27097403Sobrien 27197403Sobrien template<> 272132720Skan struct __is_floating<double> 27397403Sobrien { 274169691Skan enum { __value = 1 }; 275169691Skan typedef __true_type __type; 27697403Sobrien }; 27797403Sobrien 27897403Sobrien template<> 279132720Skan struct __is_floating<long double> 28097403Sobrien { 281169691Skan enum { __value = 1 }; 282169691Skan typedef __true_type __type; 28397403Sobrien }; 28497403Sobrien 28597403Sobrien // 286169691Skan // Pointer types 28797403Sobrien // 28897403Sobrien template<typename _Tp> 289169691Skan struct __is_pointer 29097403Sobrien { 291169691Skan enum { __value = 0 }; 292169691Skan typedef __false_type __type; 29397403Sobrien }; 294169691Skan 295169691Skan template<typename _Tp> 296169691Skan struct __is_pointer<_Tp*> 297169691Skan { 298169691Skan enum { __value = 1 }; 299169691Skan typedef __true_type __type; 300169691Skan }; 301169691Skan 30297403Sobrien // 303169691Skan // Normal iterator type 304169691Skan // 305169691Skan template<typename _Tp> 306169691Skan struct __is_normal_iterator 307169691Skan { 308169691Skan enum { __value = 0 }; 309169691Skan typedef __false_type __type; 310169691Skan }; 311169691Skan 312169691Skan template<typename _Iterator, typename _Container> 313169691Skan struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 314169691Skan _Container> > 315169691Skan { 316169691Skan enum { __value = 1 }; 317169691Skan typedef __true_type __type; 318169691Skan }; 319169691Skan 320169691Skan // 321169691Skan // An arithmetic type is an integer type or a floating point type 322169691Skan // 323169691Skan template<typename _Tp> 324169691Skan struct __is_arithmetic 325169691Skan : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 326169691Skan { }; 327169691Skan 328169691Skan // 32997403Sobrien // A fundamental type is `void' or and arithmetic type 33097403Sobrien // 33197403Sobrien template<typename _Tp> 332132720Skan struct __is_fundamental 333169691Skan : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > 334169691Skan { }; 335169691Skan 336169691Skan // 337169691Skan // A scalar type is an arithmetic type or a pointer type 338169691Skan // 339169691Skan template<typename _Tp> 340169691Skan struct __is_scalar 341169691Skan : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 342169691Skan { }; 343169691Skan 344169691Skan // For the immediate use, the following is a good approximation. 345169691Skan template<typename _Tp> 346169691Skan struct __is_pod 34797403Sobrien { 348132720Skan enum 349132720Skan { 350169691Skan __value = (sizeof(__detail::__test_type<_Tp>(0)) 351169691Skan != sizeof(__detail::__one)) 352132720Skan }; 35397403Sobrien }; 35497403Sobrien 35597403Sobrien // 356169691Skan // A stripped-down version of std::tr1::is_empty 35797403Sobrien // 35897403Sobrien template<typename _Tp> 359169691Skan struct __is_empty 360169691Skan { 361169691Skan private: 362169691Skan template<typename> 363169691Skan struct __first { }; 364169691Skan template<typename _Up> 365169691Skan struct __second 366169691Skan : public _Up { }; 367169691Skan 368169691Skan public: 369132720Skan enum 370132720Skan { 371169691Skan __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>) 372132720Skan }; 37397403Sobrien }; 37497403Sobrien 375169691Skan // 376169691Skan // For use in std::copy and std::find overloads for streambuf iterators. 377169691Skan // 378169691Skan template<typename _Tp> 379169691Skan struct __is_char 380169691Skan { 381169691Skan enum { __value = 0 }; 382169691Skan typedef __false_type __type; 383169691Skan }; 38497403Sobrien 385169691Skan template<> 386169691Skan struct __is_char<char> 387169691Skan { 388169691Skan enum { __value = 1 }; 389169691Skan typedef __true_type __type; 390169691Skan }; 391169691Skan 392169691Skan#ifdef _GLIBCXX_USE_WCHAR_T 393169691Skan template<> 394169691Skan struct __is_char<wchar_t> 395169691Skan { 396169691Skan enum { __value = 1 }; 397169691Skan typedef __true_type __type; 398169691Skan }; 399169691Skan#endif 400169691Skan 401169691Skan_GLIBCXX_END_NAMESPACE 402169691Skan 403132720Skan#endif //_CPP_TYPE_TRAITS_H 404