14#ifndef WPIUTIL_WPI_CASTING_H
15#define WPIUTIL_WPI_CASTING_H
63template <
typename To,
typename From,
typename Enabler =
void>
struct isa_impl {
64 static inline bool doit(
const From &Val) {
return To::classof(&Val); }
68template <
typename To,
typename From>
70 static inline bool doit(
const From &) {
return true; }
74 static inline bool doit(
const From &Val) {
79template <
typename To,
typename From>
struct isa_impl_cl<To, const From> {
80 static inline bool doit(
const From &Val) {
85template <
typename To,
typename From>
87 static inline bool doit(
const std::unique_ptr<From> &Val) {
88 assert(Val &&
"isa<> used on a null pointer");
93template <
typename To,
typename From>
struct isa_impl_cl<To, From *> {
94 static inline bool doit(
const From *Val) {
95 assert(Val &&
"isa<> used on a null pointer");
100template <
typename To,
typename From>
struct isa_impl_cl<To, From *
const> {
101 static inline bool doit(
const From *Val) {
102 assert(Val &&
"isa<> used on a null pointer");
107template <
typename To,
typename From>
struct isa_impl_cl<To, const From *> {
108 static inline bool doit(
const From *Val) {
109 assert(Val &&
"isa<> used on a null pointer");
114template <
typename To,
typename From>
116 static inline bool doit(
const From *Val) {
117 assert(Val &&
"isa<> used on a null pointer");
122template <
typename To,
typename From,
typename SimpleFrom>
126 static bool doit(
const From &Val) {
133template <
typename To,
typename FromTy>
136 static bool doit(
const FromTy &Val) {
145template <
class To,
class From>
struct cast_retty;
168template <
class To,
class From>
172 using ResultType = std::remove_pointer_t<PointerType>;
214 return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>
215 *)&
const_cast<FromTy &
>(Val);
219template <
class To,
class FromTy>
234 std::is_same_v<X, typename simplify_type<X>::SimpleType>;
252template <
typename To,
typename From,
typename Enable =
void>
265template <
typename To,
typename From>
267 static inline bool isPossible(
const std::optional<From> &f) {
268 assert(f &&
"CastIsPossible::isPossible called on a nullopt!");
277template <
typename To,
typename From>
279 static inline bool isPossible(
const From &f) {
return true; }
308template <
typename To,
typename From,
typename Derived>
311 if (!Derived::isPossible(f))
312 return Derived::castFailed();
313 return Derived::doCast(f);
320template <
typename OptionalDerived,
typename Default>
321using SelfType = std::conditional_t<std::is_same_v<OptionalDerived, void>,
322 Default, OptionalDerived>;
328template <
typename To,
typename From,
typename Derived =
void>
334 detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {
335 static inline To
doCast(From *f) {
return To(f); }
342template <
typename To,
typename From,
typename Derived =
void>
346 std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;
349 return CastResultType((
typename CastResultType::element_type *)f.release());
355 if (!Self::isPossible(f))
364template <
typename To,
typename From,
typename Derived =
void>
368 std::optional<To>, From,
369 detail::SelfType<Derived, OptionalValueCast<To, From>>> {
370 static inline std::optional<To>
castFailed() {
return std::optional<To>{}; }
372 static inline std::optional<To>
doCast(
const From &f) {
return To(f); }
387template <
typename To,
typename From,
typename ForwardTo>
390 using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>;
396 return ForwardTo::isPossible(
const_cast<NonConstFrom>(f));
399 static inline decltype(
auto)
castFailed() {
return ForwardTo::castFailed(); }
401 static inline decltype(
auto)
doCast(
const From &f) {
406 return ForwardTo::doCastIfPossible(
const_cast<NonConstFrom>(f));
422template <
typename To,
typename From,
typename ForwardTo>
425 return ForwardTo::isPossible(&f);
428 static inline decltype(
auto)
doCast(
const From &f) {
429 return *ForwardTo::doCast(&f);
475template <
typename To,
typename From,
typename Enable =
void>
502template <
typename To,
typename From>
509 return SimplifiedSelf::isPossible(
513 static inline decltype(
auto)
doCast(From &f) {
518 return SimplifiedSelf::castFailed();
522 return SimplifiedSelf::doCastIfPossible(
532template <
typename To,
typename From>
538template <
typename To,
typename From>
547template <
typename To,
typename From>
548[[nodiscard]]
inline bool isa(
const From &Val) {
552template <
typename First,
typename Second,
typename... Rest,
typename From>
553[[nodiscard]]
inline bool isa(
const From &Val) {
554 return isa<First>(Val) ||
isa<Second, Rest...>(Val);
564template <
typename To,
typename From>
565[[nodiscard]]
inline decltype(
auto)
cast(
const From &Val) {
566 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
570template <
typename To,
typename From>
571[[nodiscard]]
inline decltype(
auto)
cast(From &Val) {
572 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
576template <
typename To,
typename From>
577[[nodiscard]]
inline decltype(
auto)
cast(From *Val) {
578 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
582template <
typename To,
typename From>
583[[nodiscard]]
inline decltype(
auto)
cast(std::unique_ptr<From> &&Val) {
584 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
594 std::is_pointer_v<T> || std::is_constructible_v<T, std::nullptr_t>;
604 static inline bool isPresent(
const T &t) {
return true; }
611 static inline bool isPresent(
const std::optional<T> &t) {
612 return t.has_value();
614 static inline decltype(
auto)
unwrapValue(std::optional<T> &t) {
return *t; }
622 static inline bool isPresent(
const T &t) {
return t != T(
nullptr); }
629template <
typename T>
inline bool isPresent(
const T &t) {
648template <
typename To,
typename From>
649[[nodiscard]]
inline decltype(
auto)
dyn_cast(
const From &Val) {
654template <
typename To,
typename From>
655[[nodiscard]]
inline decltype(
auto)
dyn_cast(From &Val) {
660template <
typename To,
typename From>
661[[nodiscard]]
inline decltype(
auto)
dyn_cast(From *Val) {
666template <
typename To,
typename From>
667[[nodiscard]]
inline decltype(
auto)
dyn_cast(std::unique_ptr<From> &&Val) {
670 std::forward<std::unique_ptr<From> &&>(Val));
675template <
typename... X,
class Y>
679 return isa<X...>(Val);
682template <
typename... X,
class Y>
689template <
class X,
class Y>
693 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
700 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
707 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
711template <
class X,
class Y>
722 return cast_if_present<X>(Val);
726 return cast_if_present<X>(Val);
730 return cast_if_present<X>(Val);
733template <
class X,
class Y>
auto cast_or_null(std::unique_ptr<Y> &&Val) {
734 return cast_if_present<X>(std::move(Val));
761 return dyn_cast_if_present<X>(Val);
765 return dyn_cast_if_present<X>(Val);
769 return dyn_cast_if_present<X>(Val);
777template <
class X,
class Y>
778[[nodiscard]]
inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
782 return cast<X>(std::move(Val));
785template <
class X,
class Y>
787 return unique_dyn_cast<X, Y>(Val);
792template <
class X,
class Y>
793[[nodiscard]]
inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
797 return unique_dyn_cast<X, Y>(Val);
800template <
class X,
class Y>
802 return unique_dyn_cast_or_null<X, Y>(Val);
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:256
detail namespace with internal helper functions
Definition: xchar.h:20
decltype(auto) unwrapValue(T &t)
Definition: Casting.h:635
bool isPresent(const T &t)
Definition: Casting.h:629
std::conditional_t< std::is_same_v< OptionalDerived, void >, Default, OptionalDerived > SelfType
A helper to derive the type to use with Self for cast traits, when the provided CRTP derived type is ...
Definition: Casting.h:322
Definition: ntcore_cpp.h:26
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:565
auto cast_or_null(const Y &Val)
Definition: Casting.h:721
CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast_or_null(std::unique_ptr< Y > &Val)
Definition: Casting.h:794
bool isa_and_nonnull(const Y &Val)
Definition: Casting.h:683
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition: Casting.h:548
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:649
bool isa_and_present(const Y &Val)
isa_and_present<X> - Functionally identical to isa, except that a null value is accepted.
Definition: Casting.h:676
CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast(std::unique_ptr< Y > &Val)
unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, taking ownership of the in...
Definition: Casting.h:779
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition: Casting.h:739
auto dyn_cast_or_null(const Y &Val)
Definition: Casting.h:760
auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
Definition: Casting.h:690
static decltype(auto) doCastIfPossible(From &f)
Definition: Casting.h:521
typename simplify_type< From >::SimpleType SimpleFrom
Definition: Casting.h:505
static decltype(auto) doCast(From &f)
Definition: Casting.h:513
static bool isPossible(From &f)
Definition: Casting.h:508
static decltype(auto) castFailed()
Definition: Casting.h:517
This struct provides a method for customizing the way a cast is performed.
Definition: Casting.h:476
typename cast_retty< To, From >::ret_type CastReturnType
Definition: Casting.h:479
static CastReturnType doCast(const From &f)
Definition: Casting.h:481
static CastReturnType doCastIfPossible(const From &f)
Definition: Casting.h:492
static CastReturnType castFailed()
Definition: Casting.h:490
static bool isPossible(const From &f)
Definition: Casting.h:279
static bool isPossible(const std::optional< From > &f)
Definition: Casting.h:267
This struct provides a way to check if a given cast is possible.
Definition: Casting.h:253
static bool isPossible(const From &f)
Definition: Casting.h:254
Provides a cast trait that strips const from types to make it easier to implement a const-version of ...
Definition: Casting.h:388
static decltype(auto) doCastIfPossible(const From &f)
Definition: Casting.h:405
static bool isPossible(const From &f)
Definition: Casting.h:395
std::conditional_t< std::is_pointer_v< From >, DecayedFrom *, DecayedFrom & > NonConstFrom
Definition: Casting.h:393
static decltype(auto) doCast(const From &f)
Definition: Casting.h:401
std::remove_cv_t< std::remove_pointer_t< From > > DecayedFrom
Definition: Casting.h:390
static decltype(auto) castFailed()
Definition: Casting.h:399
This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...
Definition: Casting.h:309
static To doCastIfPossible(From f)
Definition: Casting.h:310
Provides a cast trait that uses a defined pointer to pointer cast as a base for reference-to-referenc...
Definition: Casting.h:423
static decltype(auto) doCast(const From &f)
Definition: Casting.h:428
static bool isPossible(const From &f)
Definition: Casting.h:424
All of these cast traits are meant to be implementations for useful casts that users may want to use ...
Definition: Casting.h:301
static To castFailed()
Definition: Casting.h:302
This cast trait provides std::optional<T> casting.
Definition: Casting.h:369
static std::optional< To > castFailed()
Definition: Casting.h:370
static std::optional< To > doCast(const From &f)
Definition: Casting.h:372
This cast trait provides std::unique_ptr casting.
Definition: Casting.h:343
std::unique_ptr< std::remove_reference_t< typename cast_retty< To, From >::ret_type > > CastResultType
Definition: Casting.h:346
static CastResultType doCastIfPossible(std::unique_ptr< From > &&f)
Definition: Casting.h:354
static CastResultType doCast(std::unique_ptr< From > &&f)
Definition: Casting.h:348
detail::SelfType< Derived, UniquePtrCast< To, From > > Self
Definition: Casting.h:344
static CastResultType castFailed()
Definition: Casting.h:352
This cast trait provides casting for the specific case of casting to a value-typed object from a poin...
Definition: Casting.h:334
static To doCast(From *f)
Definition: Casting.h:335
T UnwrappedType
Definition: Casting.h:621
static decltype(auto) unwrapValue(T &t)
Definition: Casting.h:623
static bool isPresent(const T &t)
Definition: Casting.h:622
static bool isPresent(const std::optional< T > &t)
Definition: Casting.h:611
static decltype(auto) unwrapValue(std::optional< T > &t)
Definition: Casting.h:614
T UnwrappedType
Definition: Casting.h:610
ValueIsPresent provides a way to check if a value is, well, present.
Definition: Casting.h:602
T UnwrappedType
Definition: Casting.h:603
static decltype(auto) unwrapValue(T &t)
Definition: Casting.h:605
static bool isPresent(const T &t)
Definition: Casting.h:604
const T type
Definition: type_traits.h:55
T & type
Definition: type_traits.h:44
static cast_retty< To, FromTy >::ret_type doit(const FromTy &Val)
Definition: Casting.h:213
static cast_retty< To, FromTy * >::ret_type doit(const FromTy *Val)
Definition: Casting.h:222
Definition: Casting.h:202
static cast_retty< To, From >::ret_type doit(const From &Val)
Definition: Casting.h:204
To * ret_type
Definition: Casting.h:157
const To & ret_type
Definition: Casting.h:153
const To * ret_type
Definition: Casting.h:161
const To * ret_type
Definition: Casting.h:165
std::unique_ptr< ResultType > ret_type
Definition: Casting.h:175
Definition: Casting.h:149
To & ret_type
Definition: Casting.h:150
typename cast_retty_impl< To, FromTy >::ret_type ret_type
Definition: Casting.h:187
Definition: Casting.h:178
typename cast_retty< To, SimpleFrom >::ret_type ret_type
Definition: Casting.h:182
Definition: Casting.h:190
typename cast_retty_wrap< To, From, typename simplify_type< From >::SimpleType >::ret_type ret_type
Definition: Casting.h:192
Definition: Casting.h:232
static const bool value
Definition: Casting.h:233
static bool doit(const From &)
Definition: Casting.h:70
static bool doit(const From *Val)
Definition: Casting.h:94
static bool doit(const From *Val)
Definition: Casting.h:101
static bool doit(const From &Val)
Definition: Casting.h:80
static bool doit(const From *Val)
Definition: Casting.h:108
static bool doit(const From *Val)
Definition: Casting.h:116
static bool doit(const std::unique_ptr< From > &Val)
Definition: Casting.h:87
static bool doit(const From &Val)
Definition: Casting.h:74
static bool doit(const FromTy &Val)
Definition: Casting.h:136
Definition: Casting.h:123
static bool doit(const From &Val)
Definition: Casting.h:126
static bool doit(const From &Val)
Definition: Casting.h:64
static RetType getSimplifiedValue(const From &Val)
Definition: Casting.h:47
typename add_const_past_pointer< NonConstSimpleType >::type SimpleType
Definition: Casting.h:43
typename simplify_type< From >::SimpleType NonConstSimpleType
Definition: Casting.h:42
typename add_lvalue_reference_if_not_pointer< SimpleType >::type RetType
Definition: Casting.h:45
Define a template that can be specialized by smart pointers to reflect the fact that they are automat...
Definition: Casting.h:34
From SimpleType
Definition: Casting.h:35
static SimpleType & getSimplifiedValue(From &Val)
Definition: Casting.h:38
constexpr bool IsNullable
Definition: Casting.h:593