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>
diff --git a/src/castable.h b/src/castable.h
index 072872a..0dada0d 100644
--- a/src/castable.h
+++ b/src/castable.h
@@ -83,6 +83,11 @@
/// 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 @@
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 @@
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 @@
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 @@
}
};
+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();
diff --git a/src/castable_test.cc b/src/castable_test.cc
index 3330757..05f5e4a 100644
--- a/src/castable_test.cc
+++ b/src/castable_test.cc
@@ -73,6 +73,27 @@
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>();
diff --git a/src/type/type.cc b/src/type/type.cc
index 39f309c..ecd79ea 100644
--- a/src/type/type.cc
+++ b/src/type/type.cc
@@ -71,7 +71,7 @@
}
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_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_handle() const {
- return Is<type::Sampler>() || Is<type::Texture>();
+ return IsAnyOf<Sampler, Texture>();
}
} // namespace type