00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015 #ifndef LOKI_TYPEMANIP_INC_
00016 #define LOKI_TYPEMANIP_INC_
00017
00018
00019
00020
00021 namespace Loki
00022 {
00024
00025
00026
00027
00029
00030 template <int v>
00031 struct Int2Type
00032 {
00033 enum { value = v };
00034 };
00035
00037
00038
00039
00040
00042
00043 template <typename T>
00044 struct Type2Type
00045 {
00046 typedef T OriginalType;
00047 };
00048
00050
00051
00052
00053
00054
00055
00056
00058
00059 template <bool flag, typename T, typename U>
00060 struct Select
00061 {
00062 typedef T Result;
00063 };
00064 template <typename T, typename U>
00065 struct Select<false, T, U>
00066 {
00067 typedef U Result;
00068 };
00069
00071
00072
00073
00074
00075
00076
00078
00079 template <typename T, typename U>
00080 struct IsSameType
00081 {
00082 enum { value = false };
00083 };
00084
00085 template <typename T>
00086 struct IsSameType<T,T>
00087 {
00088 enum { value = true };
00089 };
00090
00092
00094
00095 namespace Private
00096 {
00097 template <class T, class U>
00098 struct ConversionHelper
00099 {
00100 typedef char Small;
00101 struct Big { char dummy[2]; };
00102 static Big Test(...);
00103 static Small Test(U);
00104 static T MakeT();
00105 };
00106 }
00107
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00123
00124 template <class T, class U>
00125 struct Conversion
00126 {
00127 typedef Private::ConversionHelper<T, U> H;
00128 #ifndef __MWERKS__
00129 enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
00130 #else
00131 enum { exists = false };
00132 #endif
00133 enum { exists2Way = exists && Conversion<U, T>::exists };
00134 enum { sameType = false };
00135 };
00136
00137 template <class T>
00138 struct Conversion<T, T>
00139 {
00140 enum { exists = 1, exists2Way = 1, sameType = 1 };
00141 };
00142
00143 template <class T>
00144 struct Conversion<void, T>
00145 {
00146 enum { exists = 0, exists2Way = 0, sameType = 0 };
00147 };
00148
00149 template <class T>
00150 struct Conversion<T, void>
00151 {
00152 enum { exists = 0, exists2Way = 0, sameType = 0 };
00153 };
00154
00155 template <>
00156 struct Conversion<void, void>
00157 {
00158 public:
00159 enum { exists = 1, exists2Way = 1, sameType = 1 };
00160 };
00161
00163
00164
00165
00166
00167
00168
00170
00171 template <class T, class U>
00172 struct SuperSubclass
00173 {
00174 enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
00175 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
00176
00177
00178 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
00179 };
00180
00181 template <>
00182 struct SuperSubclass<void, void>
00183 {
00184 enum { value = false };
00185 };
00186
00187 template <class U>
00188 struct SuperSubclass<void, U>
00189 {
00190 enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
00191 !::Loki::Conversion<const volatile void*, const volatile void*>::sameType) };
00192
00193
00194 enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
00195 };
00196
00197 template <class T>
00198 struct SuperSubclass<T, void>
00199 {
00200 enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
00201 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
00202
00203
00204 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
00205 };
00206
00208
00209
00210
00211
00212
00214
00215 template<class T,class U>
00216 struct SuperSubclassStrict
00217 {
00218 enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
00219 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
00220 !::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
00221
00222
00223 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
00224 };
00225
00226 template<>
00227 struct SuperSubclassStrict<void, void>
00228 {
00229 enum { value = false };
00230 };
00231
00232 template<class U>
00233 struct SuperSubclassStrict<void, U>
00234 {
00235 enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
00236 !::Loki::Conversion<const volatile void*, const volatile void*>::sameType &&
00237 !::Loki::Conversion<const volatile void*, const volatile U*>::sameType) };
00238
00239
00240 enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
00241 };
00242
00243 template<class T>
00244 struct SuperSubclassStrict<T, void>
00245 {
00246 enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
00247 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
00248 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
00249
00250
00251 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
00252 };
00253
00254
00255 }
00256
00258
00259
00260
00261
00262
00263
00264
00266
00267 #define LOKI_SUPERSUBCLASS(T, U) \
00268 ::Loki::SuperSubclass<T,U>::value
00269
00271
00272
00273
00274
00275
00276
00278
00279 #define LOKI_SUPERSUBCLASS_STRICT(T, U) \
00280 ::Loki::SuperSubclassStrict<T,U>::value
00281
00282
00283 #endif // end file guardian
00284