Castable: factor out Is and As to free standing functions
These can now also be called with nullptr and will return false or nullptr respectively. Change-Id: I5fcf292503dd718f8d3771c7c39c204ce03ff4f7 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/44461 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
cc193de025
commit
81a4753c38
|
@ -83,9 +83,37 @@ struct TypeInfoOf {
|
||||||
/// The unique TypeInfo for the type T.
|
/// The unique TypeInfo for the type T.
|
||||||
static const TypeInfo info;
|
static const TypeInfo info;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
/// @returns true if `obj` is a valid pointer, and is of, or derives from the
|
||||||
|
/// class `TO`
|
||||||
|
/// @param obj the object to test from
|
||||||
|
template <typename TO, typename FROM>
|
||||||
|
bool Is(FROM* obj) {
|
||||||
|
constexpr const bool downcast = std::is_base_of<FROM, TO>::value;
|
||||||
|
constexpr const bool upcast = std::is_base_of<TO, FROM>::value;
|
||||||
|
constexpr const bool nocast = std::is_same<FROM, TO>::value;
|
||||||
|
static_assert(upcast || downcast || nocast, "impossible cast");
|
||||||
|
|
||||||
|
if (obj == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upcast || nocast) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj->TypeInfo().Is(TypeInfo::Of<std::remove_const_t<TO>>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @returns obj dynamically cast to the type `TO` or `nullptr` if
|
||||||
|
/// this object does not derive from `TO`.
|
||||||
|
/// @param obj the object to cast from
|
||||||
|
template <typename TO, typename FROM>
|
||||||
|
inline TO* As(FROM* obj) {
|
||||||
|
return Is<TO>(obj) ? static_cast<TO*>(obj) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/// CastableBase is the base class for all Castable objects.
|
/// CastableBase is the base class for all Castable objects.
|
||||||
/// It is not encouraged to directly derive from CastableBase without using the
|
/// It is not encouraged to directly derive from CastableBase without using the
|
||||||
/// Castable helper template.
|
/// Castable helper template.
|
||||||
|
@ -106,31 +134,21 @@ class CastableBase {
|
||||||
/// @returns true if this object is of, or derives from the class `TO`
|
/// @returns true if this object is of, or derives from the class `TO`
|
||||||
template <typename TO>
|
template <typename TO>
|
||||||
inline bool Is() const {
|
inline bool Is() const {
|
||||||
using FROM = CastableBase;
|
return tint::Is<TO>(this);
|
||||||
constexpr const bool downcast = std::is_base_of<FROM, TO>::value;
|
|
||||||
constexpr const bool upcast = std::is_base_of<TO, FROM>::value;
|
|
||||||
constexpr const bool nocast = std::is_same<FROM, TO>::value;
|
|
||||||
static_assert(upcast || downcast || nocast, "impossible cast");
|
|
||||||
|
|
||||||
if (upcast || nocast) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TypeInfo().Is(TypeInfo::Of<TO>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
||||||
/// this object does not derive from `TO`.
|
/// this object does not derive from `TO`.
|
||||||
template <typename TO>
|
template <typename TO>
|
||||||
inline TO* As() {
|
inline TO* As() {
|
||||||
return Is<TO>() ? static_cast<TO*>(this) : nullptr;
|
return tint::As<TO>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
||||||
/// this object does not derive from `TO`.
|
/// this object does not derive from `TO`.
|
||||||
template <typename TO>
|
template <typename TO>
|
||||||
inline const TO* As() const {
|
inline const TO* As() const {
|
||||||
return Is<TO>() ? static_cast<const TO*>(this) : nullptr;
|
return tint::As<const TO>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -178,46 +196,24 @@ class Castable : public BASE {
|
||||||
/// @returns true if this object is of, or derives from the class `TO`
|
/// @returns true if this object is of, or derives from the class `TO`
|
||||||
template <typename TO>
|
template <typename TO>
|
||||||
inline bool Is() const {
|
inline bool Is() const {
|
||||||
using FROM = Castable;
|
return tint::Is<TO>(static_cast<const CLASS*>(this));
|
||||||
constexpr const bool downcast = std::is_base_of<FROM, TO>::value;
|
|
||||||
constexpr const bool upcast = std::is_base_of<TO, FROM>::value;
|
|
||||||
constexpr const bool nocast = std::is_same<FROM, TO>::value;
|
|
||||||
static_assert(upcast || downcast || nocast, "impossible cast");
|
|
||||||
|
|
||||||
if (upcast || nocast) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TypeInfo().Is(TypeInfo::Of<TO>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
||||||
/// this object does not derive from `TO`.
|
/// this object does not derive from `TO`.
|
||||||
template <typename TO>
|
template <typename TO>
|
||||||
inline TO* As() {
|
inline TO* As() {
|
||||||
return Is<TO>() ? static_cast<TO*>(this) : nullptr;
|
return tint::As<TO>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
||||||
/// this object does not derive from `TO`.
|
/// this object does not derive from `TO`.
|
||||||
template <typename TO>
|
template <typename TO>
|
||||||
inline const TO* As() const {
|
inline const TO* As() const {
|
||||||
return Is<TO>() ? static_cast<const TO*>(this) : nullptr;
|
return tint::As<const TO>(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// As() dynamically casts `obj` to the target type `TO`.
|
|
||||||
/// @returns the cast object, or nullptr if `obj` is `nullptr` or not of the
|
|
||||||
/// type `TO`.
|
|
||||||
/// @param obj the object to cast
|
|
||||||
template <typename TO, typename FROM>
|
|
||||||
inline TO* As(FROM* obj) {
|
|
||||||
if (obj == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return obj->template As<TO>();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
TINT_CASTABLE_POP_DISABLE_WARNINGS();
|
TINT_CASTABLE_POP_DISABLE_WARNINGS();
|
||||||
|
|
Loading…
Reference in New Issue