YSTest: type_pun.hpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

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

- 文件列表
- 文件成员

type_pun.hpp
浏览该文件的文档.
1 /*
2 © 2014-2016 FrankHB.
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 YB_INC_ystdex_type_pun_hpp_
29 #define YB_INC_ystdex_type_pun_hpp_ 1
30
31 #include "placement.hpp" // for "placement.hpp", bool_, yalignof,
32 // and_, is_trivial, enable_if_t, is_object_pointer, remove_pointer_t,
33 // is_object, aligned_storage_t, is_reference, remove_reference_t,
34 // exclude_self_t, decay_t;
35 #include <new> // for placement ::operator new from standard library;
36
37 namespace ystdex
38 {
39
51 template<typename _type, typename _type2>
52 struct is_aligned_compatible : bool_<!(yalignof(_type) < yalignof(_type2))
53 && yalignof(_type) % yalignof(_type2) == 0>
54 {};
55
56
61 template<typename _type, typename _tDst>
62 struct is_aligned_placeable : bool_<sizeof(_type) == sizeof(_tDst)
63 && is_aligned_compatible<_type, _tDst>::value>
64 {};
65
66
71 template<typename _type, typename _tDst>
72 struct is_aligned_storable : bool_<!(sizeof(_type) < sizeof(_tDst))
73 && is_aligned_compatible<_type, _tDst>::value>
74 {};
75
76
81 template<typename _type, typename _tDst>
82 struct is_aligned_replaceable : and_<is_aligned_storable<_type, _tDst>,
83 is_aligned_storable<_tDst, _type>>
84 {};
85
86
91 template<typename _type, typename _tDst>
92 struct is_trivially_replaceable : and_<is_trivial<_type>, is_trivial<_tDst>,
93 is_aligned_replaceable<_type, _tDst>>
94 {};
96
97
99
100
104 template<typename _tSrc, typename _tDst, typename _type = void>
105 using enable_if_replaceable_t
106 = enable_if_t<is_trivially_replaceable<_tSrc, _tDst>::value, _type>;
107
108
113 template<typename _type, size_t _vAlign = yalignof(_type)>
114 using pun_storage_t = aligned_storage_t<sizeof(_type), _vAlign>;
115
116
128 template<typename _pDst, typename _tSrc>
129 inline yimpl(ystdex::enable_if_t)<and_<is_object_pointer<_pDst>,
130 is_aligned_compatible<_tSrc, remove_pointer_t<_pDst>>>::value, _pDst>
131 aligned_cast(_tSrc* v) ynothrow
132 {
133 return reinterpret_cast<_pDst>(v);
134 }
135 template<typename _rDst, typename _tSrc, yimpl(typename = ystdex::enable_if_t<
136 and_<is_reference<_rDst>, is_aligned_compatible<remove_reference_t<_tSrc>,
137 remove_reference_t<_rDst>>>::value>)>
138 inline auto
139 aligned_cast(_tSrc&& v) ynothrow
140 -> decltype(yforward(reinterpret_cast<_rDst>(v)))
141 {
142 return yforward(reinterpret_cast<_rDst>(v));
143 }
145
146
152 template<typename _pDst, typename _tSrc>
153 inline yimpl(ystdex::enable_if_t)<and_<is_object_pointer<_pDst>,
154 is_aligned_storable<_tSrc, remove_pointer_t<_pDst>>>::value, _pDst>
155 aligned_store_cast(_tSrc* v) ynothrow
156 {
157 return reinterpret_cast<_pDst>(v);
158 }
159 template<typename _rDst, typename _tSrc, yimpl(typename = ystdex::enable_if_t<
160 and_<is_reference<_rDst>, is_aligned_storable<remove_reference_t<_tSrc>,
161 remove_reference_t<_rDst>>>::value>)>
162 inline auto
163 aligned_store_cast(_tSrc&& v) ynothrow
164 -> decltype(yforward(reinterpret_cast<_rDst>(v)))
165 {
166 return yforward(reinterpret_cast<_rDst>(v));
167 }
169
170
176 template<typename _pDst, typename _tSrc>
177 inline yimpl(ystdex::enable_if_t)<and_<is_object_pointer<_pDst>,
178 is_aligned_replaceable<_tSrc, remove_pointer_t<_pDst>>>::value, _pDst>
179 aligned_replace_cast(_tSrc* v) ynothrow
180 {
181 return reinterpret_cast<_pDst>(v);
182 }
183 template<typename _rDst, typename _tSrc, yimpl(typename = ystdex::enable_if_t<
184 and_<is_reference<_rDst>, is_aligned_replaceable<remove_reference_t<_tSrc>,
185 remove_reference_t<_rDst>>>::value>)>
186 inline auto
187 aligned_replace_cast(_tSrc&& v) ynothrow
188 -> decltype(yforward(reinterpret_cast<_rDst>(v)))
189 {
190 return yforward(reinterpret_cast<_rDst>(v));
191 }
193
194
201 template<typename _pDst, typename _tSrc>
202 inline yimpl(ystdex::enable_if_t)<and_<is_object_pointer<_pDst>,
203 is_trivially_replaceable<_tSrc, remove_pointer_t<_pDst>>>::value, _pDst>
204 replace_cast(_tSrc* v) ynothrow
205 {
206 return reinterpret_cast<_pDst>(v);
207 }
208 template<typename _rDst, typename _tSrc, yimpl(typename = ystdex::enable_if_t<
209 and_<is_reference<_rDst>, is_trivially_replaceable<remove_reference_t<_tSrc>,
210 remove_reference_t<_rDst>>>::value>)>
211 inline auto
212 replace_cast(_tSrc&& v) ynothrow
213 -> decltype(yforward(reinterpret_cast<_rDst>(v)))
214 {
215 return yforward(reinterpret_cast<_rDst>(v));
216 }
218
219
220
221
227 template<typename _type>
228 class pun_ref
229 {
230 static_assert(is_object<_type>(), "Invalid type found.");
231
232 private:
234 _type& alias;
235
236 public:
238
239
244 YB_NONNULL(3)
245 pun_ref(default_init_t, void* p)
246 : alias(*::new(p) _type)
247 {}
248 template<typename... _tParams>
249 YB_NONNULL(2)
250 pun_ref(void* p, _tParams&&... args)
251 : alias(*::new(p) _type(yforward(args)...))
252 {}
254 ~pun_ref()
255 {
256 alias.~_type();
257 }
259
260 _type&
261 get() const ynothrow
262 {
263 return alias;
264 }
265 };
266
267
268
270
271 template<typename _type>
273 using pun_ptr = placement_ptr<decay_t<_type>>;
274
275
277 template<typename _type, typename _tObj, typename... _tParams>
278 inline pun_ptr<_type>
279 make_pun(_tObj& obj, _tParams&&... args)
280 {
281 return pun_ptr<_type>(
282 ystdex::construct_within<decay_t<_type>>(obj, yforward(args)...));
283 }
284
289 template<typename _type, typename _tObj>
290 inline pun_ptr<_type>
291 make_pun_default(_tObj& obj)
292 {
293 return
294 pun_ptr<_type>(ystdex::construct_default_within<decay_t<_type>>(obj));
295 }
297
298
306 template<typename _tUnderlying = aligned_storage_t<sizeof(void*)>>
307 struct standard_layout_storage
308 {
309 static_assert(is_standard_layout<_tUnderlying>(),
310 "Invalid underlying type found.");
311
312 using underlying = _tUnderlying;
313
314 underlying object;
315
316 standard_layout_storage() = default;
317 standard_layout_storage(const standard_layout_storage&) = default;
318
319 standard_layout_storage&
320 operator=(const standard_layout_storage&) = default;
325 template<typename _type,
326 yimpl(typename = exclude_self_t<standard_layout_storage, _type>)>
327 inline standard_layout_storage&
328 operator=(_type&& x)
329 {
330 assign(yforward(x));
331 return *this;
332 }
333
334 yconstfn_relaxed YB_PURE void*
335 access() ynothrow
336 {
337 return &object;
338 }
339 yconstfn YB_PURE const void*
340 access() const ynothrow
341 {
342 return &object;
343 }
345
346 template<typename _type>
347 yconstfn_relaxed YB_PURE _type&
348 access() ynothrow
349 {
350 static_assert(is_aligned_storable<standard_layout_storage, _type>(),
351 "Invalid type found.");
352
353 return *static_cast<_type*>(access());
354 }
355 template<typename _type>
356 yconstfn YB_PURE const _type&
357 access() const ynothrow
358 {
359 static_assert(is_aligned_storable<standard_layout_storage, _type>(),
360 "Invalid type found.");
361
362 return *static_cast<const _type*>(access());
363 }
365
367
368 template<typename _type, typename... _tParams>
370 inline _type*
371 construct(_tParams&&... args)
372 {
373 return ystdex::construct_within<decay_t<_type>>(object,
374 yforward(args)...);
375 }
376
378 template<typename _type>
379 inline void
380 destroy()
381 {
382 ystdex::destruct_in(access<decay_t<_type>>());
383 }
384
386
387 template<typename _type, typename... _tParams>
388 inline pun_ptr<_type>
389 pun(_tParams&&... args)
390 {
391 return ystdex::make_pun<_type>(object, yforward(args)...);
392 }
393
395 template<typename _type, typename... _tParams>
396 inline pun_ptr<_type>
397 pun_default()
398 {
399 return ystdex::make_pun_default<_type>(object);
400 }
402
403
404 yconstfn_relaxed YB_PURE byte*
405 data() ynothrow
406 {
407 return static_cast< byte*>(access());
408 }
409 yconstfn YB_PURE const byte*
410 data() const ynothrow
411 {
412 return static_cast<const byte*>(access());
413 }
414
419 template<typename _type>
420 inline void
421 assign(_type&& x)
422 {
423 access<decay_t<_type>>() = yforward(x);
424 }
425 };
426
427
433 template<typename _type, size_t _vAlign = yalignof(_type)>
434 using replace_storage_t
435 = standard_layout_storage<pun_storage_t<_type, _vAlign>>;
436
437 } // namespace ystdex;
438
439 #endif
440
ystdex::pun_ref::alias
_type & alias
Definition: type_pun.hpp:230
ystdex::default_init_t
默认初始化标记。
Definition: placement.hpp:48
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
ystdex::standard_layout_storage::object
underlying object
Definition: type_pun.hpp:314
v
byte v
Definition: CharRenderer.cpp:75
NPL::x
const TermNode &term ynothrow const TermNode &term ynothrow const TermNode &term ynothrow TermNode &term const TermNode &term ValueNode &node const ValueNode &node const _type & x
Definition: SContext.h:94
ystdex::aligned_replace_cast
ystdex::enable_if_t< and_< is_object_pointer< _pDst >, is_aligned_replaceable< _tSrc, remove_pointer_t< _pDst > > >::value, _pDst > aligned_replace_cast(_tSrc *v)
保证对齐替换存储的显式转换。
Definition: type_pun.hpp:179
ystdex::replace_cast
ystdex::enable_if_t< and_< is_object_pointer< _pDst >, is_trivially_replaceable< _tSrc, remove_pointer_t< _pDst > > >::value, _pDst > replace_cast(_tSrc *v)
保证平凡替换存储的显式转换。
Definition: type_pun.hpp:204
ystdex::standard_layout_storage::pun
pun_ptr< _type > pun(_tParams &&...args)
Definition: type_pun.hpp:389
ystdex::placement_ptr
std::unique_ptr< _type, placement_delete< _type, _tPointer >> placement_ptr
独占放置存储的对象所有权的指针。
Definition: placement.hpp:513
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:262
ystdex::standard_layout_storage::access
_type & access()
Definition: type_pun.hpp:348
ystdex::standard_layout_storage
任意标准布局类型对象提供空间的存储。
Definition: type_pun.hpp:307
yconstfn_relaxed
#define yconstfn_relaxed
指定编译时没有 C++11 限制和隐式成员 const 的常量函数。
Definition: ydef.h:692
ystdex::is_aligned_storable
判断是否可对齐存储。
Definition: type_pun.hpp:72
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: type_traits.hpp:343
CHRLib::args
_tParams && args
Definition: CharacterProcessing.h:538
ystdex::make_pun_default
pun_ptr< _type > make_pun_default(_tObj &obj)
构造避免严格别名分析限制的缓冲独占所有权指针指定的默认初始化对象。
Definition: type_pun.hpp:291
ystdex::replace_storage_t
standard_layout_storage< pun_storage_t< _type, _vAlign >> replace_storage_t
显式转换的替代标准布局替代存储类型。
Definition: type_pun.hpp:435
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:527
ystdex::standard_layout_storage::access
const void * access() const
Definition: type_pun.hpp:340
ystdex::standard_layout_storage::access
void * access()
Definition: type_pun.hpp:335
ystdex::pun_ref::~pun_ref
~pun_ref()
Definition: type_pun.hpp:254
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
ystdex::make_pun
pun_ptr< _type > make_pun(_tObj &obj, _tParams &&...args)
构造避免严格别名分析限制的缓冲独占所有权指针指定的值初始化对象。
Definition: type_pun.hpp:279
ystdex
特性测试宏。
Definition: ydef.h:822
ystdex::standard_layout_storage< _type >::underlying
_type underlying
Definition: type_pun.hpp:312
ystdex::pun_ref
避免严格别名分析限制的缓冲引用。
Definition: type_pun.hpp:228
ystdex::standard_layout_storage::data
byte * data()
Definition: type_pun.hpp:405
ystdex::standard_layout_storage::construct
_type * construct(_tParams &&...args)
Definition: type_pun.hpp:371
ystdex::exclude_self_t
enable_if_t<!is_same< _tClass &, decay_t< _tParam > & >::value, _type > exclude_self_t
移除选择类类型的特定重载避免构造模板和复制/转移特殊成员函数冲突。
Definition: type_traits.hpp:748
ystdex::standard_layout_storage::pun_default
pun_ptr< _type > pun_default()
Definition: type_pun.hpp:397
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:834
placement.hpp
放置对象管理操作。
ystdex::standard_layout_storage::assign
void assign(_type &&x)
Definition: type_pun.hpp:421
ystdex::standard_layout_storage::standard_layout_storage
standard_layout_storage()=default
ystdex::standard_layout_storage::data
const byte * data() const
Definition: type_pun.hpp:410
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:995
ystdex::pun_ptr
placement_ptr< decay_t< _type >> pun_ptr
避免严格别名分析限制的缓冲独占所有权指针。
Definition: type_pun.hpp:273
ystdex::is_aligned_compatible
判断是否对齐兼容。
Definition: type_pun.hpp:52
ystdex::standard_layout_storage::destroy
void destroy()
Definition: type_pun.hpp:380
ystdex::standard_layout_storage::operator=
standard_layout_storage & operator=(const standard_layout_storage &)=default
ystdex::standard_layout_storage::access
const _type & access() const
Definition: type_pun.hpp:357
ystdex::standard_layout_storage::operator=
standard_layout_storage & operator=(_type &&x)
Definition: type_pun.hpp:328
ystdex::bool_
std::integral_constant< bool, _vInt > bool_
Definition: type_traits.hpp:375
CHRLib::p
const auto p(d)
ystdex::destruct_in
void destruct_in(_type &obj)
原地析构。
Definition: placement.hpp:267