KDECore
ktypetraits.h
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2009 Jonathan Schmidt-Dominé <devel@the-user.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #ifndef KTYPETRAITS_H 00020 #define KTYPETRAITS_H 00021 00022 #include "ktypelist.h" 00023 #include "ktypelistutils.h" 00024 #include <stdint.h> 00025 00026 class QObject; 00027 class QWidget; 00028 00029 #define NC(...) __VA_ARGS__ 00030 00031 namespace KTypeTraits 00032 { 00033 00034 template<class Types, bool correct> 00035 struct TypeSelectImpl 00036 { 00037 typedef typename Types::Head Result; 00038 }; 00039 00040 template<class Types, unsigned int size> 00041 struct TypeSelect 00042 { 00043 typedef STATIC_IF(sizeof(typename Types::Head) == size, typename Types::Head, NC(typename TypeSelect<typename Types::Tail, size>::Result)) Result; 00044 }; 00045 00046 template<unsigned int size> 00047 struct TypeSelect<KDE::NullType, size> 00048 { 00049 typedef KDE::NullType Result; 00050 }; 00051 00052 template<typename T, typename U> 00053 struct CanConvert 00054 { 00055 private: 00056 class Big { char dummy[2]; }; 00057 static char test(const U&); 00058 static Big test(...); 00059 static T makeT(); 00060 public: 00061 enum { value = sizeof(test(makeT())) == sizeof(char) }; 00062 }; 00063 00064 template<typename T, typename U> 00065 struct IsParentOfChildNonStrict 00066 { 00067 enum { value = CanConvert<const U*, const T*>::value && !STATIC_EQUAL(T, void) }; 00068 }; 00069 00070 template<typename T, typename U> 00071 struct IsParentOfChild 00072 { 00073 enum { value = IsParentOfChildNonStrict<T, U>::value && !STATIC_EQUAL(const T, const U) }; 00074 }; 00075 00076 template<typename T, typename U> 00077 struct CanDynamicCast 00078 { 00079 enum { value = CanConvert<const U*, const T*>::value }; 00080 }; 00081 00082 template<class Types> 00083 struct MaxTypeSelect 00084 { 00085 enum { isMax = (int)sizeof(typename Types::Head) > MaxTypeSelect<typename Types::Tail>::max }; 00086 enum { max = isMax ? (int)sizeof(typename Types::Head) : MaxTypeSelect<typename Types::Tail>::max }; 00087 typedef STATIC_IF(isMax, typename Types::Head, typename MaxTypeSelect<typename Types::Tail>::Result) Result; 00088 }; 00089 00090 template<> 00091 struct MaxTypeSelect<KDE::NullType> 00092 { 00093 enum { isMax = true }; 00094 enum { max = -1 }; 00095 typedef KDE::NullType Result; 00096 }; 00097 00098 template<class Types> 00099 struct MinTypeSelect 00100 { 00101 enum { isMin = sizeof(typename Types::Head) < MinTypeSelect<typename Types::Tail>::min }; 00102 enum { min = isMin ? (int)sizeof(typename Types::Head) : (int)MinTypeSelect<typename Types::Tail>::min }; 00103 typedef STATIC_IF(isMin, typename Types::Head, typename MinTypeSelect<typename Types::Tail>::Result) Result; 00104 }; 00105 00106 template<> 00107 struct MinTypeSelect<KDE::NullType> 00108 { 00109 enum { isMin = true }; 00110 enum { min = 1000000 }; 00111 typedef KDE::NullType Result; 00112 }; 00113 00114 typedef K_TYPELIST_6(signed char, wchar_t, signed short, signed int, signed long, signed long long) SignedInts; 00115 typedef K_TYPELIST_6(unsigned char, wchar_t, unsigned short, unsigned int, unsigned long, unsigned long long) UnsignedInts; 00116 typedef K_TYPELIST_3(float, double, long double) Floats; 00117 typedef TypeSelect<SignedInts, 1>::Result int8; 00118 typedef TypeSelect<SignedInts, 2>::Result int16; 00119 typedef TypeSelect<SignedInts, 4>::Result int32; 00120 typedef TypeSelect<SignedInts, 8>::Result int64; 00121 typedef TypeSelect<UnsignedInts, 1>::Result uint8; 00122 typedef TypeSelect<UnsignedInts, 2>::Result uint16; 00123 typedef TypeSelect<UnsignedInts, 4>::Result uint32; 00124 typedef TypeSelect<UnsignedInts, 8>::Result uint64; 00125 typedef TypeSelect<Floats, 4>::Result float32; 00126 typedef TypeSelect<Floats, 8>::Result float64; 00127 typedef TypeSelect<Floats, 12>::Result float96; 00128 typedef MaxTypeSelect<SignedInts>::Result maxint; 00129 typedef MinTypeSelect<SignedInts>::Result minint; 00130 typedef MaxTypeSelect<UnsignedInts>::Result maxuint; 00131 typedef MinTypeSelect<UnsignedInts>::Result minuint; 00132 typedef MaxTypeSelect<Floats>::Result maxfloat; 00133 typedef MinTypeSelect<Floats>::Result minfloat; 00134 00135 #define TTQ_DECL(Name) \ 00136 template<typename T> \ 00137 struct Is ##Name \ 00138 { \ 00139 enum { value = false };\ 00140 }; \ 00141 template<typename T> \ 00142 struct Strip ##Name \ 00143 { \ 00144 typedef T Result; \ 00145 }; 00146 #define TTQ_SPECIALIZATION(Name, Check)\ 00147 template<typename T> \ 00148 struct Is ##Name<Check> \ 00149 { \ 00150 enum { value = true }; \ 00151 }; \ 00152 template<typename T> \ 00153 struct Strip ##Name<Check> \ 00154 { \ 00155 typedef T Result; \ 00156 }; 00157 #define TTQ_ALIAS(Name) \ 00158 typedef typename Modifiers::Strip ##Name<T>::Result Strip ##Name; \ 00159 enum { is ##Name = Modifiers::Is ##Name<T>::value }; 00160 00161 template<typename T> 00162 class TypeTraits; 00163 00164 namespace Modifiers 00165 { 00166 TTQ_DECL(Pointer) 00167 TTQ_DECL(Reference) 00168 TTQ_DECL(Const) 00169 TTQ_DECL(Volatile) 00170 TTQ_DECL(ConstReference) 00171 template<typename T> 00172 struct StripAll 00173 { 00174 typedef typename StripConst<typename StripVolatile<typename StripReference<T>::Result>::Result>::Result Result; 00175 }; 00176 template<typename T> 00177 struct ParameterType 00178 { 00179 typedef typename TypeTraits<T>::ParameterType Result; 00180 }; 00181 template<typename T> 00182 struct PointerType 00183 { 00184 typedef T* Result; 00185 }; 00186 template<typename T> 00187 struct ReferenceType 00188 { 00189 typedef T& Result; 00190 }; 00191 template<typename T> 00192 struct ReferenceType<T&> 00193 { 00194 typedef T& Result; 00195 }; 00196 template<typename T> 00197 struct ConstReferenceType 00198 { 00199 typedef const T& Result; 00200 }; 00201 00202 template<typename T> 00203 struct ConstReferenceType<T&> 00204 { 00205 typedef const T& Result; 00206 }; 00207 }; 00208 00209 template<typename T> 00210 struct TypeListCheck 00211 { 00212 enum { value = false }; 00213 }; 00214 00215 template<typename Head, class Tail> 00216 struct TypeListCheck<KTypeList<Head, Tail> > 00217 { 00218 enum { value = TypeTraits<Tail>::isTypeList }; 00219 }; 00220 00221 template<> 00222 struct TypeListCheck<KDE::NullType> 00223 { 00224 enum { value = true }; 00225 }; 00226 00227 template<typename T> 00228 class TypeTraits 00229 { 00230 public: 00231 TTQ_ALIAS(Volatile) 00232 TTQ_ALIAS(Pointer) 00233 TTQ_ALIAS(Reference) 00234 TTQ_ALIAS(Const) 00235 TTQ_ALIAS(ConstReference) 00236 enum { isSignedInt = KTypeListContains<SignedInts, T>::value }; 00237 enum { isUnsignedInt = KTypeListContains<UnsignedInts, T>::value }; 00238 enum { isInteger = isSignedInt || isUnsignedInt }; 00239 enum { isFloat = KTypeListContains<Floats, T>::value }; 00240 enum { isBoolean = STATIC_EQUAL(T, bool) }; 00241 enum { isNumeric = isInteger || isFloat || isBoolean }; 00242 enum { isFundamental = isPointer || isNumeric }; 00243 enum { isQObject = IsParentOfChildNonStrict<QObject, T>::value }; 00244 enum { isQWidget = IsParentOfChildNonStrict<QWidget, T>::value }; 00245 typedef typename Modifiers::ReferenceType<T>::Result ReferenceType; 00246 typedef STATIC_IF(isFundamental || isReference, T, typename Modifiers::ReferenceType<const T>::Result) ParameterType; 00247 enum { isTypeList = TypeListCheck<T>::value }; 00248 typedef typename Modifiers::StripAll<T>::Result StripAll; 00249 }; 00250 00251 namespace Modifiers 00252 { 00253 TTQ_SPECIALIZATION(Pointer, T*) 00254 TTQ_SPECIALIZATION(Reference, T&) 00255 TTQ_SPECIALIZATION(Const, const T) 00256 TTQ_SPECIALIZATION(Volatile, volatile T) 00257 TTQ_SPECIALIZATION(ConstReference, const T&) 00258 } 00259 00260 template<class Types> 00261 struct StrippedList 00262 { 00263 typedef STATIC_FOREACH(Types, Modifiers::StripAll) Result; 00264 }; 00265 00266 template<class Types> 00267 struct ParameterList 00268 { 00269 typedef STATIC_FOREACH(Types, Modifiers::ParameterType) Result; 00270 }; 00271 00272 template<class Types> 00273 struct PointerList 00274 { 00275 typedef STATIC_FOREACH(Types, Modifiers::PointerType) Result; 00276 }; 00277 00278 template<class Types> 00279 struct ReferenceList 00280 { 00281 typedef STATIC_FOREACH(Types, Modifiers::ReferenceType) Result; 00282 }; 00283 00284 } 00285 00286 #undef TTQ_SPECIALIZATION 00287 #undef TTQ_DECL 00288 #undef TTQ_ALIAS 00289 00290 #undef NC 00291 00292 #endif 00293
KDE 4.6 API Reference