00001 #ifndef TYPE_TRAITS_H
00002 #define TYPE_TRAITS_H
00003
00004 template <typename T>
00005 struct TypeTraits
00006 {
00007 private:
00008 struct NullType {};
00009 template <typename U> struct UnConst
00010 {
00011 typedef U Result;
00012 };
00013 template <typename U> struct UnConst<const U>
00014 {
00015 typedef U Result;
00016 };
00017 template <typename U> struct ReferenceTraits
00018 {
00019 enum {IsReference = 0};
00020 typedef U ReferencedType;
00021 };
00022 template <typename U> struct ReferenceTraits<U&>
00023 {
00024 enum {IsReference = 1};
00025 typedef U ReferencedType;
00026 };
00027 template <typename U> struct PointerTraits
00028 {
00029 enum {IsPointer = 0};
00030 typedef U PointeeType;
00031 };
00032 template <typename U> struct PointerTraits<U *>
00033 {
00034 enum {IsPointer = 1};
00035 typedef U PointeeType;
00036 };
00037 template <typename U> struct FunctionPtrTraits
00038 {
00039 enum {IsFunctionPointer = 0};
00040 };
00041 template <typename U>
00042 struct FunctionPtrTraits <U (*) (void)>
00043 {
00044 enum {IsFunctionPointer = 1};
00045 enum {nArgs = 0};
00046 typedef U ReturnType;
00047 };
00048 template <typename U, typename V1>
00049 struct FunctionPtrTraits <U (*) (V1)>
00050 {
00051 enum {IsFunctionPointer = 1};
00052 enum {nArgs = 1};
00053 typedef U ReturnType;
00054 typedef V1 Arg1Type;
00055 };
00056 template <typename U, typename V1, typename V2>
00057 struct FunctionPtrTraits <U (*) (V1,V2)>
00058 {
00059 enum {IsFunctionPointer = 1};
00060 enum {nArgs = 2};
00061 typedef U ReturnType;
00062 typedef V1 Arg1Type;
00063 typedef V2 Arg2Type;
00064 };
00065 template <typename U, typename V1, typename V2,
00066 typename V3>
00067 struct FunctionPtrTraits <U (*) (V1,V2,V3)>
00068 {
00069 enum {IsFunctionPointer = 1};
00070 enum {nArgs = 3};
00071 typedef U ReturnType;
00072 typedef V1 Arg1Type;
00073 typedef V2 Arg2Type;
00074 typedef V3 Arg3Type;
00075 };
00076 template <typename U, typename V1, typename V2,
00077 typename V3, typename V4>
00078 struct FunctionPtrTraits <U (*) (V1,V2,V3,V4)>
00079 {
00080 enum {IsFunctionPointer = 1};
00081 enum {nArgs = 4};
00082 typedef U ReturnType;
00083 typedef V1 Arg1Type;
00084 typedef V2 Arg2Type;
00085 typedef V3 Arg3Type;
00086 typedef V4 Arg4Type;
00087 };
00088 template <typename U, typename V1, typename V2,
00089 typename V3, typename V4,
00090 typename V5>
00091 struct FunctionPtrTraits <U (*) (V1,V2,V3,V4,V5)>
00092 {
00093 enum {IsFunctionPointer = 1};
00094 enum {nArgs = 5};
00095 typedef U ReturnType;
00096 typedef V1 Arg1Type;
00097 typedef V2 Arg2Type;
00098 typedef V3 Arg3Type;
00099 typedef V4 Arg4Type;
00100 typedef V5 Arg5Type;
00101 };
00102 template <typename U, typename V1, typename V2,
00103 typename V3, typename V4,
00104 typename V5, typename V6>
00105 struct FunctionPtrTraits <U (*) (V1,V2,V3,V4,V5,V6)>
00106 {
00107 enum {IsFunctionPointer = 1};
00108 enum {nArgs = 6};
00109 typedef U ReturnType;
00110 typedef V1 Arg1Type;
00111 typedef V2 Arg2Type;
00112 typedef V3 Arg3Type;
00113 typedef V4 Arg4Type;
00114 typedef V5 Arg5Type;
00115 typedef V6 Arg6Type;
00116 };
00117 template <typename U> struct PtrToMemberTraits
00118 {
00119 enum {IsPointerToMember = 0};
00120 };
00121 template <typename U, typename V>
00122 struct PtrToMemberTraits <U (V::*) (void)>
00123 {
00124 enum {IsPointerToMember = 1};
00125 enum {nArgs = 0};
00126 typedef U ReturnType;
00127 };
00128 template <typename U, typename V>
00129 struct PtrToMemberTraits <U (V::*) (void) const>
00130 {
00131 enum {IsPointerToMember = 1};
00132 enum {nArgs = 0};
00133 typedef U ReturnType;
00134 };
00135 template <typename U, typename V,typename W1>
00136 struct PtrToMemberTraits <U (V::*) (W1)>
00137 {
00138 enum {IsPointerToMember = 1};
00139 enum {nArgs = 1};
00140 typedef U ReturnType;
00141 typedef W1 Arg1Type;
00142 };
00143 template <typename U, typename V,typename W1>
00144 struct PtrToMemberTraits <U (V::*) (W1) const>
00145 {
00146 enum {IsPointerToMember = 1};
00147 enum {nArgs = 1};
00148 typedef U ReturnType;
00149 typedef W1 Arg1Type;
00150 };
00151 template <typename U, typename V,typename W1, typename W2>
00152 struct PtrToMemberTraits <U (V::*) (W1,W2)>
00153 {
00154 enum {IsPointerToMember = 1};
00155 enum {nArgs = 2};
00156 typedef U ReturnType;
00157 typedef W1 Arg1Type;
00158 typedef W2 Arg2Type;
00159 };
00160 template <typename U, typename V,typename W1, typename W2>
00161 struct PtrToMemberTraits <U (V::*) (W1,W2) const>
00162 {
00163 enum {IsPointerToMember = 1};
00164 enum {nArgs = 2};
00165 typedef U ReturnType;
00166 typedef W1 Arg1Type;
00167 typedef W2 Arg2Type;
00168 };
00169 template <typename U, typename V,
00170 typename W1, typename W2,
00171 typename W3>
00172 struct PtrToMemberTraits <U (V::*) (W1,W2,W3)>
00173 {
00174 enum {IsPointerToMember = 1};
00175 enum {nArgs = 3};
00176 typedef U ReturnType;
00177 typedef W1 Arg1Type;
00178 typedef W2 Arg2Type;
00179 typedef W3 Arg3Type;
00180 };
00181 template <typename U, typename V,
00182 typename W1, typename W2,
00183 typename W3>
00184 struct PtrToMemberTraits <U (V::*) (W1,W2,W3) const>
00185 {
00186 enum {IsPointerToMember = 1};
00187 enum {nArgs = 3};
00188 typedef U ReturnType;
00189 typedef W1 Arg1Type;
00190 typedef W2 Arg2Type;
00191 typedef W3 Arg3Type;
00192 };
00193 template <typename U, typename V,
00194 typename W1, typename W2,
00195 typename W3, typename W4>
00196 struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4)>
00197 {
00198 enum {IsPointerToMember = 1};
00199 enum {nArgs = 4};
00200 typedef U ReturnType;
00201 typedef W1 Arg1Type;
00202 typedef W2 Arg2Type;
00203 typedef W3 Arg3Type;
00204 typedef W4 Arg4Type;
00205 };
00206 template <typename U, typename V,
00207 typename W1, typename W2,
00208 typename W3, typename W4>
00209 struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4) const>
00210 {
00211 enum {IsPointerToMember = 1};
00212 enum {nArgs = 4};
00213 typedef U ReturnType;
00214 typedef W1 Arg1Type;
00215 typedef W2 Arg2Type;
00216 typedef W3 Arg3Type;
00217 typedef W4 Arg4Type;
00218 };
00219 template <typename U, typename V,
00220 typename W1, typename W2,
00221 typename W3, typename W4,
00222 typename W5>
00223 struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5)>
00224 {
00225 enum {IsPointerToMember = 1};
00226 enum {nArgs = 5};
00227 typedef U ReturnType;
00228 typedef W1 Arg1Type;
00229 typedef W2 Arg2Type;
00230 typedef W3 Arg3Type;
00231 typedef W4 Arg4Type;
00232 typedef W5 Arg5Type;
00233 };
00234 template <typename U, typename V,
00235 typename W1, typename W2,
00236 typename W3, typename W4,
00237 typename W5>
00238 struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5) const>
00239 {
00240 enum {IsPointerToMember = 1};
00241 enum {nArgs = 5};
00242 typedef U ReturnType;
00243 typedef W1 Arg1Type;
00244 typedef W2 Arg2Type;
00245 typedef W3 Arg3Type;
00246 typedef W4 Arg4Type;
00247 typedef W5 Arg5Type;
00248 };
00249 template <typename U, typename V,
00250 typename W1, typename W2,
00251 typename W3, typename W4,
00252 typename W5, typename W6>
00253 struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5,W6)>
00254 {
00255 enum {IsPointerToMember = 1};
00256 enum {nArgs = 6};
00257 typedef U ReturnType;
00258 typedef W1 Arg1Type;
00259 typedef W2 Arg2Type;
00260 typedef W3 Arg3Type;
00261 typedef W4 Arg4Type;
00262 typedef W5 Arg5Type;
00263 typedef W6 Arg6Type;
00264 };
00265 template <typename U, typename V,
00266 typename W1, typename W2,
00267 typename W3, typename W4,
00268 typename W5, typename W6>
00269 struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5,W6) const>
00270 {
00271 enum {IsPointerToMember = 1};
00272 enum {nArgs = 6};
00273 typedef U ReturnType;
00274 typedef W1 Arg1Type;
00275 typedef W2 Arg2Type;
00276 typedef W3 Arg3Type;
00277 typedef W4 Arg4Type;
00278 typedef W5 Arg5Type;
00279 typedef W6 Arg6Type;
00280 };
00281
00282 public:
00283 typedef typename UnConst<T>::Result NonConstType;
00284 typedef typename ReferenceTraits<T>::ReferencedType ReferencedType;
00285 typedef typename PointerTraits<T>::PointeeType PointeeType;
00286 enum {IsPointerToMember = PtrToMemberTraits<T>::IsPointerToMember};
00287 enum {IsPointer = PointerTraits<T>::IsPointer};
00288 enum {IsReference = ReferenceTraits<T>::IsReference};
00289 enum {IsFunctionPointer = FunctionPtrTraits<T>::IsFunctionPointer};
00290 typedef PtrToMemberTraits<T> PointerToMemberTraits;
00291 typedef FunctionPtrTraits<T> FunctionPointerTraits;
00292 };
00293
00294
00295 #endif