зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1232686 - Use decltype to infer Variant::match return type; r=fitzgen
--HG-- extra : rebase_source : 38f280cc3014b2285a79e377f1fa8edf4c5f4661
This commit is contained in:
Родитель
33be16a9cc
Коммит
1fe18b25cf
|
@ -137,8 +137,6 @@ parseMessage(ZeroCopyInputStream& stream, uint32_t sizeOfMessage, MessageType& m
|
|||
template<typename CharT, typename InternedStringSet>
|
||||
struct GetOrInternStringMatcher
|
||||
{
|
||||
using ReturnType = const CharT*;
|
||||
|
||||
InternedStringSet& internedStrings;
|
||||
|
||||
explicit GetOrInternStringMatcher(InternedStringSet& strings) : internedStrings(strings) { }
|
||||
|
@ -860,8 +858,6 @@ class TwoByteString : public Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName
|
|||
|
||||
struct AsTwoByteStringMatcher
|
||||
{
|
||||
using ReturnType = TwoByteString;
|
||||
|
||||
TwoByteString match(JSAtom* atom) {
|
||||
return TwoByteString(atom);
|
||||
}
|
||||
|
@ -873,16 +869,12 @@ class TwoByteString : public Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName
|
|||
|
||||
struct IsNonNullMatcher
|
||||
{
|
||||
using ReturnType = bool;
|
||||
|
||||
template<typename T>
|
||||
bool match(const T& t) { return t != nullptr; }
|
||||
};
|
||||
|
||||
struct LengthMatcher
|
||||
{
|
||||
using ReturnType = size_t;
|
||||
|
||||
size_t match(JSAtom* atom) {
|
||||
MOZ_ASSERT(atom);
|
||||
JS::ubi::AtomOrTwoByteChars s(atom);
|
||||
|
@ -902,8 +894,6 @@ class TwoByteString : public Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName
|
|||
|
||||
struct CopyToBufferMatcher
|
||||
{
|
||||
using ReturnType = size_t;
|
||||
|
||||
RangedPtr<char16_t> destination;
|
||||
size_t maxLength;
|
||||
|
||||
|
@ -985,8 +975,6 @@ struct TwoByteString::HashPolicy {
|
|||
using Lookup = TwoByteString;
|
||||
|
||||
struct HashingMatcher {
|
||||
using ReturnType = js::HashNumber;
|
||||
|
||||
js::HashNumber match(const JSAtom* atom) {
|
||||
return js::DefaultHasher<const JSAtom*>::hash(atom);
|
||||
}
|
||||
|
@ -1009,7 +997,6 @@ struct TwoByteString::HashPolicy {
|
|||
}
|
||||
|
||||
struct EqualityMatcher {
|
||||
using ReturnType = bool;
|
||||
const TwoByteString& rhs;
|
||||
explicit EqualityMatcher(const TwoByteString& rhs) : rhs(rhs) { }
|
||||
|
||||
|
|
|
@ -133,9 +133,8 @@ struct TraceIncomingFunctor {
|
|||
TraceIncomingFunctor(JSTracer* trc, const JS::CompartmentSet& compartments)
|
||||
: trc_(trc), compartments_(compartments)
|
||||
{}
|
||||
using ReturnType = void;
|
||||
template <typename T>
|
||||
ReturnType operator()(T tp) {
|
||||
void operator()(T tp) {
|
||||
if (!compartments_.has((*tp)->compartment()))
|
||||
return;
|
||||
TraceManuallyBarrieredEdge(trc_, tp, "cross-compartment wrapper");
|
||||
|
@ -143,7 +142,7 @@ struct TraceIncomingFunctor {
|
|||
// StringWrappers are just used to avoid copying strings
|
||||
// across zones multiple times, and don't hold a strong
|
||||
// reference.
|
||||
ReturnType operator()(JSString** tp) {}
|
||||
void operator()(JSString** tp) {}
|
||||
};
|
||||
} // namespace (anonymous)
|
||||
|
||||
|
|
|
@ -227,7 +227,6 @@ class WrapperMapRef : public BufferableRef
|
|||
const char* name_;
|
||||
TraceFunctor(JSTracer *trc, const char* name) : trc_(trc), name_(name) {}
|
||||
|
||||
using ReturnType = void;
|
||||
template <class T> void operator()(T* t) { TraceManuallyBarrieredEdge(trc_, t, name_); }
|
||||
};
|
||||
void trace(JSTracer* trc) override {
|
||||
|
@ -250,7 +249,6 @@ class WrapperMapRef : public BufferableRef
|
|||
#ifdef JSGC_HASH_TABLE_CHECKS
|
||||
namespace {
|
||||
struct CheckGCThingAfterMovingGCFunctor {
|
||||
using ReturnType = void;
|
||||
template <class T> void operator()(T* t) { CheckGCThingAfterMovingGC(*t); }
|
||||
};
|
||||
} // namespace (anonymous)
|
||||
|
@ -275,7 +273,6 @@ JSCompartment::checkWrapperMapAfterMovingGC()
|
|||
|
||||
namespace {
|
||||
struct IsInsideNurseryFunctor {
|
||||
using ReturnType = bool;
|
||||
template <class T> bool operator()(T tp) { return IsInsideNursery(*tp); }
|
||||
};
|
||||
} // namespace (anonymous)
|
||||
|
@ -775,11 +772,9 @@ struct TraceRootFunctor {
|
|||
JSTracer* trc;
|
||||
const char* name;
|
||||
TraceRootFunctor(JSTracer* trc, const char* name) : trc(trc), name(name) {}
|
||||
using ReturnType = void;
|
||||
template <class T> ReturnType operator()(T* t) { return TraceRoot(trc, t, name); }
|
||||
template <class T> void operator()(T* t) { return TraceRoot(trc, t, name); }
|
||||
};
|
||||
struct NeedsSweepUnbarrieredFunctor {
|
||||
using ReturnType = bool;
|
||||
template <class T> bool operator()(T* t) const { return IsAboutToBeFinalizedUnbarriered(t); }
|
||||
};
|
||||
} // namespace (anonymous)
|
||||
|
|
|
@ -106,9 +106,9 @@ struct CrossCompartmentKey
|
|||
template <typename T> const T& as() const { return wrapped.as<T>(); }
|
||||
|
||||
template <typename F>
|
||||
auto applyToWrapped(F f) -> typename F::ReturnType {
|
||||
auto applyToWrapped(F f) -> decltype(f(static_cast<JSObject**>(nullptr))) {
|
||||
using ReturnType = decltype(f(static_cast<JSObject**>(nullptr)));
|
||||
struct WrappedMatcher {
|
||||
using ReturnType = typename F::ReturnType;
|
||||
F f_;
|
||||
explicit WrappedMatcher(F f) : f_(f) {}
|
||||
ReturnType match(JSObject*& obj) { return f_(&obj); }
|
||||
|
@ -120,9 +120,9 @@ struct CrossCompartmentKey
|
|||
}
|
||||
|
||||
template <typename F>
|
||||
auto applyToDebugger(F f) -> typename F::ReturnType {
|
||||
auto applyToDebugger(F f) -> decltype(f(static_cast<NativeObject**>(nullptr))) {
|
||||
using ReturnType = decltype(f(static_cast<NativeObject**>(nullptr)));
|
||||
struct DebuggerMatcher {
|
||||
using ReturnType = typename F::ReturnType;
|
||||
F f_;
|
||||
explicit DebuggerMatcher(F f) : f_(f) {}
|
||||
ReturnType match(JSObject*& obj) { return ReturnType(); }
|
||||
|
@ -137,10 +137,9 @@ struct CrossCompartmentKey
|
|||
// JSString* key.
|
||||
JSCompartment* compartment() {
|
||||
struct GetCompartmentFunctor {
|
||||
using ReturnType = JSCompartment*;
|
||||
ReturnType operator()(JSObject** tp) const { return (*tp)->compartment(); }
|
||||
ReturnType operator()(JSScript** tp) const { return (*tp)->compartment(); }
|
||||
ReturnType operator()(JSString** tp) const {
|
||||
JSCompartment* operator()(JSObject** tp) const { return (*tp)->compartment(); }
|
||||
JSCompartment* operator()(JSScript** tp) const { return (*tp)->compartment(); }
|
||||
JSCompartment* operator()(JSString** tp) const {
|
||||
MOZ_CRASH("invalid ccw key"); return nullptr;
|
||||
}
|
||||
};
|
||||
|
@ -150,14 +149,13 @@ struct CrossCompartmentKey
|
|||
struct Hasher : public DefaultHasher<CrossCompartmentKey>
|
||||
{
|
||||
struct HashFunctor {
|
||||
using ReturnType = HashNumber;
|
||||
ReturnType match(JSObject* obj) { return DefaultHasher<JSObject*>::hash(obj); }
|
||||
ReturnType match(JSString* str) { return DefaultHasher<JSString*>::hash(str); }
|
||||
ReturnType match(const DebuggerAndScript& tpl) {
|
||||
HashNumber match(JSObject* obj) { return DefaultHasher<JSObject*>::hash(obj); }
|
||||
HashNumber match(JSString* str) { return DefaultHasher<JSString*>::hash(str); }
|
||||
HashNumber match(const DebuggerAndScript& tpl) {
|
||||
return DefaultHasher<NativeObject*>::hash(mozilla::Get<0>(tpl)) ^
|
||||
DefaultHasher<JSScript*>::hash(mozilla::Get<1>(tpl));
|
||||
}
|
||||
ReturnType match(const DebuggerAndObject& tpl) {
|
||||
HashNumber match(const DebuggerAndObject& tpl) {
|
||||
return DefaultHasher<NativeObject*>::hash(mozilla::Get<0>(tpl)) ^
|
||||
DefaultHasher<JSObject*>::hash(mozilla::Get<1>(tpl)) ^
|
||||
(mozilla::Get<2>(tpl) << 5);
|
||||
|
|
|
@ -614,9 +614,8 @@ struct VisitGrayCallbackFunctor {
|
|||
: callback_(callback), closure_(closure)
|
||||
{}
|
||||
|
||||
using ReturnType = void;
|
||||
template <class T>
|
||||
ReturnType operator()(T tp) const {
|
||||
void operator()(T tp) const {
|
||||
if ((*tp)->isTenured() && (*tp)->asTenured().isMarked(gc::GRAY))
|
||||
callback_(closure_, JS::GCCellPtr(*tp));
|
||||
}
|
||||
|
|
|
@ -3671,7 +3671,6 @@ struct IsDestComparatorFunctor {
|
|||
JS::GCCellPtr dst_;
|
||||
explicit IsDestComparatorFunctor(JS::GCCellPtr dst) : dst_(dst) {}
|
||||
|
||||
using ReturnType = bool;
|
||||
template <typename T> bool operator()(T* t) { return (*t) == dst_.asCell(); }
|
||||
};
|
||||
} // namespace (anonymous)
|
||||
|
@ -4379,9 +4378,8 @@ struct AddOutgoingEdgeFunctor {
|
|||
: needsEdge_(needsEdge), finder_(finder)
|
||||
{}
|
||||
|
||||
using ReturnType = void;
|
||||
template <typename T>
|
||||
ReturnType operator()(T tp) {
|
||||
void operator()(T tp) {
|
||||
TenuredCell& other = (*tp)->asTenured();
|
||||
|
||||
/*
|
||||
|
|
|
@ -1861,8 +1861,6 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde
|
|||
{
|
||||
struct CharsMatcher
|
||||
{
|
||||
using ReturnType = const char16_t*;
|
||||
|
||||
JSContext* cx;
|
||||
ScriptSource& ss;
|
||||
UncompressedSourceCache::AutoHoldEntry& holder;
|
||||
|
@ -1874,11 +1872,11 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde
|
|||
, holder(holder)
|
||||
{ }
|
||||
|
||||
ReturnType match(Uncompressed& u) {
|
||||
const char16_t* match(Uncompressed& u) {
|
||||
return u.string.chars();
|
||||
}
|
||||
|
||||
ReturnType match(Compressed& c) {
|
||||
const char16_t* match(Compressed& c) {
|
||||
if (const char16_t* decompressed = cx->caches.uncompressedSourceCache.lookup(&ss, holder))
|
||||
return decompressed;
|
||||
|
||||
|
@ -1916,7 +1914,7 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde
|
|||
return ss.data.as<Uncompressed>().string.chars();
|
||||
}
|
||||
|
||||
ReturnType ret = decompressed.get();
|
||||
const char16_t* ret = decompressed.get();
|
||||
if (!cx->caches.uncompressedSourceCache.put(&ss, Move(decompressed), holder)) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
|
@ -1924,7 +1922,7 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde
|
|||
return ret;
|
||||
}
|
||||
|
||||
ReturnType match(Missing&) {
|
||||
const char16_t* match(Missing&) {
|
||||
MOZ_CRASH("ScriptSource::chars() on ScriptSource with SourceType = Missing");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2147,17 +2145,15 @@ ScriptSource::performXDR(XDRState<mode>* xdr)
|
|||
{
|
||||
struct CompressedLengthMatcher
|
||||
{
|
||||
using ReturnType = size_t;
|
||||
|
||||
ReturnType match(Uncompressed&) {
|
||||
size_t match(Uncompressed&) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReturnType match(Compressed& c) {
|
||||
size_t match(Compressed& c) {
|
||||
return c.raw.length();
|
||||
}
|
||||
|
||||
ReturnType match(Missing&) {
|
||||
size_t match(Missing&) {
|
||||
MOZ_CRASH("Missing source data in ScriptSource::performXDR");
|
||||
return 0;
|
||||
}
|
||||
|
@ -2165,17 +2161,15 @@ ScriptSource::performXDR(XDRState<mode>* xdr)
|
|||
|
||||
struct RawDataMatcher
|
||||
{
|
||||
using ReturnType = void*;
|
||||
|
||||
ReturnType match(Uncompressed& u) {
|
||||
void* match(Uncompressed& u) {
|
||||
return (void*) u.string.chars();
|
||||
}
|
||||
|
||||
ReturnType match(Compressed& c) {
|
||||
void* match(Compressed& c) {
|
||||
return (void*) c.raw.chars();
|
||||
}
|
||||
|
||||
ReturnType match(Missing&) {
|
||||
void* match(Missing&) {
|
||||
MOZ_CRASH("Missing source data in ScriptSource::performXDR");
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -739,17 +739,15 @@ class ScriptSource
|
|||
size_t length() const {
|
||||
struct LengthMatcher
|
||||
{
|
||||
using ReturnType = size_t;
|
||||
|
||||
ReturnType match(const Uncompressed& u) {
|
||||
size_t match(const Uncompressed& u) {
|
||||
return u.string.length();
|
||||
}
|
||||
|
||||
ReturnType match(const Compressed& c) {
|
||||
size_t match(const Compressed& c) {
|
||||
return c.uncompressedLength;
|
||||
}
|
||||
|
||||
ReturnType match(const Missing& m) {
|
||||
size_t match(const Missing& m) {
|
||||
MOZ_CRASH("ScriptSource::length on a missing source");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1565,8 +1565,6 @@ ConcreteStackFrame<SavedFrame>::constructSavedFrameStack(JSContext* cx,
|
|||
// `JS::ubi::AtomOrTwoByteChars` string to a `JSAtom*`.
|
||||
struct MOZ_STACK_CLASS AtomizingMatcher
|
||||
{
|
||||
using ReturnType = JSAtom*;
|
||||
|
||||
JSContext* cx;
|
||||
size_t length;
|
||||
|
||||
|
|
|
@ -55,8 +55,6 @@ using JS::ubi::TracerConcreteWithCompartment;
|
|||
|
||||
struct CopyToBufferMatcher
|
||||
{
|
||||
using ReturnType = size_t;
|
||||
|
||||
RangedPtr<char16_t> destination;
|
||||
size_t maxLength;
|
||||
|
||||
|
@ -108,8 +106,6 @@ JS::ubi::AtomOrTwoByteChars::copyToBuffer(RangedPtr<char16_t> destination, size_
|
|||
|
||||
struct LengthMatcher
|
||||
{
|
||||
using ReturnType = size_t;
|
||||
|
||||
size_t
|
||||
match(JSAtom* atom)
|
||||
{
|
||||
|
|
|
@ -169,10 +169,11 @@ struct VariantImplementation<N, T> {
|
|||
return aLhs.template as<T>() == aRhs.template as<T>();
|
||||
}
|
||||
|
||||
template<typename Matcher, typename ConcreteVariant,
|
||||
typename ReturnType = typename RemoveReference<Matcher>::Type::ReturnType>
|
||||
static ReturnType
|
||||
match(Matcher&& aMatcher, ConcreteVariant& aV) {
|
||||
template<typename Matcher, typename ConcreteVariant>
|
||||
static auto
|
||||
match(Matcher&& aMatcher, ConcreteVariant& aV)
|
||||
-> decltype(aMatcher.match(aV.template as<T>()))
|
||||
{
|
||||
return aMatcher.match(aV.template as<T>());
|
||||
}
|
||||
};
|
||||
|
@ -226,10 +227,10 @@ struct VariantImplementation<N, T, Ts...>
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Matcher, typename ConcreteVariant,
|
||||
typename ReturnType = typename RemoveReference<Matcher>::Type::ReturnType>
|
||||
static ReturnType
|
||||
template<typename Matcher, typename ConcreteVariant>
|
||||
static auto
|
||||
match(Matcher&& aMatcher, ConcreteVariant& aV)
|
||||
-> decltype(aMatcher.match(aV.template as<T>()))
|
||||
{
|
||||
if (aV.template is<T>()) {
|
||||
return aMatcher.match(aV.template as<T>());
|
||||
|
@ -370,11 +371,11 @@ struct AsVariantTemporary
|
|||
* // Good!
|
||||
* struct FooMatcher
|
||||
* {
|
||||
* using ReturnType = char*;
|
||||
* ReturnType match(A& a) { ... }
|
||||
* ReturnType match(B& b) { ... }
|
||||
* ReturnType match(C& c) { ... }
|
||||
* ReturnType match(D& d) { ... } // Compile-time error to forget D!
|
||||
* // The return type of all matchers must be identical.
|
||||
* char* match(A& a) { ... }
|
||||
* char* match(B& b) { ... }
|
||||
* char* match(C& c) { ... }
|
||||
* char* match(D& d) { ... } // Compile-time error to forget D!
|
||||
* }
|
||||
* char* foo(Variant<A, B, C, D>& v) {
|
||||
* return v.match(FooMatcher());
|
||||
|
@ -558,15 +559,19 @@ public:
|
|||
|
||||
/** Match on an immutable const reference. */
|
||||
template<typename Matcher>
|
||||
typename RemoveReference<Matcher>::Type::ReturnType
|
||||
match(Matcher&& aMatcher) const {
|
||||
auto
|
||||
match(Matcher&& aMatcher) const
|
||||
-> decltype(Impl::match(aMatcher, *this))
|
||||
{
|
||||
return Impl::match(aMatcher, *this);
|
||||
}
|
||||
|
||||
/** Match on a mutable non-const reference. */
|
||||
template<typename Matcher>
|
||||
typename RemoveReference<Matcher>::Type::ReturnType
|
||||
match(Matcher&& aMatcher) {
|
||||
auto
|
||||
match(Matcher&& aMatcher)
|
||||
-> decltype(Impl::match(aMatcher, *this))
|
||||
{
|
||||
return Impl::match(aMatcher, *this);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -129,8 +129,6 @@ struct Describer
|
|||
static const char* medium;
|
||||
static const char* big;
|
||||
|
||||
using ReturnType = const char*;
|
||||
|
||||
const char* match(const uint8_t&) { return little; }
|
||||
const char* match(const uint32_t&) { return medium; }
|
||||
const char* match(const uint64_t&) { return big; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче