JSDynamicDowncast.h [plain text]
#pragma once
#include <runtime/JSCJSValueInlines.h>
#include <runtime/JSCellInlines.h>
#include <type_traits>
namespace WebCore {
template<typename To, typename From>
using JSDynamicCastResult = typename std::conditional<std::is_const<From>::value, const To, To>::type*;
class JSNode;
template<typename From>
JSDynamicCastResult<JSNode, From> jsNodeCast(From* value);
class JSElement;
template<typename From>
JSDynamicCastResult<JSElement, From> jsElementCast(From* value);
class JSDocument;
template<typename From>
JSDynamicCastResult<JSDocument, From> jsDocumentCast(From* value);
class JSEvent;
template<typename From>
JSDynamicCastResult<JSEvent, From> jsEventCast(From* value);
template<typename Select>
struct JSDynamicCastTrait {
template<typename To, typename From>
ALWAYS_INLINE static To cast(JSC::VM& vm, From* from)
{
return JSC::jsDynamicCast<To>(vm, from);
}
};
template<>
struct JSDynamicCastTrait<JSNode> {
template<typename To, typename From>
ALWAYS_INLINE static To cast(JSC::VM&, From* from)
{
return jsNodeCast(from);
}
};
template<>
struct JSDynamicCastTrait<JSElement> {
template<typename To, typename From>
ALWAYS_INLINE static To cast(JSC::VM&, From* from)
{
return jsElementCast(from);
}
};
template<>
struct JSDynamicCastTrait<JSDocument> {
template<typename To, typename From>
ALWAYS_INLINE static To cast(JSC::VM&, From* from)
{
return jsDocumentCast(from);
}
};
template<>
struct JSDynamicCastTrait<JSEvent> {
template<typename To, typename From>
ALWAYS_INLINE static To cast(JSC::VM&, From* from)
{
return jsEventCast(from);
}
};
template<typename To, typename From>
ALWAYS_INLINE To jsDynamicDowncast(JSC::VM& vm, From* from)
{
typedef JSDynamicCastTrait<typename std::remove_cv<typename std::remove_pointer<To>::type>::type> Dispatcher;
return Dispatcher::template cast<To>(vm, from);
}
template<typename To>
ALWAYS_INLINE To jsDynamicDowncast(JSC::VM& vm, JSC::JSValue from)
{
if (UNLIKELY(!from.isCell()))
return nullptr;
return jsDynamicDowncast<To>(vm, from.asCell());
}
}