YSTest: cast.hpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

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

- 文件列表
- 文件成员

cast.hpp
浏览该文件的文档.
1 /*
2 © 2010-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_cast_hpp_
29 #define YB_INC_ystdex_cast_hpp_ 1
30
31 #include "type_op.hpp" // for is_object, is_void, is_function, decay_t,
32 // is_same, have_common_nonempty_virtual_base, _t;
33 #include <memory> // for std::addressof;
34 #include <typeinfo> // for std::bad_cast;
35 #include "cassert.h" // for yassume;
36
38 namespace ystdex
39 {
40
52 template<typename _tSrc, typename _tDst = const decay_t<_tSrc>&&>
54 yconstfn _tDst
55 qualify(_tSrc&& arg) ynothrow
56 {
57 static_assert(is_same<decay_t<_tSrc>, decay_t<_tDst>>(),
58 "Non-qualification conversion found.");
59
60 return static_cast<_tDst>(arg);
61 }
62
63
73 template<typename _pDst, class _tSrc>
74 inline _pDst
75 polymorphic_cast(_tSrc* v)
76 {
77 static_assert(is_polymorphic<_tSrc>(), "Non-polymorphic class found.");
78 static_assert(is_pointer<_pDst>(), "Non-pointer destination found.");
79
80 if(const auto p = dynamic_cast<_pDst>(v))
81 return p;
82 throw std::bad_cast();
83 }
84
98 template<typename _pDst, class _tSrc>
99 inline _pDst
100 polymorphic_downcast(_tSrc* v) ynothrowv
101 {
102 static_assert(is_polymorphic<_tSrc>(), "Non-polymorphic class found.");
103 static_assert(is_pointer<_pDst>(), "Non-pointer destination found.");
104 static_assert(is_base_of<_tSrc, remove_cv_t<
105 remove_pointer_t<_pDst>>>(), "Wrong destination type found.");
106
107 yassume(dynamic_cast<_pDst>(v) == v);
108 return static_cast<_pDst>(v);
109 }
115 template<typename _rDst, class _tSrc>
116 yconstfn yimpl(enable_if_t)<is_lvalue_reference<_rDst>::value, _rDst>
117 polymorphic_downcast(_tSrc& v) ynothrowv
118 {
119 return *ystdex::polymorphic_downcast<remove_reference_t<_rDst>*>(
120 std::addressof(v));
121 }
127 template<typename _rDst, class _tSrc>
128 yconstfn yimpl(enable_if_t)<is_rvalue_reference<_rDst>::value
129 && !is_reference<_tSrc>::value, _rDst>
130 polymorphic_downcast(_tSrc&& v) ynothrowv
131 {
132 return std::move(ystdex::polymorphic_downcast<_rDst&>(v));
133 }
142 template<class _tDst, typename _tSrc, typename _tDeleter>
143 inline yimpl(enable_if_t)<!is_reference<_tDst>::value
144 && !is_array<_tDst>::value, std::unique_ptr<_tDst, _tDeleter>>
145 polymorphic_downcast(std::unique_ptr<_tSrc, _tDeleter>&& v) ynothrowv
146 {
147 using dst_type = std::unique_ptr<_tDst, _tDeleter>;
148 using pointer = typename dst_type::pointer;
149 auto ptr(v.release());
150 ynoexcept_assert("Invalid cast found.", polymorphic_downcast<pointer>(ptr));
151
152 yassume(bool(ptr));
153 return dst_type(polymorphic_downcast<pointer>(ptr),
154 std::move(v.get_deleter()));
155 }
161 template<class _tDst, typename _tSrc>
162 inline yimpl(enable_if_t)<!is_reference<_tDst>::value
163 && !is_array<_tDst>::value, std::shared_ptr<_tDst>>
164 polymorphic_downcast(const std::unique_ptr<_tSrc>& v) ynothrowv
165 {
166 yassume(dynamic_cast<_tDst*>(v.get()) == v.get());
167
168 return std::static_pointer_cast<_tDst>(v);
169 }
171
173
174
184 template<typename _pDst, class _tSrc>
185 inline _pDst
186 polymorphic_crosscast(_tSrc* v)
187 {
188 static_assert(is_polymorphic<_tSrc>(), "Non-polymorphic class found.");
189 static_assert(is_pointer<_pDst>(), "Non-pointer destination found.");
190
191 auto p(dynamic_cast<_pDst>(v));
192
193 yassume(p);
194 return p;
195 }
202 template<typename _rDst, class _tSrc>
203 yconstfn _rDst
204 polymorphic_crosscast(_tSrc& v)
205 {
206 static_assert(is_lvalue_reference<_rDst>(),
207 "Invalid destination type found.");
208
209 return *ystdex::polymorphic_crosscast<remove_reference_t<_rDst>*>(
210 std::addressof(v));
211 }
218 template<typename _rDst, class _tSrc>
219 yconstfn enable_if_t<!is_reference<_tSrc>::value, _rDst>
220 polymorphic_crosscast(_tSrc&& v)
221 {
222 static_assert(is_rvalue_reference<_rDst>(),
223 "Invalid destination type found.");
224
225 return std::move(ystdex::polymorphic_crosscast<_rDst&>(v));
226 }
228
229
230 namespace details
231 {
232
234
235 template<typename _tFrom, typename _tTo, bool _bNonVirtualDownCast>
236 struct general_polymorphic_cast_helper
237 {
238 static yconstfn _tTo
239 cast(_tFrom v)
240 {
241 return ystdex::polymorphic_downcast<_tTo>(v);
242 }
243 };
244
245 template<typename _tFrom, typename _tTo>
246 struct general_polymorphic_cast_helper<_tFrom, _tTo, false>
247 {
248 static yconstfn _tTo
249 cast(_tFrom v)
250 {
251 return dynamic_cast<_tTo>(v);
252 }
253 };
254
255
256 template<typename _tFrom, typename _tTo, bool _bUseStaticCast>
257 struct general_cast_helper
258 {
259 static yconstfn _tTo
260 cast(_tFrom v)
261 {
262 return _tTo(v);
263 }
264 };
265
266 template<typename _tFrom, typename _tTo>
267 struct general_cast_helper<_tFrom, _tTo, false>
268 {
269 static yconstfn _tTo
270 cast(_tFrom v)
271 {
272 return general_polymorphic_cast_helper<_tFrom, _tTo, and_<is_base_of<
273 _tFrom, _tTo>, not_<have_common_nonempty_virtual_base<
274 _t<remove_rp<_tFrom>>, _t<remove_rp<_tTo>>>>>::value>::cast(v);
275 }
276 };
277
278 template<typename _type>
279 struct general_cast_helper<_type, _type, true>
280 {
281 static _type
282 cast(_type v)
283 {
284 return v;
285 }
286 };
287
288 template<typename _type>
289 struct general_cast_helper<_type, _type, false>
290 {
291 static yconstfn _type
292 cast(_type v)
293 {
294 return v;
295 }
296 };
297
298 template<typename _tFrom, typename _tTo>
299 struct general_cast_type_helper
300 : bool_constant<is_convertible<_tFrom, _tTo>::value>
301 {};
303
304 } // namespace details;
305
318 template<typename _tDst, typename _tSrc>
319 yconstfn _tDst
320 general_cast(_tSrc* v)
321 {
322 return details::general_cast_helper<_tSrc*, _tDst,
323 details::general_cast_type_helper<_tSrc*, _tDst>::value>::cast(v);
324 }
325 template<typename _tDst, typename _tSrc>
326 yconstfn _tDst
327 general_cast(_tSrc& v)
328 {
329 return details::general_cast_helper<_tSrc&, _tDst,
330 details::general_cast_type_helper<_tSrc&, _tDst>::value>::cast(v);
331 }
332 template<typename _tDst, typename _tSrc>
333 yconstfn const _tDst
334 general_cast(const _tSrc& v)
335 {
336 return details::general_cast_helper<const _tSrc&, _tDst, details
337 ::general_cast_type_helper<const _tSrc&, const _tDst>::value>::cast(v);
338 }
340
341
342 } // namespace ystdex;
343
344 #endif
345
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:99
ystdex::details::general_cast_helper< _tFrom, _tTo, false >::cast
static _tTo cast(_tFrom v)
Definition: cast.hpp:270
platform::p
while p p
Definition: YCLib/FileSystem.h:225
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
cassert.h
ISO C 断言/调试跟踪扩展。
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::qualify
_tDst qualify(_tSrc &&arg)
允许添加限定符转换。
Definition: cast.hpp:55
ystdex::details::general_cast_helper
Definition: cast.hpp:257
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:760
ystdex::bool_constant
integral_constant< bool, _b > bool_constant
bool 常量。
Definition: type_traits.hpp:382
ystdex::polymorphic_crosscast
_pDst polymorphic_crosscast(_tSrc *v)
多态类指针交叉转换。
Definition: cast.hpp:186
ystdex::general_cast
_tDst general_cast(_tSrc *v)
一般类型转换。
Definition: cast.hpp:320
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:256
ystdex::cpp2014::remove_cv_t
typename remove_cv< _type >::type remove_cv_t
Definition: type_traits.hpp:291
ystdex::polymorphic_downcast
_pDst polymorphic_downcast(_tSrc *v)
多态类指针向派生类指针转换。
Definition: cast.hpp:100
ynoexcept_assert
#define ynoexcept_assert(_msg,...)
表达式 noexcept 静态断言。
Definition: ydef.h:721
ystdex::details::general_polymorphic_cast_helper::cast
static _tTo cast(_tFrom v)
Definition: cast.hpp:239
ystdex::_t
typename _type::type _t
嵌套类型别名。
Definition: type_traits.hpp:96
ystdex::static_pointer_cast
std::unique_ptr< _tDst > static_pointer_cast(std::unique_ptr< _type > p)
智能指针转换。
Definition: memory.hpp:847
ystdex::details::general_polymorphic_cast_helper
Definition: cast.hpp:236
ystdex
特性测试宏。
Definition: ydef.h:796
ystdex::details::general_cast_helper::cast
static _tTo cast(_tFrom v)
Definition: cast.hpp:260
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:654
type_op.hpp
C++ 类型操作。
ystdex::details::general_polymorphic_cast_helper< _tFrom, _tTo, false >::cast
static _tTo cast(_tFrom v)
Definition: cast.hpp:249
ystdex::and_
逻辑操作元函数。
Definition: type_traits.hpp:394
ystdex::not_
Definition: type_traits.hpp:430
ystdex::polymorphic_cast
_pDst polymorphic_cast(_tSrc *v)
多态类指针类型转换。
Definition: cast.hpp:75
ystdex::details::have_common_nonempty_virtual_base
Definition: type_op.hpp:81
ystdex::details::general_cast_helper< _type, _type, true >::cast
static _type cast(_type v)
Definition: cast.hpp:282
ystdex::details::general_cast_type_helper
Definition: cast.hpp:299
ystdex::details::general_cast_helper< _type, _type, false >::cast
static _type cast(_type v)
Definition: cast.hpp:292