CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

type_traits.h

Go to the documentation of this file.
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 // ======================================================================

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7