Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __PLCORE_TYPETRAITS_H__
00024 #define __PLCORE_TYPETRAITS_H__
00025 #pragma once
00026
00027
00028
00029
00030
00031 #include "PLCore/Base/Type/EnumType.h"
00032 #include "PLCore/Base/Tools/CompileError.h"
00033
00034
00035
00036
00037
00038 namespace PLCore {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 class NullType {
00049 };
00050
00051
00052
00053
00054
00055 template <typename T>
00056 class InvalidType {
00057 };
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 class TrueType {
00068 };
00069
00070
00071
00072
00073
00074 class FalseType {
00075 };
00076
00077
00078
00079
00080
00081 struct ConversionHelper
00082 {
00083 template <typename T> ConversionHelper(const volatile T&);
00084 template <typename T> ConversionHelper(T&);
00085 };
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 template <typename T1, typename T2, template <typename T> class TMPL, typename TYPE>
00106 class SpecializeIfEqual {
00107 public:
00108 typedef FalseType Type;
00109 };
00110
00111
00112 template <typename T1, template <typename T> class TMPL, typename TYPE>
00113 class SpecializeIfEqual<T1, T1, TMPL, TYPE> {
00114 public:
00115 typedef TMPL<TYPE> Type;
00116 };
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 template <bool CHECK, typename TYPE, typename REST>
00131 struct ChooseType {
00132 };
00133
00134
00135 template <typename TYPE, typename REST>
00136 struct ChooseType<true, TYPE, REST> {
00137 typedef TYPE Type;
00138 };
00139
00140
00141 template <typename TYPE, typename REST>
00142 struct ChooseType<false, TYPE, REST> {
00143 typedef typename REST::Type Type;
00144 };
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 template <typename T1, typename T2>
00159 struct BooleanOr {
00160 static const bool Value = (T1::Value || T2::Value);
00161 };
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 template <typename T1, typename T2>
00176 struct BooleanAnd {
00177 static const bool Value = (T1::Value && T2::Value);
00178 };
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 template <typename T>
00191 struct BooleanNot {
00192 static const bool Value = (!T::Value);
00193 };
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 template <typename T>
00212 class IntegralType {
00213 public:
00214 enum { IsIntegral = 0 };
00215 typedef NullType Type;
00216 };
00217
00218 template <>
00219 class IntegralType<uint8> {
00220 public:
00221 enum { IsIntegral = 1 };
00222 typedef uint8 Type;
00223 };
00224
00225 template <>
00226 class IntegralType<uint16> {
00227 public:
00228 enum { IsIntegral = 1 };
00229 typedef uint16 Type;
00230 };
00231
00232 template <>
00233 class IntegralType<uint32> {
00234 public:
00235 enum { IsIntegral = 1 };
00236 typedef uint32 Type;
00237 };
00238
00239 template <>
00240 class IntegralType<int8> {
00241 public:
00242 enum { IsIntegral = 1 };
00243 typedef int8 Type;
00244 };
00245
00246 template <>
00247 class IntegralType<int16> {
00248 public:
00249 enum { IsIntegral = 1 };
00250 typedef int16 Type;
00251 };
00252
00253 template <>
00254 class IntegralType<int32> {
00255 public:
00256 enum { IsIntegral = 1 };
00257 typedef int32 Type;
00258 };
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 template<typename T1, typename T2>
00274 struct IsEqual
00275 {
00276 static const bool Value = false;
00277 };
00278
00279
00280 template<typename T>
00281 struct IsEqual<T, T>
00282 {
00283 static const bool Value = true;
00284 };
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 template<typename From, typename To>
00300 struct IsConvertible
00301 {
00302 private:
00303 typedef char one_byte;
00304 typedef struct { char two_chars[2]; } two_bytes;
00305
00306 private:
00307 static one_byte test(const To&, int);
00308 static two_bytes test(ConversionHelper, ...);
00309
00310 public:
00311 static const bool Value = sizeof(test(*(static_cast<From*>(nullptr)), 0)) == 1;
00312
00313
00314 };
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 template<typename Class, typename Base>
00329 struct IsBaseClass
00330 {
00331 static const bool Value = BooleanAnd< IsConvertible<Class, Base>, BooleanNot< IsEqual<Class, Base> > >::Value;
00332 };
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 template<typename T>
00345 struct IsEnum
00346 {
00347 static const bool Value = IsConvertible<T, int>::Value;
00348 };
00349
00350 template<typename T>
00351 struct IsEnum< InvalidType<T> >
00352 {
00353 static const bool Value = false;
00354 };
00355
00356
00357
00358
00359
00360
00361
00362
00363 template <typename T>
00364 struct TypeClassification {
00365 static const bool Value = IsEnum<T>::Value;
00366 };
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 template <typename T>
00381 struct CheckType {
00382 typedef typename ChooseType< TypeClassification<T>::Value, PLCore::EnumTypePlain<T>,
00383 ChooseType< true, InvalidType<T>, InvalidType<T> >
00384 >::Type Type;
00385 };
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 template <bool Condition, typename Class, typename Base>
00401 struct CheckBaseClassBool {
00402
00403 static void Error() {
00404 }
00405 };
00406
00407
00408 template <typename Class, typename Base>
00409 struct CheckBaseClassBool<false, Class, Base> {
00410
00411 static void Error() {
00412 PLCORE_ERROR(Not_A_Base_Class)
00413 }
00414 };
00415
00416
00417 template <typename Class, typename Base>
00418 struct CheckBaseClass {
00419 typedef CheckBaseClassBool< IsBaseClass<Class, Base>::Value, Class, Base > Type;
00420 };
00421
00422
00423
00424
00425
00426 }
00427
00428
00429 #endif // __PLCORE_TYPETRAITS_H__