SimpleWindow
载入中...
搜索中...
未找到
Variant.h
1#pragma once
2
3#include "Reflection.h"
4
5namespace sw
6{
10 class Variant final : public IEqualityComparable<Variant>
11 {
12 private:
16 std::unique_ptr<DynamicObject> _obj;
17
21 DynamicObject *(*_cloner)(const DynamicObject &) = nullptr;
22
23 public:
27 Variant() = default;
28
32 template <
33 typename T,
34 typename std::enable_if<!std::is_same<Variant, typename std::decay<T>::type>::value, int>::type = 0>
35 Variant(T &&obj)
36 {
37 Reset(std::forward<T>(obj));
38 }
39
44 {
45 if (other._obj != nullptr) {
46 _obj.reset(other._cloner(*other._obj));
47 _cloner = other._cloner;
48 }
49 }
50
55 : _obj(std::move(other._obj)), _cloner(other._cloner)
56 {
57 other._cloner = nullptr;
58 }
59
65 {
66 Reset(other);
67 return *this;
68 }
69
74 {
75 Reset(std::move(other));
76 return *this;
77 }
78
83 operator bool() const noexcept
84 {
85 return _obj != nullptr;
86 }
87
93 {
94 return _obj == nullptr;
95 }
96
100 bool Equals(const Variant &other) const noexcept
101 {
102 return _obj == other._obj;
103 }
104
108 void Reset()
109 {
110 _obj.reset();
111 _cloner = nullptr;
112 }
113
118 void Reset(const Variant &other)
119 {
120 if (this == &other) {
121 return;
122 }
123
124 if (other._obj == nullptr) {
125 Reset();
126 } else {
127 _obj.reset(other._cloner(*other._obj));
128 _cloner = other._cloner;
129 }
130 }
131
135 void Reset(Variant &&other) noexcept
136 {
137 if (this != &other) {
138 _obj = std::move(other._obj);
139 _cloner = other._cloner;
140 other._cloner = nullptr;
141 }
142 }
143
149 template <typename T>
150 auto Reset(T &&obj)
151 -> typename std::enable_if<
152 !std::is_same<Variant, typename std::decay<T>::type>::value &&
153 std::is_base_of<DynamicObject, typename std::decay<T>::type>::value>::type
154 {
155 using U = typename std::decay<T>::type;
156 _obj.reset(new U(std::forward<T>(obj)));
158 }
159
165 template <typename T>
166 auto Reset(T &&obj)
167 -> typename std::enable_if<
168 !std::is_same<Variant, typename std::decay<T>::type>::value &&
169 !std::is_base_of<DynamicObject, typename std::decay<T>::type>::value>::type
170 {
171 using U = typename std::decay<T>::type;
172 _obj.reset(new BoxedObject<U>(std::forward<T>(obj)));
174 }
175
181 {
182 return _obj.get();
183 }
184
191 template <typename T>
192 bool IsType(T **pout = nullptr)
193 {
194 if (_obj == nullptr) {
195 if (pout != nullptr) {
196 *pout = nullptr;
197 }
198 return false;
199 } else {
200 return _obj->IsType<T>(pout);
201 }
202 }
203
210 template <typename T>
211 bool IsType(const T **pout = nullptr) const
212 {
213 if (_obj == nullptr) {
214 if (pout != nullptr) {
215 *pout = nullptr;
216 }
217 return false;
218 } else {
219 return _obj->IsType<T>(pout);
220 }
221 }
222
229 template <typename T>
231 {
232 ThrowBadCastIfEmpty();
233 return _obj->DynamicCast<T>();
234 }
235
242 template <typename T>
243 const T &DynamicCast() const
244 {
245 ThrowBadCastIfEmpty();
246 return _obj->DynamicCast<T>();
247 }
248
256 template <typename T>
258 {
259 ThrowBadCastIfEmpty();
260 return _obj->UnsafeCast<T>();
261 }
262
270 template <typename T>
271 const T &UnsafeCast() const
272 {
273 ThrowBadCastIfEmpty();
274 return _obj->UnsafeCast<T>();
275 }
276
277 private:
281 void ThrowBadCastIfEmpty() const
282 {
283 if (_obj == nullptr) {
284 throw std::bad_cast();
285 }
286 }
287
292 template <typename T>
293 auto ResetCloner()
294 -> typename std::enable_if<std::is_copy_constructible<T>::value && std::is_base_of<DynamicObject, T>::value>::type
295 {
296 _cloner = [](const DynamicObject &other) -> DynamicObject * {
297 return new T(other.UnsafeCast<T>());
298 };
299 }
300
305 template <typename T>
306 auto ResetCloner()
307 -> typename std::enable_if<std::is_copy_constructible<T>::value && !std::is_base_of<DynamicObject, T>::value>::type
308 {
309 _cloner = [](const DynamicObject &other) -> DynamicObject * {
310 return new BoxedObject<T>(other.UnsafeCast<BoxedObject<T>>());
311 };
312 }
313
318 template <typename T>
319 auto ResetCloner()
320 -> typename std::enable_if<!std::is_copy_constructible<T>::value>::type
321 {
322 _cloner = [](const DynamicObject &other) -> DynamicObject * {
323 throw std::runtime_error("Object is not copy constructible.");
324 };
325 }
326 };
327}
动态对象基类
Definition Reflection.h:27
相等性比较接口
Definition IComparable.h:14
值转换器接口
Definition IValueConverter.h:14
通用变体类,用于存储任意类型的对象
Definition Variant.h:11
const T & UnsafeCast() const
将Variant对象转换为指定类型的常量引用
Definition Variant.h:271
Variant(T &&obj)
通用构造函数,接受任意类型的对象
Definition Variant.h:35
DynamicObject * Object() const noexcept
获取内部动态对象指针
Definition Variant.h:180
void Reset(Variant &&other) noexcept
重置Variant对象为另一个Variant对象的值
Definition Variant.h:135
bool IsType(T **pout=nullptr)
判断当前Variant存储的对象是否为指定类型
Definition Variant.h:192
bool Equals(const Variant &other) const noexcept
判断两Variant是否为同一对象
Definition Variant.h:100
Variant(Variant &&other) noexcept
移动构造函数
Definition Variant.h:54
auto Reset(T &&obj) -> typename std::enable_if< !std::is_same< Variant, typename std::decay< T >::type >::value &&std::is_base_of< DynamicObject, typename std::decay< T >::type >::value >::type
重置Variant对象为指定类型的对象
Definition Variant.h:150
void Reset()
重置Variant对象为空
Definition Variant.h:108
bool IsNull() const noexcept
判断Variant对象是否为空
Definition Variant.h:92
const T & DynamicCast() const
将Variant对象动态转换为指定类型的常量引用
Definition Variant.h:243
Variant & operator=(Variant &&other) noexcept
移动构造函数
Definition Variant.h:73
Variant & operator=(const Variant &other)
拷贝构造函数
Definition Variant.h:64
T & DynamicCast()
将Variant对象动态转换为指定类型的引用
Definition Variant.h:230
Variant()=default
默认构造函数,创建一个空的Variant对象
bool IsType(const T **pout=nullptr) const
判断当前Variant存储的对象是否为指定类型
Definition Variant.h:211
auto Reset(T &&obj) -> typename std::enable_if< !std::is_same< Variant, typename std::decay< T >::type >::value &&!std::is_base_of< DynamicObject, typename std::decay< T >::type >::value >::type
重置Variant对象为指定类型的对象
Definition Variant.h:166
T & UnsafeCast()
将Variant对象转换为指定类型的引用
Definition Variant.h:257
Variant(const Variant &other)
拷贝构造函数
Definition Variant.h:43
void Reset(const Variant &other)
重置Variant对象为另一个Variant对象的值
Definition Variant.h:118