14 #ifndef NOM_SUPPORT_CASTING_H 15 #define NOM_SUPPORT_CASTING_H 25 #define NOMNIGRAPH_NODISCARD 26 #if __cplusplus > 201402L && defined(__has_cpp_attribute) 27 #if __has_cpp_attribute(nodiscard) 28 #undef NOMNIGRAPH_NODISCARD 29 #define NOMNIGRAPH_NODISCARD [[nodiscard]] 33 #elif __cplusplus && defined(__has_cpp_attribute) 34 #if __has_cpp_attribute(clang::warn_unused_result) 35 #undef NOMNIGRAPH_NODISCARD 36 #define NOMNIGRAPH_NODISCARD [[clang::warn_unused_result]] 41 template <
typename T,
typename Enable =
void>
57 using SimpleType = From;
60 static SimpleType &getSimplifiedValue(From &Val) {
return Val; }
64 using NonConstSimpleType =
typename simplify_type<From>::SimpleType;
65 using SimpleType =
typename add_const_past_pointer<NonConstSimpleType>::type;
67 typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
69 static RetType getSimplifiedValue(
const From &Val) {
77 template <
typename To,
typename From,
typename Enabler =
void>
struct isa_impl {
78 static inline bool doit(
const From &Val) {
return To::classof(&Val); }
82 template <
typename To,
typename From>
84 To, From, typename
std::enable_if<std::is_base_of<To, From>::value>::type> {
85 static inline bool doit(
const From &) {
return true; }
89 static inline bool doit(
const From &Val) {
94 template <
typename To,
typename From>
struct isa_impl_cl<To, const From> {
95 static inline bool doit(
const From &Val) {
100 template <
typename To,
typename From>
102 static inline bool doit(
const std::unique_ptr<From> &Val) {
103 assert(Val &&
"isa<> used on a null pointer");
108 template <
typename To,
typename From>
struct isa_impl_cl<To, From *> {
109 static inline bool doit(
const From *Val) {
110 assert(Val &&
"isa<> used on a null pointer");
115 template <
typename To,
typename From>
struct isa_impl_cl<To, From *
const> {
116 static inline bool doit(
const From *Val) {
117 assert(Val &&
"isa<> used on a null pointer");
122 template <
typename To,
typename From>
struct isa_impl_cl<To, const From *> {
123 static inline bool doit(
const From *Val) {
124 assert(Val &&
"isa<> used on a null pointer");
129 template <
typename To,
typename From>
131 static inline bool doit(
const From *Val) {
132 assert(Val &&
"isa<> used on a null pointer");
137 template <
typename To,
typename From,
typename SimpleFrom>
141 static bool doit(
const From &Val) {
143 typename simplify_type<SimpleFrom>::SimpleType>::
148 template <
typename To,
typename FromTy>
151 static bool doit(
const FromTy &Val) {
161 template <
class X,
class Y> NOMNIGRAPH_NODISCARD
inline bool isa(
const Y &Val) {
163 typename simplify_type<const Y>::SimpleType>::doit(Val);
175 using ret_type = To &;
178 using ret_type =
const To &;
182 using ret_type = To *;
186 using ret_type =
const To *;
190 using ret_type =
const To *;
193 template <
class To,
class From>
197 using ResultType =
typename std::remove_pointer<PointerType>::type;
200 using ret_type = std::unique_ptr<ResultType>;
207 using ret_type =
typename cast_retty<To, SimpleFrom>::ret_type;
212 using ret_type =
typename cast_retty_impl<To, FromTy>::ret_type;
215 template <
class To,
class From>
struct cast_retty {
217 To, From,
typename simplify_type<From>::SimpleType>::ret_type;
225 static typename cast_retty<To, From>::ret_type doit(From &Val) {
227 typename simplify_type<SimpleFrom>::SimpleType>::
234 static typename cast_retty<To, FromTy>::ret_type doit(
const FromTy &Val) {
235 typename cast_retty<To, FromTy>::ret_type Res2 =
236 (
typename cast_retty<To, FromTy>::ret_type) const_cast<FromTy &>(Val);
242 static const bool value =
243 std::is_same<X, typename simplify_type<X>::SimpleType>::value;
253 template <
class X,
class Y>
254 inline typename std::enable_if<!is_simple_type<Y>::value,
255 typename cast_retty<X, const Y>::ret_type>::type
257 assert(isa<X>(Val) &&
"cast<Ty>() argument of incompatible type!");
259 X,
const Y,
typename simplify_type<const Y>::SimpleType>::doit(Val);
262 template <
class X,
class Y>
263 inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
264 assert(isa<X>(Val) &&
"cast<Ty>() argument of incompatible type!");
269 template <
class X,
class Y>
270 inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
271 assert(isa<X>(Val) &&
"cast<Ty>() argument of incompatible type!");
273 typename simplify_type<Y *>::SimpleType>::doit(Val);
276 template <
class X,
class Y>
278 cast(std::unique_ptr<Y> &&Val) {
279 assert(isa<X>(Val.get()) &&
"cast<Ty>() argument of incompatible type!");
289 template <
class X,
class Y>
290 NOMNIGRAPH_NODISCARD
inline 291 typename std::enable_if<!is_simple_type<Y>::value,
292 typename cast_retty<X, const Y>::ret_type>::type
293 cast_or_null(
const Y &Val) {
296 assert(isa<X>(Val) &&
"cast_or_null<Ty>() argument of incompatible type!");
300 template <
class X,
class Y>
301 NOMNIGRAPH_NODISCARD
inline 302 typename std::enable_if<!is_simple_type<Y>::value,
303 typename cast_retty<X, Y>::ret_type>::type
304 cast_or_null(Y &Val) {
307 assert(isa<X>(Val) &&
"cast_or_null<Ty>() argument of incompatible type!");
311 template <
class X,
class Y>
312 NOMNIGRAPH_NODISCARD
inline typename cast_retty<X, Y *>::ret_type
313 cast_or_null(Y *Val) {
316 assert(isa<X>(Val) &&
"cast_or_null<Ty>() argument of incompatible type!");
320 template <
class X,
class Y>
322 cast_or_null(std::unique_ptr<Y> &&Val) {
325 return cast<X>(std::move(Val));
336 template <
class X,
class Y>
337 NOMNIGRAPH_NODISCARD
inline 338 typename std::enable_if<!is_simple_type<Y>::value,
339 typename cast_retty<X, const Y>::ret_type>::type
340 dyn_cast(
const Y &Val) {
341 return isa<X>(Val) ? cast<X>(Val) :
nullptr;
344 template <
class X,
class Y>
345 NOMNIGRAPH_NODISCARD
inline typename cast_retty<X, Y>::ret_type
347 return isa<X>(Val) ? cast<X>(Val) :
nullptr;
350 template <
class X,
class Y>
351 NOMNIGRAPH_NODISCARD
inline typename cast_retty<X, Y *>::ret_type
353 return isa<X>(Val) ? cast<X>(Val) :
nullptr;
359 template <
class X,
class Y>
360 NOMNIGRAPH_NODISCARD
inline 361 typename std::enable_if<!is_simple_type<Y>::value,
362 typename cast_retty<X, const Y>::ret_type>::type
363 dyn_cast_or_null(
const Y &Val) {
364 return (Val && isa<X>(Val)) ? cast<X>(Val) :
nullptr;
367 template <
class X,
class Y>
368 NOMNIGRAPH_NODISCARD
inline 369 typename std::enable_if<!is_simple_type<Y>::value,
370 typename cast_retty<X, Y>::ret_type>::type
371 dyn_cast_or_null(Y &Val) {
372 return (Val && isa<X>(Val)) ? cast<X>(Val) :
nullptr;
375 template <
class X,
class Y>
376 NOMNIGRAPH_NODISCARD
inline typename cast_retty<X, Y *>::ret_type
377 dyn_cast_or_null(Y *Val) {
378 return (Val && isa<X>(Val)) ? cast<X>(Val) :
nullptr;
386 template <
class X,
class Y>
387 NOMNIGRAPH_NODISCARD
inline auto unique_dyn_cast(std::unique_ptr<Y> &Val)
388 -> decltype(cast<X>(Val)) {
391 return cast<X>(std::move(Val));
394 template <
class X,
class Y>
395 NOMNIGRAPH_NODISCARD
inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val)
396 -> decltype(cast<X>(Val)) {
397 return unique_dyn_cast<X, Y>(Val);
402 template <
class X,
class Y>
403 NOMNIGRAPH_NODISCARD
inline auto 404 unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) -> decltype(cast<X>(Val)) {
407 return unique_dyn_cast<X, Y>(Val);
410 template <
class X,
class Y>
411 NOMNIGRAPH_NODISCARD
inline auto 412 unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) -> decltype(cast<X>(Val)) {
413 return unique_dyn_cast_or_null<X, Y>(Val);
416 #endif // NOM_SUPPORT_CASTING_H
If T is a pointer, just return it. If it is not, return T&.
If T is a pointer to X, return a pointer to const X.