SimpleWindow
载入中...
搜索中...
未找到
Reflection.h
1#pragma once
2
3// 定义_SW_DISABLE_REFLECTION可以禁用反射相关功能
4// 若该宏被定义,则相关功能会抛出runtime_error异常
5// #define _SW_DISABLE_REFLECTION
6
7#include "Delegate.h"
8#include "IComparable.h"
9#include "IToString.h"
10#include "Property.h"
11#include <type_traits>
12#include <typeindex>
13
14namespace sw
15{
19 template <typename TFrom, typename TTo>
20 using _IsStaticCastable = _IsExplicitlyConvertable<TFrom, TTo>;
21
26 {
27 public:
31 virtual ~DynamicObject() = default;
32
37 std::type_index GetTypeIndex() const
38 {
39#if defined(_SW_DISABLE_REFLECTION)
40 throw std::runtime_error("Reflection is disabled, cannot get type index.");
41#else
42 return typeid(*this);
43#endif
44 }
45
52 template <typename T>
53 bool IsType(T **pout = nullptr)
54 {
55#if defined(_SW_DISABLE_REFLECTION)
56 throw std::runtime_error("Reflection is disabled, cannot check type.");
57#else
58 if (pout == nullptr) {
59 return dynamic_cast<T *>(this) != nullptr;
60 } else {
61 *pout = dynamic_cast<T *>(this);
62 return *pout != nullptr;
63 }
64#endif
65 }
66
73 template <typename T>
74 bool IsType(const T **pout = nullptr) const
75 {
76#if defined(_SW_DISABLE_REFLECTION)
77 throw std::runtime_error("Reflection is disabled, cannot check type.");
78#else
79 if (pout == nullptr) {
80 return dynamic_cast<const T *>(this) != nullptr;
81 } else {
82 *pout = dynamic_cast<const T *>(this);
83 return *pout != nullptr;
84 }
85#endif
86 }
87
94 template <typename T>
96 {
97#if defined(_SW_DISABLE_REFLECTION)
98 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
99#else
100 return dynamic_cast<T &>(*this);
101#endif
102 }
103
110 template <typename T>
111 const T &DynamicCast() const
112 {
113#if defined(_SW_DISABLE_REFLECTION)
114 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
115#else
116 return dynamic_cast<const T &>(*this);
117#endif
118 }
119
126 template <typename T>
128 -> typename std::enable_if<_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
129 {
130 return static_cast<T &>(*this);
131 }
132
139 template <typename T>
141 -> typename std::enable_if<!_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
142 {
143 return DynamicCast<T>();
144 }
145
152 template <typename T>
153 auto UnsafeCast() const
154 -> typename std::enable_if<_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
155 {
156 return static_cast<const T &>(*this);
157 }
158
165 template <typename T>
166 auto UnsafeCast() const
167 -> typename std::enable_if<!_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
168 {
169 return DynamicCast<T>();
170 }
171 };
172
176 struct FieldId : public IToString<FieldId>,
177 public IComparable<FieldId, FieldId> {
181 uint32_t value;
182
186 FieldId() = default;
187
191 FieldId(uint32_t value)
192 : value(value)
193 {
194 }
195
199 std::wstring ToString() const
200 {
201 return std::to_wstring(value);
202 }
203
208 int CompareTo(FieldId other) const
209 {
210 if (value == other.value) {
211 return 0;
212 } else {
213 return value < other.value ? -1 : 1;
214 }
215 }
216 };
217
222 {
223 public:
227 Reflection() = delete;
228
236 template <typename T, typename TField>
237 static FieldId GetFieldId(TField T::*field) noexcept
238 {
239 auto pfunc = &Reflection::GetFieldId<T, TField>;
240
241 uint8_t buffer[sizeof(pfunc) + sizeof(field)];
242 memcpy(buffer, &pfunc, sizeof(pfunc));
243 memcpy(buffer + sizeof(pfunc), &field, sizeof(field));
244
245 uint32_t prime = 16777619u;
246 uint32_t hash = 2166136261u;
247
248 for (size_t i = 0; i < sizeof(buffer); ++i) {
249 hash ^= static_cast<uint32_t>(buffer[i]);
250 hash *= prime;
251 }
252
253 return FieldId{hash};
254 }
255
264 template <typename T, typename TRet, typename... Args>
265 static auto GetMethod(TRet (T::*method)(Args...))
266 -> typename std::enable_if<
267 std::is_base_of<DynamicObject, T>::value, Delegate<TRet(DynamicObject &, Args...)>>::type
268 {
269 return [method](DynamicObject &obj, Args... args) -> TRet {
270 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
271 };
272 }
273
282 template <typename T, typename TRet, typename... Args>
283 static auto GetMethod(TRet (T::*method)(Args...) const)
284 -> typename std::enable_if<
285 std::is_base_of<DynamicObject, T>::value, Delegate<TRet(DynamicObject &, Args...)>>::type
286 {
287 return [method](DynamicObject &obj, Args... args) -> TRet {
288 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
289 };
290 }
291
299 template <typename T, typename TField>
300 static auto GetFieldAccessor(TField T::*field)
301 -> typename std::enable_if<
302 std::is_base_of<DynamicObject, T>::value, Delegate<TField &(DynamicObject &)>>::type
303 {
304 return [field](DynamicObject &obj) -> TField & {
305 return obj.UnsafeCast<T>().*field;
306 };
307 }
308
317 template <typename T, typename TProperty>
318 static auto GetPropertyGetter(TProperty T::*prop)
319 -> typename std::enable_if<
320 std::is_base_of<DynamicObject, T>::value && _IsReadableProperty<TProperty>::value,
321 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
322 {
323 return [prop](DynamicObject &obj) -> typename TProperty::TValue {
324 return (obj.UnsafeCast<T>().*prop).Get();
325 };
326 }
327
336 template <typename T, typename TProperty>
337 static auto GetPropertyGetter(TProperty T::*prop)
338 -> typename std::enable_if<
339 std::is_base_of<DynamicObject, T>::value && !_IsReadableProperty<TProperty>::value,
340 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
341 {
342 return nullptr;
343 }
344
353 template <typename T, typename TProperty>
354 static auto GetPropertySetter(TProperty T::*prop)
355 -> typename std::enable_if<
356 std::is_base_of<DynamicObject, T>::value && _IsWritableProperty<TProperty>::value,
357 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
358 {
359 return [prop](DynamicObject &obj, typename TProperty::TSetterParam value) {
360 (obj.UnsafeCast<T>().*prop).Set(std::forward<typename TProperty::TSetterParam>(value));
361 };
362 }
363
372 template <typename T, typename TProperty>
373 static auto GetPropertySetter(TProperty T::*prop)
374 -> typename std::enable_if<
375 std::is_base_of<DynamicObject, T>::value && !_IsWritableProperty<TProperty>::value,
376 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
377 {
378 return nullptr;
379 }
380 };
381}
382
383// 为sw::FieldId特化std::hash
384template <>
385struct std::hash<sw::FieldId> //
386{
387 size_t operator()(sw::FieldId fieldId) const noexcept
388 {
389 return static_cast<size_t>(fieldId.value);
390 }
391};
Definition Delegate.h:21
动态对象基类
Definition Reflection.h:26
auto UnsafeCast() -> typename std::enable_if<!_IsStaticCastable< DynamicObject *, T * >::value, T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:140
virtual ~DynamicObject()=default
析构函数
auto UnsafeCast() const -> typename std::enable_if< _IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:153
T & DynamicCast()
将对象动态转换为指定类型的引用
Definition Reflection.h:95
bool IsType(const T **pout=nullptr) const
判断对象是否为指定类型
Definition Reflection.h:74
auto UnsafeCast() -> typename std::enable_if< _IsStaticCastable< DynamicObject *, T * >::value, T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:127
auto UnsafeCast() const -> typename std::enable_if<!_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:166
const T & DynamicCast() const
将对象动态转换为指定类型的常量引用
Definition Reflection.h:111
bool IsType(T **pout=nullptr)
判断对象是否为指定类型
Definition Reflection.h:53
std::type_index GetTypeIndex() const
获取对象的类型索引
Definition Reflection.h:37
全序比较接口
Definition IComparable.h:54
为支持ToString方法的类提供统一接口
Definition IToString.h:13
提供反射相关功能
Definition Reflection.h:222
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:337
static auto GetMethod(TRet(T::*method)(Args...) const) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, Delegate< TRet(DynamicObject &, Args...)> >::type
获取常量成员函数的委托
Definition Reflection.h:283
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:373
static auto GetMethod(TRet(T::*method)(Args...)) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, Delegate< TRet(DynamicObject &, Args...)> >::type
获取成员函数的委托
Definition Reflection.h:265
static auto GetFieldAccessor(TField T::*field) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, Delegate< TField &(DynamicObject &)> >::type
获取字段的访问器
Definition Reflection.h:300
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:237
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:354
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:318
Reflection()=delete
静态类,不允许实例化
表示字段的唯一标识符
Definition Reflection.h:177
std::wstring ToString() const
获取字段ID的字符串表示形式
Definition Reflection.h:199
int CompareTo(FieldId other) const
比较字段ID
Definition Reflection.h:208
uint32_t value
字段ID的数值
Definition Reflection.h:181
FieldId()=default
默认构造函数
FieldId(uint32_t value)
构造指定值的字段ID
Definition Reflection.h:191
判断类型是否可以显式转换的辅助模板
Definition Property.h:163
判断类型是否为可读属性的辅助模板
Definition Property.h:132
判断类型是否为可写属性的辅助模板
Definition Property.h:140