1 // The -*- C++ -*- type traits classes for internal use in libstdc++ 2 3 // Copyright (C) 2000, 2001 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 2, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License along 17 // with this library; see the file COPYING. If not, write to the Free 18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19 // USA. 20 21 // As a special exception, you may use this file as part of a free software 22 // library without restriction. Specifically, if other files instantiate 23 // templates or use macros or inline functions from this file, or you compile 24 // this file and link it with other files to produce an executable, this 25 // file does not by itself cause the resulting executable to be covered by 26 // the GNU General Public License. This exception does not however 27 // invalidate any other reasons why the executable file might be covered by 28 // the GNU General Public License. 29 30 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 31 32 /** @file cpp_type_traits.h 33 * This is an internal header file, included by other library headers. 34 * You should not attempt to use it directly. 35 */ 36 37 #ifndef _CPP_BITS_CPP_TYPE_TRAITS_H 38 #define _CPP_BITS_CPP_TYPE_TRAITS_H 1 39 40 #pragma GCC system_header 41 42 // 43 // This file provides some compile-time information about various types. 44 // These representations were designed, on purpose, to be constant-expressions 45 // and not types as found in <stl/bits/type_traits.h>. In particular, they 46 // can be used in control structures and the optimizer hopefully will do 47 // the obvious thing. 48 // 49 // Why integral expressions, and not functions nor types? 50 // Firstly, these compile-time entities are used as template-arguments 51 // so function return values won't work: We need compile-time entities. 52 // We're left with types and constant integral expressions. 53 // Secondly, from the point of view of ease of use, type-based compile-time 54 // information is -not- *that* convenient. On has to write lots of 55 // overloaded functions and to hope that the compiler will select the right 56 // one. As a net effect, the overall structure isn't very clear at first 57 // glance. 58 // Thirdly, partial ordering and overload resolution (of function templates) 59 // is highly costly in terms of compiler-resource. It is a Good Thing to 60 // keep these resource consumption as least as possible. 61 // 62 // See valarray_array.h for a case use. 63 // 64 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. 65 // 66 67 namespace std 68 { 69 // Compare for equality of types. 70 template<typename, typename> 71 struct __are_same 72 { 73 enum 74 { 75 _M_type = 0 76 }; 77 }; 78 79 template<typename _Tp> 80 struct __are_same<_Tp, _Tp> 81 { 82 enum 83 { 84 _M_type = 1 85 }; 86 }; 87 88 // Define a nested type if some predicate holds. 89 template<typename, bool> 90 struct __enable_if 91 { 92 }; 93 94 template<typename _Tp> 95 struct __enable_if<_Tp, true> 96 { 97 typedef _Tp _M_type; 98 }; 99 100 // Holds if the template-argument is a void type. 101 template<typename _Tp> 102 struct __is_void 103 { 104 enum 105 { 106 _M_type = 0 107 }; 108 }; 109 110 template<> 111 struct __is_void<void> 112 { 113 enum 114 { 115 _M_type = 1 116 }; 117 }; 118 119 // 120 // Integer types 121 // 122 template<typename _Tp> 123 struct __is_integer 124 { 125 enum 126 { 127 _M_type = 0 128 }; 129 }; 130 131 // Thirteen specializations (yes there are eleven standard integer 132 // types; 'long long' and 'unsigned long long' are supported as 133 // extensions) 134 template<> 135 struct __is_integer<bool> 136 { 137 enum 138 { 139 _M_type = 1 140 }; 141 }; 142 143 template<> 144 struct __is_integer<char> 145 { 146 enum 147 { 148 _M_type = 1 149 }; 150 }; 151 152 template<> 153 struct __is_integer<signed char> 154 { 155 enum 156 { 157 _M_type = 1 158 }; 159 }; 160 161 template<> 162 struct __is_integer<unsigned char> 163 { 164 enum 165 { 166 _M_type = 1 167 }; 168 }; 169 170 #if defined(_GLIBCPP_USE_WCHAR_T) || defined(_GLIBCPP_USE_TYPE_WCHAR_T) 171 template<> 172 struct __is_integer<wchar_t> 173 { 174 enum 175 { 176 _M_type = 1 177 }; 178 }; 179 # endif 180 181 template<> 182 struct __is_integer<short> 183 { 184 enum 185 { 186 _M_type = 1 187 }; 188 }; 189 190 template<> 191 struct __is_integer<unsigned short> 192 { 193 enum 194 { 195 _M_type = 1 196 }; 197 }; 198 199 template<> 200 struct __is_integer<int> 201 { 202 enum 203 { 204 _M_type = 1 205 }; 206 }; 207 208 template<> 209 struct __is_integer<unsigned int> 210 { 211 enum 212 { 213 _M_type = 1 214 }; 215 }; 216 217 template<> 218 struct __is_integer<long> 219 { 220 enum 221 { 222 _M_type = 1 223 }; 224 }; 225 226 template<> 227 struct __is_integer<unsigned long> 228 { 229 enum 230 { 231 _M_type = 1 232 }; 233 }; 234 235 template<> 236 struct __is_integer<long long> 237 { 238 enum 239 { 240 _M_type = 1 241 }; 242 }; 243 244 template<> 245 struct __is_integer<unsigned long long> 246 { 247 enum 248 { 249 _M_type = 1 250 }; 251 }; 252 253 // 254 // Floating point types 255 // 256 template<typename _Tp> 257 struct __is_floating 258 { 259 enum 260 { 261 _M_type = 0 262 }; 263 }; 264 265 // three specializations (float, double and 'long double') 266 template<> 267 struct __is_floating<float> 268 { 269 enum 270 { 271 _M_type = 1 272 }; 273 }; 274 275 template<> 276 struct __is_floating<double> 277 { 278 enum 279 { 280 _M_type = 1 281 }; 282 }; 283 284 template<> 285 struct __is_floating<long double> 286 { 287 enum 288 { 289 _M_type = 1 290 }; 291 }; 292 293 // 294 // An arithmetic type is an integer type or a floating point type 295 // 296 template<typename _Tp> 297 struct __is_arithmetic 298 { 299 enum 300 { 301 _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type 302 }; 303 }; 304 305 // 306 // A fundamental type is `void' or and arithmetic type 307 // 308 template<typename _Tp> 309 struct __is_fundamental 310 { 311 enum 312 { 313 _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type 314 }; 315 }; 316 317 // 318 // For the immediate use, the following is a good approximation 319 // 320 template<typename _Tp> 321 struct __is_pod 322 { 323 enum 324 { 325 _M_type = __is_fundamental<_Tp>::_M_type 326 }; 327 }; 328 329 } // namespace std 330 331 332 #endif //_CPP_BITS_CPP_TYPE_TRAITS_H 333