YSTest: type_pun.hpp 源文件

YSTest PreAlpha_b700_20160611 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 "type_traits.hpp" // for "type_traits.hpp", bool_constant, yalignof,
32 // and_, is_trivial, enable_if_t, is_object_pointer, remove_pointer_t,
33 // aligned_storage_t, is_reference, remove_reference_t, exclude_self_t,
34 // 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_constant<!(yalignof(_type)
53 < yalignof(_type2)) && yalignof(_type) % yalignof(_type2) == 0>
54 {};
55
56
61 template<typename _type, typename _tDst>
62 struct is_aligned_placeable : bool_constant<sizeof(_type)
63 == sizeof(_tDst) && is_aligned_compatible<_type, _tDst>::value>
64 {};
65
66
71 template<typename _type, typename _tDst>
72 struct is_aligned_storable : bool_constant<!(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
226 template<typename _tUnderlying = aligned_storage_t<sizeof(void*)>>
227 struct standard_layout_storage
228 {
229 static_assert(is_standard_layout<_tUnderlying>(),
230 "Invalid underlying type found.");
231
232 using underlying = _tUnderlying;
233
234 underlying object;
235
236 standard_layout_storage() = default;
237 standard_layout_storage(const standard_layout_storage&) = default;
239 template<typename _type,
240 yimpl(typename = exclude_self_t<standard_layout_storage, _type>)>
241 inline
242 standard_layout_storage(_type&& x)
243 {
244 new(access()) decay_t<_type>(yforward(x));
245 }
246
247 standard_layout_storage&
248 operator=(const standard_layout_storage&) = default;
253 template<typename _type,
254 yimpl(typename = exclude_self_t<standard_layout_storage, _type>)>
255 inline standard_layout_storage&
256 operator=(_type&& x)
257 {
258 assign(yforward(x));
259 return *this;
260 }
261
262 yconstfn_relaxed YB_PURE void*
263 access() ynothrow
264 {
265 return &object;
266 }
267 yconstfn YB_PURE const void*
268 access() const ynothrow
269 {
270 return &object;
271 }
272 template<typename _type>
273 yconstfn_relaxed YB_PURE _type&
274 access() ynothrow
275 {
276 static_assert(is_aligned_storable<standard_layout_storage, _type>(),
277 "Invalid type found.");
278
279 return *static_cast<_type*>(access());
280 }
281 template<typename _type>
282 yconstfn YB_PURE const _type&
283 access() const ynothrow
284 {
285 static_assert(is_aligned_storable<standard_layout_storage, _type>(),
286 "Invalid type found.");
287
288 return *static_cast<const _type*>(access());
289 }
290
291 yconstfn_relaxed YB_PURE byte*
292 data() ynothrow
293 {
294 return static_cast< byte*>(access());
295 }
296 yconstfn YB_PURE const byte*
297 data() const ynothrow
298 {
299 return static_cast<const byte*>(access());
300 }
301
303 template<typename _type>
304 inline void
305 assign(_type&& x)
306 {
307 access<decay_t<_type>>() = yforward(x);
308 }
309 };
310
311
317 template<typename _type, size_t _vAlign = yalignof(_type)>
318 using replace_storage_t
319 = standard_layout_storage<pun_storage_t<_type, _vAlign>>;
320
321 } // namespace ystdex;
322
323 #endif
324
YSLib::Drawing::x
The boundary is out of the const Rect SDst SPos x
Definition: YDraw.h:127
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
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::standard_layout_storage::object
underlying object
Definition: type_pun.hpp:234
v
byte v
Definition: CharRenderer.cpp:75
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: type_traits.hpp:350
ystdex::standard_layout_storage::data
const byte * data() const
Definition: type_pun.hpp:297
ystdex::standard_layout_storage::access
_type & access()
Definition: type_pun.hpp:274
ystdex::standard_layout_storage::operator=
standard_layout_storage & operator=(_type &&x)
Definition: type_pun.hpp:256
ystdex::standard_layout_storage::assign
void assign(_type &&x)
Definition: type_pun.hpp:305
ystdex::bool_constant
integral_constant< bool, _b > bool_constant
bool 常量。
Definition: type_traits.hpp:382
ystdex::standard_layout_storage::access
void * access()
Definition: type_pun.hpp:263
ystdex::replace_storage_t
standard_layout_storage< pun_storage_t< _type, _vAlign >> replace_storage_t
显式转换的替代标准布局替代存储类型。
Definition: type_pun.hpp:319
ystdex::exclude_self_t
enable_if_t<!is_same< _tClass &, decay_t< _tParam > & >::value, _type > exclude_self_t
移除选择类类型的特定重载避免构造模板和复制/转移特殊成员函数冲突。
Definition: type_traits.hpp:708
ystdex::standard_layout_storage::operator=
standard_layout_storage & operator=(const standard_layout_storage &)=default
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:256
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:501
ystdex::standard_layout_storage::data
byte * data()
Definition: type_pun.hpp:292
ystdex::standard_layout_storage::access
const void * access() const
Definition: type_pun.hpp:268
yconstfn_relaxed
#define yconstfn_relaxed
指定编译时没有 C++11 限制和隐式成员 const 的常量函数。
Definition: ydef.h:666
ystdex::standard_layout_storage::standard_layout_storage
standard_layout_storage(_type &&x)
Definition: type_pun.hpp:242
ystdex
特性测试宏。
Definition: ydef.h:796
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
type_traits.hpp
ISO C++ 类型特征扩展。
ystdex::standard_layout_storage< _type >::underlying
_type underlying
Definition: type_pun.hpp:232
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:808
ystdex::standard_layout_storage::standard_layout_storage
standard_layout_storage()=default
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:654
ystdex::standard_layout_storage
任意标准布局类型存储。
Definition: type_pun.hpp:227
ystdex::is_aligned_compatible
判断是否对齐兼容。
Definition: type_pun.hpp:52
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:969
ystdex::is_aligned_storable
判断是否可对齐存储。
Definition: type_pun.hpp:72
ystdex::standard_layout_storage::access
const _type & access() const
Definition: type_pun.hpp:283