Geant4_10
type_traits.h
Go to the documentation of this file.
1 #ifndef CLHEP_TYPE_TRAITS_H
2 #define CLHEP_TYPE_TRAITS_H
3 
4 // ======================================================================
5 //
6 // type_traits - selected C++0X metaprogramming constructs
7 //
8 // Author: W. E. Brown; 2010-03-05
9 //
10 // ======================================================================
11 
12 
13 #include "CLHEP/Utility/defs.h"
14 
15 #include <memory> // for auto_ptr
16 
17 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
18 # define CLHEP_HAS_RVALUE_REFERENCE
19 #else
20 # define CLHEP_NO_RVALUE_REFERENCE
21 #endif
22 
23 
24 namespace CLHEP {
25 
26 // ----------------------------------------------------------------------
27 // Contents:
28 // ----------------------------------------------------------------------
29 
30 // helper class:
31 template< typename T, T v > struct integral_constant;
34 
35 // primary type categories:
36 template< typename T > struct is_void;
37 template< typename T > struct is_integral;
38 template< typename T > struct is_floating_point;
39 template< typename T > struct is_array;
40 template< typename T > struct is_pointer;
41 template< typename T > struct is_lvalue_reference;
42 template< typename T > struct is_rvalue_reference;
43 template< typename T > struct is_member_object_pointer;
44 template< typename T > struct is_member_function_pointer;
45 template< typename T > struct is_enum;
46 template< typename T > struct is_union;
47 template< typename T > struct is_class;
48 template< typename T > struct is_function;
49 
50 // composite type categories:
51 template< typename T > struct is_reference;
52 template< typename T > struct is_arithmetic;
53 template< typename T > struct is_fundamental;
54 template< typename T > struct is_object;
55 template< typename T > struct is_scalar;
56 template< typename T > struct is_compound;
57 template< typename T > struct is_member_pointer;
58 
59 // type properties:
60 template< typename T > struct is_const;
61 template< typename T > struct is_volatile;
62 #if 0
63 template< typename T > struct is_trivial;
64 template< typename T > struct is_trivially_copyable;
65 template< typename T > struct is_standard_layout;
66 template< typename T > struct is_pod;
67 template< typename T > struct is_literal_type;
68 template< typename T > struct is_empty;
69 template< typename T > struct is_polymorphic;
70 #endif // 0
71 template< typename T > struct is_abstract;
72 #if 0
73 template< typename T, typename... Args > struct is_constructible;
74 template< typename T, typename... Args > struct is_nothrow_constructible;
75 template< typename T > struct has_default_constructor;
76 template< typename T > struct has_copy_constructor;
77 template< typename T > struct has_copy_assign;
78 template< typename T > struct has_move_constructor;
79 template< typename T > struct has_move_assign;
80 template< typename T > struct has_trivial_default_constructor;
81 template< typename T > struct has_trivial_copy_constructor;
82 template< typename T > struct has_trivial_move_constructor;
83 template< typename T > struct has_trivial_copy_assign;
84 template< typename T > struct has_trivial_move_assign;
85 template< typename T > struct has_trivial_destructor;
86 template< typename T > struct has_nothrow_default_constructor;
87 template< typename T > struct has_nothrow_copy_constructor;
88 template< typename T > struct has_nothrow_move_constructor;
89 template< typename T > struct has_nothrow_copy_assign;
90 template< typename T > struct has_nothrow_move_assign;
91 template< typename T > struct has_virtual_destructor;
92 #endif // 0
93 template< typename T > struct is_signed;
94 template< typename T > struct is_unsigned;
95 #if 0
96 template< typename T > struct alignment_of;
97 #endif // 0
98 template< typename T > struct rank;
99 template< typename T, unsigned I = 0 > struct extent;
100 
101 // type relations:
102 template< typename T, typename U > struct is_same;
103 #if 0
104 template< typename Base, typename Derived > struct is_base_of;
105 #endif // 0
106 template< typename From, typename To > struct is_convertible;
107 #if 0
108 template< typename From, typename To > struct is_explicitly_convertible;
109 #endif // 0
110 
111 // const-volatile modifications:
112 template< typename T > struct remove_const;
113 template< typename T > struct remove_volatile;
114 template< typename T > struct remove_cv;
115 template< typename T > struct add_const;
116 template< typename T > struct add_volatile;
117 template< typename T > struct add_cv;
118 
119 // reference modifications:
120 template< typename T > struct remove_reference;
121 template< typename T > struct add_lvalue_reference;
122 template< typename T > struct add_rvalue_reference;
123 
124 // sign modifications:
125 #if 0
126 template< typename T > struct make_signed;
127 template< typename T > struct make_unsigned;
128 #endif // 0
129 
130 // array modifications:
131 template< typename T > struct remove_extent;
132 template< typename T > struct remove_all_extents;
133 
134 // pointer modifications:
135 template< typename T > struct remove_pointer;
136 template< typename T > struct add_pointer;
137 
138 // other transformations:
139 #if 0
140 template< std::size_t Len, std::size_t Align > struct aligned_storage;
141 template< std::size_t Len, typename... Types > struct aligned_union;
142 template< typename T > struct decay;
143 #endif // 0
144 template< bool, typename T = void > struct enable_if;
145 template< bool, typename T, typename F > struct conditional;
146 #if 0
147 template< typename... T > struct common_type;
148 template< typename T > struct underlying_type;
149 template< typename > typename result_of; // undefined
150 template< typename F, typename... ArgTypes > typename result_of<F(ArgTypes...)>;
151 #endif // 0
152 
153 // non-standard (but useful) extensions:
154 template< typename From, typename To > struct is_ptr_convertible;
155 template< typename From, typename To, typename R=void > struct enable_if_convertible;
156 template< typename From, typename To, typename R=void > struct enable_if_ptr_convertible;
157 template< typename P, typename R=void > struct enable_if_auto_ptr;
158 
159 
160 // ----------------------------------------------------------------------
161 // integral_constant - a helper class, useful in its own right
162 // ----------------------------------------------------------------------
163 
164 template< typename T, T v >
165  struct integral_constant
166 {
167  typedef T value_type;
169 
170  static value_type const value = v;
171 
172  operator value_type() { return value; }
173 }; // integral_constant<,>
174 
175 
176 // ----------------------------------------------------------------------
177 // yes_t, no_t - unimplemented types with distinct sizeof
178 // ----------------------------------------------------------------------
179 
180 namespace tt {
181 
182 typedef char (& yes_t); // ref to char
183 typedef char (& no_t ) [2]; // ref to 2-char array
184 
185 } // namespace tt
186 
187 
188 // ----------------------------------------------------------------------
189 // primary<,> - type classification helper
190 // ----------------------------------------------------------------------
191 
192 namespace tt {
193 
195 { _unknown = 0u
196 , _void = 1u << 0
197 , _integral = 1u << 1
198 , _floating_point = 1u << 2
199 , _array = 1u << 3
200 , _pointer = 1u << 4
201 , _lvalue_reference = 1u << 5
202 , _rvalue_reference = 1u << 6
205 , _enum = 1u << 9
206 , _union = 1u << 10 // Help, compiler!
207 , _class = 1u << 11
208 , _function = 1u << 12
209 }; // primary_code
210 
211 // Helpers to recognize classes:
212 template< typename U > yes_t isAclass( void(U::*)() );
213 template< typename U > no_t isAclass( ... );
214 
215 // Helpers to recognize functions:
216 template< typename U >
217  no_t isAfunction( U(*)[1] ); // arrays of non-{fctn/ref/void}s
218 template< typename U >
219  yes_t isAfunction( ... );
220 
221 // encode via helpers or by elimination:
222 // enum
223 // union // need help, compiler!
224 // class
225 // function
226 template< typename T >
227 struct encode
228 {
229  static primary_code const value
230  = ( sizeof(isAclass <T>(0)) == sizeof(yes_t) ) ? _class
231  : ( ( sizeof(isAfunction<T>(0)) == sizeof(yes_t) ) ? _function
232  : /* by elimination */ _enum
233  );
234 }; // encode<>
235 
236 // encode cv-qualified type:
237 template< typename T >
238  struct encode<T const> : public encode<T> { };
239 template< typename T >
240  struct encode<T volatile> : public encode<T> { };
241 template< typename T >
242  struct encode<T const volatile> : public encode<T> { };
243 
244 // encode array:
245 template< typename T >
246  struct encode<T[]>
247 { static primary_code const value = _array; };
248 template< typename T >
249  struct encode<T const[]>
250 { static primary_code const value = _array; };
251 template< typename T >
252  struct encode<T volatile[]>
253 { static primary_code const value = _array; };
254 template< typename T >
255  struct encode<T const volatile[]>
256 { static primary_code const value = _array; };
257 template< typename T, unsigned N >
258  struct encode<T[N]>
259 { static primary_code const value = _array; };
260 template< typename T, unsigned N >
261  struct encode<T const[N]>
262 { static primary_code const value = _array; };
263 template< typename T, unsigned N >
264  struct encode<T volatile[N]>
265 { static primary_code const value = _array; };
266 template< typename T, unsigned N >
267  struct encode<T const volatile[N]>
268 { static primary_code const value = _array; };
269 
270 // encode floating_point:
271 template<>
272  struct encode<float>
273 { static primary_code const value = _floating_point; };
274 template<>
275  struct encode<double>
276 { static primary_code const value = _floating_point; };
277 template<>
278  struct encode<long double>
279 { static primary_code const value = _floating_point; };
280 
281 // encode integral:
282 template<>
283  struct encode<bool>
284 { static primary_code const value = _integral; };
285 template<>
286  struct encode<signed char>
287 { static primary_code const value = _integral; };
288 template<>
289  struct encode<char>
290 { static primary_code const value = _integral; };
291 template<>
292  struct encode<unsigned char>
293 { static primary_code const value = _integral; };
294 #if 0
295 template<>
296  struct encode<wchar_t>
297 { static primary_code const value = _integral; };
298 #endif
299 template<>
300  struct encode<short>
301 { static primary_code const value = _integral; };
302 template<>
303  struct encode<unsigned short>
304 { static primary_code const value = _integral; };
305 template<>
306  struct encode<int>
307 { static primary_code const value = _integral; };
308 template<>
309  struct encode<unsigned int>
310 { static primary_code const value = _integral; };
311 template<>
312  struct encode<long>
313 { static primary_code const value = _integral; };
314 template<>
315  struct encode<unsigned long>
316 { static primary_code const value = _integral; };
317 
318 // encode member_function_pointer:
319 template< typename T, typename C >
320  struct encode<T (C::*)()>
322 template< typename T, typename C >
323  struct encode<T (C::*)() const>
325 template< typename T, typename C >
326  struct encode<T (C::*)() volatile>
328 template< typename T, typename C >
329  struct encode<T (C::*)() const volatile>
331 template< typename T, typename C
332  , typename A1 >
333  struct encode<T (C::*)(A1)>
335 template< typename T, typename C
336  , typename A1 >
337  struct encode<T (C::*)(A1) const>
339 template< typename T, typename C
340  , typename A1 >
341  struct encode<T (C::*)(A1) volatile>
343 template< typename T, typename C
344  , typename A1 >
345  struct encode<T (C::*)(A1) const volatile>
347 template< typename T, typename C
348  , typename A1, typename A2 >
349  struct encode<T (C::*)(A1,A2)>
351 template< typename T, typename C
352  , typename A1, typename A2 >
353  struct encode<T (C::*)(A1,A2) const>
355 template< typename T, typename C
356  , typename A1, typename A2 >
357  struct encode<T (C::*)(A1,A2) volatile>
359 template< typename T, typename C
360  , typename A1, typename A2 >
361  struct encode<T (C::*)(A1,A2) const volatile>
363 template< typename T, typename C
364  , typename A1, typename A2, typename A3 >
365  struct encode<T (C::*)(A1,A2,A3)>
367 template< typename T, typename C
368  , typename A1, typename A2, typename A3 >
369  struct encode<T (C::*)(A1,A2,A3) const>
371 template< typename T, typename C
372  , typename A1, typename A2, typename A3 >
373  struct encode<T (C::*)(A1,A2,A3) volatile>
375 template< typename T, typename C
376  , typename A1, typename A2, typename A3 >
377  struct encode<T (C::*)(A1,A2,A3) const volatile>
379 template< typename T, typename C
380  , typename A1, typename A2, typename A3, typename A4 >
381  struct encode<T (C::*)(A1,A2,A3,A4)>
383 template< typename T, typename C
384  , typename A1, typename A2, typename A3, typename A4 >
385  struct encode<T (C::*)(A1,A2,A3,A4) const>
387 template< typename T, typename C
388  , typename A1, typename A2, typename A3, typename A4 >
389  struct encode<T (C::*)(A1,A2,A3,A4) volatile>
391 template< typename T, typename C
392  , typename A1, typename A2, typename A3, typename A4 >
393  struct encode<T (C::*)(A1,A2,A3,A4) const volatile>
395 template< typename T, typename C
396  , typename A1, typename A2, typename A3, typename A4, typename A5 >
397  struct encode<T (C::*)(A1,A2,A3,A4,A5)>
399 template< typename T, typename C
400  , typename A1, typename A2, typename A3, typename A4, typename A5 >
401  struct encode<T (C::*)(A1,A2,A3,A4,A5) const>
403 template< typename T, typename C
404  , typename A1, typename A2, typename A3, typename A4, typename A5 >
405  struct encode<T (C::*)(A1,A2,A3,A4,A5) volatile>
407 template< typename T, typename C
408  , typename A1, typename A2, typename A3, typename A4, typename A5 >
409  struct encode<T (C::*)(A1,A2,A3,A4,A5) const volatile>
411 
412 // encode member_object_pointer:
413 template< typename T, typename C >
414  struct encode<T C::*>
416 
417 // encode pointer:
418 template< typename T >
419  struct encode<T *>
420 { static primary_code const value = _pointer; };
421 
422 // encode lvalue_reference:
423 template< typename T >
424  struct encode<T &>
426 
427 // encode rvalue_reference:
428 #if defined(CLHEP_HAS_RVALUE_REFERENCE)
429 template< typename T >
430  struct encode<T&&>
431 { static primary_code const value = _rvalue_reference; };
432 #endif // CLHEP_HAS_RVALUE_REFERENCE
433 
434 // encode void:
435 template<>
436  struct encode<void>
437 { static primary_code const value = _void; };
438 
439 // apply encoding:
440 template< typename T, unsigned int p >
441  struct primary : integral_constant<bool, bool(p & encode<T>::value)> { };
442 
443 } // namespace tt
444 
445 
446 // ----------------------------------------------------------------------
447 // is_void - metaprogramming type trait detecting void types
448 // ----------------------------------------------------------------------
449 
450 template< typename T >
451  struct is_void
452  : public tt::primary<T, tt::_void > { };
453 
454 
455 // ----------------------------------------------------------------------
456 // is_integral - metaprogramming type trait detecting integer types
457 // ----------------------------------------------------------------------
458 
459 template< typename T >
460  struct is_integral
461  : public tt::primary<T, tt::_integral > { };
462 
463 
464 // ----------------------------------------------------------------------
465 // is_floating_point - metaprogramming type trait detecting real types
466 // ----------------------------------------------------------------------
467 
468 template< typename T >
469  struct is_floating_point
470  : public tt::primary<T, tt::_floating_point > { };
471 
472 // ----------------------------------------------------------------------
473 // is_array - metaprogramming type trait detecting T[...] types
474 // ----------------------------------------------------------------------
475 
476 template< typename T >
477  struct is_array
478  : public tt::primary<T, tt::_array > { };
479 
480 
481 // ----------------------------------------------------------------------
482 // is_pointer - metaprogramming type trait detecting T* types
483 // ----------------------------------------------------------------------
484 
485 template< typename T >
486  struct is_pointer
487  : public tt::primary<T, tt::_pointer > { };
488 
489 
490 // ----------------------------------------------------------------------
491 // is_lvalue_reference - metaprogramming type trait detecting T& types
492 // ----------------------------------------------------------------------
493 
494 template< typename T >
495  struct is_lvalue_reference
496  : public tt::primary<T, tt::_lvalue_reference > { };
497 
498 
499 // ----------------------------------------------------------------------
500 // is_rvalue_reference - metaprogramming type trait detecting T&& types
501 // ----------------------------------------------------------------------
502 
503 template< typename T > struct is_rvalue_reference
504  : public tt::primary<T, tt::_rvalue_reference > { };
505 
506 
507 // ----------------------------------------------------------------------
508 // is_member_object_pointer - metaprogramming type trait
509 // ----------------------------------------------------------------------
510 
511 template< typename T > struct is_member_object_pointer
512  : public conditional< is_member_function_pointer<T>::value
513  , false_type
514  , tt::primary<T, tt::_member_object_pointer>
515  >::type
516 { };
517 
518 
519 // ----------------------------------------------------------------------
520 // is_member_function_pointer - metaprogramming type trait
521 // ----------------------------------------------------------------------
522 
523 template< typename T >
524  struct is_member_function_pointer
525  : public tt::primary<T, tt::_member_function_pointer > { };
526 
527 
528 // ----------------------------------------------------------------------
529 // is_enum - metaprogramming type trait detecting enumeration types
530 // ----------------------------------------------------------------------
531 
532 template< typename T >
533  struct is_enum
534  : public tt::primary<T, tt::_enum > { };
535 
536 
537 // ----------------------------------------------------------------------
538 // is_union - metaprogramming type trait detecting union types
539 // ----------------------------------------------------------------------
540 
541 template< typename T >
542  struct is_union
543  : public tt::primary<T, tt::_union > { };
544 
545 
546 // ----------------------------------------------------------------------
547 // is_class - metaprogramming type trait detecting class types
548 // ----------------------------------------------------------------------
549 
550 template< typename T >
551  struct is_class
552  : public tt::primary<T, tt::_class > { };
553 
554 
555 // ----------------------------------------------------------------------
556 // is_function - metaprogramming type trait detecting function types
557 // ----------------------------------------------------------------------
558 
559 template< typename T >
560  struct is_function
561  : public tt::primary<T, tt::_function > { };
562 
563 
564 // ----------------------------------------------------------------------
565 // is_reference - metaprogramming composite type trait
566 // ----------------------------------------------------------------------
567 
568 template< typename T >
569  struct is_reference
570  : public tt::primary< T, tt::_lvalue_reference
571  | tt::_rvalue_reference
572  >
573 { };
574 
575 
576 // ----------------------------------------------------------------------
577 // is_arithmetic - metaprogramming composite type trait
578 // ----------------------------------------------------------------------
579 
580 template< typename T >
581  struct is_arithmetic
582  : public tt::primary< T, tt::_integral
583  | tt::_floating_point
584  >
585 { };
586 
587 
588 // ----------------------------------------------------------------------
589 // is_fundamental - metaprogramming composite type trait
590 // ----------------------------------------------------------------------
591 
592 template< typename T >
593  struct is_fundamental
594  : public tt::primary< T, tt::_integral
595  | tt::_floating_point
596  | tt::_void
597  >
598 { };
599 
600 
601 // ----------------------------------------------------------------------
602 // is_object - metaprogramming composite type trait
603 // ----------------------------------------------------------------------
604 
605 template< typename T >
606  struct is_object
607  : public tt::primary< T, tt::_array
608  | tt::_class
609  | tt::_enum
610  | tt::_floating_point
611  | tt::_integral
612  | tt::_member_object_pointer
613  | tt::_member_function_pointer
614  | tt::_pointer
615  | tt::_union
616  >
617 { };
618 
619 
620 // ----------------------------------------------------------------------
621 // is_scalar - metaprogramming composite type trait
622 // ----------------------------------------------------------------------
623 
624 template< typename T >
625  struct is_scalar
626  : public tt::primary< T, tt::_integral
627  | tt::_floating_point
628  | tt::_enum
629  | tt::_pointer
630  | tt::_member_object_pointer
631  | tt::_member_function_pointer
632  >
633 { };
634 
635 
636 // ----------------------------------------------------------------------
637 // is_compound - metaprogramming composite type trait
638 // ----------------------------------------------------------------------
639 
640 template< typename T >
641  struct is_compound
642  : public tt::primary< T, tt::_array
643  | tt::_pointer
644  | tt::_lvalue_reference
645  | tt::_rvalue_reference
646  | tt::_member_object_pointer
647  | tt::_member_function_pointer
648  | tt::_enum
649  | tt::_union
650  | tt::_class
651  | tt::_function
652  >
653 { };
654 
655 
656 // ----------------------------------------------------------------------
657 // is_member_pointer - metaprogramming composite type trait
658 // ----------------------------------------------------------------------
659 
660 template< typename T >
661  struct is_member_pointer
662  : public tt::primary< T, tt::_member_object_pointer
663  | tt::_member_function_pointer
664  >
665 { };
666 
667 
668 // ----------------------------------------------------------------------
669 // cv<> - helper analyzing a type's cv-qualification(s)
670 // ----------------------------------------------------------------------
671 
672 namespace tt {
673 
674 template< typename T >
675  struct cv
676 {
677  static bool const is_c = false;
678  static bool const is_v = false;
679  typedef T const add_c_type;
680  typedef T volatile add_v_type;
681  typedef T const volatile add_cv_type;
682  typedef T rem_c_type;
683  typedef T rem_v_type;
684  typedef T rem_cv_type;
685 };
686 
687 template< typename T >
688  struct cv<T const>
689 {
690  static bool const is_c = true;
691  static bool const is_v = false;
692  typedef T const add_c_type;
693  typedef T const volatile add_v_type;
694  typedef T const volatile add_cv_type;
695  typedef T rem_c_type;
696  typedef T const rem_v_type;
697  typedef T rem_cv_type;
698 };
699 
700 template< typename T >
701  struct cv<T volatile>
702 {
703  static bool const is_c = false;
704  static bool const is_v = true;
705  typedef T const volatile add_c_type;
706  typedef T volatile add_v_type;
707  typedef T const volatile add_cv_type;
708  typedef T volatile rem_c_type;
709  typedef T rem_v_type;
710  typedef T rem_cv_type;
711 };
712 
713 template< typename T >
714  struct cv<T const volatile>
715 {
716  static bool const is_c = true;
717  static bool const is_v = true;
718  typedef T const volatile add_c_type;
719  typedef T const volatile add_v_type;
720  typedef T const volatile add_cv_type;
721  typedef T volatile rem_c_type;
722  typedef T const rem_v_type;
723  typedef T rem_cv_type;
724 };
725 
726 template< typename T >
727  struct cv<T &>
728 {
729  static bool const is_c = false;
730  static bool const is_v = false;
731  typedef T & add_c_type;
732  typedef T & add_v_type;
733  typedef T & add_cv_type;
734  typedef T & rem_c_type;
735  typedef T & rem_v_type;
736  typedef T & rem_cv_type;
737 };
738 
739 } // namespace tt
740 
741 
742 // ----------------------------------------------------------------------
743 // is_const - metaprogramming type trait detecting type constness
744 // ----------------------------------------------------------------------
745 
746 template< typename T >
747  struct is_const
748  : public integral_constant<bool, tt::cv<T>::is_c > { };
749 
750 
751 // ----------------------------------------------------------------------
752 // is_volatile - metaprogramming type trait detecting type volatility
753 // ----------------------------------------------------------------------
754 
755 template< typename T >
756  struct is_volatile
757  : public integral_constant<bool, tt::cv<T>::is_v > { };
758 
759 
760 // ----------------------------------------------------------------------
761 // is_abstract_class - helper detecting when a class is abstract
762 // ----------------------------------------------------------------------
763 
764 namespace tt {
765 
766 template< typename, bool >
768  : public false_type { }; // default: not a class, hence not abstract
769 
770 template< typename C >
771  struct is_abstract_class<C,true> // C is known to be a class type
772 {
773 protected:
774  template< typename T >
775  static no_t take( T (*)[1] ); // can't form array of abstract T
776  template< typename T >
777  static yes_t take( ... );
778 
779 public:
780  static bool const value = sizeof( take<C>(0) ) == sizeof(yes_t);
781 }; // is_abstract_class<,true>
782 
783 } // namespace tt
784 
785 
786 // ----------------------------------------------------------------------
787 // is_abstract - metaprogramming type trait detecting abstract classes
788 // ----------------------------------------------------------------------
789 
790 template< typename T >
791  struct is_abstract
792  : public tt::is_abstract_class< T
793  , is_class<T>::value
794  >
795  { };
796 
797 
798 // ----------------------------------------------------------------------
799 // is_signed - metaprogramming type trait detecting type signedness
800 // ----------------------------------------------------------------------
801 
802 template< typename >
803  struct is_signed
804  : public false_type { };
805 
806 template<>
807  struct is_signed<signed char>
808  : public true_type { };
809 template<>
810  struct is_signed<short>
811  : public true_type { };
812 template<>
813  struct is_signed<int>
814  : public true_type { };
815 template<>
816  struct is_signed<long>
817  : public true_type { };
818 
819 template< typename T >
820  struct is_signed<T const>
821  : public is_signed<T> { };
822 template< typename T >
823  struct is_signed<T volatile>
824  : public is_signed<T> { };
825 template< typename T >
826  struct is_signed<T const volatile>
827  : public is_signed<T> { };
828 
829 
830 // ----------------------------------------------------------------------
831 // is_unsigned - metaprogramming type trait detecting type unsignedness
832 // ----------------------------------------------------------------------
833 
834 template< typename >
835  struct is_unsigned
836  : public false_type { };
837 
838 template<>
839  struct is_unsigned<unsigned char>
840  : public true_type { };
841 template<>
842  struct is_unsigned<unsigned short>
843  : public true_type { };
844 template<>
845  struct is_unsigned<unsigned int>
846  : public true_type { };
847 template<>
848  struct is_unsigned<unsigned long>
849  : public true_type { };
850 
851 template< typename T >
852  struct is_unsigned<T const>
853  : public is_unsigned<T> { };
854 template< typename T >
855  struct is_unsigned<T volatile>
856  : public is_unsigned<T> { };
857 template< typename T >
858  struct is_unsigned<T const volatile>
859  : public is_unsigned<T> { };
860 
861 
862 // ----------------------------------------------------------------------
863 // arr<> - helper analyzing a type's array qualification(s)
864 // ----------------------------------------------------------------------
865 
866 namespace tt {
867 
868 template< typename T >
869  struct arr // non-array
870 {
871  typedef T rem_ext_type;
872  typedef T rem_arr_type;
873 
874  static int const rank = 0;
875 
876  template< unsigned I >
877  struct extent { static int const value = 0; };
878 };
879 
880 template< typename T, unsigned N >
881  struct arr<T[N]>
882 {
883  typedef T rem_ext_type;
885 
886  static int const rank = 1 + tt::arr<T>::rank;
887 
888  template< unsigned I >
889  struct extent
890  {
891  static int const value = (I == rank)
892  ? N
894  };
895 };
896 
897 template< typename T >
898  struct arr<T[]>
899 {
900  typedef T rem_ext_type;
901  typedef T rem_arr_type;
902 
903  static int const rank = 1;
904 
905  template< unsigned I >
906  struct extent { static int const value = 0; };
907 };
908 
909 } // namespace tt
910 
911 
912 // ----------------------------------------------------------------------
913 // rank - metaprogramming type trait detecting array's rank
914 // ----------------------------------------------------------------------
915 
916 template< typename T >
917  struct rank
918  : public integral_constant<int, tt::arr<T>::rank> { };
919 
920 
921 // ----------------------------------------------------------------------
922 // extent - metaprogramming type trait detecting array's extent
923 // ----------------------------------------------------------------------
924 
925 template< typename T, unsigned I >
926  struct extent
927  : public integral_constant<int, tt::arr<T>::template extent<I>::value> { };
928 
929 
930 // ----------------------------------------------------------------------
931 // is_same - metaprogramming type trait detecting type identity
932 // ----------------------------------------------------------------------
933 
934 template< typename T, typename U >
935  struct is_same : public false_type { };
936 template< typename T >
937  struct is_same<T,T> : public true_type { };
938 
939 
940 // ----------------------------------------------------------------------
941 // any_conversion - helper to avoid passing a UDT through ... parameter
942 // ----------------------------------------------------------------------
943 
944 namespace tt {
945 
947 {
948  template< typename T >
949  any_conversion( T const volatile & );
950  template< typename T >
951  any_conversion( T & ); // no cv-qual on fctn-refs
952 }; // any_conversion
953 
954 } // namespace tt
955 
956 
957 // ----------------------------------------------------------------------
958 // converts_to - helper detecting convertability
959 // ----------------------------------------------------------------------
960 
961 namespace tt {
962 
963 template< typename From, typename To, bool >
964  struct converts
965  : public false_type { }; // default: can't convert to abstract To
966 
967 template< typename From, typename To >
968 struct converts<From,To,false> // To is non-abstract
969 {
970 protected:
971  static yes_t take( To, int );
972  static no_t take( any_conversion, ... );
973  static From from;
974 
975 public:
976  static bool const value
977  = sizeof( take( from, 0 ) ) == sizeof(yes_t);
978 }; // converts<>
979 
980 } // namespace tt
981 
982 
983 // ----------------------------------------------------------------------
984 // is_convertible - metaprogramming type trait detecting convertability
985 // ----------------------------------------------------------------------
986 
987 template< typename From, typename To >
988  struct is_convertible
989  : public tt::converts<From,To,is_abstract<To>::value> { };
990 
991 template< > struct is_convertible<void,void>
992  : public true_type { };
993 
994 template< typename T >
996  : public true_type { };
997 
998 template< typename T >
1000  : public false_type { };
1001 
1002 template< >
1004  : public true_type { };
1005 
1006 template< typename T >
1008  : public true_type { };
1009 
1010 template< typename T >
1012  : public false_type { };
1013 
1014 template< >
1015  struct is_convertible<volatile void,volatile void>
1016  : public true_type { };
1017 
1018 template< typename T >
1019  struct is_convertible<T,volatile void>
1020  : public true_type { };
1021 
1022 template< typename T >
1023  struct is_convertible<volatile void,T>
1024  : public false_type { };
1025 
1026 template< >
1027  struct is_convertible<const volatile void,const volatile void>
1028  : public true_type { };
1029 
1030 template< typename T >
1031  struct is_convertible<T,const volatile void>
1032  : public true_type { };
1033 
1034 template< typename T >
1035  struct is_convertible<const volatile void,T>
1036  : public false_type { };
1037 
1038 template< typename From, int N, typename To >
1039  struct is_convertible<From[N],To>
1040  : public is_convertible<From*,To> { };
1041 
1042 template< typename From, typename To, int N >
1043  struct is_convertible<From,To[N]>
1044  : public false_type { };
1045 
1046 
1047 // ----------------------------------------------------------------------
1048 // remove_const - metaprogramming type trait ensuring non-constness
1049 // ----------------------------------------------------------------------
1050 
1051 template< typename T >
1052  struct remove_const
1053 {
1054  typedef typename tt::cv<T>::rem_c_type type;
1055 };
1056 
1057 
1058 // ----------------------------------------------------------------------
1059 // remove_volatile - metaprogramming type trait ensuring non-volatility
1060 // ----------------------------------------------------------------------
1061 
1062 template< typename T >
1063  struct remove_volatile
1064 {
1065  typedef typename tt::cv<T>::rem_v_type type;
1066 };
1067 
1068 
1069 // ----------------------------------------------------------------------
1070 // remove_cv - metaprogramming type trait ensuring no cv-qualification
1071 // ----------------------------------------------------------------------
1072 
1073 template< typename T >
1074  struct remove_cv
1075 {
1076  typedef typename tt::cv<T>::rem_cv_type type;
1077 };
1078 
1079 
1080 // ----------------------------------------------------------------------
1081 // add_const - metaprogramming type trait ensuring constness
1082 // ----------------------------------------------------------------------
1083 
1084 template< typename T >
1085  struct add_const
1086 {
1087  typedef typename tt::cv<T>::add_c_type type;
1088 };
1089 
1090 
1091 // ----------------------------------------------------------------------
1092 // add_volatile - metaprogramming type trait ensuring volatility
1093 // ----------------------------------------------------------------------
1094 
1095 template< typename T >
1096  struct add_volatile
1097 {
1098  typedef typename tt::cv<T>::add_v_type type;
1099 };
1100 
1101 
1102 // ----------------------------------------------------------------------
1103 // add_cv - metaprogramming type trait ensuring constness & volatility
1104 // ----------------------------------------------------------------------
1105 
1106 template< typename T >
1107  struct add_cv
1108 {
1109  typedef typename tt::cv<T>::add_cv_type type;
1110 };
1111 
1112 
1113 // ----------------------------------------------------------------------
1114 // ref<> - helper analyzing a type's reference qualification
1115 // ----------------------------------------------------------------------
1116 
1117 namespace tt {
1118 
1119 template< typename T
1121  >
1122  struct ref // non-lref && non-rref && non-void
1123 {
1124  typedef T& add_lref_type;
1125  #if defined(CLHEP_HAS_RVALUE_REFERENCE)
1126  typedef T&& add_rref_type;
1127  #endif // CLHEP_HAS_RVALUE_REFERENCE
1128  typedef T rem_ref_type;
1129 };
1130 
1131 template< typename T >
1133 {
1134  typedef T& add_lref_type;
1135  typedef T& add_rref_type;
1136  typedef T rem_ref_type;
1137 };
1138 
1139 #if defined(CLHEP_HAS_RVALUE_REFERENCE)
1140 template< typename T >
1141  struct ref<T&&,_rvalue_reference>
1142 {
1143  typedef T& add_lref_type;
1144  typedef T&& add_rref_type;
1145  typedef T rem_ref_type;
1146 };
1147 #endif // CLHEP_HAS_RVALUE_REFERENCE
1148 
1149 template< typename T >
1150  struct ref<T,_void>
1151 {
1152  typedef T add_lref_type;
1153  typedef T add_rref_type;
1154  typedef T rem_ref_type;
1155 };
1156 
1157 } // namespace tt
1158 
1159 
1160 // ----------------------------------------------------------------------
1161 // remove_reference - metaprogramming type trait ensuring non-reference
1162 // ----------------------------------------------------------------------
1163 
1164 template< typename T >
1165  struct remove_reference
1166 {
1167  typedef typename tt::ref<T>::rem_ref_type type;
1168 };
1169 
1170 
1171 // ----------------------------------------------------------------------
1172 // add_lvalue_reference - metaprogramming type trait ensuring lvalue-ref
1173 // ----------------------------------------------------------------------
1174 
1175 template< typename T >
1176  struct add_lvalue_reference
1177 {
1179 };
1180 
1181 
1182 // ----------------------------------------------------------------------
1183 // add_rvalue_reference - metaprogramming type trait ensuring rvalue-ref
1184 // ----------------------------------------------------------------------
1185 
1186 template< typename T >
1187  struct add_rvalue_reference
1188 {
1190 };
1191 
1192 
1193 // ----------------------------------------------------------------------
1194 // ptr<> - helper analyzing a type's pointer qualification
1195 // ----------------------------------------------------------------------
1196 
1197 namespace tt {
1198 
1199 template< typename T >
1200  struct ptr
1201 {
1203  typedef T rem_ptr_type;
1204 };
1205 
1206 template< typename T >
1207  struct ptr<T *>
1208 {
1209  typedef T * * add_ptr_type;
1210  typedef T rem_ptr_type;
1211 };
1212 
1213 template< typename T >
1214  struct ptr<T * const>
1215 {
1216  typedef T * const * add_ptr_type;
1217  typedef T rem_ptr_type;
1218 };
1219 
1220 template< typename T >
1221  struct ptr<T * volatile>
1222 {
1223  typedef T * volatile * add_ptr_type;
1224  typedef T rem_ptr_type;
1225 };
1226 
1227 template< typename T >
1228  struct ptr<T * const volatile>
1229 {
1230  typedef T * const volatile * add_ptr_type;
1231  typedef T rem_ptr_type;
1232 };
1233 
1234 } // namespace tt
1235 
1236 
1237 // ----------------------------------------------------------------------
1238 // remove_extent - metaprogramming type trait reducing an array's extent
1239 // ----------------------------------------------------------------------
1240 
1241 template< typename T >
1242  struct remove_extent
1243 {
1244  typedef typename tt::arr<T>::rem_ext_type type;
1245 };
1246 
1247 
1248 // ----------------------------------------------------------------------
1249 // remove_all_extents - metaprogramming type trait yielding a non-array
1250 // ----------------------------------------------------------------------
1251 
1252 template< typename T >
1253  struct remove_all_extents
1254 {
1255  typedef typename tt::arr<T>::rem_arr_type type;
1256 };
1257 
1258 
1259 // ----------------------------------------------------------------------
1260 // remove_pointer - metaprogramming type trait ensuring non-pointer
1261 // ----------------------------------------------------------------------
1262 
1263 template< typename T >
1264  struct remove_pointer
1265 {
1266  typedef typename tt::ptr<T>::rem_ptr_type type;
1267 };
1268 
1269 
1270 // ----------------------------------------------------------------------
1271 // add_pointer - metaprogramming type trait ensuring pointer
1272 // ----------------------------------------------------------------------
1273 
1274 template< typename T >
1275  struct add_pointer
1276 {
1277  typedef typename tt::ptr<T>::add_ptr_type type;
1278 };
1279 
1280 
1281 // ----------------------------------------------------------------------
1282 // enable_if - metaprogramming construct for applied SFINAE
1283 // ----------------------------------------------------------------------
1284 
1285 template< typename T > struct enable_if<true ,T> { typedef T type; };
1286 template< typename T > struct enable_if<false,T> { };
1287 
1288 
1289 // ----------------------------------------------------------------------
1290 // conditional - metaprogramming construct for type selection
1291 // ----------------------------------------------------------------------
1292 
1293 template< typename T, typename F > struct conditional<true ,T,F> { typedef T type; };
1294 template< typename T, typename F > struct conditional<false,T,F> { typedef F type; };
1295 
1296 
1297 // ----------------------------------------------------------------------
1298 // is_ptr_convertible - variant of is_convertible, based on ptrs to types
1299 // ----------------------------------------------------------------------
1300 
1301 template< typename From, typename To >
1302  struct is_ptr_convertible
1303 {
1304 protected:
1305  static tt::yes_t take( To * );
1306  static tt::no_t take( ... );
1307 
1308 public:
1309  static bool const value
1310  = sizeof( take( static_cast<From*>(0) ) ) == sizeof(tt::yes_t);
1311 }; // is_ptr_convertible<,>
1312 
1313 
1314 // ----------------------------------------------------------------------
1315 // enable_if_convertible - convenience metaprogramming type trait
1316 // ----------------------------------------------------------------------
1317 
1318 template< typename From // type of conversion's source
1319  , typename To // type of conversion's target
1320  , typename R // result type if conversion is valid
1321  >
1322  struct enable_if_convertible
1323  : public enable_if< is_convertible<From,To>::value, R > { };
1324 
1325 
1326 // ----------------------------------------------------------------------
1327 // enable_if_ptr_convertible - convenience metaprogramming type trait
1328 // ----------------------------------------------------------------------
1329 
1330 template< typename From // type of conversion's source
1331  , typename To // type of conversion's target
1332  , typename R // result type if conversion is valid
1333  >
1334  struct enable_if_ptr_convertible
1335  : public enable_if< is_ptr_convertible<From,To>::value, R > { };
1336 
1337 
1338 // ----------------------------------------------------------------------
1339 // enable_if_auto_ptr - convenience metaprogramming type trait
1340 // ----------------------------------------------------------------------
1341 
1342 template< typename P // pointee type
1343  , typename R // result type
1344  >
1345  struct enable_if_auto_ptr { };
1346 
1347 template< typename P, typename R >
1348  struct enable_if_auto_ptr< std::auto_ptr<P>, R >
1349 {
1350  typedef R type;
1351 };
1352 
1353 
1354 // ----------------------------------------------------------------------
1355 
1356 } // namespace CLHEP
1357 
1358 
1359 #endif // HEP_TYPE_TRAITS_H
1360 
1361 // ======================================================================
integral_constant< bool, false > false_type
Definition: type_traits.h:33
tt::cv< T >::rem_c_type type
Definition: type_traits.h:1054
tt::cv< T >::add_cv_type type
Definition: type_traits.h:1109
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
any_conversion(T const volatile &)
static bool const is_c
Definition: type_traits.h:677
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
tt::arr< T >::rem_arr_type type
Definition: type_traits.h:1255
tt::ref< T >::add_rref_type type
Definition: type_traits.h:1189
T const volatile add_cv_type
Definition: type_traits.h:681
tt::cv< T >::add_v_type type
Definition: type_traits.h:1098
static int const rank
Definition: type_traits.h:874
const G4ThreeVector const G4double const
tt::ptr< T >::rem_ptr_type type
Definition: type_traits.h:1266
integral_constant< bool, true > true_type
Definition: type_traits.h:31
tt::cv< T >::add_c_type type
Definition: type_traits.h:1087
T const volatile add_cv_type
Definition: type_traits.h:694
no_t isAfunction(U(*)[1])
tt::cv< T >::rem_v_type type
Definition: type_traits.h:1065
yes_t isAclass(void(U::*)())
char(& no_t)[2]
Definition: type_traits.h:183
ParticleList decay(Cluster *const c)
Carries out a cluster decay.
static bool const is_v
Definition: type_traits.h:678
tt::ref< T >::rem_ref_type * add_ptr_type
Definition: type_traits.h:1202
tt::ref< T >::rem_ref_type type
Definition: type_traits.h:1167
T const volatile add_v_type
Definition: type_traits.h:693
integral_constant< T, v > type
Definition: type_traits.h:168
#define Len
Definition: deflate.h:79
tuple v
Definition: test.py:18
T const volatile add_c_type
Definition: type_traits.h:705
tt::ptr< T >::add_ptr_type type
Definition: type_traits.h:1277
tt::cv< T >::rem_cv_type type
Definition: type_traits.h:1076
static value_type const value
Definition: type_traits.h:170
T const add_c_type
Definition: type_traits.h:679
tt::ref< T >::add_lref_type type
Definition: type_traits.h:1178
tt::arr< T >::rem_arr_type rem_arr_type
Definition: type_traits.h:884
tt::arr< T >::rem_ext_type type
Definition: type_traits.h:1244
const XML_Char int const XML_Char * value
Definition: expat.h:331
**D E S C R I P T I O N
Definition: HEPEvtcom.cc:77
T volatile add_v_type
Definition: type_traits.h:680
char & yes_t
Definition: type_traits.h:182
T const volatile add_cv_type
Definition: type_traits.h:707
static tt::yes_t take(To *)