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

Utility/CLHEP/Utility/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
24namespace CLHEP {
25
26// ----------------------------------------------------------------------
27// Contents:
28// ----------------------------------------------------------------------
29
30// helper class:
31template< typename T, T v > struct integral_constant;
32typedef integral_constant<bool, true > true_type;
33typedef integral_constant<bool, false > false_type;
34
35// primary type categories:
36template< typename T > struct is_void;
37template< typename T > struct is_integral;
38template< typename T > struct is_floating_point;
39template< typename T > struct is_array;
40template< typename T > struct is_pointer;
41template< typename T > struct is_lvalue_reference;
42template< typename T > struct is_rvalue_reference;
43template< typename T > struct is_member_object_pointer;
44template< typename T > struct is_member_function_pointer;
45template< typename T > struct is_enum;
46template< typename T > struct is_union;
47template< typename T > struct is_class;
48template< typename T > struct is_function;
49
50// composite type categories:
51template< typename T > struct is_reference;
52template< typename T > struct is_arithmetic;
53template< typename T > struct is_fundamental;
54template< typename T > struct is_object;
55template< typename T > struct is_scalar;
56template< typename T > struct is_compound;
57template< typename T > struct is_member_pointer;
58
59// type properties:
60template< typename T > struct is_const;
61template< typename T > struct is_volatile;
62#if 0
63template< typename T > struct is_trivial;
64template< typename T > struct is_trivially_copyable;
65template< typename T > struct is_standard_layout;
66template< typename T > struct is_pod;
67template< typename T > struct is_literal_type;
68template< typename T > struct is_empty;
69template< typename T > struct is_polymorphic;
70#endif // 0
71template< typename T > struct is_abstract;
72#if 0
73template< typename T, typename... Args > struct is_constructible;
74template< typename T, typename... Args > struct is_nothrow_constructible;
75template< typename T > struct has_default_constructor;
76template< typename T > struct has_copy_constructor;
77template< typename T > struct has_copy_assign;
78template< typename T > struct has_move_constructor;
79template< typename T > struct has_move_assign;
80template< typename T > struct has_trivial_default_constructor;
81template< typename T > struct has_trivial_copy_constructor;
82template< typename T > struct has_trivial_move_constructor;
83template< typename T > struct has_trivial_copy_assign;
84template< typename T > struct has_trivial_move_assign;
85template< typename T > struct has_trivial_destructor;
86template< typename T > struct has_nothrow_default_constructor;
87template< typename T > struct has_nothrow_copy_constructor;
88template< typename T > struct has_nothrow_move_constructor;
89template< typename T > struct has_nothrow_copy_assign;
90template< typename T > struct has_nothrow_move_assign;
91template< typename T > struct has_virtual_destructor;
92#endif // 0
93template< typename T > struct is_signed;
94template< typename T > struct is_unsigned;
95#if 0
96template< typename T > struct alignment_of;
97#endif // 0
98template< typename T > struct rank;
99template< typename T, unsigned I = 0 > struct extent;
100
101// type relations:
102template< typename T, typename U > struct is_same;
103#if 0
104template< typename Base, typename Derived > struct is_base_of;
105#endif // 0
106template< typename From, typename To > struct is_convertible;
107#if 0
108template< typename From, typename To > struct is_explicitly_convertible;
109#endif // 0
110
111// const-volatile modifications:
112template< typename T > struct remove_const;
113template< typename T > struct remove_volatile;
114template< typename T > struct remove_cv;
115template< typename T > struct add_const;
116template< typename T > struct add_volatile;
117template< typename T > struct add_cv;
118
119// reference modifications:
120template< typename T > struct remove_reference;
121template< typename T > struct add_lvalue_reference;
122template< typename T > struct add_rvalue_reference;
123
124// sign modifications:
125#if 0
126template< typename T > struct make_signed;
127template< typename T > struct make_unsigned;
128#endif // 0
129
130// array modifications:
131template< typename T > struct remove_extent;
132template< typename T > struct remove_all_extents;
133
134// pointer modifications:
135template< typename T > struct remove_pointer;
136template< typename T > struct add_pointer;
137
138// other transformations:
139#if 0
140template< std::size_t Len, std::size_t Align > struct aligned_storage;
141template< std::size_t Len, typename... Types > struct aligned_union;
142template< typename T > struct decay;
143#endif // 0
144template< bool, typename T = void > struct enable_if;
145template< bool, typename T, typename F > struct conditional;
146#if 0
147template< typename... T > struct common_type;
148template< typename T > struct underlying_type;
149template< typename > typename result_of; // undefined
150template< typename F, typename... ArgTypes > typename result_of<F(ArgTypes...)>;
151#endif // 0
152
153// non-standard (but useful) extensions:
154template< typename From, typename To > struct is_ptr_convertible;
155template< typename From, typename To, typename R=void > struct enable_if_convertible;
156template< typename From, typename To, typename R=void > struct enable_if_ptr_convertible;
157template< 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
164template< 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
180namespace tt {
181
182typedef char (& yes_t); // ref to char
183typedef char (& no_t ) [2]; // ref to 2-char array
184
185} // namespace tt
186
187
188// ----------------------------------------------------------------------
189// primary<,> - type classification helper
190// ----------------------------------------------------------------------
191
192namespace 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
203, _member_object_pointer = 1u << 7
204, _member_function_pointer = 1u << 8
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:
212template< typename U > yes_t isAclass( void(U::*)() );
213template< typename U > no_t isAclass( ... );
214
215// Helpers to recognize functions:
216template< typename U >
217 no_t isAfunction( U(*)[1] ); // arrays of non-{fctn/ref/void}s
218template< 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
226template< typename T >
227struct 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:
237template< typename T >
238 struct encode<T const> : public encode<T> { };
239template< typename T >
240 struct encode<T volatile> : public encode<T> { };
241template< typename T >
242 struct encode<T const volatile> : public encode<T> { };
243
244// encode array:
245template< typename T >
246 struct encode<T[]>
247{ static primary_code const value = _array; };
248template< typename T >
249 struct encode<T const[]>
250{ static primary_code const value = _array; };
251template< typename T >
252 struct encode<T volatile[]>
253{ static primary_code const value = _array; };
254template< typename T >
255 struct encode<T const volatile[]>
256{ static primary_code const value = _array; };
257template< typename T, unsigned N >
258 struct encode<T[N]>
259{ static primary_code const value = _array; };
260template< typename T, unsigned N >
261 struct encode<T const[N]>
262{ static primary_code const value = _array; };
263template< typename T, unsigned N >
264 struct encode<T volatile[N]>
265{ static primary_code const value = _array; };
266template< typename T, unsigned N >
267 struct encode<T const volatile[N]>
268{ static primary_code const value = _array; };
269
270// encode floating_point:
271template<>
272 struct encode<float>
273{ static primary_code const value = _floating_point; };
274template<>
275 struct encode<double>
276{ static primary_code const value = _floating_point; };
277template<>
278 struct encode<long double>
279{ static primary_code const value = _floating_point; };
280
281// encode integral:
282template<>
283 struct encode<bool>
284{ static primary_code const value = _integral; };
285template<>
286 struct encode<signed char>
287{ static primary_code const value = _integral; };
288template<>
289 struct encode<char>
290{ static primary_code const value = _integral; };
291template<>
292 struct encode<unsigned char>
293{ static primary_code const value = _integral; };
294#if 0
295template<>
296 struct encode<wchar_t>
297{ static primary_code const value = _integral; };
298#endif
299template<>
300 struct encode<short>
301{ static primary_code const value = _integral; };
302template<>
303 struct encode<unsigned short>
304{ static primary_code const value = _integral; };
305template<>
306 struct encode<int>
307{ static primary_code const value = _integral; };
308template<>
309 struct encode<unsigned int>
310{ static primary_code const value = _integral; };
311template<>
312 struct encode<long>
313{ static primary_code const value = _integral; };
314template<>
315 struct encode<unsigned long>
316{ static primary_code const value = _integral; };
317
318// encode member_function_pointer:
319template< typename T, typename C >
320 struct encode<T (C::*)()>
322template< typename T, typename C >
323 struct encode<T (C::*)() const>
325template< typename T, typename C >
326 struct encode<T (C::*)() volatile>
328template< typename T, typename C >
329 struct encode<T (C::*)() const volatile>
331template< typename T, typename C
332 , typename A1 >
333 struct encode<T (C::*)(A1)>
335template< typename T, typename C
336 , typename A1 >
337 struct encode<T (C::*)(A1) const>
339template< typename T, typename C
340 , typename A1 >
341 struct encode<T (C::*)(A1) volatile>
343template< typename T, typename C
344 , typename A1 >
345 struct encode<T (C::*)(A1) const volatile>
347template< typename T, typename C
348 , typename A1, typename A2 >
349 struct encode<T (C::*)(A1,A2)>
351template< typename T, typename C
352 , typename A1, typename A2 >
353 struct encode<T (C::*)(A1,A2) const>
355template< typename T, typename C
356 , typename A1, typename A2 >
357 struct encode<T (C::*)(A1,A2) volatile>
359template< typename T, typename C
360 , typename A1, typename A2 >
361 struct encode<T (C::*)(A1,A2) const volatile>
363template< typename T, typename C
364 , typename A1, typename A2, typename A3 >
365 struct encode<T (C::*)(A1,A2,A3)>
367template< typename T, typename C
368 , typename A1, typename A2, typename A3 >
369 struct encode<T (C::*)(A1,A2,A3) const>
371template< typename T, typename C
372 , typename A1, typename A2, typename A3 >
373 struct encode<T (C::*)(A1,A2,A3) volatile>
375template< typename T, typename C
376 , typename A1, typename A2, typename A3 >
377 struct encode<T (C::*)(A1,A2,A3) const volatile>
379template< typename T, typename C
380 , typename A1, typename A2, typename A3, typename A4 >
381 struct encode<T (C::*)(A1,A2,A3,A4)>
383template< typename T, typename C
384 , typename A1, typename A2, typename A3, typename A4 >
385 struct encode<T (C::*)(A1,A2,A3,A4) const>
387template< typename T, typename C
388 , typename A1, typename A2, typename A3, typename A4 >
389 struct encode<T (C::*)(A1,A2,A3,A4) volatile>
391template< typename T, typename C
392 , typename A1, typename A2, typename A3, typename A4 >
393 struct encode<T (C::*)(A1,A2,A3,A4) const volatile>
395template< 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)>
399template< 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>
403template< 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>
407template< 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:
413template< typename T, typename C >
414 struct encode<T C::*>
415{ static primary_code const value = _member_object_pointer; };
416
417// encode pointer:
418template< typename T >
419 struct encode<T *>
420{ static primary_code const value = _pointer; };
421
422// encode lvalue_reference:
423template< typename T >
424 struct encode<T &>
425{ static primary_code const value = _lvalue_reference; };
426
427// encode rvalue_reference:
428#if defined(CLHEP_HAS_RVALUE_REFERENCE)
429template< typename T >
430 struct encode<T&&>
431{ static primary_code const value = _rvalue_reference; };
432#endif // CLHEP_HAS_RVALUE_REFERENCE
433
434// encode void:
435template<>
436 struct encode<void>
437{ static primary_code const value = _void; };
438
439// apply encoding:
440template< 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
450template< 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
459template< 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
468template< 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
476template< 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
485template< 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
494template< 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
503template< 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
511template< 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
523template< 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
532template< 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
541template< 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
550template< 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
559template< 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
568template< 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
580template< 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
592template< 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
605template< 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
624template< 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
640template< 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
660template< 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
672namespace tt {
673
674template< 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
687template< 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
700template< 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
713template< 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
726template< 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
746template< 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
755template< 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
764namespace tt {
765
766template< typename, bool >
767 struct is_abstract_class
768 : public false_type { }; // default: not a class, hence not abstract
769
770template< typename C >
771 struct is_abstract_class<C,true> // C is known to be a class type
772{
773protected:
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
779public:
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
790template< 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
802template< typename >
803 struct is_signed
804 : public false_type { };
805
806template<>
807 struct is_signed<signed char>
808 : public true_type { };
809template<>
810 struct is_signed<short>
811 : public true_type { };
812template<>
813 struct is_signed<int>
814 : public true_type { };
815template<>
816 struct is_signed<long>
817 : public true_type { };
818
819template< typename T >
820 struct is_signed<T const>
821 : public is_signed<T> { };
822template< typename T >
823 struct is_signed<T volatile>
824 : public is_signed<T> { };
825template< 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
834template< typename >
835 struct is_unsigned
836 : public false_type { };
837
838template<>
839 struct is_unsigned<unsigned char>
840 : public true_type { };
841template<>
842 struct is_unsigned<unsigned short>
843 : public true_type { };
844template<>
845 struct is_unsigned<unsigned int>
846 : public true_type { };
847template<>
848 struct is_unsigned<unsigned long>
849 : public true_type { };
850
851template< typename T >
852 struct is_unsigned<T const>
853 : public is_unsigned<T> { };
854template< typename T >
855 struct is_unsigned<T volatile>
856 : public is_unsigned<T> { };
857template< 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
866namespace tt {
867
868template< 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
880template< 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
897template< 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
916template< 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
925template< 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
934template< typename T, typename U >
935 struct is_same : public false_type { };
936template< 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
944namespace tt {
945
946struct any_conversion
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
961namespace tt {
962
963template< typename From, typename To, bool >
964 struct converts
965 : public false_type { }; // default: can't convert to abstract To
966
967template< typename From, typename To >
968struct converts<From,To,false> // To is non-abstract
969{
970protected:
971 static yes_t take( To, int );
972 static no_t take( any_conversion, ... );
973 static From from;
974
975public:
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
987template< typename From, typename To >
988 struct is_convertible
989 : public tt::converts<From,To,is_abstract<To>::value> { };
990
991template< > struct is_convertible<void,void>
992 : public true_type { };
993
994template< typename T >
995 struct is_convertible<T,void>
996 : public true_type { };
997
998template< typename T >
999 struct is_convertible<void,T>
1000 : public false_type { };
1001
1002template< >
1003 struct is_convertible<const void,const void>
1004 : public true_type { };
1005
1006template< typename T >
1007 struct is_convertible<T,const void>
1008 : public true_type { };
1009
1010template< typename T >
1011 struct is_convertible<const void,T>
1012 : public false_type { };
1013
1014template< >
1015 struct is_convertible<volatile void,volatile void>
1016 : public true_type { };
1017
1018template< typename T >
1019 struct is_convertible<T,volatile void>
1020 : public true_type { };
1021
1022template< typename T >
1023 struct is_convertible<volatile void,T>
1024 : public false_type { };
1025
1026template< >
1027 struct is_convertible<const volatile void,const volatile void>
1028 : public true_type { };
1029
1030template< typename T >
1031 struct is_convertible<T,const volatile void>
1032 : public true_type { };
1033
1034template< typename T >
1035 struct is_convertible<const volatile void,T>
1036 : public false_type { };
1037
1038template< typename From, int N, typename To >
1039 struct is_convertible<From[N],To>
1040 : public is_convertible<From*,To> { };
1041
1042template< 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
1051template< 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
1062template< 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
1073template< typename T >
1074 struct remove_cv
1075{
1077};
1078
1079
1080// ----------------------------------------------------------------------
1081// add_const - metaprogramming type trait ensuring constness
1082// ----------------------------------------------------------------------
1083
1084template< 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
1095template< 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
1106template< typename T >
1107 struct add_cv
1108{
1110};
1111
1112
1113// ----------------------------------------------------------------------
1114// ref<> - helper analyzing a type's reference qualification
1115// ----------------------------------------------------------------------
1116
1117namespace tt {
1118
1119template< 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
1131template< typename T >
1132 struct ref<T&,_lvalue_reference>
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)
1140template< 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
1149template< 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
1164template< typename T >
1165 struct remove_reference
1166{
1168};
1169
1170
1171// ----------------------------------------------------------------------
1172// add_lvalue_reference - metaprogramming type trait ensuring lvalue-ref
1173// ----------------------------------------------------------------------
1174
1175template< typename T >
1177{
1179};
1180
1181
1182// ----------------------------------------------------------------------
1183// add_rvalue_reference - metaprogramming type trait ensuring rvalue-ref
1184// ----------------------------------------------------------------------
1185
1186template< typename T >
1188{
1190};
1191
1192
1193// ----------------------------------------------------------------------
1194// ptr<> - helper analyzing a type's pointer qualification
1195// ----------------------------------------------------------------------
1196
1197namespace tt {
1198
1199template< typename T >
1200 struct ptr
1201{
1203 typedef T rem_ptr_type;
1204};
1205
1206template< typename T >
1207 struct ptr<T *>
1208{
1209 typedef T * * add_ptr_type;
1210 typedef T rem_ptr_type;
1211};
1212
1213template< typename T >
1214 struct ptr<T * const>
1215{
1216 typedef T * const * add_ptr_type;
1217 typedef T rem_ptr_type;
1218};
1219
1220template< typename T >
1221 struct ptr<T * volatile>
1222{
1223 typedef T * volatile * add_ptr_type;
1224 typedef T rem_ptr_type;
1225};
1226
1227template< 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
1241template< typename T >
1242 struct remove_extent
1243{
1245};
1246
1247
1248// ----------------------------------------------------------------------
1249// remove_all_extents - metaprogramming type trait yielding a non-array
1250// ----------------------------------------------------------------------
1251
1252template< typename T >
1253 struct remove_all_extents
1254{
1256};
1257
1258
1259// ----------------------------------------------------------------------
1260// remove_pointer - metaprogramming type trait ensuring non-pointer
1261// ----------------------------------------------------------------------
1262
1263template< typename T >
1264 struct remove_pointer
1265{
1267};
1268
1269
1270// ----------------------------------------------------------------------
1271// add_pointer - metaprogramming type trait ensuring pointer
1272// ----------------------------------------------------------------------
1273
1274template< typename T >
1275 struct add_pointer
1276{
1278};
1279
1280
1281// ----------------------------------------------------------------------
1282// enable_if - metaprogramming construct for applied SFINAE
1283// ----------------------------------------------------------------------
1284
1285template< typename T > struct enable_if<true ,T> { typedef T type; };
1286template< typename T > struct enable_if<false,T> { };
1287
1288
1289// ----------------------------------------------------------------------
1290// conditional - metaprogramming construct for type selection
1291// ----------------------------------------------------------------------
1292
1293template< typename T, typename F > struct conditional<true ,T,F> { typedef T type; };
1294template< 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
1301template< typename From, typename To >
1302 struct is_ptr_convertible
1303{
1304protected:
1305 static tt::yes_t take( To * );
1306 static tt::no_t take( ... );
1307
1308public:
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
1318template< 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 >
1323 : public enable_if< is_convertible<From,To>::value, R > { };
1324
1325
1326// ----------------------------------------------------------------------
1327// enable_if_ptr_convertible - convenience metaprogramming type trait
1328// ----------------------------------------------------------------------
1329
1330template< 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
1342template< typename P // pointee type
1343 , typename R // result type
1344 >
1345 struct enable_if_auto_ptr { };
1346
1347template< 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 // CLHEP_TYPE_TRAITS_H
1360
1361// ======================================================================
#define double(obj)
Definition: excDblThrow.cc:32
no_t isAfunction(U(*)[1])
yes_t isAclass(void(U::*)())
integral_constant< bool, true > true_type
integral_constant< bool, false > false_type
tt::cv< T >::add_cv_type type
tt::ptr< T >::add_ptr_type type
static tt::yes_t take(To *)
static tt::no_t take(...)
any_conversion(T const volatile &)
tt::arr< T >::rem_arr_type rem_arr_type
static no_t take(any_conversion,...)
static primary_code const value
tt::ref< T >::rem_ref_type * add_ptr_type