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
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
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
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
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>
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
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
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>
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>
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>
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
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>
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,
324 }
325 template<typename _tDst, typename _tSrc>
326 yconstfn _tDst
327 general_cast(_tSrc& x)
328 {
329  return details::general_cast_helper<_tSrc&, _tDst,
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
338 }
340 
341 } // namespace ystdex;
342 
343 #endif
344 
_tDst union_cast(_tSrc x)
使用匿名联合体进行的类型转换。
Definition: cast.hpp:56
bool return true
Definition: DSMain.cpp:177
_pDst polymorphic_cast(_tSrc *x)
多态类指针类型转换。
Definition: cast.hpp:96
ISO C 断言/调试跟踪扩展。
_tDst general_cast(_tSrc *x)
一般类型转换。
Definition: cast.hpp:320
static _tTo cast(_tFrom x)
Definition: cast.hpp:258
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
typename remove_pointer< _type >::type remove_pointer_t
Definition: type_op.hpp:255
#define yassume
假定:环境语义。
Definition: cassert.h:58
_pDst polymorphic_crosscast(_tSrc *x)
多态类指针交叉转换。
Definition: cast.hpp:184
remove_pointer_t< remove_reference_t< _type >> type
Definition: type_op.hpp:677
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
_pDst polymorphic_downcast(_tSrc *x)
多态类指针向派生类指针转换。
Definition: cast.hpp:124
std::initializer_list< _tDst > initializer_cast(_tSrc &&...x)
初值符列表转换。
Definition: cast.hpp:78
typename remove_cv< _type >::type remove_cv_t
Definition: type_op.hpp:222
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:463
判断指定的两个类类型是否有非空虚基类。
Definition: type_op.hpp:623
C++ 类型操作。