YSTest: cast.hpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
cast.hpp
浏览该文件的文档.
1 /*
2 © 2010-2014 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_cast_hpp_
29 #define YB_INC_ystdex_cast_hpp_ 1
30
31 #include "type_op.hpp"
32 #include "cassert.h"
33 #include <memory>
34 #include <typeinfo> // for dynamic_cast;
35 #include <initializer_list> // for std::initializer_list;
36
37 namespace ystdex
38 {
39
54 template<typename _tDst, typename _tSrc>
55 inline _tDst
56 union_cast(_tSrc x) ynothrow
57 {
58 static_assert(is_pod<_tDst>::value, "Non-POD destination type found.");
59 static_assert(sizeof(_tSrc) == sizeof(_tDst), "Incompatible types found.");
60
61 union
62 {
63 _tSrc x;
64 _tDst y;
65 } u = {x};
66 return u.y;
67 }
68
69
76 template<typename _tDst, typename... _tSrc>
77 yconstfn std::initializer_list<_tDst>
78 initializer_cast(_tSrc&&... x)
79 {
80 return {_tDst(yforward(x))...};
81 }
82
83
94 template<typename _pDst, class _tSrc>
95 inline _pDst
96 polymorphic_cast(_tSrc* x)
97 {
98 static_assert(is_polymorphic<_tSrc>::value, "Non-polymorphic class found.");
99 static_assert(is_pointer<_pDst>::value, "Non-pointer destination found.");
100
101 const auto tmp(dynamic_cast<_pDst>(x));
102
103 if(!tmp)
104 throw std::bad_cast();
105 return tmp;
106 }
107
122 template<typename _pDst, class _tSrc>
123 inline _pDst
124 polymorphic_downcast(_tSrc* x)
125 {
126 static_assert(is_polymorphic<_tSrc>::value, "Non-polymorphic class found.");
127 static_assert(is_pointer<_pDst>::value, "Non-pointer destination found.");
128 static_assert(is_base_of<_tSrc, remove_cv_t<
129 remove_pointer_t<_pDst>>>::value, "Wrong destination type found.");
130
131 yassume(dynamic_cast<_pDst>(x) == x);
132 return static_cast<_pDst>(x);
133 }
140 template<typename _rDst, class _tSrc>
141 yconstfn _rDst
142 polymorphic_downcast(_tSrc& x)
143 {
144 static_assert(is_lvalue_reference<_rDst>::value,
145 "Invalid destination type found.");
146
147 return *ystdex::polymorphic_downcast<remove_reference_t<_rDst>*>(
148 std::addressof(x));
149 }
156 template<typename _rDst, class _tSrc>
157 yconstfn enable_if_t<!is_reference<_tSrc>::value, _rDst>
158 polymorphic_downcast(_tSrc&& x)
159 {
160 static_assert(is_rvalue_reference<_rDst>::value,
161 "Invalid destination found.");
162
163 return std::move(ystdex::polymorphic_downcast<_rDst&>(x));
164 }
166
182 template<typename _pDst, class _tSrc>
183 inline _pDst
184 polymorphic_crosscast(_tSrc* x)
185 {
186 static_assert(is_polymorphic<_tSrc>::value, "Non-polymorphic class found.");
187 static_assert(is_pointer<_pDst>::value, "Non-pointer destination found.");
188
189 auto p(dynamic_cast<_pDst>(x));
190
191 yassume(p);
192 return p;
193 }
200 template<typename _rDst, class _tSrc>
201 yconstfn _rDst
202 polymorphic_crosscast(_tSrc& x)
203 {
204 static_assert(is_lvalue_reference<_rDst>::value,
205 "Invalid destination type found.");
206
207 return *ystdex::polymorphic_crosscast<remove_reference_t<_rDst>*>(
208 std::addressof(x));
209 }
216 template<typename _rDst, class _tSrc>
217 yconstfn enable_if_t<!is_reference<_tSrc>::value, _rDst>
218 polymorphic_crosscast(_tSrc&& x)
219 {
220 static_assert(is_rvalue_reference<_rDst>::value,
221 "Invalid destination type found.");
222
223 return std::move(ystdex::polymorphic_crosscast<_rDst&>(x));
224 }
226
227
228 namespace details
229 {
230
232
233 template<typename _tFrom, typename _tTo, bool _bNonVirtualDownCast>
234 struct general_polymorphic_cast_helper
235 {
236 static yconstfn _tTo
237 cast(_tFrom x)
238 {
239 return ystdex::polymorphic_downcast<_tTo>(x);
240 }
241 };
242
243 template<typename _tFrom, typename _tTo>
244 struct general_polymorphic_cast_helper<_tFrom, _tTo, false>
245 {
246 static yconstfn _tTo
247 cast(_tFrom x)
248 {
249 return dynamic_cast<_tTo>(x);
250 }
251 };
252
253
254 template<typename _tFrom, typename _tTo, bool _bUseStaticCast>
255 struct general_cast_helper
256 {
257 static yconstfn _tTo
258 cast(_tFrom x)
259 {
260 return _tTo(x);
261 }
262 };
263
264 template<typename _tFrom, typename _tTo>
265 struct general_cast_helper<_tFrom, _tTo, false>
266 {
267 static yconstfn _tTo
268 cast(_tFrom x)
269 {
270 return general_polymorphic_cast_helper<_tFrom, _tTo, (is_base_of<
271 _tFrom, _tTo>::value && !has_common_nonempty_virtual_base<typename
272 remove_rp<_tFrom>::type, typename remove_rp<_tTo>::type>::value)
273 >::cast(x);
274 }
275 };
276
277 template<typename _type>
278 struct general_cast_helper<_type, _type, true>
279 {
280 static inline _type
281 cast(_type x)
282 {
283 return x;
284 }
285 };
286
287 template<typename _type>
288 struct general_cast_helper<_type, _type, false>
289 {
290 static yconstfn _type
291 cast(_type x)
292 {
293 return x;
294 }
295 };
296
297 template<typename _tFrom, typename _tTo>
298 struct general_cast_type_helper
299 : integral_constant<bool, is_convertible<_tFrom, _tTo>::value>
300 {};
302
303 } // namespace details;
304
318 template<typename _tDst, typename _tSrc>
319 yconstfn _tDst
320 general_cast(_tSrc* x)
321 {
322 return details::general_cast_helper<_tSrc*, _tDst,
323 details::general_cast_type_helper<_tSrc*, _tDst>::value>::cast(x);
324 }
325 template<typename _tDst, typename _tSrc>
326 yconstfn _tDst
327 general_cast(_tSrc& x)
328 {
329 return details::general_cast_helper<_tSrc&, _tDst,
330 details::general_cast_type_helper<_tSrc&, _tDst>::value>::cast(x);
331 }
332 template<typename _tDst, typename _tSrc>
333 yconstfn const _tDst
334 general_cast(const _tSrc& x)
335 {
336 return details::general_cast_helper<const _tSrc&, _tDst, details
337 ::general_cast_type_helper<const _tSrc&, const _tDst>::value>::cast(x);
338 }
340
341 } // namespace ystdex;
342
343 #endif
344
ystdex::union_cast
_tDst union_cast(_tSrc x)
使用匿名联合体进行的类型转换。
Definition: cast.hpp:56
YSLib::true
bool return true
Definition: DSMain.cpp:177
ystdex::details::general_cast_helper< _type, _type, true >::cast
static _type cast(_type x)
Definition: cast.hpp:281
ystdex::polymorphic_cast
_pDst polymorphic_cast(_tSrc *x)
多态类指针类型转换。
Definition: cast.hpp:96
cassert.h
ISO C 断言/调试跟踪扩展。
ystdex::general_cast
_tDst general_cast(_tSrc *x)
一般类型转换。
Definition: cast.hpp:320
ystdex::details::general_cast_helper::cast
static _tTo cast(_tFrom x)
Definition: cast.hpp:258
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
ystdex::remove_pointer_t
typename remove_pointer< _type >::type remove_pointer_t
Definition: type_op.hpp:255
ystdex::details::general_polymorphic_cast_helper::cast
static _tTo cast(_tFrom x)
Definition: cast.hpp:237
ystdex::details::general_cast_helper< _type, _type, false >::cast
static _type cast(_type x)
Definition: cast.hpp:291
yassume
#define yassume
假定：环境语义。
Definition: cassert.h:58
ystdex::polymorphic_crosscast
_pDst polymorphic_crosscast(_tSrc *x)
多态类指针交叉转换。
Definition: cast.hpp:184
ystdex::remove_rp::type
remove_pointer_t< remove_reference_t< _type >> type
Definition: type_op.hpp:677
ystdex::details::general_polymorphic_cast_helper
Definition: cast.hpp:234
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
ystdex::polymorphic_downcast
_pDst polymorphic_downcast(_tSrc *x)
多态类指针向派生类指针转换。
Definition: cast.hpp:124
ystdex::initializer_cast
std::initializer_list< _tDst > initializer_cast(_tSrc &&...x)
初值符列表转换。
Definition: cast.hpp:78
ystdex::remove_cv_t
typename remove_cv< _type >::type remove_cv_t
Definition: type_op.hpp:222
ystdex::details::general_polymorphic_cast_helper< _tFrom, _tTo, false >::cast
static _tTo cast(_tFrom x)
Definition: cast.hpp:247
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:463
ystdex::details::general_cast_type_helper
Definition: cast.hpp:298
ystdex::has_common_nonempty_virtual_base
判断指定的两个类类型是否有非空虚基类。
Definition: type_op.hpp:623
type_op.hpp
C++ 类型操作。
ystdex::details::general_cast_helper< _tFrom, _tTo, false >::cast
static _tTo cast(_tFrom x)
Definition: cast.hpp:268
ystdex::details::general_cast_helper
Definition: cast.hpp:255