AK+LibWeb: Add a fast_as<T>() method for quickly casting mixin types

`as_if<T>()` previously had a fast path that used `fast_is<T>()` and a
static cast. Mixin types couldn't use this fast path, since a static
cast from a sibling base is not valid, so would fall back to using a
slow dynamic cast instead.

This change adds a `fast_as<T>()` mechanism for mixin types to opt in
to and teaches `as_if<T>()` to use it. This means `as<T>()` and
`as_if<T>()` can be used with mixin types without incurring the
overhead of a dynamic cast
This commit is contained in:
Tim Ledbetter 2026-05-07 22:16:39 +01:00 committed by Shannon Booth
parent 33eac1c7cf
commit 0533f6d1a6
2 changed files with 8 additions and 1 deletions

View file

@ -38,7 +38,9 @@ ALWAYS_INLINE bool is(NonnullRefPtr<InputType> const& input)
template<typename OutputType, typename InputType>
ALWAYS_INLINE CopyConst<InputType, OutputType>* as_if(InputType& input)
{
if constexpr (requires { input.template fast_is<RemoveCVReference<OutputType>>(); static_cast<CopyConst<InputType, OutputType>*>(&input); }) {
if constexpr (requires { input.template fast_as<RemoveCVReference<OutputType>>(); }) {
return input.template fast_as<RemoveCVReference<OutputType>>();
} else if constexpr (requires { input.template fast_is<RemoveCVReference<OutputType>>(); static_cast<CopyConst<InputType, OutputType>*>(&input); }) {
if (!is<OutputType>(input))
return nullptr;
return static_cast<CopyConst<InputType, OutputType>*>(&input);

View file

@ -379,6 +379,11 @@ public:
template<typename T>
bool fast_is() const = delete;
template<typename T>
T* fast_as() = delete;
template<typename T>
T const* fast_as() const = delete;
WebIDL::ExceptionOr<void> ensure_pre_insertion_validity(JS::Realm&, GC::Ref<Node> node, GC::Ptr<Node> child) const;
bool is_host_including_inclusive_ancestor_of(Node const&) const;