00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CSUTIL_TYPETRAITS_H__
00020 #define __CSUTIL_TYPETRAITS_H__
00021
00027 namespace CS
00028 {
00029 namespace Meta
00030 {
00031 namespace Implementation
00032 {
00033
00034
00036 typedef char YesType;
00037
00039 struct NoType
00040 {
00041 char padding[8];
00042 };
00043
00045 template <class T>
00046 struct Wrap { Wrap () {} };
00047
00048 template <class T> T&(* IsReferenceHelper1(Wrap<T>) )(Wrap<T>);
00049 char IsReferenceHelper1(...);
00050
00051 template <class T> NoType IsReferenceHelper2(T&(*)(Wrap<T>));
00052 YesType IsReferenceHelper2(...);
00053
00054 template <class T>
00055 struct IsReferenceImpl
00056 {
00057 static const bool value = sizeof(IsReferenceHelper2 (
00058 IsReferenceHelper1 (Wrap<T>()))) == 1;
00059 };
00060
00061
00062 template <bool b1, bool b2, bool b3 = true, bool b4 = true, bool b5 = true,
00063 bool b6 = true, bool b7 = true>
00064 struct TraitAnd;
00065
00066 template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
00067 struct TraitAnd
00068 {
00069 static const bool value = false;
00070 };
00071
00072 template <>
00073 struct TraitAnd<true, true, true, true, true, true, true>
00074 {
00075 static const bool value = true;
00076 };
00077
00078 template <bool b1, bool b2, bool b3 = false, bool b4 = false, bool b5 = false,
00079 bool b6 = false, bool b7 = false>
00080 struct TraitOr;
00081
00082 template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
00083 struct TraitOr
00084 {
00085 static const bool value = true;
00086 };
00087
00088 template<>
00089 struct TraitOr<false, false, false, false, false, false, false>
00090 {
00091 static const bool value = false;
00092 };
00093
00094 template <class T>
00095 YesType IsSameTester(T*, T*);
00096
00097 NoType IsSameTester(...);
00098
00099 template <class T, class U>
00100 struct IsSameImpl
00101 {
00102 static T* t;
00103 static U* u;
00104
00105 static const bool value = TraitAnd<
00106 sizeof(YesType) == sizeof(IsSameTester(t, u)),
00107 IsReferenceImpl<T>::value == IsReferenceImpl<U>::value,
00108 sizeof(T) == sizeof(U)>::value;
00109 };
00110
00111 template<typename B, typename D>
00112 struct IsBaseOfHelper
00113 {
00114 operator const B*() const;
00115 operator const D*();
00116 };
00117
00118 template<typename B, typename D>
00119 struct IsBaseOfImpl
00120 {
00121 template<typename T>
00122 static YesType Test(const D*,T);
00123 static NoType Test(const B*,int);
00124 static const bool value = TraitOr<
00125 sizeof(YesType) == sizeof(Test(IsBaseOfHelper<B,D>(),0)),
00126 IsSameImpl<B,D>::value>::value;
00127 };
00128 }
00129
00130
00134 template <class Type>
00135 struct IsReference
00136 {
00137 static const bool value = CS::Meta::Implementation
00138 ::IsReferenceImpl<Type>::value;
00139 };
00140
00144 template <class Type1, class Type2>
00145 struct IsSame
00146 {
00147 static const bool value = CS::Meta::Implementation
00148 ::IsSameImpl<Type1, Type2>::value;
00149 };
00150
00154 template <class Type1, class Type2>
00155 struct IsBaseOf
00156 {
00157 static const bool value = CS::Meta::Implementation
00158 ::IsBaseOfImpl<Type1, Type2>::value;
00159 };
00160 }
00161
00162 }
00163
00164 #endif