libstdc++
|
00001 // TR1 type_traits -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file tr1_impl/type_traits 00026 * This is an internal header file, included by other library headers. 00027 * You should not attempt to use it directly. 00028 */ 00029 00030 namespace std 00031 { 00032 _GLIBCXX_BEGIN_NAMESPACE_TR1 00033 00034 /** 00035 * @defgroup metaprogramming Type Traits 00036 * @ingroup utilities 00037 * 00038 * Compile time type transformation and information. 00039 * @{ 00040 */ 00041 00042 // For use in __is_convertible_simple. 00043 struct __sfinae_types 00044 { 00045 typedef char __one; 00046 typedef struct { char __arr[2]; } __two; 00047 }; 00048 00049 #define _DEFINE_SPEC_0_HELPER \ 00050 template<> 00051 00052 #define _DEFINE_SPEC_1_HELPER \ 00053 template<typename _Tp> 00054 00055 #define _DEFINE_SPEC_2_HELPER \ 00056 template<typename _Tp, typename _Cp> 00057 00058 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ 00059 _DEFINE_SPEC_##_Order##_HELPER \ 00060 struct _Trait<_Type> \ 00061 : public integral_constant<bool, _Value> { }; 00062 00063 // helper classes [4.3]. 00064 00065 /// integral_constant 00066 template<typename _Tp, _Tp __v> 00067 struct integral_constant 00068 { 00069 static const _Tp value = __v; 00070 typedef _Tp value_type; 00071 typedef integral_constant<_Tp, __v> type; 00072 }; 00073 00074 /// typedef for true_type 00075 typedef integral_constant<bool, true> true_type; 00076 00077 /// typedef for false_type 00078 typedef integral_constant<bool, false> false_type; 00079 00080 template<typename _Tp, _Tp __v> 00081 const _Tp integral_constant<_Tp, __v>::value; 00082 00083 /// remove_cv 00084 template<typename> 00085 struct remove_cv; 00086 00087 template<typename> 00088 struct __is_void_helper 00089 : public false_type { }; 00090 _DEFINE_SPEC(0, __is_void_helper, void, true) 00091 00092 // primary type categories [4.5.1]. 00093 00094 /// is_void 00095 template<typename _Tp> 00096 struct is_void 00097 : public integral_constant<bool, (__is_void_helper<typename 00098 remove_cv<_Tp>::type>::value)> 00099 { }; 00100 00101 template<typename> 00102 struct __is_integral_helper 00103 : public false_type { }; 00104 _DEFINE_SPEC(0, __is_integral_helper, bool, true) 00105 _DEFINE_SPEC(0, __is_integral_helper, char, true) 00106 _DEFINE_SPEC(0, __is_integral_helper, signed char, true) 00107 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) 00108 #ifdef _GLIBCXX_USE_WCHAR_T 00109 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) 00110 #endif 00111 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 00112 _DEFINE_SPEC(0, __is_integral_helper, char16_t, true) 00113 _DEFINE_SPEC(0, __is_integral_helper, char32_t, true) 00114 #endif 00115 _DEFINE_SPEC(0, __is_integral_helper, short, true) 00116 _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true) 00117 _DEFINE_SPEC(0, __is_integral_helper, int, true) 00118 _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true) 00119 _DEFINE_SPEC(0, __is_integral_helper, long, true) 00120 _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true) 00121 _DEFINE_SPEC(0, __is_integral_helper, long long, true) 00122 _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true) 00123 00124 /// is_integral 00125 template<typename _Tp> 00126 struct is_integral 00127 : public integral_constant<bool, (__is_integral_helper<typename 00128 remove_cv<_Tp>::type>::value)> 00129 { }; 00130 00131 template<typename> 00132 struct __is_floating_point_helper 00133 : public false_type { }; 00134 _DEFINE_SPEC(0, __is_floating_point_helper, float, true) 00135 _DEFINE_SPEC(0, __is_floating_point_helper, double, true) 00136 _DEFINE_SPEC(0, __is_floating_point_helper, long double, true) 00137 00138 /// is_floating_point 00139 template<typename _Tp> 00140 struct is_floating_point 00141 : public integral_constant<bool, (__is_floating_point_helper<typename 00142 remove_cv<_Tp>::type>::value)> 00143 { }; 00144 00145 /// is_array 00146 template<typename> 00147 struct is_array 00148 : public false_type { }; 00149 00150 template<typename _Tp, std::size_t _Size> 00151 struct is_array<_Tp[_Size]> 00152 : public true_type { }; 00153 00154 template<typename _Tp> 00155 struct is_array<_Tp[]> 00156 : public true_type { }; 00157 00158 template<typename> 00159 struct __is_pointer_helper 00160 : public false_type { }; 00161 _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true) 00162 00163 /// is_pointer 00164 template<typename _Tp> 00165 struct is_pointer 00166 : public integral_constant<bool, (__is_pointer_helper<typename 00167 remove_cv<_Tp>::type>::value)> 00168 { }; 00169 00170 /// is_reference 00171 template<typename _Tp> 00172 struct is_reference; 00173 00174 /// is_function 00175 template<typename _Tp> 00176 struct is_function; 00177 00178 template<typename> 00179 struct __is_member_object_pointer_helper 00180 : public false_type { }; 00181 _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*, 00182 !is_function<_Tp>::value) 00183 00184 /// is_member_object_pointer 00185 template<typename _Tp> 00186 struct is_member_object_pointer 00187 : public integral_constant<bool, (__is_member_object_pointer_helper< 00188 typename remove_cv<_Tp>::type>::value)> 00189 { }; 00190 00191 template<typename> 00192 struct __is_member_function_pointer_helper 00193 : public false_type { }; 00194 _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*, 00195 is_function<_Tp>::value) 00196 00197 /// is_member_function_pointer 00198 template<typename _Tp> 00199 struct is_member_function_pointer 00200 : public integral_constant<bool, (__is_member_function_pointer_helper< 00201 typename remove_cv<_Tp>::type>::value)> 00202 { }; 00203 00204 /// is_enum 00205 template<typename _Tp> 00206 struct is_enum 00207 : public integral_constant<bool, __is_enum(_Tp)> 00208 { }; 00209 00210 /// is_union 00211 template<typename _Tp> 00212 struct is_union 00213 : public integral_constant<bool, __is_union(_Tp)> 00214 { }; 00215 00216 /// is_class 00217 template<typename _Tp> 00218 struct is_class 00219 : public integral_constant<bool, __is_class(_Tp)> 00220 { }; 00221 00222 /// is_function 00223 template<typename> 00224 struct is_function 00225 : public false_type { }; 00226 template<typename _Res, typename... _ArgTypes> 00227 struct is_function<_Res(_ArgTypes...)> 00228 : public true_type { }; 00229 template<typename _Res, typename... _ArgTypes> 00230 struct is_function<_Res(_ArgTypes......)> 00231 : public true_type { }; 00232 template<typename _Res, typename... _ArgTypes> 00233 struct is_function<_Res(_ArgTypes...) const> 00234 : public true_type { }; 00235 template<typename _Res, typename... _ArgTypes> 00236 struct is_function<_Res(_ArgTypes......) const> 00237 : public true_type { }; 00238 template<typename _Res, typename... _ArgTypes> 00239 struct is_function<_Res(_ArgTypes...) volatile> 00240 : public true_type { }; 00241 template<typename _Res, typename... _ArgTypes> 00242 struct is_function<_Res(_ArgTypes......) volatile> 00243 : public true_type { }; 00244 template<typename _Res, typename... _ArgTypes> 00245 struct is_function<_Res(_ArgTypes...) const volatile> 00246 : public true_type { }; 00247 template<typename _Res, typename... _ArgTypes> 00248 struct is_function<_Res(_ArgTypes......) const volatile> 00249 : public true_type { }; 00250 00251 // composite type traits [4.5.2]. 00252 00253 /// is_arithmetic 00254 template<typename _Tp> 00255 struct is_arithmetic 00256 : public integral_constant<bool, (is_integral<_Tp>::value 00257 || is_floating_point<_Tp>::value)> 00258 { }; 00259 00260 /// is_fundamental 00261 template<typename _Tp> 00262 struct is_fundamental 00263 : public integral_constant<bool, (is_arithmetic<_Tp>::value 00264 || is_void<_Tp>::value)> 00265 { }; 00266 00267 /// is_object 00268 template<typename _Tp> 00269 struct is_object 00270 : public integral_constant<bool, !(is_function<_Tp>::value 00271 || is_reference<_Tp>::value 00272 || is_void<_Tp>::value)> 00273 { }; 00274 00275 /// is_member_pointer 00276 template<typename _Tp> 00277 struct is_member_pointer; 00278 00279 /// is_scalar 00280 template<typename _Tp> 00281 struct is_scalar 00282 : public integral_constant<bool, (is_arithmetic<_Tp>::value 00283 || is_enum<_Tp>::value 00284 || is_pointer<_Tp>::value 00285 || is_member_pointer<_Tp>::value)> 00286 { }; 00287 00288 /// is_compound 00289 template<typename _Tp> 00290 struct is_compound 00291 : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 00292 00293 /// is_member_pointer 00294 template<typename _Tp> 00295 struct __is_member_pointer_helper 00296 : public false_type { }; 00297 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) 00298 00299 template<typename _Tp> 00300 struct is_member_pointer 00301 : public integral_constant<bool, (__is_member_pointer_helper< 00302 typename remove_cv<_Tp>::type>::value)> 00303 { }; 00304 00305 // type properties [4.5.3]. 00306 /// is_const 00307 template<typename> 00308 struct is_const 00309 : public false_type { }; 00310 00311 template<typename _Tp> 00312 struct is_const<_Tp const> 00313 : public true_type { }; 00314 00315 /// is_volatile 00316 template<typename> 00317 struct is_volatile 00318 : public false_type { }; 00319 00320 template<typename _Tp> 00321 struct is_volatile<_Tp volatile> 00322 : public true_type { }; 00323 00324 /// is_empty 00325 template<typename _Tp> 00326 struct is_empty 00327 : public integral_constant<bool, __is_empty(_Tp)> 00328 { }; 00329 00330 /// is_polymorphic 00331 template<typename _Tp> 00332 struct is_polymorphic 00333 : public integral_constant<bool, __is_polymorphic(_Tp)> 00334 { }; 00335 00336 /// is_abstract 00337 template<typename _Tp> 00338 struct is_abstract 00339 : public integral_constant<bool, __is_abstract(_Tp)> 00340 { }; 00341 00342 /// has_virtual_destructor 00343 template<typename _Tp> 00344 struct has_virtual_destructor 00345 : public integral_constant<bool, __has_virtual_destructor(_Tp)> 00346 { }; 00347 00348 /// alignment_of 00349 template<typename _Tp> 00350 struct alignment_of 00351 : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 00352 00353 /// rank 00354 template<typename> 00355 struct rank 00356 : public integral_constant<std::size_t, 0> { }; 00357 00358 template<typename _Tp, std::size_t _Size> 00359 struct rank<_Tp[_Size]> 00360 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 00361 00362 template<typename _Tp> 00363 struct rank<_Tp[]> 00364 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 00365 00366 /// extent 00367 template<typename, unsigned _Uint = 0> 00368 struct extent 00369 : public integral_constant<std::size_t, 0> { }; 00370 00371 template<typename _Tp, unsigned _Uint, std::size_t _Size> 00372 struct extent<_Tp[_Size], _Uint> 00373 : public integral_constant<std::size_t, 00374 _Uint == 0 ? _Size : extent<_Tp, 00375 _Uint - 1>::value> 00376 { }; 00377 00378 template<typename _Tp, unsigned _Uint> 00379 struct extent<_Tp[], _Uint> 00380 : public integral_constant<std::size_t, 00381 _Uint == 0 ? 0 : extent<_Tp, 00382 _Uint - 1>::value> 00383 { }; 00384 00385 // relationships between types [4.6]. 00386 00387 /// is_same 00388 template<typename, typename> 00389 struct is_same 00390 : public false_type { }; 00391 00392 template<typename _Tp> 00393 struct is_same<_Tp, _Tp> 00394 : public true_type { }; 00395 00396 // const-volatile modifications [4.7.1]. 00397 00398 /// remove_const 00399 template<typename _Tp> 00400 struct remove_const 00401 { typedef _Tp type; }; 00402 00403 template<typename _Tp> 00404 struct remove_const<_Tp const> 00405 { typedef _Tp type; }; 00406 00407 /// remove_volatile 00408 template<typename _Tp> 00409 struct remove_volatile 00410 { typedef _Tp type; }; 00411 00412 template<typename _Tp> 00413 struct remove_volatile<_Tp volatile> 00414 { typedef _Tp type; }; 00415 00416 /// remove_cv 00417 template<typename _Tp> 00418 struct remove_cv 00419 { 00420 typedef typename 00421 remove_const<typename remove_volatile<_Tp>::type>::type type; 00422 }; 00423 00424 /// add_const 00425 template<typename _Tp> 00426 struct add_const 00427 { typedef _Tp const type; }; 00428 00429 /// add_volatile 00430 template<typename _Tp> 00431 struct add_volatile 00432 { typedef _Tp volatile type; }; 00433 00434 /// add_cv 00435 template<typename _Tp> 00436 struct add_cv 00437 { 00438 typedef typename 00439 add_const<typename add_volatile<_Tp>::type>::type type; 00440 }; 00441 00442 // array modifications [4.7.3]. 00443 00444 /// remove_extent 00445 template<typename _Tp> 00446 struct remove_extent 00447 { typedef _Tp type; }; 00448 00449 template<typename _Tp, std::size_t _Size> 00450 struct remove_extent<_Tp[_Size]> 00451 { typedef _Tp type; }; 00452 00453 template<typename _Tp> 00454 struct remove_extent<_Tp[]> 00455 { typedef _Tp type; }; 00456 00457 /// remove_all_extents 00458 template<typename _Tp> 00459 struct remove_all_extents 00460 { typedef _Tp type; }; 00461 00462 template<typename _Tp, std::size_t _Size> 00463 struct remove_all_extents<_Tp[_Size]> 00464 { typedef typename remove_all_extents<_Tp>::type type; }; 00465 00466 template<typename _Tp> 00467 struct remove_all_extents<_Tp[]> 00468 { typedef typename remove_all_extents<_Tp>::type type; }; 00469 00470 // pointer modifications [4.7.4]. 00471 00472 template<typename _Tp, typename> 00473 struct __remove_pointer_helper 00474 { typedef _Tp type; }; 00475 00476 template<typename _Tp, typename _Up> 00477 struct __remove_pointer_helper<_Tp, _Up*> 00478 { typedef _Up type; }; 00479 00480 /// remove_pointer 00481 template<typename _Tp> 00482 struct remove_pointer 00483 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> 00484 { }; 00485 00486 template<typename> 00487 struct remove_reference; 00488 00489 /// add_pointer 00490 template<typename _Tp> 00491 struct add_pointer 00492 { typedef typename remove_reference<_Tp>::type* type; }; 00493 00494 #undef _DEFINE_SPEC_0_HELPER 00495 #undef _DEFINE_SPEC_1_HELPER 00496 #undef _DEFINE_SPEC_2_HELPER 00497 #undef _DEFINE_SPEC 00498 00499 // @} group metaprogramming 00500 _GLIBCXX_END_NAMESPACE_TR1 00501 }