00001 #ifndef classTraits_header_included_p
00002 #define classTraits_header_included_p
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00047
00048
00049 #include <memory>
00050
00051 namespace cxxtls
00052 {
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 struct true_value_type
00073 {
00074 typedef true_value_type type;
00075
00076 enum constants { value = 1 };
00077
00078 };
00079
00080 struct false_value_type
00086 {
00087 typedef false_value_type type;
00088
00089 enum constants { value = 0 };
00090
00091 };
00092
00093 struct not_a_type{};
00094
00095 template<bool, class ZeroClass, class OneClass>
00096 struct EvalTypeIf
00165 {
00166
00167 };
00168
00169 template<class ZeroClass, class OneClass>
00170 struct EvalTypeIf<0, ZeroClass, OneClass>
00171 {
00172 typedef ZeroClass type;
00173 };
00174
00175 template<class ZeroClass, class OneClass>
00176 struct EvalTypeIf<1, ZeroClass, OneClass>
00177 {
00178 typedef OneClass type;
00179 };
00180
00181 template<class T, class U>
00182 struct isSameType
00210 {
00211
00212
00213 template<class V> static char is_same_type_func(V&,V&);
00214
00215 static int is_same_type_func(...);
00216
00217 static T t;
00218 static U u;
00219
00220
00221
00222
00223 enum { value = (sizeof( is_same_type_func(t,u) ) == sizeof(char))
00224 && (sizeof( is_same_type_func(u,t) ) == sizeof(char))
00225 };
00226
00227 };
00228
00229
00230 template<class T>
00231 struct isConstType
00254 {
00255 typedef T type;
00256
00257 typedef false_value_type valueType;
00258
00259 enum constants { value = 0 };
00260
00261 };
00262
00263 template<class T>
00264 struct isConstType<const T>
00265 {
00266 typedef T type;
00267
00268 enum constants { value = 1 };
00269
00270 typedef true_value_type valueType;
00271
00272 };
00273
00274 template<class T>
00275 struct removeConst
00299 {
00300 typedef typename isConstType<T>::type type;
00301 };
00302
00303
00304
00305 template<class T>
00306 struct removeVolatile
00330 {
00331 typedef T type;
00332 };
00333
00334
00335 template<class T>
00336 struct removeVolatile<volatile T>
00337 {
00338 typedef T type;
00339 };
00340
00341 template<class T>
00342 struct removeCV
00347 {
00348 typedef typename removeConst< typename removeVolatile<T>::type >::type type;
00349 };
00350
00351
00352
00353
00354
00355 template<class U> struct removeReference_impl { typedef U type; };
00356 template<class V> struct removeReference_impl <V&> { typedef V type; };
00357
00358 template<class T>
00359 struct removeReference
00364 {
00365
00366 typedef typename removeReference_impl<T>::type type;
00367
00368 };
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 template<class From, class To>
00380 struct isConvertibleType
00389 {
00390
00391
00392 static char f(...);
00393 static int f(To);
00394
00395
00396
00397 static From fromp;
00398 static To top;
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 enum constants
00414 {
00415 value = sizeof( f(fromp) ) == sizeof( f(top) )
00416 };
00417
00418
00419 };
00420
00421 template<class To>
00422 struct isConvertibleType<void, To>
00424 {
00425 enum { value = false };
00426 };
00427 template<class To>
00428 struct isConvertibleType<const void, To>
00430 {
00431 enum { value = false };
00432 };
00433
00434 template<>
00435 struct isConvertibleType<float, int>
00436 {
00437 enum { value = true };
00438 };
00439 template<>
00440 struct isConvertibleType<const float, int>
00441 {
00442 enum { value = true };
00443 };
00444 template<>
00445 struct isConvertibleType<double, int>
00446 {
00447 enum { value = true };
00448 };
00449 template<>
00450 struct isConvertibleType<const double, int>
00451 {
00452 enum { value = true };
00453 };
00454 template<>
00455 struct isConvertibleType<long double, int>
00456 {
00457 enum { value = true };
00458 };
00459 template<>
00460 struct isConvertibleType<const long double, int>
00461 {
00462 enum { value = true };
00463 };
00464
00465
00466
00467 template<class Type>
00468 struct isClassType
00473 {
00474
00475 template <typename ClassType>
00476 static short fun(void (ClassType::*)());
00477
00478 template <typename NonClassType>
00479 static char fun(...);
00480
00481 enum { value = sizeof(fun<Type>(0)) == sizeof(short) };
00482 };
00483
00484
00485 template<class T>
00486 struct isFunctionType
00491 {
00492
00493
00494 template<class RV> static char f(RV (*func0)());
00495 template<class RV, class A> static char f(RV (*func1)(A));
00496 template<class RV, class A, class B> static char f(RV (*func2)(A, B));
00497 template<class RV, class A, class B, class C> static char f(RV (*func3)(A, B, C));
00498 template<class RV, class A, class B, class C, class D> static char f(RV (*func4)(A, B, C, D));
00499 template<class RV, class A, class B, class C, class D, class E> static char f(RV (*func5)(A, B, C, D, E));
00500 template<class RV, class A, class B, class C, class D, class E, class F> static char f(RV (*func6)(A, B, C, D, E, F));
00501 template<class RV, class A, class B, class C, class D, class E, class F, class G> static char f(RV (*func7)(A, B, C, D, E, F, G));
00502 template<class RV, class A, class B, class C, class D, class E, class F, class G, class H> static char f(RV (*func8)(A, B, C, D, E, F, G, H));
00503 template<class RV, class A, class B, class C, class D, class E, class F, class G, class H, class I> static char f(RV (*func9)(A, B, C, D, E, F, G, H, I));
00504
00505 static int f(...);
00506
00507 static T t;
00508
00509 enum { value = sizeof(char) == sizeof( f(t) ) };
00510
00511 };
00512
00513 template<>
00514 struct isFunctionType<void>
00515 {
00516 enum { value = false };
00517 };
00518
00519 template<>
00520 struct isFunctionType<const void>
00521 {
00522 enum { value = false };
00523 };
00524
00525
00526
00527 template<class T>
00528 struct isPointerType
00534 {
00535 enum constants { value = 0 };
00536 };
00537
00538 template<class T>
00539 struct isPointerType<T*>
00540 {
00541 enum constants { value = 1 };
00542 };
00543
00544 template<class T>
00545 struct isPointerType<T const*>
00546 {
00547 enum constants { value = 1 };
00548 };
00549
00550 template<class T>
00551 struct isPointerType<T* const>
00552 {
00553 enum constants { value = 1 };
00554 };
00555
00556 template<class T>
00557 struct isPointerType<T const* const>
00558 {
00559 enum constants { value = 1 };
00560 };
00561
00562 template<class T, size_t N>
00563 struct isPointerType<T [N]>
00564 {
00565 enum constants { value = 1 };
00566 };
00567
00568 template<class T, size_t N>
00569 struct isPointerType<T const [N]>
00570 {
00571 enum constants { value = 1 };
00572 };
00573
00574 template<class T>
00575 struct isArrayType
00579 {
00580 enum constants { value = 0 };
00581 };
00582
00583
00584 template<class T, size_t N>
00585 struct isArrayType<T [N]>
00589 {
00590 enum constants { value = 1 };
00591 };
00592
00593 template<class T, size_t N>
00594 struct isArrayType<T const [N]>
00598 {
00599 enum constants { value = 1 };
00600 };
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 template<class T>
00611 struct pointerReferent
00617 {
00618 typedef T type;
00619
00620 };
00621
00622 template<class T>
00623 struct pointerReferent<T*>
00625 {
00626 typedef T type;
00627 };
00628
00629 template<class T>
00630 struct pointerReferent<T const*>
00632 {
00633 typedef T const type;
00634 };
00635
00636 template<class T, size_t N>
00638 struct pointerReferent<T [N]>
00639 {
00640 typedef T type;
00641 };
00642
00643 template<class T, size_t N>
00644 struct pointerReferent<T const [N]>
00646 {
00647 typedef T const type;
00648 };
00649
00650
00651 template<class T>struct ispodtype_impl: public false_value_type {};
00655
00656
00657
00658
00659 template<class T> struct ispodtype_impl<T*> : public true_value_type {};
00660 template<class T> struct ispodtype_impl<T* const> : public true_value_type {};
00661 template<> struct ispodtype_impl<char> : public true_value_type {};
00662 template<> struct ispodtype_impl<short> : public true_value_type {};
00663 template<> struct ispodtype_impl<int> : public true_value_type {};
00664 template<> struct ispodtype_impl<long> : public true_value_type {};
00665 template<> struct ispodtype_impl<long long> : public true_value_type {};
00666 template<> struct ispodtype_impl<unsigned char> : public true_value_type {};
00667 template<> struct ispodtype_impl<unsigned short> : public true_value_type {};
00668 template<> struct ispodtype_impl<unsigned int> : public true_value_type {};
00669 template<> struct ispodtype_impl<unsigned long long> : public true_value_type {};
00670 template<> struct ispodtype_impl<float> : public true_value_type {};
00671 template<> struct ispodtype_impl<double> : public true_value_type {};
00672
00673
00674
00675
00676 template<class T>
00677 struct isPodType
00683 {
00684 enum { value = ispodtype_impl<T>::value || isConvertibleType<T,int>::value || isFunctionType<T>::value };
00685 };
00686
00687 template<class T, size_t N> struct ispodtype_impl<T [N]> : public isPodType<T> {};
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 template <class plainT>
00699 struct isPolymorphicType_impl
00700
00701
00702
00703 {
00704
00705
00706
00707
00708
00709
00710
00711
00712 struct d1 : public plainT
00713 {
00714 d1();
00715 ~d1()throw();
00716 char padding[256];
00717 };
00718
00719 struct d2 : public plainT
00720 {
00721 d2();
00722 virtual ~d2() throw();
00723 char padding[256];
00724 };
00725
00726 enum constants { value = sizeof(d1) == sizeof(d2) };
00727
00728 typedef typename EvalTypeIf<value, false_value_type, true_value_type>::type type;
00729
00730 operator bool() const { return value; }
00731
00732 };
00733
00751
00752 template <bool is_class>
00753 struct isPolymorphicType_selector
00754 {
00755
00756
00757 template <class T>
00758 struct rebind
00759 {
00760 typedef false_value_type type;
00761 };
00762 };
00763
00764 template<>
00765 struct isPolymorphicType_selector<true>
00766 {
00767
00768
00769 template <class T>
00770 struct rebind
00771 {
00772 typedef isPolymorphicType_impl<T> type;
00773 };
00774 };
00775
00776 template <class T>
00777 struct isPolymorphicType
00787 {
00788
00789
00790
00791
00792
00793
00794
00795
00796 typedef isPolymorphicType_selector< isClassType<T>::value> selector;
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 typedef typename selector::template rebind<T> binder;
00810 typedef typename binder::type imp_type;
00811 enum { value = imp_type::value };
00812 };
00813
00814
00815
00816
00817
00818
00819
00820
00821 template<class T>
00822 struct isSignedType
00828 {
00829 typedef typename removeCV<T>::type mutableType;
00830
00831 static char f(char &);
00832 static char f(int &);
00833 static char f(short &);
00834 static char f(long &);
00835 static char f(long long &);
00836 static char f(float &);
00837 static char f(double &);
00838 static char f(long double &);
00839
00840 static int f(...);
00841
00842 static mutableType t;
00843
00844 enum { value = (sizeof(f(t)) == sizeof(char) ) };
00845
00846
00847 };
00848
00849 template<>
00850 struct isSignedType<void>
00851 {
00852 enum { value = 0 };
00853 };
00854 template<>
00855 struct isSignedType<const void>
00856 {
00857 enum { value = 0 };
00858 };
00859
00860 template<class T>
00861 struct isUnsignedType
00870 {
00871 typedef typename removeCV<T>::type mutableType;
00872 typedef typename removeReference<mutableType>::type UnrefType;
00873
00874 static char f(unsigned char &);
00875 static char f(unsigned int &);
00876 static char f(unsigned short &);
00877 static char f(unsigned long &);
00878 static char f(unsigned long long&);
00879
00880 static int f(...);
00881
00882 static UnrefType t;
00883
00884 enum { value =sizeof(f(t)) == sizeof(char) };
00885
00886 };
00887
00888 template<>
00889 struct isUnsignedType<void>
00890 {
00891 enum { value = 0 };
00892 };
00893 template<>
00894 struct isUnsignedType<const void>
00895 {
00896 enum { value = 0 };
00897 };
00898
00899
00900
00901 template<class T>
00902 struct isFloatType
00908 {
00909 typedef typename removeCV<T>::type mutableType;
00910 typedef typename removeReference<T>::type unrefType;
00911
00912 static char f(float &);
00913 static char f(double &);
00914 static char f(long double &);
00915 static int f(...);
00916
00917 static unrefType *t;
00918
00919 enum { value = sizeof(f(*t)) == sizeof(char) };
00920 };
00921
00922 template<>
00923 struct isFloatType<void>
00927 {
00928 enum { value = 0 };
00929 };
00930
00931 template<>
00932 struct isFloatType<const void>
00936 {
00937 enum { value = 0 };
00938 };
00939
00940
00941
00942
00943
00944
00945 template<class T>
00946 struct isEnumType
00953 {
00954 typedef typename removeCV<T>::type mutableType;
00955 typedef typename removeReference<mutableType>::type UnrefType;
00956
00957 static char f(unsigned char &);
00958 static char f(unsigned int &);
00959 static char f(unsigned short &);
00960 static char f(unsigned long &);
00961 static char f(unsigned long long&);
00962 static char f(char &);
00963 static char f(int &);
00964 static char f(short &);
00965 static char f(long &);
00966 static char f(long long&);
00967 static char f(float &);
00968 static char f(double &);
00969 static char f(long double &);
00970
00971
00972 static int f(...);
00973
00974 static UnrefType t;
00975
00976 enum { value = !isClassType<UnrefType>::value
00977 && isConvertibleType<UnrefType, int>::value
00978 && sizeof( f(t) ) != sizeof(char)
00979 };
00980 };
00981
00982 template<>
00983 struct isEnumType<void>
00984 {
00985 enum { value = 0 };
00986 };
00987 template<>
00988 struct isEnumType<const void>
00989 {
00990 enum { value = 0 };
00991 };
00992
00993
00994
00995 template<class T>
00996 struct isIntegralType
01002 {
01003 typedef typename removeCV<T>::type MutableType;
01004 typedef typename removeReference<MutableType>::type U;
01005
01006
01007 enum { value = ( isSignedType<U>::value
01008 || isUnsignedType<U>::value
01009 )
01010 && !isEnumType<U>::value
01011 && !isFloatType<U>::value
01012 } ;
01013 };
01014
01015 template<class T>
01016 struct isArithmeticType
01022 {
01023 typedef typename removeCV<T>::type MutableType;
01024 typedef typename removeReference<MutableType>::type U;
01025
01026
01027 enum { value = isIntegralType<U>::value || isFloatType<U>::value };
01028 };
01029
01030 template<>
01031 struct isArithmeticType<void>
01032 : public false_value_type
01037 {
01038 };
01039
01040 template<>
01041 struct isIntegralType<void>
01042 : public false_value_type
01047 {
01048 };
01049
01050 template<>
01051 struct isArithmeticType<const void>
01052 : public false_value_type
01057 {
01058 };
01059
01060 template<>
01061 struct isIntegralType<const void>
01062 : public false_value_type
01067 {
01068 };
01069
01070
01071 template<class T>
01072 struct isTemplate
01073
01083 {
01084 static typename removeCV<T>::type *t;
01085
01086 static int f(...);
01087
01088 template<class A,
01089 template<class A1> class Template
01090 >
01091 static char f( Template<A> *);
01092
01093 template<class A, class B,
01094 template<class A1, class B1> class Template
01095 >
01096 static char f( Template<A,B> *);
01097
01098 template<class A, class B, class C,
01099 template<class A1, class B1, class C1> class Template
01100 >
01101 static char f( Template<A,B,C> *);
01102
01103 template<class A, class B, class C, class D,
01104 template<class A1, class B1, class C1, class D1> class Template
01105 >
01106 static char f( Template<A,B,C,D> *);
01107
01108 template<class A, class B, class C, class D, class E,
01109 template<class A1, class B1, class C1, class D1, class E1>
01110 class Template
01111 >
01112 static char f( Template<A,B,C,D,E> *);
01113
01114 template<class A, class B, class C, class D, class E, class F,
01115 template<class A1, class B1, class C1, class D1, class E1, class F1>
01116 class Template
01117 >
01118 static char f( Template<A,B,C,D,E,F> *);
01119
01120 template<class A, class B, class C, class D, class E, class F, class G,
01121 template<class A1, class B1, class C1, class D1, class E1, class F1, class G1>
01122 class Template
01123 >
01124 static char f( Template<A,B,C,D,E,F,G> *);
01125
01126 template<class A, class B, class C, class D, class E, class F, class G, class H,
01127 template<class A1, class B1, class C1, class D1, class E1, class F1, class G1, class H1>
01128 class Template
01129 >
01130 static char f( Template<A,B,C,D,E,F,G,H> *);
01131
01132 template<class A, class B, class C, class D, class E, class F, class G, class H, class I,
01133 template<class A1, class B1, class C1, class D1, class E1, class F1, class G1, class H1, class I1>
01134 class Template
01135 >
01136 static char f( Template<A,B,C,D,E,F,G,H,I> *);
01137
01138
01139 enum { value = sizeof( f(t) ) == 1 };
01140 };
01141
01142
01143 enum basicClassTypes
01146 {
01147 bctUnknownType =0,
01148 bctVoidType =1,
01149 bctIntegralType =2,
01150 bctEnumType =3,
01151 bctPointerType =4,
01152 bctArrayType =5,
01153 bctFloatType =6,
01154 bctFunctionType =7,
01155 bctClassType =8,
01156 };
01157
01158 template<class T> struct basicClassType;
01159
01160 template<>
01161 struct basicClassType<void>
01169 {
01170 enum { value = bctVoidType };
01171 };
01172
01173 template<class T>
01174 struct basicClassType
01218 {
01219 typedef typename removeCV<T>::type MutableType;
01220 typedef typename removeReference<MutableType>::type RawType;
01221
01222 enum {
01223 value = ( isIntegralType<RawType>::value
01224 ? bctIntegralType
01225 : ( isEnumType<RawType>::value
01226 ? bctEnumType
01227 : ( isArrayType<RawType>::value
01228 ? bctArrayType
01229 : ( isFunctionType<RawType>::value
01230 ? bctFunctionType
01231 : ( isFloatType<RawType>::value
01232 ? bctFloatType
01233 : ( isPointerType<RawType>::value
01234 ? bctPointerType
01235 : ( isClassType<RawType>::value
01236 ? bctClassType
01237 : bctUnknownType
01238 )
01239 )
01240 )
01241 )
01242 )
01243 )
01244 )
01245 };
01246 };
01247
01248 template<class Base, class Derived>
01249 void derivedFromBase(Base *bptr, Derived *&dref)
01277 {
01278 static Derived *d= (Derived *)(0x100);
01279 static Base *b=d;
01280
01281 static size_t const bOffset = ((char *)b) - ((char *)d);
01282
01283 dref = (Derived*)( ((char*)bptr) - bOffset);
01284
01285 }
01286
01287 template<class T, class U, class W=false_value_type, class X=false_value_type>
01288 struct EvalOr
01293 {
01294 enum { value = T::value || U::value || W::value || X::value };
01295 };
01296
01297
01298 template<class T, class U, class W=true_value_type, class X=true_value_type>
01299 struct EvalAnd
01304 {
01305 enum { value = T::value && U::value && W::value && X::value};
01306 };
01307
01308
01309
01310 template<class T>
01311 struct removeAllExtents
01317 {
01318
01319 typedef typename removeReference<T>::type ReferenceStripped;
01320 typedef typename pointerReferent<ReferenceStripped>::type PointerStripped;
01321 typedef typename removeCV<T>::type CVStripped;
01322
01323 typedef CVStripped type;
01324
01325 };
01326
01327 template<class T, unsigned long long N>
01328 struct removeAllExtents<T [N]>
01330 {
01331
01332 typedef typename removeAllExtents<T>::type type;
01333
01334 };
01335
01336
01337
01338 }
01339
01340 #endif