21 #ifndef GTIRB_CASTING_H
22 #define GTIRB_CASTING_H
25 #include <type_traits>
28 #ifndef GTIRB_WRAP_UTILS_IN_NAMESPACE
29 #define GTIRB_DEPRECATED_UTILS \
30 [[deprecated("Define GTIRB_WRAP_UTILS_IN_NAMESPACE and access via the " \
31 "gtirb namespace to suppress this error.")]]
33 #define GTIRB_DEPRECATED_UTILS
238 template <
typename From>
struct simplify_type {
239 using SimpleType = From;
242 static SimpleType& getSimplifiedValue(From& Val) {
return Val; }
250 template <
typename To,
typename From,
typename Enabler =
void>
struct isa_impl {
251 static inline bool doit(
const From& Val) {
return To::classof(&Val); }
257 template <
typename To,
typename From>
259 To, From, typename
std::enable_if<std::is_base_of<To, From>::value>::type> {
260 static inline bool doit(
const From&) {
return true; }
265 template <
typename To,
typename From>
struct isa_impl_cl {
266 static inline bool doit(
const From& Val) {
267 return isa_impl<To, From>::doit(Val);
273 template <
typename To,
typename From>
struct isa_impl_cl<To, const From> {
274 static inline bool doit(
const From& Val) {
275 return isa_impl<To, From>::doit(Val);
281 template <
typename To,
typename From>
struct isa_impl_cl<To, From*> {
282 static inline bool doit(
const From* Val) {
283 assert(Val &&
"isa<> used on a null pointer");
284 return isa_impl<To, From>::doit(*Val);
290 template <
typename To,
typename From>
struct isa_impl_cl<To, From*
const> {
291 static inline bool doit(
const From* Val) {
292 assert(Val &&
"isa<> used on a null pointer");
293 return isa_impl<To, From>::doit(*Val);
299 template <
typename To,
typename From>
struct isa_impl_cl<To, const From*> {
300 static inline bool doit(
const From* Val) {
301 assert(Val &&
"isa<> used on a null pointer");
302 return isa_impl<To, From>::doit(*Val);
308 template <
typename To,
typename From>
309 struct isa_impl_cl<To, const From*
const> {
310 static inline bool doit(
const From* Val) {
311 assert(Val &&
"isa<> used on a null pointer");
312 return isa_impl<To, From>::doit(*Val);
318 template <
typename To,
typename From,
typename SimpleFrom>
319 struct isa_impl_wrap {
322 static bool doit(
const From& Val) {
323 return isa_impl_wrap<To, SimpleFrom,
324 typename simplify_type<SimpleFrom>::SimpleType>::
325 doit(simplify_type<const From>::getSimplifiedValue(Val));
331 template <
typename To,
typename FromTy>
332 struct isa_impl_wrap<To, FromTy, FromTy> {
334 static bool doit(
const FromTy& Val) {
335 return isa_impl_cl<To, FromTy>::doit(Val);
345 template <
class X,
class Y>
346 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline bool isa(
const Y& Val) {
347 return isa_impl_wrap<X,
const Y,
348 typename simplify_type<const Y>::SimpleType>::doit(Val);
355 template <
class To,
class From>
struct cast_retty;
361 template <
class To,
class From>
struct cast_retty_impl {
362 using ret_type = To&;
364 template <
class To,
class From>
struct cast_retty_impl<To, const From> {
365 using ret_type =
const To&;
368 template <
class To,
class From>
struct cast_retty_impl<To, From*> {
369 using ret_type = To*;
372 template <
class To,
class From>
struct cast_retty_impl<To, const From*> {
373 using ret_type =
const To*;
376 template <
class To,
class From>
struct cast_retty_impl<To, const From*
const> {
377 using ret_type =
const To*;
382 template <
class To,
class From,
class SimpleFrom>
struct cast_retty_wrap {
386 using ret_type =
typename cast_retty<To, SimpleFrom>::ret_type;
389 template <
class To,
class FromTy>
struct cast_retty_wrap<To, FromTy, FromTy> {
391 using ret_type =
typename cast_retty_impl<To, FromTy>::ret_type;
394 template <
class To,
class From>
struct cast_retty {
395 using ret_type =
typename cast_retty_wrap<
396 To, From,
typename simplify_type<From>::SimpleType>::ret_type;
404 template <
class To,
class From,
class SimpleFrom>
struct cast_convert_val {
406 static typename cast_retty<To, From>::ret_type doit(From& Val) {
407 return cast_convert_val<To, SimpleFrom,
408 typename simplify_type<SimpleFrom>::SimpleType>::
409 doit(simplify_type<From>::getSimplifiedValue(Val));
413 template <
class To,
class FromTy>
struct cast_convert_val<To, FromTy, FromTy> {
415 static typename cast_retty<To, FromTy>::ret_type doit(
const FromTy& Val) {
416 typename cast_retty<To, FromTy>::ret_type Res2 =
417 (
typename cast_retty<To, FromTy>::ret_type)
const_cast<FromTy&
>(Val);
424 template <
class X>
struct is_simple_type {
425 static const bool value =
426 std::is_same<X, typename simplify_type<X>::SimpleType>::value;
437 template <
class X,
class Y>
438 GTIRB_DEPRECATED_UTILS
inline
439 typename std::enable_if<!is_simple_type<Y>::value,
440 typename cast_retty<X, const Y>::ret_type>::type
442 assert(isa<X>(Val) &&
"cast<Ty>() argument of incompatible type!");
443 return cast_convert_val<
444 X,
const Y,
typename simplify_type<const Y>::SimpleType>::doit(Val);
447 template <
class X,
class Y>
448 GTIRB_DEPRECATED_UTILS
inline typename cast_retty<X, Y>::ret_type
cast(Y& Val) {
449 assert(isa<X>(Val) &&
"cast<Ty>() argument of incompatible type!");
450 return cast_convert_val<X, Y, typename simplify_type<Y>::SimpleType>::doit(
454 template <
class X,
class Y>
455 GTIRB_DEPRECATED_UTILS
inline typename cast_retty<X, Y*>::ret_type
457 assert(isa<X>(Val) &&
"cast<Ty>() argument of incompatible type!");
458 return cast_convert_val<X, Y*, typename simplify_type<Y*>::SimpleType>::doit(
465 template <
class X,
class Y>
466 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline
467 typename std::enable_if<!is_simple_type<Y>::value,
468 typename cast_retty<X, const Y>::ret_type>::type
472 assert(isa<X>(Val) &&
"cast_or_null<Ty>() argument of incompatible type!");
476 template <
class X,
class Y>
477 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline
478 typename std::enable_if<!is_simple_type<Y>::value,
479 typename cast_retty<X, Y>::ret_type>::type
483 assert(isa<X>(Val) &&
"cast_or_null<Ty>() argument of incompatible type!");
487 template <
class X,
class Y>
488 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline typename cast_retty<X, Y*>::ret_type
492 assert(isa<X>(Val) &&
"cast_or_null<Ty>() argument of incompatible type!");
504 template <
class X,
class Y>
505 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline
506 typename std::enable_if<!is_simple_type<Y>::value,
507 typename cast_retty<X, const Y>::ret_type>::type
509 return isa<X>(Val) ? cast<X>(Val) :
nullptr;
512 template <
class X,
class Y>
513 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline typename cast_retty<X, Y>::ret_type
515 return isa<X>(Val) ? cast<X>(Val) :
nullptr;
518 template <
class X,
class Y>
519 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline typename cast_retty<X, Y*>::ret_type
521 return isa<X>(Val) ? cast<X>(Val) :
nullptr;
527 template <
class X,
class Y>
528 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline
529 typename std::enable_if<!is_simple_type<Y>::value,
530 typename cast_retty<X, const Y>::ret_type>::type
532 return (Val && isa<X>(Val)) ? cast<X>(Val) :
nullptr;
535 template <
class X,
class Y>
536 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline
537 typename std::enable_if<!is_simple_type<Y>::value,
538 typename cast_retty<X, Y>::ret_type>::type
540 return (Val && isa<X>(Val)) ? cast<X>(Val) :
nullptr;
543 template <
class X,
class Y>
544 GTIRB_DEPRECATED_UTILS [[nodiscard]]
inline typename cast_retty<X, Y*>::ret_type
546 return (Val && isa<X>(Val)) ? cast<X>(Val) :
nullptr;
553 #ifdef GTIRB_WRAP_UTILS_IN_NAMESPACE
561 #endif // GTIRB_WRAP_UTILS_IN_NAMESPACE
565 #ifndef GTIRB_WRAP_UTILS_IN_NAMESPACE
573 #endif // GTIRB_WRAP_UTILS_IN_NAMESPACE
575 #endif // GTIRB_CASTING_H