CLHEP VERSION Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 #ifndef CLHEP_TYPE_TRAITS_H 00002 #define CLHEP_TYPE_TRAITS_H 00003 00004 // ====================================================================== 00005 // 00006 // type_traits - selected C++0X metaprogramming constructs 00007 // 00008 // Author: W. E. Brown; 2010-03-05 00009 // 00010 // ====================================================================== 00011 00012 00013 #include "CLHEP/Utility/defs.h" 00014 00015 #include <memory> // for auto_ptr 00016 00017 #if defined(__GXX_EXPERIMENTAL_CXX0X__) 00018 # define CLHEP_HAS_RVALUE_REFERENCE 00019 #else 00020 # define CLHEP_NO_RVALUE_REFERENCE 00021 #endif 00022 00023 00024 namespace CLHEP { 00025 00026 // ---------------------------------------------------------------------- 00027 // Contents: 00028 // ---------------------------------------------------------------------- 00029 00030 // helper class: 00031 template< typename T, T v > struct integral_constant; 00032 typedef integral_constant<bool, true > true_type; 00033 typedef integral_constant<bool, false > false_type; 00034 00035 // primary type categories: 00036 template< typename T > struct is_void; 00037 template< typename T > struct is_integral; 00038 template< typename T > struct is_floating_point; 00039 template< typename T > struct is_array; 00040 template< typename T > struct is_pointer; 00041 template< typename T > struct is_lvalue_reference; 00042 template< typename T > struct is_rvalue_reference; 00043 template< typename T > struct is_member_object_pointer; 00044 template< typename T > struct is_member_function_pointer; 00045 template< typename T > struct is_enum; 00046 template< typename T > struct is_union; 00047 template< typename T > struct is_class; 00048 template< typename T > struct is_function; 00049 00050 // composite type categories: 00051 template< typename T > struct is_reference; 00052 template< typename T > struct is_arithmetic; 00053 template< typename T > struct is_fundamental; 00054 template< typename T > struct is_object; 00055 template< typename T > struct is_scalar; 00056 template< typename T > struct is_compound; 00057 template< typename T > struct is_member_pointer; 00058 00059 // type properties: 00060 template< typename T > struct is_const; 00061 template< typename T > struct is_volatile; 00062 #if 0 00063 template< typename T > struct is_trivial; 00064 template< typename T > struct is_trivially_copyable; 00065 template< typename T > struct is_standard_layout; 00066 template< typename T > struct is_pod; 00067 template< typename T > struct is_literal_type; 00068 template< typename T > struct is_empty; 00069 template< typename T > struct is_polymorphic; 00070 #endif // 0 00071 template< typename T > struct is_abstract; 00072 #if 0 00073 template< typename T, typename... Args > struct is_constructible; 00074 template< typename T, typename... Args > struct is_nothrow_constructible; 00075 template< typename T > struct has_default_constructor; 00076 template< typename T > struct has_copy_constructor; 00077 template< typename T > struct has_copy_assign; 00078 template< typename T > struct has_move_constructor; 00079 template< typename T > struct has_move_assign; 00080 template< typename T > struct has_trivial_default_constructor; 00081 template< typename T > struct has_trivial_copy_constructor; 00082 template< typename T > struct has_trivial_move_constructor; 00083 template< typename T > struct has_trivial_copy_assign; 00084 template< typename T > struct has_trivial_move_assign; 00085 template< typename T > struct has_trivial_destructor; 00086 template< typename T > struct has_nothrow_default_constructor; 00087 template< typename T > struct has_nothrow_copy_constructor; 00088 template< typename T > struct has_nothrow_move_constructor; 00089 template< typename T > struct has_nothrow_copy_assign; 00090 template< typename T > struct has_nothrow_move_assign; 00091 template< typename T > struct has_virtual_destructor; 00092 #endif // 0 00093 template< typename T > struct is_signed; 00094 template< typename T > struct is_unsigned; 00095 #if 0 00096 template< typename T > struct alignment_of; 00097 #endif // 0 00098 template< typename T > struct rank; 00099 template< typename T, unsigned I = 0 > struct extent; 00100 00101 // type relations: 00102 template< typename T, typename U > struct is_same; 00103 #if 0 00104 template< typename Base, typename Derived > struct is_base_of; 00105 #endif // 0 00106 template< typename From, typename To > struct is_convertible; 00107 #if 0 00108 template< typename From, typename To > struct is_explicitly_convertible; 00109 #endif // 0 00110 00111 // const-volatile modifications: 00112 template< typename T > struct remove_const; 00113 template< typename T > struct remove_volatile; 00114 template< typename T > struct remove_cv; 00115 template< typename T > struct add_const; 00116 template< typename T > struct add_volatile; 00117 template< typename T > struct add_cv; 00118 00119 // reference modifications: 00120 template< typename T > struct remove_reference; 00121 template< typename T > struct add_lvalue_reference; 00122 template< typename T > struct add_rvalue_reference; 00123 00124 // sign modifications: 00125 #if 0 00126 template< typename T > struct make_signed; 00127 template< typename T > struct make_unsigned; 00128 #endif // 0 00129 00130 // array modifications: 00131 template< typename T > struct remove_extent; 00132 template< typename T > struct remove_all_extents; 00133 00134 // pointer modifications: 00135 template< typename T > struct remove_pointer; 00136 template< typename T > struct add_pointer; 00137 00138 // other transformations: 00139 #if 0 00140 template< std::size_t Len, std::size_t Align > struct aligned_storage; 00141 template< std::size_t Len, typename... Types > struct aligned_union; 00142 template< typename T > struct decay; 00143 #endif // 0 00144 template< bool, typename T = void > struct enable_if; 00145 template< bool, typename T, typename F > struct conditional; 00146 #if 0 00147 template< typename... T > struct common_type; 00148 template< typename T > struct underlying_type; 00149 template< typename > typename result_of; // undefined 00150 template< typename F, typename... ArgTypes > typename result_of<F(ArgTypes...)>; 00151 #endif // 0 00152 00153 // non-standard (but useful) extensions: 00154 template< typename From, typename To > struct is_ptr_convertible; 00155 template< typename From, typename To, typename R=void > struct enable_if_convertible; 00156 template< typename From, typename To, typename R=void > struct enable_if_ptr_convertible; 00157 template< typename P, typename R=void > struct enable_if_auto_ptr; 00158 00159 00160 // ---------------------------------------------------------------------- 00161 // integral_constant - a helper class, useful in its own right 00162 // ---------------------------------------------------------------------- 00163 00164 template< typename T, T v > 00165 struct integral_constant 00166 { 00167 typedef T value_type; 00168 typedef integral_constant<T,v> type; 00169 00170 static value_type const value = v; 00171 00172 operator value_type() { return value; } 00173 }; // integral_constant<,> 00174 00175 00176 // ---------------------------------------------------------------------- 00177 // yes_t, no_t - unimplemented types with distinct sizeof 00178 // ---------------------------------------------------------------------- 00179 00180 namespace tt { 00181 00182 typedef char (& yes_t); // ref to char 00183 typedef char (& no_t ) [2]; // ref to 2-char array 00184 00185 } // namespace tt 00186 00187 00188 // ---------------------------------------------------------------------- 00189 // primary<,> - type classification helper 00190 // ---------------------------------------------------------------------- 00191 00192 namespace tt { 00193 00194 enum primary_code 00195 { _unknown = 0u 00196 , _void = 1u << 0 00197 , _integral = 1u << 1 00198 , _floating_point = 1u << 2 00199 , _array = 1u << 3 00200 , _pointer = 1u << 4 00201 , _lvalue_reference = 1u << 5 00202 , _rvalue_reference = 1u << 6 00203 , _member_object_pointer = 1u << 7 00204 , _member_function_pointer = 1u << 8 00205 , _enum = 1u << 9 00206 , _union = 1u << 10 // Help, compiler! 00207 , _class = 1u << 11 00208 , _function = 1u << 12 00209 }; // primary_code 00210 00211 // Helpers to recognize classes: 00212 template< typename U > yes_t isAclass( void(U::*)() ); 00213 template< typename U > no_t isAclass( ... ); 00214 00215 // Helpers to recognize functions: 00216 template< typename U > 00217 no_t isAfunction( U(*)[1] ); // arrays of non-{fctn/ref/void}s 00218 template< typename U > 00219 yes_t isAfunction( ... ); 00220 00221 // encode via helpers or by elimination: 00222 // enum 00223 // union // need help, compiler! 00224 // class 00225 // function 00226 template< typename T > 00227 struct encode 00228 { 00229 static primary_code const value 00230 = ( sizeof(isAclass <T>(0)) == sizeof(yes_t) ) ? _class 00231 : ( ( sizeof(isAfunction<T>(0)) == sizeof(yes_t) ) ? _function 00232 : /* by elimination */ _enum 00233 ); 00234 }; // encode<> 00235 00236 // encode cv-qualified type: 00237 template< typename T > 00238 struct encode<T const> : public encode<T> { }; 00239 template< typename T > 00240 struct encode<T volatile> : public encode<T> { }; 00241 template< typename T > 00242 struct encode<T const volatile> : public encode<T> { }; 00243 00244 // encode array: 00245 template< typename T > 00246 struct encode<T[]> 00247 { static primary_code const value = _array; }; 00248 template< typename T > 00249 struct encode<T const[]> 00250 { static primary_code const value = _array; }; 00251 template< typename T > 00252 struct encode<T volatile[]> 00253 { static primary_code const value = _array; }; 00254 template< typename T > 00255 struct encode<T const volatile[]> 00256 { static primary_code const value = _array; }; 00257 template< typename T, unsigned N > 00258 struct encode<T[N]> 00259 { static primary_code const value = _array; }; 00260 template< typename T, unsigned N > 00261 struct encode<T const[N]> 00262 { static primary_code const value = _array; }; 00263 template< typename T, unsigned N > 00264 struct encode<T volatile[N]> 00265 { static primary_code const value = _array; }; 00266 template< typename T, unsigned N > 00267 struct encode<T const volatile[N]> 00268 { static primary_code const value = _array; }; 00269 00270 // encode floating_point: 00271 template<> 00272 struct encode<float> 00273 { static primary_code const value = _floating_point; }; 00274 template<> 00275 struct encode<double> 00276 { static primary_code const value = _floating_point; }; 00277 template<> 00278 struct encode<long double> 00279 { static primary_code const value = _floating_point; }; 00280 00281 // encode integral: 00282 template<> 00283 struct encode<bool> 00284 { static primary_code const value = _integral; }; 00285 template<> 00286 struct encode<signed char> 00287 { static primary_code const value = _integral; }; 00288 template<> 00289 struct encode<char> 00290 { static primary_code const value = _integral; }; 00291 template<> 00292 struct encode<unsigned char> 00293 { static primary_code const value = _integral; }; 00294 #if 0 00295 template<> 00296 struct encode<wchar_t> 00297 { static primary_code const value = _integral; }; 00298 #endif 00299 template<> 00300 struct encode<short> 00301 { static primary_code const value = _integral; }; 00302 template<> 00303 struct encode<unsigned short> 00304 { static primary_code const value = _integral; }; 00305 template<> 00306 struct encode<int> 00307 { static primary_code const value = _integral; }; 00308 template<> 00309 struct encode<unsigned int> 00310 { static primary_code const value = _integral; }; 00311 template<> 00312 struct encode<long> 00313 { static primary_code const value = _integral; }; 00314 template<> 00315 struct encode<unsigned long> 00316 { static primary_code const value = _integral; }; 00317 00318 // encode member_function_pointer: 00319 template< typename T, typename C > 00320 struct encode<T (C::*)()> 00321 { static primary_code const value = _member_function_pointer; }; 00322 template< typename T, typename C > 00323 struct encode<T (C::*)() const> 00324 { static primary_code const value = _member_function_pointer; }; 00325 template< typename T, typename C > 00326 struct encode<T (C::*)() volatile> 00327 { static primary_code const value = _member_function_pointer; }; 00328 template< typename T, typename C > 00329 struct encode<T (C::*)() const volatile> 00330 { static primary_code const value = _member_function_pointer; }; 00331 template< typename T, typename C 00332 , typename A1 > 00333 struct encode<T (C::*)(A1)> 00334 { static primary_code const value = _member_function_pointer; }; 00335 template< typename T, typename C 00336 , typename A1 > 00337 struct encode<T (C::*)(A1) const> 00338 { static primary_code const value = _member_function_pointer; }; 00339 template< typename T, typename C 00340 , typename A1 > 00341 struct encode<T (C::*)(A1) volatile> 00342 { static primary_code const value = _member_function_pointer; }; 00343 template< typename T, typename C 00344 , typename A1 > 00345 struct encode<T (C::*)(A1) const volatile> 00346 { static primary_code const value = _member_function_pointer; }; 00347 template< typename T, typename C 00348 , typename A1, typename A2 > 00349 struct encode<T (C::*)(A1,A2)> 00350 { static primary_code const value = _member_function_pointer; }; 00351 template< typename T, typename C 00352 , typename A1, typename A2 > 00353 struct encode<T (C::*)(A1,A2) const> 00354 { static primary_code const value = _member_function_pointer; }; 00355 template< typename T, typename C 00356 , typename A1, typename A2 > 00357 struct encode<T (C::*)(A1,A2) volatile> 00358 { static primary_code const value = _member_function_pointer; }; 00359 template< typename T, typename C 00360 , typename A1, typename A2 > 00361 struct encode<T (C::*)(A1,A2) const volatile> 00362 { static primary_code const value = _member_function_pointer; }; 00363 template< typename T, typename C 00364 , typename A1, typename A2, typename A3 > 00365 struct encode<T (C::*)(A1,A2,A3)> 00366 { static primary_code const value = _member_function_pointer; }; 00367 template< typename T, typename C 00368 , typename A1, typename A2, typename A3 > 00369 struct encode<T (C::*)(A1,A2,A3) const> 00370 { static primary_code const value = _member_function_pointer; }; 00371 template< typename T, typename C 00372 , typename A1, typename A2, typename A3 > 00373 struct encode<T (C::*)(A1,A2,A3) volatile> 00374 { static primary_code const value = _member_function_pointer; }; 00375 template< typename T, typename C 00376 , typename A1, typename A2, typename A3 > 00377 struct encode<T (C::*)(A1,A2,A3) const volatile> 00378 { static primary_code const value = _member_function_pointer; }; 00379 template< typename T, typename C 00380 , typename A1, typename A2, typename A3, typename A4 > 00381 struct encode<T (C::*)(A1,A2,A3,A4)> 00382 { static primary_code const value = _member_function_pointer; }; 00383 template< typename T, typename C 00384 , typename A1, typename A2, typename A3, typename A4 > 00385 struct encode<T (C::*)(A1,A2,A3,A4) const> 00386 { static primary_code const value = _member_function_pointer; }; 00387 template< typename T, typename C 00388 , typename A1, typename A2, typename A3, typename A4 > 00389 struct encode<T (C::*)(A1,A2,A3,A4) volatile> 00390 { static primary_code const value = _member_function_pointer; }; 00391 template< typename T, typename C 00392 , typename A1, typename A2, typename A3, typename A4 > 00393 struct encode<T (C::*)(A1,A2,A3,A4) const volatile> 00394 { static primary_code const value = _member_function_pointer; }; 00395 template< typename T, typename C 00396 , typename A1, typename A2, typename A3, typename A4, typename A5 > 00397 struct encode<T (C::*)(A1,A2,A3,A4,A5)> 00398 { static primary_code const value = _member_function_pointer; }; 00399 template< typename T, typename C 00400 , typename A1, typename A2, typename A3, typename A4, typename A5 > 00401 struct encode<T (C::*)(A1,A2,A3,A4,A5) const> 00402 { static primary_code const value = _member_function_pointer; }; 00403 template< typename T, typename C 00404 , typename A1, typename A2, typename A3, typename A4, typename A5 > 00405 struct encode<T (C::*)(A1,A2,A3,A4,A5) volatile> 00406 { static primary_code const value = _member_function_pointer; }; 00407 template< typename T, typename C 00408 , typename A1, typename A2, typename A3, typename A4, typename A5 > 00409 struct encode<T (C::*)(A1,A2,A3,A4,A5) const volatile> 00410 { static primary_code const value = _member_function_pointer; }; 00411 00412 // encode member_object_pointer: 00413 template< typename T, typename C > 00414 struct encode<T C::*> 00415 { static primary_code const value = _member_object_pointer; }; 00416 00417 // encode pointer: 00418 template< typename T > 00419 struct encode<T *> 00420 { static primary_code const value = _pointer; }; 00421 00422 // encode lvalue_reference: 00423 template< typename T > 00424 struct encode<T &> 00425 { static primary_code const value = _lvalue_reference; }; 00426 00427 // encode rvalue_reference: 00428 #if defined(CLHEP_HAS_RVALUE_REFERENCE) 00429 template< typename T > 00430 struct encode<T&&> 00431 { static primary_code const value = _rvalue_reference; }; 00432 #endif // CLHEP_HAS_RVALUE_REFERENCE 00433 00434 // encode void: 00435 template<> 00436 struct encode<void> 00437 { static primary_code const value = _void; }; 00438 00439 // apply encoding: 00440 template< typename T, unsigned int p > 00441 struct primary : integral_constant<bool, bool(p & encode<T>::value)> { }; 00442 00443 } // namespace tt 00444 00445 00446 // ---------------------------------------------------------------------- 00447 // is_void - metaprogramming type trait detecting void types 00448 // ---------------------------------------------------------------------- 00449 00450 template< typename T > 00451 struct is_void 00452 : public tt::primary<T, tt::_void > { }; 00453 00454 00455 // ---------------------------------------------------------------------- 00456 // is_integral - metaprogramming type trait detecting integer types 00457 // ---------------------------------------------------------------------- 00458 00459 template< typename T > 00460 struct is_integral 00461 : public tt::primary<T, tt::_integral > { }; 00462 00463 00464 // ---------------------------------------------------------------------- 00465 // is_floating_point - metaprogramming type trait detecting real types 00466 // ---------------------------------------------------------------------- 00467 00468 template< typename T > 00469 struct is_floating_point 00470 : public tt::primary<T, tt::_floating_point > { }; 00471 00472 // ---------------------------------------------------------------------- 00473 // is_array - metaprogramming type trait detecting T[...] types 00474 // ---------------------------------------------------------------------- 00475 00476 template< typename T > 00477 struct is_array 00478 : public tt::primary<T, tt::_array > { }; 00479 00480 00481 // ---------------------------------------------------------------------- 00482 // is_pointer - metaprogramming type trait detecting T* types 00483 // ---------------------------------------------------------------------- 00484 00485 template< typename T > 00486 struct is_pointer 00487 : public tt::primary<T, tt::_pointer > { }; 00488 00489 00490 // ---------------------------------------------------------------------- 00491 // is_lvalue_reference - metaprogramming type trait detecting T& types 00492 // ---------------------------------------------------------------------- 00493 00494 template< typename T > 00495 struct is_lvalue_reference 00496 : public tt::primary<T, tt::_lvalue_reference > { }; 00497 00498 00499 // ---------------------------------------------------------------------- 00500 // is_rvalue_reference - metaprogramming type trait detecting T&& types 00501 // ---------------------------------------------------------------------- 00502 00503 template< typename T > struct is_rvalue_reference 00504 : public tt::primary<T, tt::_rvalue_reference > { }; 00505 00506 00507 // ---------------------------------------------------------------------- 00508 // is_member_object_pointer - metaprogramming type trait 00509 // ---------------------------------------------------------------------- 00510 00511 template< typename T > struct is_member_object_pointer 00512 : public conditional< is_member_function_pointer<T>::value 00513 , false_type 00514 , tt::primary<T, tt::_member_object_pointer> 00515 >::type 00516 { }; 00517 00518 00519 // ---------------------------------------------------------------------- 00520 // is_member_function_pointer - metaprogramming type trait 00521 // ---------------------------------------------------------------------- 00522 00523 template< typename T > 00524 struct is_member_function_pointer 00525 : public tt::primary<T, tt::_member_function_pointer > { }; 00526 00527 00528 // ---------------------------------------------------------------------- 00529 // is_enum - metaprogramming type trait detecting enumeration types 00530 // ---------------------------------------------------------------------- 00531 00532 template< typename T > 00533 struct is_enum 00534 : public tt::primary<T, tt::_enum > { }; 00535 00536 00537 // ---------------------------------------------------------------------- 00538 // is_union - metaprogramming type trait detecting union types 00539 // ---------------------------------------------------------------------- 00540 00541 template< typename T > 00542 struct is_union 00543 : public tt::primary<T, tt::_union > { }; 00544 00545 00546 // ---------------------------------------------------------------------- 00547 // is_class - metaprogramming type trait detecting class types 00548 // ---------------------------------------------------------------------- 00549 00550 template< typename T > 00551 struct is_class 00552 : public tt::primary<T, tt::_class > { }; 00553 00554 00555 // ---------------------------------------------------------------------- 00556 // is_function - metaprogramming type trait detecting function types 00557 // ---------------------------------------------------------------------- 00558 00559 template< typename T > 00560 struct is_function 00561 : public tt::primary<T, tt::_function > { }; 00562 00563 00564 // ---------------------------------------------------------------------- 00565 // is_reference - metaprogramming composite type trait 00566 // ---------------------------------------------------------------------- 00567 00568 template< typename T > 00569 struct is_reference 00570 : public tt::primary< T, tt::_lvalue_reference 00571 | tt::_rvalue_reference 00572 > 00573 { }; 00574 00575 00576 // ---------------------------------------------------------------------- 00577 // is_arithmetic - metaprogramming composite type trait 00578 // ---------------------------------------------------------------------- 00579 00580 template< typename T > 00581 struct is_arithmetic 00582 : public tt::primary< T, tt::_integral 00583 | tt::_floating_point 00584 > 00585 { }; 00586 00587 00588 // ---------------------------------------------------------------------- 00589 // is_fundamental - metaprogramming composite type trait 00590 // ---------------------------------------------------------------------- 00591 00592 template< typename T > 00593 struct is_fundamental 00594 : public tt::primary< T, tt::_integral 00595 | tt::_floating_point 00596 | tt::_void 00597 > 00598 { }; 00599 00600 00601 // ---------------------------------------------------------------------- 00602 // is_object - metaprogramming composite type trait 00603 // ---------------------------------------------------------------------- 00604 00605 template< typename T > 00606 struct is_object 00607 : public tt::primary< T, tt::_array 00608 | tt::_class 00609 | tt::_enum 00610 | tt::_floating_point 00611 | tt::_integral 00612 | tt::_member_object_pointer 00613 | tt::_member_function_pointer 00614 | tt::_pointer 00615 | tt::_union 00616 > 00617 { }; 00618 00619 00620 // ---------------------------------------------------------------------- 00621 // is_scalar - metaprogramming composite type trait 00622 // ---------------------------------------------------------------------- 00623 00624 template< typename T > 00625 struct is_scalar 00626 : public tt::primary< T, tt::_integral 00627 | tt::_floating_point 00628 | tt::_enum 00629 | tt::_pointer 00630 | tt::_member_object_pointer 00631 | tt::_member_function_pointer 00632 > 00633 { }; 00634 00635 00636 // ---------------------------------------------------------------------- 00637 // is_compound - metaprogramming composite type trait 00638 // ---------------------------------------------------------------------- 00639 00640 template< typename T > 00641 struct is_compound 00642 : public tt::primary< T, tt::_array 00643 | tt::_pointer 00644 | tt::_lvalue_reference 00645 | tt::_rvalue_reference 00646 | tt::_member_object_pointer 00647 | tt::_member_function_pointer 00648 | tt::_enum 00649 | tt::_union 00650 | tt::_class 00651 | tt::_function 00652 > 00653 { }; 00654 00655 00656 // ---------------------------------------------------------------------- 00657 // is_member_pointer - metaprogramming composite type trait 00658 // ---------------------------------------------------------------------- 00659 00660 template< typename T > 00661 struct is_member_pointer 00662 : public tt::primary< T, tt::_member_object_pointer 00663 | tt::_member_function_pointer 00664 > 00665 { }; 00666 00667 00668 // ---------------------------------------------------------------------- 00669 // cv<> - helper analyzing a type's cv-qualification(s) 00670 // ---------------------------------------------------------------------- 00671 00672 namespace tt { 00673 00674 template< typename T > 00675 struct cv 00676 { 00677 static bool const is_c = false; 00678 static bool const is_v = false; 00679 typedef T const add_c_type; 00680 typedef T volatile add_v_type; 00681 typedef T const volatile add_cv_type; 00682 typedef T rem_c_type; 00683 typedef T rem_v_type; 00684 typedef T rem_cv_type; 00685 }; 00686 00687 template< typename T > 00688 struct cv<T const> 00689 { 00690 static bool const is_c = true; 00691 static bool const is_v = false; 00692 typedef T const add_c_type; 00693 typedef T const volatile add_v_type; 00694 typedef T const volatile add_cv_type; 00695 typedef T rem_c_type; 00696 typedef T const rem_v_type; 00697 typedef T rem_cv_type; 00698 }; 00699 00700 template< typename T > 00701 struct cv<T volatile> 00702 { 00703 static bool const is_c = false; 00704 static bool const is_v = true; 00705 typedef T const volatile add_c_type; 00706 typedef T volatile add_v_type; 00707 typedef T const volatile add_cv_type; 00708 typedef T volatile rem_c_type; 00709 typedef T rem_v_type; 00710 typedef T rem_cv_type; 00711 }; 00712 00713 template< typename T > 00714 struct cv<T const volatile> 00715 { 00716 static bool const is_c = true; 00717 static bool const is_v = true; 00718 typedef T const volatile add_c_type; 00719 typedef T const volatile add_v_type; 00720 typedef T const volatile add_cv_type; 00721 typedef T volatile rem_c_type; 00722 typedef T const rem_v_type; 00723 typedef T rem_cv_type; 00724 }; 00725 00726 template< typename T > 00727 struct cv<T &> 00728 { 00729 static bool const is_c = false; 00730 static bool const is_v = false; 00731 typedef T & add_c_type; 00732 typedef T & add_v_type; 00733 typedef T & add_cv_type; 00734 typedef T & rem_c_type; 00735 typedef T & rem_v_type; 00736 typedef T & rem_cv_type; 00737 }; 00738 00739 } // namespace tt 00740 00741 00742 // ---------------------------------------------------------------------- 00743 // is_const - metaprogramming type trait detecting type constness 00744 // ---------------------------------------------------------------------- 00745 00746 template< typename T > 00747 struct is_const 00748 : public integral_constant<bool, tt::cv<T>::is_c > { }; 00749 00750 00751 // ---------------------------------------------------------------------- 00752 // is_volatile - metaprogramming type trait detecting type volatility 00753 // ---------------------------------------------------------------------- 00754 00755 template< typename T > 00756 struct is_volatile 00757 : public integral_constant<bool, tt::cv<T>::is_v > { }; 00758 00759 00760 // ---------------------------------------------------------------------- 00761 // is_abstract_class - helper detecting when a class is abstract 00762 // ---------------------------------------------------------------------- 00763 00764 namespace tt { 00765 00766 template< typename, bool > 00767 struct is_abstract_class 00768 : public false_type { }; // default: not a class, hence not abstract 00769 00770 template< typename C > 00771 struct is_abstract_class<C,true> // C is known to be a class type 00772 { 00773 protected: 00774 template< typename T > 00775 static no_t take( T (*)[1] ); // can't form array of abstract T 00776 template< typename T > 00777 static yes_t take( ... ); 00778 00779 public: 00780 static bool const value = sizeof( take<C>(0) ) == sizeof(yes_t); 00781 }; // is_abstract_class<,true> 00782 00783 } // namespace tt 00784 00785 00786 // ---------------------------------------------------------------------- 00787 // is_abstract - metaprogramming type trait detecting abstract classes 00788 // ---------------------------------------------------------------------- 00789 00790 template< typename T > 00791 struct is_abstract 00792 : public tt::is_abstract_class< T 00793 , is_class<T>::value 00794 > 00795 { }; 00796 00797 00798 // ---------------------------------------------------------------------- 00799 // is_signed - metaprogramming type trait detecting type signedness 00800 // ---------------------------------------------------------------------- 00801 00802 template< typename > 00803 struct is_signed 00804 : public false_type { }; 00805 00806 template<> 00807 struct is_signed<signed char> 00808 : public true_type { }; 00809 template<> 00810 struct is_signed<short> 00811 : public true_type { }; 00812 template<> 00813 struct is_signed<int> 00814 : public true_type { }; 00815 template<> 00816 struct is_signed<long> 00817 : public true_type { }; 00818 00819 template< typename T > 00820 struct is_signed<T const> 00821 : public is_signed<T> { }; 00822 template< typename T > 00823 struct is_signed<T volatile> 00824 : public is_signed<T> { }; 00825 template< typename T > 00826 struct is_signed<T const volatile> 00827 : public is_signed<T> { }; 00828 00829 00830 // ---------------------------------------------------------------------- 00831 // is_unsigned - metaprogramming type trait detecting type unsignedness 00832 // ---------------------------------------------------------------------- 00833 00834 template< typename > 00835 struct is_unsigned 00836 : public false_type { }; 00837 00838 template<> 00839 struct is_unsigned<unsigned char> 00840 : public true_type { }; 00841 template<> 00842 struct is_unsigned<unsigned short> 00843 : public true_type { }; 00844 template<> 00845 struct is_unsigned<unsigned int> 00846 : public true_type { }; 00847 template<> 00848 struct is_unsigned<unsigned long> 00849 : public true_type { }; 00850 00851 template< typename T > 00852 struct is_unsigned<T const> 00853 : public is_unsigned<T> { }; 00854 template< typename T > 00855 struct is_unsigned<T volatile> 00856 : public is_unsigned<T> { }; 00857 template< typename T > 00858 struct is_unsigned<T const volatile> 00859 : public is_unsigned<T> { }; 00860 00861 00862 // ---------------------------------------------------------------------- 00863 // arr<> - helper analyzing a type's array qualification(s) 00864 // ---------------------------------------------------------------------- 00865 00866 namespace tt { 00867 00868 template< typename T > 00869 struct arr // non-array 00870 { 00871 typedef T rem_ext_type; 00872 typedef T rem_arr_type; 00873 00874 static int const rank = 0; 00875 00876 template< unsigned I > 00877 struct extent { static int const value = 0; }; 00878 }; 00879 00880 template< typename T, unsigned N > 00881 struct arr<T[N]> 00882 { 00883 typedef T rem_ext_type; 00884 typedef typename tt::arr<T>::rem_arr_type rem_arr_type; 00885 00886 static int const rank = 1 + tt::arr<T>::rank; 00887 00888 template< unsigned I > 00889 struct extent 00890 { 00891 static int const value = (I == rank) 00892 ? N 00893 : tt::arr<T>::template extent<I>::value; 00894 }; 00895 }; 00896 00897 template< typename T > 00898 struct arr<T[]> 00899 { 00900 typedef T rem_ext_type; 00901 typedef T rem_arr_type; 00902 00903 static int const rank = 1; 00904 00905 template< unsigned I > 00906 struct extent { static int const value = 0; }; 00907 }; 00908 00909 } // namespace tt 00910 00911 00912 // ---------------------------------------------------------------------- 00913 // rank - metaprogramming type trait detecting array's rank 00914 // ---------------------------------------------------------------------- 00915 00916 template< typename T > 00917 struct rank 00918 : public integral_constant<int, tt::arr<T>::rank> { }; 00919 00920 00921 // ---------------------------------------------------------------------- 00922 // extent - metaprogramming type trait detecting array's extent 00923 // ---------------------------------------------------------------------- 00924 00925 template< typename T, unsigned I > 00926 struct extent 00927 : public integral_constant<int, tt::arr<T>::template extent<I>::value> { }; 00928 00929 00930 // ---------------------------------------------------------------------- 00931 // is_same - metaprogramming type trait detecting type identity 00932 // ---------------------------------------------------------------------- 00933 00934 template< typename T, typename U > 00935 struct is_same : public false_type { }; 00936 template< typename T > 00937 struct is_same<T,T> : public true_type { }; 00938 00939 00940 // ---------------------------------------------------------------------- 00941 // any_conversion - helper to avoid passing a UDT through ... parameter 00942 // ---------------------------------------------------------------------- 00943 00944 namespace tt { 00945 00946 struct any_conversion 00947 { 00948 template< typename T > 00949 any_conversion( T const volatile & ); 00950 template< typename T > 00951 any_conversion( T & ); // no cv-qual on fctn-refs 00952 }; // any_conversion 00953 00954 } // namespace tt 00955 00956 00957 // ---------------------------------------------------------------------- 00958 // converts_to - helper detecting convertability 00959 // ---------------------------------------------------------------------- 00960 00961 namespace tt { 00962 00963 template< typename From, typename To, bool > 00964 struct converts 00965 : public false_type { }; // default: can't convert to abstract To 00966 00967 template< typename From, typename To > 00968 struct converts<From,To,false> // To is non-abstract 00969 { 00970 protected: 00971 static yes_t take( To, int ); 00972 static no_t take( any_conversion, ... ); 00973 static From from; 00974 00975 public: 00976 static bool const value 00977 = sizeof( take( from, 0 ) ) == sizeof(yes_t); 00978 }; // converts<> 00979 00980 } // namespace tt 00981 00982 00983 // ---------------------------------------------------------------------- 00984 // is_convertible - metaprogramming type trait detecting convertability 00985 // ---------------------------------------------------------------------- 00986 00987 template< typename From, typename To > 00988 struct is_convertible 00989 : public tt::converts<From,To,is_abstract<To>::value> { }; 00990 00991 template< > struct is_convertible<void,void> 00992 : public true_type { }; 00993 00994 template< typename T > 00995 struct is_convertible<T,void> 00996 : public true_type { }; 00997 00998 template< typename T > 00999 struct is_convertible<void,T> 01000 : public false_type { }; 01001 01002 template< > 01003 struct is_convertible<const void,const void> 01004 : public true_type { }; 01005 01006 template< typename T > 01007 struct is_convertible<T,const void> 01008 : public true_type { }; 01009 01010 template< typename T > 01011 struct is_convertible<const void,T> 01012 : public false_type { }; 01013 01014 template< > 01015 struct is_convertible<volatile void,volatile void> 01016 : public true_type { }; 01017 01018 template< typename T > 01019 struct is_convertible<T,volatile void> 01020 : public true_type { }; 01021 01022 template< typename T > 01023 struct is_convertible<volatile void,T> 01024 : public false_type { }; 01025 01026 template< > 01027 struct is_convertible<const volatile void,const volatile void> 01028 : public true_type { }; 01029 01030 template< typename T > 01031 struct is_convertible<T,const volatile void> 01032 : public true_type { }; 01033 01034 template< typename T > 01035 struct is_convertible<const volatile void,T> 01036 : public false_type { }; 01037 01038 template< typename From, int N, typename To > 01039 struct is_convertible<From[N],To> 01040 : public is_convertible<From*,To> { }; 01041 01042 template< typename From, typename To, int N > 01043 struct is_convertible<From,To[N]> 01044 : public false_type { }; 01045 01046 01047 // ---------------------------------------------------------------------- 01048 // remove_const - metaprogramming type trait ensuring non-constness 01049 // ---------------------------------------------------------------------- 01050 01051 template< typename T > 01052 struct remove_const 01053 { 01054 typedef typename tt::cv<T>::rem_c_type type; 01055 }; 01056 01057 01058 // ---------------------------------------------------------------------- 01059 // remove_volatile - metaprogramming type trait ensuring non-volatility 01060 // ---------------------------------------------------------------------- 01061 01062 template< typename T > 01063 struct remove_volatile 01064 { 01065 typedef typename tt::cv<T>::rem_v_type type; 01066 }; 01067 01068 01069 // ---------------------------------------------------------------------- 01070 // remove_cv - metaprogramming type trait ensuring no cv-qualification 01071 // ---------------------------------------------------------------------- 01072 01073 template< typename T > 01074 struct remove_cv 01075 { 01076 typedef typename tt::cv<T>::rem_cv_type type; 01077 }; 01078 01079 01080 // ---------------------------------------------------------------------- 01081 // add_const - metaprogramming type trait ensuring constness 01082 // ---------------------------------------------------------------------- 01083 01084 template< typename T > 01085 struct add_const 01086 { 01087 typedef typename tt::cv<T>::add_c_type type; 01088 }; 01089 01090 01091 // ---------------------------------------------------------------------- 01092 // add_volatile - metaprogramming type trait ensuring volatility 01093 // ---------------------------------------------------------------------- 01094 01095 template< typename T > 01096 struct add_volatile 01097 { 01098 typedef typename tt::cv<T>::add_v_type type; 01099 }; 01100 01101 01102 // ---------------------------------------------------------------------- 01103 // add_cv - metaprogramming type trait ensuring constness & volatility 01104 // ---------------------------------------------------------------------- 01105 01106 template< typename T > 01107 struct add_cv 01108 { 01109 typedef typename tt::cv<T>::add_cv_type type; 01110 }; 01111 01112 01113 // ---------------------------------------------------------------------- 01114 // ref<> - helper analyzing a type's reference qualification 01115 // ---------------------------------------------------------------------- 01116 01117 namespace tt { 01118 01119 template< typename T 01120 , primary_code = encode<T>::value 01121 > 01122 struct ref // non-lref && non-rref && non-void 01123 { 01124 typedef T& add_lref_type; 01125 #if defined(CLHEP_HAS_RVALUE_REFERENCE) 01126 typedef T&& add_rref_type; 01127 #endif // CLHEP_HAS_RVALUE_REFERENCE 01128 typedef T rem_ref_type; 01129 }; 01130 01131 template< typename T > 01132 struct ref<T&,_lvalue_reference> 01133 { 01134 typedef T& add_lref_type; 01135 typedef T& add_rref_type; 01136 typedef T rem_ref_type; 01137 }; 01138 01139 #if defined(CLHEP_HAS_RVALUE_REFERENCE) 01140 template< typename T > 01141 struct ref<T&&,_rvalue_reference> 01142 { 01143 typedef T& add_lref_type; 01144 typedef T&& add_rref_type; 01145 typedef T rem_ref_type; 01146 }; 01147 #endif // CLHEP_HAS_RVALUE_REFERENCE 01148 01149 template< typename T > 01150 struct ref<T,_void> 01151 { 01152 typedef T add_lref_type; 01153 typedef T add_rref_type; 01154 typedef T rem_ref_type; 01155 }; 01156 01157 } // namespace tt 01158 01159 01160 // ---------------------------------------------------------------------- 01161 // remove_reference - metaprogramming type trait ensuring non-reference 01162 // ---------------------------------------------------------------------- 01163 01164 template< typename T > 01165 struct remove_reference 01166 { 01167 typedef typename tt::ref<T>::rem_ref_type type; 01168 }; 01169 01170 01171 // ---------------------------------------------------------------------- 01172 // add_lvalue_reference - metaprogramming type trait ensuring lvalue-ref 01173 // ---------------------------------------------------------------------- 01174 01175 template< typename T > 01176 struct add_lvalue_reference 01177 { 01178 typedef typename tt::ref<T>::add_lref_type type; 01179 }; 01180 01181 01182 // ---------------------------------------------------------------------- 01183 // add_rvalue_reference - metaprogramming type trait ensuring rvalue-ref 01184 // ---------------------------------------------------------------------- 01185 01186 template< typename T > 01187 struct add_rvalue_reference 01188 { 01189 typedef typename tt::ref<T>::add_rref_type type; 01190 }; 01191 01192 01193 // ---------------------------------------------------------------------- 01194 // ptr<> - helper analyzing a type's pointer qualification 01195 // ---------------------------------------------------------------------- 01196 01197 namespace tt { 01198 01199 template< typename T > 01200 struct ptr 01201 { 01202 typedef typename tt::ref<T>::rem_ref_type * add_ptr_type; 01203 typedef T rem_ptr_type; 01204 }; 01205 01206 template< typename T > 01207 struct ptr<T *> 01208 { 01209 typedef T * * add_ptr_type; 01210 typedef T rem_ptr_type; 01211 }; 01212 01213 template< typename T > 01214 struct ptr<T * const> 01215 { 01216 typedef T * const * add_ptr_type; 01217 typedef T rem_ptr_type; 01218 }; 01219 01220 template< typename T > 01221 struct ptr<T * volatile> 01222 { 01223 typedef T * volatile * add_ptr_type; 01224 typedef T rem_ptr_type; 01225 }; 01226 01227 template< typename T > 01228 struct ptr<T * const volatile> 01229 { 01230 typedef T * const volatile * add_ptr_type; 01231 typedef T rem_ptr_type; 01232 }; 01233 01234 } // namespace tt 01235 01236 01237 // ---------------------------------------------------------------------- 01238 // remove_extent - metaprogramming type trait reducing an array's extent 01239 // ---------------------------------------------------------------------- 01240 01241 template< typename T > 01242 struct remove_extent 01243 { 01244 typedef typename tt::arr<T>::rem_ext_type type; 01245 }; 01246 01247 01248 // ---------------------------------------------------------------------- 01249 // remove_all_extents - metaprogramming type trait yielding a non-array 01250 // ---------------------------------------------------------------------- 01251 01252 template< typename T > 01253 struct remove_all_extents 01254 { 01255 typedef typename tt::arr<T>::rem_arr_type type; 01256 }; 01257 01258 01259 // ---------------------------------------------------------------------- 01260 // remove_pointer - metaprogramming type trait ensuring non-pointer 01261 // ---------------------------------------------------------------------- 01262 01263 template< typename T > 01264 struct remove_pointer 01265 { 01266 typedef typename tt::ptr<T>::rem_ptr_type type; 01267 }; 01268 01269 01270 // ---------------------------------------------------------------------- 01271 // add_pointer - metaprogramming type trait ensuring pointer 01272 // ---------------------------------------------------------------------- 01273 01274 template< typename T > 01275 struct add_pointer 01276 { 01277 typedef typename tt::ptr<T>::add_ptr_type type; 01278 }; 01279 01280 01281 // ---------------------------------------------------------------------- 01282 // enable_if - metaprogramming construct for applied SFINAE 01283 // ---------------------------------------------------------------------- 01284 01285 template< typename T > struct enable_if<true ,T> { typedef T type; }; 01286 template< typename T > struct enable_if<false,T> { }; 01287 01288 01289 // ---------------------------------------------------------------------- 01290 // conditional - metaprogramming construct for type selection 01291 // ---------------------------------------------------------------------- 01292 01293 template< typename T, typename F > struct conditional<true ,T,F> { typedef T type; }; 01294 template< typename T, typename F > struct conditional<false,T,F> { typedef F type; }; 01295 01296 01297 // ---------------------------------------------------------------------- 01298 // is_ptr_convertible - variant of is_convertible, based on ptrs to types 01299 // ---------------------------------------------------------------------- 01300 01301 template< typename From, typename To > 01302 struct is_ptr_convertible 01303 { 01304 protected: 01305 static tt::yes_t take( To * ); 01306 static tt::no_t take( ... ); 01307 01308 public: 01309 static bool const value 01310 = sizeof( take( static_cast<From*>(0) ) ) == sizeof(tt::yes_t); 01311 }; // is_ptr_convertible<,> 01312 01313 01314 // ---------------------------------------------------------------------- 01315 // enable_if_convertible - convenience metaprogramming type trait 01316 // ---------------------------------------------------------------------- 01317 01318 template< typename From // type of conversion's source 01319 , typename To // type of conversion's target 01320 , typename R // result type if conversion is valid 01321 > 01322 struct enable_if_convertible 01323 : public enable_if< is_convertible<From,To>::value, R > { }; 01324 01325 01326 // ---------------------------------------------------------------------- 01327 // enable_if_ptr_convertible - convenience metaprogramming type trait 01328 // ---------------------------------------------------------------------- 01329 01330 template< typename From // type of conversion's source 01331 , typename To // type of conversion's target 01332 , typename R // result type if conversion is valid 01333 > 01334 struct enable_if_ptr_convertible 01335 : public enable_if< is_ptr_convertible<From,To>::value, R > { }; 01336 01337 01338 // ---------------------------------------------------------------------- 01339 // enable_if_auto_ptr - convenience metaprogramming type trait 01340 // ---------------------------------------------------------------------- 01341 01342 template< typename P // pointee type 01343 , typename R // result type 01344 > 01345 struct enable_if_auto_ptr { }; 01346 01347 template< typename P, typename R > 01348 struct enable_if_auto_ptr< std::auto_ptr<P>, R > 01349 { 01350 typedef R type; 01351 }; 01352 01353 01354 // ---------------------------------------------------------------------- 01355 01356 } // namespace CLHEP 01357 01358 01359 #endif // CLHEP_TYPE_TRAITS_H 01360 01361 // ======================================================================