YSTest: yobject.h 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
yobject.h
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2009 - 2013.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YSL_INC_Core_yobject_h_
29 #define YSL_INC_Core_yobject_h_ 1
30
31 #include "ycutil.h"
32 #include "yexcept.h"
33 #include "../Adaptor/ycont.h"
34 #include <ystdex/any.h> // for ystdex::any_holder, ystdex::any;
35 #include <ystdex/examiner.hpp> // for ystdex::equal_examiner;
36
37 YSL_BEGIN
38
39 //特征类策略：对象类型标签模板。
40
45 template<typename>
46 struct OwnershipTag
47 {};
48
49
54 struct MoveTag
55 {};
56
57
62 struct PointerTag
63 {};
64
65
70 template<class _tOwner, typename _type>
71 struct HasOwnershipOf : public std::integral_constant<bool,
72 std::is_base_of<OwnershipTag<_type>, _tOwner>::value>
73 {};
74
75
81 DeclDerivedI(YF_API, IValueHolder, ystdex::any_ops::holder)
83
84 DefDeCtor(IValueHolder)
85 DefDeCopyCtor(IValueHolder)
86 DefDeMoveCtor(IValueHolder)
88
89 DeclIEntry(bool operator==(const IValueHolder&) const)
90 EndDecl
91
92
99 template<typename _type>
100 class ValueHolder : implements IValueHolder
101 {
102 static_assert(std::is_object<_type>::value, "Non-object type found.");
103 static_assert(!(std::is_const<_type>::value
104 || std::is_volatile<_type>::value), "Cv-qualified type found.");
105
106 public:
108 typedef _type value_type;
109
110 protected:
112 mutable _type held;
113
114 public:
115 ValueHolder(const _type& value)
116 : held(value)
117 {}
119 ValueHolder(_type&& value)
120 : held(std::move(value))
121 {}
122 DefDeCopyCtor(ValueHolder)
123 DefDeMoveCtor(ValueHolder)
124
126 DefDeCopyAssignment(ValueHolder)
127
128 ImplI(IValueHolder) bool
129 operator==(const IValueHolder& obj) const override
130 {
131 return ystdex::examiners::equal_examiner::are_equal(held,
132 static_cast<const ValueHolder&>(obj).held);
133 }
134
135 ImplI(IValueHolder) DefClone(const override, ValueHolder, clone)
136
138 ImplI(IValueHolder) void*
139 get() const override
140 {
141 return std::addressof(held);
142 }
143
145 ImplI(IValueHolder) const std::type_info&
146 type() const ynothrow override
147 {
148 return typeid(_type);
149 }
150 };
151
152
159 template<typename _type>
160 class PointerHolder : implements IValueHolder
161 {
162 static_assert(std::is_object<_type>::value, "Invalid type found.");
163
164 public:
166 typedef _type value_type;
167
168 protected:
169 _type* p_held;
170
171 public:
173 PointerHolder(_type* value)
174 : p_held(value)
175 {}
177
178 PointerHolder(const PointerHolder& h)
179 : PointerHolder(h.p_held ? new _type(*h.p_held) : nullptr)
180 {}
181 PointerHolder(PointerHolder&& h)
182 : p_held(h.p_held)
183 {
184 h.p_held = nullptr;
185 }
187 virtual
188 ~PointerHolder() ynothrow
189 {
190 // TODO: Provide other deleters.
191 delete p_held;
192 }
193
195 DefDeCopyAssignment(PointerHolder)
196
197 ImplI(IValueHolder) bool
198 operator==(const IValueHolder& obj) const
199 {
200 return ystdex::examiners::equal_examiner::are_equal(*p_held,
201 *static_cast<const PointerHolder&>(obj).p_held);
202 }
203
204 ImplI(IValueHolder) DefClone(const override, PointerHolder, clone)
205
207 ImplI(IValueHolder) void*
208 get() const override
209 {
210 return p_held;
211 }
212
214 ImplI(IValueHolder) const std::type_info&
215 type() const ynothrow override
216 {
217 return p_held ? typeid(_type) : typeid(void);
218 }
219 };
220
221
231 class YF_API ValueObject
232 {
233 public:
235 ystdex::any content;
236
237 public:
243 DefDeCtor(ValueObject)
249 template<typename _type, typename = typename
250 std::enable_if<!std::is_same<_type&, ValueObject&>::value, int>::type>
251 ValueObject(_type&& obj)
252 : content(ystdex::any_ops::holder_tag(), make_unique<ValueHolder<
253 typename ystdex::remove_rcv<_type>::type>>(yforward(obj)))
254 {}
261 template<typename _type>
262 ValueObject(_type* p, PointerTag)
263 : content(ystdex::any_ops::holder_tag(), make_unique<PointerHolder<
264 _type>>(p))
265 {}
270 DefDeCopyCtor(ValueObject)
275 DefDeMoveCtor(ValueObject)
280 DefDeDtor(ValueObject)
281
283
284 DefDeCopyAssignment(ValueObject)
285 DefDeMoveAssignment(ValueObject)
287
292 PDefHOp(bool, !, ) const ynothrow
293 ImplRet(!content)
294
295 bool
296 operator==(const ValueObject&) const;
297
302 explicit DefCvt(const ynothrow, bool, content.get_holder())
303
304 private:
311 template<typename _type>
312 inline _type&
313 GetMutableObject() const
314 {
315 YAssert(bool(content), "Null pointer found.");
316 YAssert(content.type() == typeid(_type), "Invalid type found.");
317
318 return *static_cast<_type*>(content.get());
319 }
320
321 public:
322 template<typename _type>
323 inline _type&
324 GetObject()
325 {
326 return GetMutableObject<_type>();
327 }
328 template<typename _type>
329 inline const _type&
330 GetObject() const
331 {
332 return GetMutableObject<_type>();
333 }
335 DefGetter(const ynothrow, const std::type_info&, Type, content.type())
336
343 template<typename _type>
344 inline _type&
345 Access()
346 {
347 return ystdex::any_cast<_type&>(content);
348 }
349 template<typename _type>
350 inline const _type&
351 Access() const
352 {
353 return ystdex::any_cast<const _type&>(content);
354 }
356
362 template<typename _type>
363 inline _type*
364 AccessPtr() ynothrow
365 {
366 return ystdex::any_cast<_type*>(&content);
367 }
368 template<typename _type>
369 inline const _type*
370 AccessPtr() const ynothrow
371 {
372 return ystdex::any_cast<const _type*>(&content);
373 }
375
376 /*
377 \brief 清除。
378 \post <tt>*this == ValueObject()</tt> 。
379 \since build 296
380 */
381 PDefH(void, Clear, ) ynothrow
382 ImplBodyMem(content, clear, )
383
388 PDefH(void, Swap, ValueObject& vo) ynothrow
389 ImplBodyMem(content, swap, vo.content)
390 };
391
397 template<typename _type>
398 inline ValueObject
399 MakeValueObjectByPtr(_type* p)
400 {
401 return ValueObject(p, PointerTag());
402 }
403
404
416 template<typename _type, class _tOwnerPointer = shared_ptr<_type>>
417 class GDependency
418 {
419 public:
420 typedef _type DependentType;
421 typedef _tOwnerPointer PointerType;
422 typedef decltype(*PointerType()) ConstReferenceType;
423 typedef typename std::remove_const<typename std::remove_reference<
424 ConstReferenceType>::type>::type ReferentType;
425 typedef ReferentType& ReferenceType;
426
427 private:
428 PointerType ptr;
429
430 public:
431 inline
432 GDependency(PointerType p = PointerType())
433 : ptr(p)
434 {
435 GetCopyOnWritePtr();
436 }
437
438 DefDeCopyAssignment(GDependency)
439 DefDeMoveAssignment(GDependency)
440
441 DefCvt(const ynothrow, ConstReferenceType, *ptr)
442 DefCvt(ynothrow, ReferenceType, *ptr)
443 DefCvt(const ynothrow, bool, bool(ptr))
444
445 DefGetter(const ynothrow, ConstReferenceType, Ref,
446 operator ConstReferenceType())
447 DefGetter(ynothrow, ReferenceType, Ref, operator ReferenceType())
448 DefGetter(ynothrow, ReferenceType, NewRef, *GetCopyOnWritePtr())
449
450 PointerType
451 GetCopyOnWritePtr()
452 {
453 if(!ptr)
454 ptr = PointerType(new DependentType());
455 else if(!ptr.unique())
456 ptr = PointerType(CloneNonpolymorphic(ptr));
457
458 YAssert(bool(ptr), "Null pointer found.");
459
460 return ptr;
461 }
462
463 inline
464 void Reset()
465 {
466 reset(ptr);
467 }
468 };
469
470
476 template<typename _type>
477 class GMRange
478 {
479 public:
480 typedef _type ValueType;
481
482 protected:
483 ValueType max_value;
484 ValueType value;
485
489 GMRange(ValueType m, ValueType v)
490 : max_value(m), value(v)
491 {}
492
493 public:
494 DefGetter(const ynothrow, ValueType, MaxValue, max_value)
495 DefGetter(const ynothrow, ValueType, Value, value)
496 };
497
498 YSL_END
499
500 #endif
501