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 83263774Sdim#ifdef __clang__ 84263774Sdim// When using clang, suppress warnings about possible keywords (such as 85263774Sdim// __is_void, __is_pod, etc) being used as identifiers. 86263774Sdim#pragma clang diagnostic push 87263774Sdim#pragma clang diagnostic ignored "-Wkeyword-compat" 88263774Sdim#endif 89263774Sdim 90169691Skannamespace __detail 91132720Skan{ 92169691Skan // NB: g++ can not compile these if declared within the class 93169691Skan // __is_pod itself. 94132720Skan typedef char __one; 95132720Skan typedef char __two[2]; 96132720Skan 97169691Skan template<typename _Tp> 98169691Skan __one __test_type(int _Tp::*); 99169691Skan template<typename _Tp> 100169691Skan __two& __test_type(...); 101169691Skan} // namespace __detail 102132720Skan 103169691Skan 104169691Skan struct __true_type { }; 105169691Skan struct __false_type { }; 106169691Skan 107169691Skan template<bool> 108169691Skan struct __truth_type 109169691Skan { typedef __false_type __type; }; 110169691Skan 111169691Skan template<> 112169691Skan struct __truth_type<true> 113169691Skan { typedef __true_type __type; }; 114169691Skan 115169691Skan // N.B. The conversions to bool are needed due to the issue 116169691Skan // explained in c++/19404. 117169691Skan template<class _Sp, class _Tp> 118169691Skan struct __traitor 119169691Skan { 120169691Skan enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 121169691Skan typedef typename __truth_type<__value>::__type __type; 122169691Skan }; 123169691Skan 124132720Skan // Compare for equality of types. 125132720Skan template<typename, typename> 126132720Skan struct __are_same 127132720Skan { 128169691Skan enum { __value = 0 }; 129169691Skan typedef __false_type __type; 130132720Skan }; 131132720Skan 13297403Sobrien template<typename _Tp> 133132720Skan struct __are_same<_Tp, _Tp> 134132720Skan { 135169691Skan enum { __value = 1 }; 136169691Skan typedef __true_type __type; 137132720Skan }; 138132720Skan 139132720Skan // Holds if the template-argument is a void type. 140132720Skan template<typename _Tp> 14197403Sobrien struct __is_void 14297403Sobrien { 143169691Skan enum { __value = 0 }; 144169691Skan typedef __false_type __type; 14597403Sobrien }; 14697403Sobrien 14797403Sobrien template<> 14897403Sobrien struct __is_void<void> 14997403Sobrien { 150169691Skan enum { __value = 1 }; 151169691Skan typedef __true_type __type; 15297403Sobrien }; 15397403Sobrien 15497403Sobrien // 15597403Sobrien // Integer types 15697403Sobrien // 15797403Sobrien template<typename _Tp> 15897403Sobrien struct __is_integer 15997403Sobrien { 160169691Skan enum { __value = 0 }; 161169691Skan typedef __false_type __type; 16297403Sobrien }; 16397403Sobrien 16497403Sobrien // Thirteen specializations (yes there are eleven standard integer 16597403Sobrien // types; 'long long' and 'unsigned long long' are supported as 16697403Sobrien // extensions) 16797403Sobrien template<> 16897403Sobrien struct __is_integer<bool> 16997403Sobrien { 170169691Skan enum { __value = 1 }; 171169691Skan typedef __true_type __type; 17297403Sobrien }; 173132720Skan 17497403Sobrien template<> 17597403Sobrien struct __is_integer<char> 17697403Sobrien { 177169691Skan enum { __value = 1 }; 178169691Skan typedef __true_type __type; 17997403Sobrien }; 18097403Sobrien 18197403Sobrien template<> 18297403Sobrien struct __is_integer<signed char> 18397403Sobrien { 184169691Skan enum { __value = 1 }; 185169691Skan typedef __true_type __type; 18697403Sobrien }; 187132720Skan 18897403Sobrien template<> 189132720Skan struct __is_integer<unsigned char> 19097403Sobrien { 191169691Skan enum { __value = 1 }; 192169691Skan typedef __true_type __type; 19397403Sobrien }; 19497403Sobrien 195132720Skan# ifdef _GLIBCXX_USE_WCHAR_T 19697403Sobrien template<> 197132720Skan struct __is_integer<wchar_t> 19897403Sobrien { 199169691Skan enum { __value = 1 }; 200169691Skan typedef __true_type __type; 20197403Sobrien }; 20297403Sobrien# endif 203132720Skan 20497403Sobrien template<> 205132720Skan struct __is_integer<short> 20697403Sobrien { 207169691Skan enum { __value = 1 }; 208169691Skan typedef __true_type __type; 20997403Sobrien }; 21097403Sobrien 21197403Sobrien template<> 212132720Skan struct __is_integer<unsigned short> 21397403Sobrien { 214169691Skan enum { __value = 1 }; 215169691Skan typedef __true_type __type; 21697403Sobrien }; 21797403Sobrien 21897403Sobrien template<> 219132720Skan struct __is_integer<int> 22097403Sobrien { 221169691Skan enum { __value = 1 }; 222169691Skan typedef __true_type __type; 22397403Sobrien }; 22497403Sobrien 22597403Sobrien template<> 226132720Skan struct __is_integer<unsigned int> 22797403Sobrien { 228169691Skan enum { __value = 1 }; 229169691Skan typedef __true_type __type; 23097403Sobrien }; 23197403Sobrien 23297403Sobrien template<> 233132720Skan struct __is_integer<long> 23497403Sobrien { 235169691Skan enum { __value = 1 }; 236169691Skan typedef __true_type __type; 23797403Sobrien }; 23897403Sobrien 23997403Sobrien template<> 240132720Skan struct __is_integer<unsigned long> 24197403Sobrien { 242169691Skan enum { __value = 1 }; 243169691Skan typedef __true_type __type; 24497403Sobrien }; 24597403Sobrien 24697403Sobrien template<> 247132720Skan struct __is_integer<long long> 24897403Sobrien { 249169691Skan enum { __value = 1 }; 250169691Skan typedef __true_type __type; 25197403Sobrien }; 25297403Sobrien 25397403Sobrien template<> 254132720Skan struct __is_integer<unsigned long long> 25597403Sobrien { 256169691Skan enum { __value = 1 }; 257169691Skan typedef __true_type __type; 25897403Sobrien }; 25997403Sobrien 26097403Sobrien // 26197403Sobrien // Floating point types 26297403Sobrien // 26397403Sobrien template<typename _Tp> 264132720Skan struct __is_floating 26597403Sobrien { 266169691Skan enum { __value = 0 }; 267169691Skan typedef __false_type __type; 26897403Sobrien }; 26997403Sobrien 27097403Sobrien // three specializations (float, double and 'long double') 27197403Sobrien template<> 272132720Skan struct __is_floating<float> 27397403Sobrien { 274169691Skan enum { __value = 1 }; 275169691Skan typedef __true_type __type; 27697403Sobrien }; 27797403Sobrien 27897403Sobrien template<> 279132720Skan struct __is_floating<double> 28097403Sobrien { 281169691Skan enum { __value = 1 }; 282169691Skan typedef __true_type __type; 28397403Sobrien }; 28497403Sobrien 28597403Sobrien template<> 286132720Skan struct __is_floating<long double> 28797403Sobrien { 288169691Skan enum { __value = 1 }; 289169691Skan typedef __true_type __type; 29097403Sobrien }; 29197403Sobrien 29297403Sobrien // 293169691Skan // Pointer types 29497403Sobrien // 29597403Sobrien template<typename _Tp> 296169691Skan struct __is_pointer 29797403Sobrien { 298169691Skan enum { __value = 0 }; 299169691Skan typedef __false_type __type; 30097403Sobrien }; 301169691Skan 302169691Skan template<typename _Tp> 303169691Skan struct __is_pointer<_Tp*> 304169691Skan { 305169691Skan enum { __value = 1 }; 306169691Skan typedef __true_type __type; 307169691Skan }; 308169691Skan 30997403Sobrien // 310169691Skan // Normal iterator type 311169691Skan // 312169691Skan template<typename _Tp> 313169691Skan struct __is_normal_iterator 314169691Skan { 315169691Skan enum { __value = 0 }; 316169691Skan typedef __false_type __type; 317169691Skan }; 318169691Skan 319169691Skan template<typename _Iterator, typename _Container> 320169691Skan struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 321169691Skan _Container> > 322169691Skan { 323169691Skan enum { __value = 1 }; 324169691Skan typedef __true_type __type; 325169691Skan }; 326169691Skan 327169691Skan // 328169691Skan // An arithmetic type is an integer type or a floating point type 329169691Skan // 330169691Skan template<typename _Tp> 331169691Skan struct __is_arithmetic 332169691Skan : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 333169691Skan { }; 334169691Skan 335169691Skan // 33697403Sobrien // A fundamental type is `void' or and arithmetic type 33797403Sobrien // 33897403Sobrien template<typename _Tp> 339132720Skan struct __is_fundamental 340169691Skan : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > 341169691Skan { }; 342169691Skan 343169691Skan // 344169691Skan // A scalar type is an arithmetic type or a pointer type 345169691Skan // 346169691Skan template<typename _Tp> 347169691Skan struct __is_scalar 348169691Skan : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 349169691Skan { }; 350169691Skan 351169691Skan // For the immediate use, the following is a good approximation. 352169691Skan template<typename _Tp> 353169691Skan struct __is_pod 35497403Sobrien { 355132720Skan enum 356132720Skan { 357169691Skan __value = (sizeof(__detail::__test_type<_Tp>(0)) 358169691Skan != sizeof(__detail::__one)) 359132720Skan }; 36097403Sobrien }; 36197403Sobrien 36297403Sobrien // 363169691Skan // A stripped-down version of std::tr1::is_empty 36497403Sobrien // 36597403Sobrien template<typename _Tp> 366169691Skan struct __is_empty 367169691Skan { 368169691Skan private: 369169691Skan template<typename> 370169691Skan struct __first { }; 371169691Skan template<typename _Up> 372169691Skan struct __second 373169691Skan : public _Up { }; 374169691Skan 375169691Skan public: 376132720Skan enum 377132720Skan { 378169691Skan __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>) 379132720Skan }; 38097403Sobrien }; 38197403Sobrien 382169691Skan // 383169691Skan // For use in std::copy and std::find overloads for streambuf iterators. 384169691Skan // 385169691Skan template<typename _Tp> 386169691Skan struct __is_char 387169691Skan { 388169691Skan enum { __value = 0 }; 389169691Skan typedef __false_type __type; 390169691Skan }; 39197403Sobrien 392169691Skan template<> 393169691Skan struct __is_char<char> 394169691Skan { 395169691Skan enum { __value = 1 }; 396169691Skan typedef __true_type __type; 397169691Skan }; 398169691Skan 399169691Skan#ifdef _GLIBCXX_USE_WCHAR_T 400169691Skan template<> 401169691Skan struct __is_char<wchar_t> 402169691Skan { 403169691Skan enum { __value = 1 }; 404169691Skan typedef __true_type __type; 405169691Skan }; 406169691Skan#endif 407169691Skan 408263774Sdim#ifdef __clang__ 409263774Sdim#pragma clang diagnostic pop 410263774Sdim#endif 411263774Sdim 412169691Skan_GLIBCXX_END_NAMESPACE 413169691Skan 414132720Skan#endif //_CPP_TYPE_TRAITS_H 415