Castable: Optimize Switch() (part 2)
Use the TypeInfo already obtained from the object instead of calling As<T>() again, which would trigger another virtual call. Bug: tint:1383 Change-Id: I0394ea049589b0f7f72c80509ac8e9536196f368 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/79302 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
3fbe98e657
commit
3d5b38447a
|
@ -130,14 +130,13 @@ struct TypeInfo {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type->Is(&Of<std::remove_const_t<TO>>());
|
return type->Is(&Of<std::remove_cv_t<TO>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns the static TypeInfo for the type T
|
/// @returns the static TypeInfo for the type T
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static const TypeInfo& Of() {
|
static const TypeInfo& Of() {
|
||||||
using NO_CV = typename std::remove_cv<T>::type;
|
return detail::TypeInfoOf<std::remove_cv_t<T>>::info;
|
||||||
return detail::TypeInfoOf<NO_CV>::info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns a compile-time hashcode for the type `T`.
|
/// @returns a compile-time hashcode for the type `T`.
|
||||||
|
@ -148,6 +147,9 @@ struct TypeInfo {
|
||||||
static constexpr HashCode HashCodeOf() {
|
static constexpr HashCode HashCodeOf() {
|
||||||
static_assert(traits::IsTypeOrDerived<T, CastableBase>::value,
|
static_assert(traits::IsTypeOrDerived<T, CastableBase>::value,
|
||||||
"T is not Castable");
|
"T is not Castable");
|
||||||
|
static_assert(
|
||||||
|
std::is_same_v<T, std::remove_cv_t<T>>,
|
||||||
|
"Strip const / volatile decorations before calling HashCodeOf");
|
||||||
/// Use the compiler's "pretty" function name, which includes the template
|
/// Use the compiler's "pretty" function name, which includes the template
|
||||||
/// type, to obtain a unique hash value.
|
/// type, to obtain a unique hash value.
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -180,7 +182,7 @@ struct TypeInfo {
|
||||||
if constexpr (kCount == 0) {
|
if constexpr (kCount == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if constexpr (kCount == 1) {
|
} else if constexpr (kCount == 1) {
|
||||||
return HashCodeOf<std::tuple_element_t<0, TUPLE>>();
|
return HashCodeOf<std::remove_cv_t<std::tuple_element_t<0, TUPLE>>>();
|
||||||
} else {
|
} else {
|
||||||
constexpr auto kMid = kCount / 2;
|
constexpr auto kMid = kCount / 2;
|
||||||
return CombinedHashCodeOfTuple<traits::SliceTuple<0, kMid, TUPLE>>() |
|
return CombinedHashCodeOfTuple<traits::SliceTuple<0, kMid, TUPLE>>() |
|
||||||
|
@ -472,8 +474,8 @@ namespace detail {
|
||||||
/// @note does not handle the Default case
|
/// @note does not handle the Default case
|
||||||
/// @see Switch().
|
/// @see Switch().
|
||||||
template <typename FN>
|
template <typename FN>
|
||||||
using SwitchCaseType = std::remove_const_t<std::remove_pointer_t<
|
using SwitchCaseType = std::remove_pointer_t<
|
||||||
traits::ParameterType<std::remove_reference_t<FN>, 0>>>;
|
traits::ParameterType<std::remove_reference_t<FN>, 0>>;
|
||||||
|
|
||||||
/// Evaluates to true if the function `FN` has the signature of a Default case
|
/// Evaluates to true if the function `FN` has the signature of a Default case
|
||||||
/// in a Switch().
|
/// in a Switch().
|
||||||
|
@ -530,7 +532,8 @@ inline bool NonDefaultCases(T* object,
|
||||||
// Attempt to dynamically cast the object to the handler type. If that
|
// Attempt to dynamically cast the object to the handler type. If that
|
||||||
// succeeds, call the case handler with the cast object.
|
// succeeds, call the case handler with the cast object.
|
||||||
using CaseType = SwitchCaseType<CaseFunc>;
|
using CaseType = SwitchCaseType<CaseFunc>;
|
||||||
if (auto* ptr = As<CaseType>(object)) {
|
if (type->Is(&TypeInfo::Of<CaseType>())) {
|
||||||
|
auto* ptr = static_cast<CaseType*>(object);
|
||||||
if constexpr (kHasReturnType) {
|
if constexpr (kHasReturnType) {
|
||||||
*result = std::get<0>(cases)(ptr);
|
*result = std::get<0>(cases)(ptr);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue