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 #pragma once
00019
00020 #ifndef __OpenKarto_MetaType_h__
00021 #define __OpenKarto_MetaType_h__
00022
00023 #include <OpenKarto/Types.h>
00024
00025 namespace karto
00026 {
00027
00029
00030
00031
00032
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template <bool B, class T = void>
00051 struct enable_if_c
00052 {
00053 typedef T type;
00054 };
00055
00056 template <class T>
00057 struct enable_if_c<false, T>
00058 {
00059 };
00060
00061 template <class Cond, class T = void>
00062 struct enable_if : public enable_if_c<Cond::value, T>
00063 {
00064 };
00065
00066 template <bool B, class T>
00067 struct lazy_enable_if_c
00068 {
00069 typedef typename T::type type;
00070 };
00071
00072 template <class T>
00073 struct lazy_enable_if_c<false, T>
00074 {
00075 };
00076
00077 template <class Cond, class T>
00078 struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T>
00079 {
00080 };
00081
00082 template <bool B, class T = void>
00083 struct disable_if_c
00084 {
00085 typedef T type;
00086 };
00087
00088 template <class T>
00089 struct disable_if_c<true, T>
00090 {
00091 };
00092
00093 template <class Cond, class T = void>
00094 struct disable_if : public disable_if_c<Cond::value, T>
00095 {
00096 };
00097
00098 template <bool B, class T>
00099 struct lazy_disable_if_c
00100 {
00101 typedef typename T::type type;
00102 };
00103
00104 template <class T>
00105 struct lazy_disable_if_c<true, T>
00106 {
00107 };
00108
00109 template <class Cond, class T>
00110 struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T>
00111 {
00112 };
00113
00117
00118
00119 template<class T>
00120 struct remove_reference
00121 {
00122 typedef T Type;
00123 };
00124
00125
00126 template<class T>
00127 struct remove_reference<T&>
00128 {
00129 typedef T Type;
00130 };
00131
00133
00134
00135
00136
00137
00138
00142
00143
00144 template <typename T>
00145 struct is_pointer
00146 {
00147 enum
00148 {
00149 value = false
00150 };
00151 };
00152
00153
00154 template <typename T>
00155 struct is_pointer<T*>
00156 {
00157 enum
00158 {
00159 value = true
00160 };
00161 };
00162
00166
00170 template <typename T>
00171 struct KartoTypeId
00172 {
00173 static const char* Get(kt_bool = true)
00174 {
00175
00176 return T::KARTO_REGISTER_ME_WITH_KARTO_TYPE();
00177 }
00178 };
00179
00183
00189 template <typename T>
00190 struct KartoType
00191 {
00192 typedef T Type;
00193 };
00194
00198 template <typename T>
00199 struct KartoType<const T>
00200 {
00201 typedef typename KartoType<T>::Type Type;
00202 };
00203
00208 template <typename T>
00209 struct KartoType<T&>
00210 {
00211 typedef typename KartoType<T>::Type Type;
00212 };
00213
00218 template <typename T>
00219 struct KartoType<T*>
00220 {
00221 typedef typename KartoType<T>::Type Type;
00222 };
00223
00227
00231 template <typename T>
00232 const char* GetKartoTypeIdTemplate()
00233 {
00234 return KartoTypeId<typename KartoType<T>::Type>::Get();
00235 }
00236
00240 template <typename T>
00241 const char* GetKartoTypeIdTemplate(const T&)
00242 {
00243 return KartoTypeId<typename KartoType<T>::Type>::Get();
00244 }
00245
00249
00254 template <typename T, typename E = void>
00255 struct KartoObjectTraits
00256 {
00257 typedef T& RefReturnType;
00258
00259 static RefReturnType Get(void* pPointer)
00260 {
00261 return *static_cast<T*>(pPointer);
00262 }
00263 };
00264
00268 template <typename T>
00269 struct KartoObjectTraits<T*>
00270 {
00271 typedef T* RefReturnType;
00272 typedef T* PointerType;
00273
00274 static RefReturnType Get(void* pPointer)
00275 {
00276 return static_cast<T*>(pPointer);
00277 }
00278
00279 static PointerType GetPointer(T* rValue)
00280 {
00281 return rValue;
00282 }
00283 };
00284
00288 template <typename T>
00289 struct KartoObjectTraits<T&, typename disable_if<is_pointer<typename KartoObjectTraits<T>::RefReturnType> >::type>
00290 {
00291 typedef T& RefReturnType;
00292 typedef T* PointerType;
00293
00294 static RefReturnType Get(void* pPointer)
00295 {
00296 return *static_cast<T*>(pPointer);
00297 }
00298
00299 static PointerType GetPointer(T& rValue)
00300 {
00301 return &rValue;
00302 }
00303 };
00304
00308 template <typename T>
00309 struct KartoObjectTraits<T&, typename enable_if< is_pointer< typename KartoObjectTraits< T >::RefReturnType > >::type > : KartoObjectTraits<T>
00310 {
00311 };
00312
00316 template <typename T>
00317 struct KartoObjectTraits<const T> : KartoObjectTraits<T>
00318 {
00319 };
00320
00324
00329 template <typename T>
00330 struct KartoTypeHasRtti
00331 {
00332 typedef kt_int16s Yes;
00333 typedef kt_int32s No;
00334
00335 template <typename U, const char* (U::*)() const>
00336 struct CheckForMember
00337 {
00338 };
00339
00340 template <typename U> static Yes HasMemberFunction(CheckForMember<U, &U::GetKartoClassId>*);
00341 template <typename U> static No HasMemberFunction(...);
00342
00343 enum
00344 {
00345 value = sizeof(HasMemberFunction<typename KartoType<T>::Type>(0)) == sizeof(Yes)
00346 };
00347 };
00348
00352
00357 template <typename T, typename E = void>
00358 struct GetKartoTypeIdTemplateRTTI
00359 {
00360 typedef KartoObjectTraits<const T&> Traits;
00361
00362 static const char* Get(const T& rObject)
00363 {
00364 typename Traits::PointerType pointer = Traits::GetPointer(rObject);
00365 return pointer ? pointer->GetKartoClassId() : GetKartoTypeIdTemplate<T>();
00366 }
00367 };
00368
00372 template <typename T>
00373 struct GetKartoTypeIdTemplateRTTI< T, typename disable_if< KartoTypeHasRtti<T> >::type >
00374 {
00375 static const char* Get(const T&)
00376 {
00377 return GetKartoTypeIdTemplate<T>();
00378 }
00379 };
00380
00384
00388 template <typename T> const char* GetTypeId()
00389 {
00390 return GetKartoTypeIdTemplate<T>();
00391 }
00392
00396 template <typename T> const char* GetTypeId(const T& rObject)
00397 {
00398 return GetKartoTypeIdTemplateRTTI<T>::Get(rObject);
00399 }
00400
00401
00402
00404
00405 }
00406
00407 #endif // __OpenKarto_MetaType_h__