Add Castsable::IsAnyOf<T1, T2, ...>()
This makes it a little easier to check if an object is one of any of the types provided. Updated Type query functions to make use of IsAnyOf. Added tests. Change-Id: I12ea62b32042b6675d998ab85b86f2fe15861330 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/44462 Commit-Queue: Antonio Maiorano <amaiorano@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
81a4753c38
commit
a089a56c73
|
@ -83,6 +83,11 @@ struct TypeInfoOf {
|
|||
/// The unique TypeInfo for the type T.
|
||||
static const TypeInfo info;
|
||||
};
|
||||
|
||||
// Forward declaration
|
||||
template <typename TO_FIRST, typename... TO_REST>
|
||||
struct IsAnyOf;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// @returns true if `obj` is a valid pointer, and is of, or derives from the
|
||||
|
@ -106,6 +111,14 @@ bool Is(FROM* obj) {
|
|||
return obj->TypeInfo().Is(TypeInfo::Of<std::remove_const_t<TO>>());
|
||||
}
|
||||
|
||||
/// @returns true if `obj` is of, or derives from any of the `TO`
|
||||
/// classes.
|
||||
/// @param obj the object to cast from
|
||||
template <typename... TO, typename FROM>
|
||||
inline bool IsAnyOf(FROM* obj) {
|
||||
return detail::IsAnyOf<TO...>::Exec(obj);
|
||||
}
|
||||
|
||||
/// @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
|
||||
|
@ -137,6 +150,13 @@ class CastableBase {
|
|||
return tint::Is<TO>(this);
|
||||
}
|
||||
|
||||
/// @returns true if this object is of, or derives from any of the `TO`
|
||||
/// classes.
|
||||
template <typename... TO>
|
||||
inline bool IsAnyOf() const {
|
||||
return tint::IsAnyOf<TO...>(this);
|
||||
}
|
||||
|
||||
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
||||
/// this object does not derive from `TO`.
|
||||
template <typename TO>
|
||||
|
@ -199,6 +219,13 @@ class Castable : public BASE {
|
|||
return tint::Is<TO>(static_cast<const CLASS*>(this));
|
||||
}
|
||||
|
||||
/// @returns true if this object is of, or derives from any of the `TO`
|
||||
/// classes.
|
||||
template <typename... TO>
|
||||
inline bool IsAnyOf() const {
|
||||
return tint::IsAnyOf<TO...>(static_cast<const CLASS*>(this));
|
||||
}
|
||||
|
||||
/// @returns this object dynamically cast to the type `TO` or `nullptr` if
|
||||
/// this object does not derive from `TO`.
|
||||
template <typename TO>
|
||||
|
@ -214,6 +241,30 @@ class Castable : public BASE {
|
|||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
/// Helper for Castable::IsAnyOf
|
||||
template <typename TO_FIRST, typename... TO_REST>
|
||||
struct IsAnyOf {
|
||||
/// @param obj castable object to test
|
||||
/// @returns true if `obj` is of, or derives from any of `[TO_FIRST,
|
||||
/// ...TO_REST]`
|
||||
template <typename FROM>
|
||||
static bool Exec(FROM* obj) {
|
||||
return Is<TO_FIRST>(obj) || IsAnyOf<TO_REST...>::Exec(obj);
|
||||
}
|
||||
};
|
||||
/// Terminal specialization
|
||||
template <typename TO>
|
||||
struct IsAnyOf<TO> {
|
||||
/// @param obj castable object to test
|
||||
/// @returns true if `obj` is of, or derives from TO
|
||||
template <typename FROM>
|
||||
static bool Exec(FROM* obj) {
|
||||
return Is<TO>(obj);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
} // namespace tint
|
||||
|
||||
TINT_CASTABLE_POP_DISABLE_WARNINGS();
|
||||
|
|
|
@ -73,6 +73,27 @@ TEST(CastableBase, Is) {
|
|||
ASSERT_TRUE(gecko->Is<Reptile>());
|
||||
}
|
||||
|
||||
TEST(CastableBase, IsAnyOf) {
|
||||
std::unique_ptr<CastableBase> frog = std::make_unique<Frog>();
|
||||
std::unique_ptr<CastableBase> bear = std::make_unique<Bear>();
|
||||
std::unique_ptr<CastableBase> gecko = std::make_unique<Gecko>();
|
||||
|
||||
ASSERT_TRUE((frog->IsAnyOf<Animal, Mammal, Amphibian, Reptile>()));
|
||||
ASSERT_TRUE((frog->IsAnyOf<Mammal, Amphibian>()));
|
||||
ASSERT_TRUE((frog->IsAnyOf<Amphibian, Reptile>()));
|
||||
ASSERT_FALSE((frog->IsAnyOf<Mammal, Reptile>()));
|
||||
|
||||
ASSERT_TRUE((bear->IsAnyOf<Animal, Mammal, Amphibian, Reptile>()));
|
||||
ASSERT_TRUE((bear->IsAnyOf<Mammal, Amphibian>()));
|
||||
ASSERT_TRUE((bear->IsAnyOf<Mammal, Reptile>()));
|
||||
ASSERT_FALSE((bear->IsAnyOf<Amphibian, Reptile>()));
|
||||
|
||||
ASSERT_TRUE((gecko->IsAnyOf<Animal, Mammal, Amphibian, Reptile>()));
|
||||
ASSERT_TRUE((gecko->IsAnyOf<Mammal, Reptile>()));
|
||||
ASSERT_TRUE((gecko->IsAnyOf<Amphibian, Reptile>()));
|
||||
ASSERT_FALSE((gecko->IsAnyOf<Mammal, Amphibian>()));
|
||||
}
|
||||
|
||||
TEST(CastableBase, As) {
|
||||
std::unique_ptr<CastableBase> frog = std::make_unique<Frog>();
|
||||
std::unique_ptr<CastableBase> bear = std::make_unique<Bear>();
|
||||
|
|
|
@ -71,7 +71,7 @@ Type* Type::UnwrapAll() {
|
|||
}
|
||||
|
||||
bool Type::is_scalar() const {
|
||||
return is_float_scalar() || is_integer_scalar() || Is<Bool>();
|
||||
return IsAnyOf<F32, U32, I32, Bool>();
|
||||
}
|
||||
|
||||
bool Type::is_float_scalar() const {
|
||||
|
@ -91,7 +91,7 @@ bool Type::is_float_scalar_or_vector() const {
|
|||
}
|
||||
|
||||
bool Type::is_integer_scalar() const {
|
||||
return Is<U32>() || Is<I32>();
|
||||
return IsAnyOf<U32, I32>();
|
||||
}
|
||||
|
||||
bool Type::is_unsigned_integer_vector() const {
|
||||
|
@ -123,7 +123,7 @@ bool Type::is_bool_scalar_or_vector() const {
|
|||
}
|
||||
|
||||
bool Type::is_handle() const {
|
||||
return Is<type::Sampler>() || Is<type::Texture>();
|
||||
return IsAnyOf<Sampler, Texture>();
|
||||
}
|
||||
|
||||
} // namespace type
|
||||
|
|
Loading…
Reference in New Issue