mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1170325 - Convert js::Vector into a template alias to mozilla::Vector with a single customized default argument. Also get rid of the CRTP support in mozilla::Vector (through mozilla::VectorBase) now that template aliasing is good enough, and make mozilla::Vector final so that people will use composition and not inheritance with it. (Inheritance plays poorly with movability and a few other things, in addition to messing up template argument deduction matching.) r=Waldo, patch sort of a tag-team between him and me
This commit is contained in:
parent
1c73cd386d
commit
4c67f636ce
@ -43,14 +43,11 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the deferred tasks in |mDeferredTasks|. See |mDeferredTasks|
|
||||
* for more information.
|
||||
* Clears |mDeferredTasks|.
|
||||
* Get the deferred tasks in |mDeferredTasks| and place them in |aTasks|. See
|
||||
* |mDeferredTasks| for more information. Clears |mDeferredTasks|.
|
||||
*/
|
||||
Vector<Task*> TakeDeferredTasks() {
|
||||
Vector<Task*> result;
|
||||
mDeferredTasks.swap(result);
|
||||
return result;
|
||||
void TakeDeferredTasks(Vector<Task*>& aTasks) {
|
||||
mDeferredTasks.swap(aTasks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2880,7 +2880,7 @@ bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
||||
|
||||
if (mAnimation) {
|
||||
bool continueAnimation = mAnimation->Sample(mFrameMetrics, sampleTimeDelta);
|
||||
*aOutDeferredTasks = mAnimation->TakeDeferredTasks();
|
||||
mAnimation->TakeDeferredTasks(*aOutDeferredTasks);
|
||||
if (continueAnimation) {
|
||||
if (mPaintThrottler->TimeSinceLastRequest(aSampleTime) >
|
||||
mAnimation->mRepaintInterval) {
|
||||
|
@ -33,26 +33,96 @@ template <typename T,
|
||||
size_t MinInlineCapacity = 0,
|
||||
typename AllocPolicy = TempAllocPolicy,
|
||||
typename GCPolicy = DefaultGCPolicy<T>>
|
||||
class TraceableVector
|
||||
: public mozilla::VectorBase<T,
|
||||
MinInlineCapacity,
|
||||
AllocPolicy,
|
||||
TraceableVector<T, MinInlineCapacity, AllocPolicy, GCPolicy>>,
|
||||
public JS::Traceable
|
||||
class TraceableVector : public JS::Traceable
|
||||
{
|
||||
using Base = mozilla::VectorBase<T, MinInlineCapacity, AllocPolicy, TraceableVector>;
|
||||
mozilla::Vector<T, MinInlineCapacity, AllocPolicy> vector;
|
||||
|
||||
public:
|
||||
explicit TraceableVector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {}
|
||||
TraceableVector(TraceableVector&& vec) : Base(mozilla::Forward<TraceableVector>(vec)) {}
|
||||
explicit TraceableVector(AllocPolicy alloc = AllocPolicy())
|
||||
: vector(alloc)
|
||||
{}
|
||||
|
||||
TraceableVector(TraceableVector&& vec)
|
||||
: vector(mozilla::Move(vec.vector))
|
||||
{}
|
||||
|
||||
TraceableVector& operator=(TraceableVector&& vec) {
|
||||
return Base::operator=(mozilla::Forward<TraceableVector>(vec));
|
||||
vector = mozilla::Move(vec.vector);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t length() const { return vector.length(); }
|
||||
bool empty() const { return vector.empty(); }
|
||||
size_t capacity() const { return vector.capacity(); }
|
||||
|
||||
T* begin() { return vector.begin(); }
|
||||
const T* begin() const { return vector.begin(); }
|
||||
|
||||
T* end() { return vector.end(); }
|
||||
const T* end() const { return vector.end(); }
|
||||
|
||||
T& operator[](size_t i) { return vector[i]; }
|
||||
const T& operator[](size_t i) const { return vector[i]; }
|
||||
|
||||
T& back() { return vector.back(); }
|
||||
const T& back() const { return vector.back(); }
|
||||
|
||||
bool initCapacity(size_t cap) { return vector.initCapacity(cap); }
|
||||
bool reserve(size_t req) { return vector.reserve(req); }
|
||||
void shrinkBy(size_t amount) { return vector.shrinkBy(amount); }
|
||||
bool growBy(size_t amount) { return vector.growBy(amount); }
|
||||
bool resize(size_t newLen) { return vector.resize(newLen); }
|
||||
|
||||
void clear() { return vector.clear(); }
|
||||
|
||||
template<typename U> bool append(U&& item) { return vector.append(mozilla::Forward<U>(item)); }
|
||||
|
||||
template<typename... Args>
|
||||
bool
|
||||
emplaceBack(Args&&... args) {
|
||||
return vector.emplaceBack(mozilla::Forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
void infallibleAppend(U&& aU) {
|
||||
return vector.infallibleAppend(mozilla::Forward<U>(aU));
|
||||
}
|
||||
void infallibleAppendN(const T& aT, size_t aN) {
|
||||
return vector.infallibleAppendN(aT, aN);
|
||||
}
|
||||
template<typename U> void
|
||||
infallibleAppend(const U* aBegin, const U* aEnd) {
|
||||
return vector.infallibleAppend(aBegin, aEnd);
|
||||
}
|
||||
template<typename U> void infallibleAppend(const U* aBegin, size_t aLength) {
|
||||
return vector.infallibleAppend(aBegin, aLength);
|
||||
}
|
||||
|
||||
bool appendN(const T& val, size_t count) { return vector.appendN(val, count); }
|
||||
|
||||
template<typename U> bool append(const U* aBegin, const U* aEnd) {
|
||||
return vector.append(aBegin, aEnd);
|
||||
}
|
||||
template<typename U> bool append(const U* aBegin, size_t aLength) {
|
||||
return vector.append(aBegin, aLength);
|
||||
}
|
||||
|
||||
void popBack() { return vector.popBack(); }
|
||||
T popCopy() { return vector.popCopy(); }
|
||||
|
||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
|
||||
return vector.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
|
||||
return vector.sizeOfIncludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
static void trace(TraceableVector* vec, JSTracer* trc) { vec->trace(trc); }
|
||||
|
||||
void trace(JSTracer* trc) {
|
||||
for (size_t i = 0; i < this->length(); ++i)
|
||||
GCPolicy::trace(trc, &Base::operator[](i), "vector element");
|
||||
for (auto& elem : vector)
|
||||
GCPolicy::trace(trc, &elem, "vector element");
|
||||
}
|
||||
};
|
||||
|
||||
@ -114,8 +184,8 @@ class MutableTraceableVectorOperations
|
||||
template<typename... Args> bool emplaceBack(Args&&... aArgs) {
|
||||
return vec().emplaceBack(mozilla::Forward<Args...>(aArgs...));
|
||||
}
|
||||
template<typename U, size_t O, class BP, class UV>
|
||||
bool appendAll(const mozilla::VectorBase<U, O, BP, UV>& aU) { return vec().appendAll(aU); }
|
||||
template<typename U, size_t O, class BP>
|
||||
bool appendAll(const mozilla::Vector<U, O, BP>& aU) { return vec().appendAll(aU); }
|
||||
bool appendN(const T& aT, size_t aN) { return vec().appendN(aT, aN); }
|
||||
template<typename U> bool append(const U* aBegin, const U* aEnd) {
|
||||
return vec().append(aBegin, aEnd);
|
||||
|
@ -19,47 +19,32 @@ namespace js {
|
||||
|
||||
class TempAllocPolicy;
|
||||
|
||||
// If we had C++11 template aliases, we could just use this:
|
||||
//
|
||||
// template <typename T,
|
||||
// size_t MinInlineCapacity = 0,
|
||||
// class AllocPolicy = TempAllocPolicy>
|
||||
// using Vector = mozilla::Vector<T, MinInlineCapacity, AllocPolicy>;
|
||||
//
|
||||
// ...and get rid of all the CRTP madness in mozilla::Vector(Base). But we
|
||||
// can't because compiler support's not up to snuff. (Template aliases are in
|
||||
// gcc 4.7 and clang 3.0 and are expected to be in MSVC 2013.) Instead, have a
|
||||
// completely separate class inheriting from mozilla::Vector, and throw CRTP at
|
||||
// the problem til things work.
|
||||
//
|
||||
// This workaround presents a couple issues. First, because js::Vector is a
|
||||
// distinct type from mozilla::Vector, overload resolution, method calls, etc.
|
||||
// are affected. *Hopefully* this won't be too bad in practice. (A bunch of
|
||||
// places had to be fixed when mozilla::Vector was introduced, but it wasn't a
|
||||
// crazy number.) Second, mozilla::Vector's interface has to be made subclass-
|
||||
// ready via CRTP -- or rather, via mozilla::VectorBase, which basically no one
|
||||
// should use. :-) Third, we have to redefine the constructors and the non-
|
||||
// inherited operators. Blech. Happily there aren't too many of these, so it
|
||||
// isn't the end of the world.
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct TypeIsGCThing : mozilla::FalseType
|
||||
{};
|
||||
|
||||
// Uncomment this once we actually can assert it:
|
||||
//template <>
|
||||
//struct TypeIsGCThing<JS::Value> : mozilla::TrueType
|
||||
//{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T,
|
||||
size_t MinInlineCapacity = 0,
|
||||
class AllocPolicy = TempAllocPolicy>
|
||||
class Vector
|
||||
: public mozilla::VectorBase<T,
|
||||
MinInlineCapacity,
|
||||
AllocPolicy,
|
||||
Vector<T, MinInlineCapacity, AllocPolicy> >
|
||||
{
|
||||
typedef typename mozilla::VectorBase<T, MinInlineCapacity, AllocPolicy, Vector> Base;
|
||||
|
||||
public:
|
||||
explicit Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {}
|
||||
Vector(Vector&& vec) : Base(mozilla::Move(vec)) {}
|
||||
Vector& operator=(Vector&& vec) {
|
||||
return Base::operator=(mozilla::Move(vec));
|
||||
}
|
||||
};
|
||||
class AllocPolicy = TempAllocPolicy
|
||||
// 1800 is MSVC2013. Optimistically assume MSVC2015 (1900) is fixed.
|
||||
// If you're porting to MSVC2015 and this doesn't work, extend the
|
||||
// condition to encompass that additional version (but *do* keep the
|
||||
// version-check so we know when MSVC's fixed).
|
||||
#if !defined(_MSC_VER) || (1800 <= _MSC_VER && _MSC_VER <= 1800)
|
||||
// Don't use this with JS::Value! Use JS::AutoValueVector instead.
|
||||
, typename = typename mozilla::EnableIf<!detail::TypeIsGCThing<T>::value>::Type
|
||||
#endif
|
||||
>
|
||||
using Vector = mozilla::Vector<T, MinInlineCapacity, AllocPolicy>;
|
||||
|
||||
} // namespace js
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "mozilla/EnumeratedRange.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/TaggedAnonymousMemory.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include "jslibmath.h"
|
||||
#include "jsmath.h"
|
||||
@ -1132,7 +1133,7 @@ AsmJSModule::Name::clone(ExclusiveContext* cx, Name* out) const
|
||||
|
||||
template <class T, size_t N>
|
||||
size_t
|
||||
SerializedVectorSize(const Vector<T, N, SystemAllocPolicy>& vec)
|
||||
SerializedVectorSize(const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
|
||||
{
|
||||
size_t size = sizeof(uint32_t);
|
||||
for (size_t i = 0; i < vec.length(); i++)
|
||||
@ -1142,7 +1143,7 @@ SerializedVectorSize(const Vector<T, N, SystemAllocPolicy>& vec)
|
||||
|
||||
template <class T, size_t N>
|
||||
uint8_t*
|
||||
SerializeVector(uint8_t* cursor, const Vector<T, N, SystemAllocPolicy>& vec)
|
||||
SerializeVector(uint8_t* cursor, const mozilla::Vector<T, N, SystemAllocPolicy>& vec)
|
||||
{
|
||||
cursor = WriteScalar<uint32_t>(cursor, vec.length());
|
||||
for (size_t i = 0; i < vec.length(); i++)
|
||||
@ -1152,7 +1153,8 @@ SerializeVector(uint8_t* cursor, const Vector<T, N, SystemAllocPolicy>& vec)
|
||||
|
||||
template <class T, size_t N>
|
||||
const uint8_t*
|
||||
DeserializeVector(ExclusiveContext* cx, const uint8_t* cursor, Vector<T, N, SystemAllocPolicy>* vec)
|
||||
DeserializeVector(ExclusiveContext* cx, const uint8_t* cursor,
|
||||
mozilla::Vector<T, N, SystemAllocPolicy>* vec)
|
||||
{
|
||||
uint32_t length;
|
||||
cursor = ReadScalar<uint32_t>(cursor, &length);
|
||||
@ -1167,8 +1169,8 @@ DeserializeVector(ExclusiveContext* cx, const uint8_t* cursor, Vector<T, N, Syst
|
||||
|
||||
template <class T, size_t N>
|
||||
bool
|
||||
CloneVector(ExclusiveContext* cx, const Vector<T, N, SystemAllocPolicy>& in,
|
||||
Vector<T, N, SystemAllocPolicy>* out)
|
||||
CloneVector(ExclusiveContext* cx, const mozilla::Vector<T, N, SystemAllocPolicy>& in,
|
||||
mozilla::Vector<T, N, SystemAllocPolicy>* out)
|
||||
{
|
||||
if (!out->resize(in.length()))
|
||||
return false;
|
||||
@ -1179,27 +1181,27 @@ CloneVector(ExclusiveContext* cx, const Vector<T, N, SystemAllocPolicy>& in,
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T, size_t N, class AllocPolicy, class ThisVector>
|
||||
template <class T, size_t N, class AllocPolicy>
|
||||
size_t
|
||||
SerializedPodVectorSize(const mozilla::VectorBase<T, N, AllocPolicy, ThisVector>& vec)
|
||||
SerializedPodVectorSize(const mozilla::Vector<T, N, AllocPolicy>& vec)
|
||||
{
|
||||
return sizeof(uint32_t) +
|
||||
vec.length() * sizeof(T);
|
||||
}
|
||||
|
||||
template <class T, size_t N, class AllocPolicy, class ThisVector>
|
||||
template <class T, size_t N, class AllocPolicy>
|
||||
uint8_t*
|
||||
SerializePodVector(uint8_t* cursor, const mozilla::VectorBase<T, N, AllocPolicy, ThisVector>& vec)
|
||||
SerializePodVector(uint8_t* cursor, const mozilla::Vector<T, N, AllocPolicy>& vec)
|
||||
{
|
||||
cursor = WriteScalar<uint32_t>(cursor, vec.length());
|
||||
cursor = WriteBytes(cursor, vec.begin(), vec.length() * sizeof(T));
|
||||
return cursor;
|
||||
}
|
||||
|
||||
template <class T, size_t N, class AllocPolicy, class ThisVector>
|
||||
template <class T, size_t N, class AllocPolicy>
|
||||
const uint8_t*
|
||||
DeserializePodVector(ExclusiveContext* cx, const uint8_t* cursor,
|
||||
mozilla::VectorBase<T, N, AllocPolicy, ThisVector>* vec)
|
||||
mozilla::Vector<T, N, AllocPolicy>* vec)
|
||||
{
|
||||
uint32_t length;
|
||||
cursor = ReadScalar<uint32_t>(cursor, &length);
|
||||
@ -1211,8 +1213,8 @@ DeserializePodVector(ExclusiveContext* cx, const uint8_t* cursor,
|
||||
|
||||
template <class T, size_t N>
|
||||
bool
|
||||
ClonePodVector(ExclusiveContext* cx, const Vector<T, N, SystemAllocPolicy>& in,
|
||||
Vector<T, N, SystemAllocPolicy>* out)
|
||||
ClonePodVector(ExclusiveContext* cx, const mozilla::Vector<T, N, SystemAllocPolicy>& in,
|
||||
mozilla::Vector<T, N, SystemAllocPolicy>* out)
|
||||
{
|
||||
if (!out->resize(in.length()))
|
||||
return false;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/NumericLimits.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
@ -40,6 +41,7 @@
|
||||
#include "builtin/TypedObject.h"
|
||||
#include "ctypes/Library.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
@ -2658,7 +2660,7 @@ jsvalToPtrExplicit(JSContext* cx, Value val, uintptr_t* result)
|
||||
|
||||
template<class IntegerType, class CharType, size_t N, class AP>
|
||||
void
|
||||
IntegerToString(IntegerType i, int radix, Vector<CharType, N, AP>& result)
|
||||
IntegerToString(IntegerType i, int radix, mozilla::Vector<CharType, N, AP>& result)
|
||||
{
|
||||
JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
|
||||
|
||||
@ -3654,7 +3656,7 @@ BuildTypeSource(JSContext* cx,
|
||||
|
||||
const FieldInfoHash* fields = StructType::GetFieldInfo(typeObj);
|
||||
size_t length = fields->count();
|
||||
Array<const FieldInfoHash::Entry*, 64> fieldsArray;
|
||||
Vector<const FieldInfoHash::Entry*, 64, SystemAllocPolicy> fieldsArray;
|
||||
if (!fieldsArray.resize(length))
|
||||
break;
|
||||
|
||||
@ -3812,7 +3814,7 @@ BuildDataSource(JSContext* cx,
|
||||
// be able to ImplicitConvert successfully.
|
||||
const FieldInfoHash* fields = StructType::GetFieldInfo(typeObj);
|
||||
size_t length = fields->count();
|
||||
Array<const FieldInfoHash::Entry*, 64> fieldsArray;
|
||||
Vector<const FieldInfoHash::Entry*, 64, SystemAllocPolicy> fieldsArray;
|
||||
if (!fieldsArray.resize(length))
|
||||
return false;
|
||||
|
||||
@ -6510,7 +6512,7 @@ FunctionType::ConstructData(JSContext* cx,
|
||||
return JS_FreezeObject(cx, dataObj);
|
||||
}
|
||||
|
||||
typedef Array<AutoValue, 16> AutoValueAutoArray;
|
||||
typedef Vector<AutoValue, 16, SystemAllocPolicy> AutoValueAutoArray;
|
||||
|
||||
static bool
|
||||
ConvertArgument(JSContext* cx,
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define ctypes_CTypes_h
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include "ffi.h"
|
||||
#include "jsalloc.h"
|
||||
@ -25,14 +26,6 @@ namespace ctypes {
|
||||
** Utility classes
|
||||
*******************************************************************************/
|
||||
|
||||
// Container class for Vector, using SystemAllocPolicy.
|
||||
template<class T, size_t N = 0>
|
||||
class Array : public Vector<T, N, SystemAllocPolicy>
|
||||
{
|
||||
static_assert(!mozilla::IsSame<T, JS::Value>::value,
|
||||
"use JS::AutoValueVector instead");
|
||||
};
|
||||
|
||||
// String and AutoString classes, based on Vector.
|
||||
typedef Vector<char16_t, 0, SystemAllocPolicy> String;
|
||||
typedef Vector<char16_t, 64, SystemAllocPolicy> AutoString;
|
||||
@ -42,7 +35,7 @@ typedef Vector<char, 64, SystemAllocPolicy> AutoCString;
|
||||
// Convenience functions to append, insert, and compare Strings.
|
||||
template <class T, size_t N, class AP, size_t ArrayLength>
|
||||
void
|
||||
AppendString(Vector<T, N, AP>& v, const char (&array)[ArrayLength])
|
||||
AppendString(mozilla::Vector<T, N, AP>& v, const char (&array)[ArrayLength])
|
||||
{
|
||||
// Don't include the trailing '\0'.
|
||||
size_t alen = ArrayLength - 1;
|
||||
@ -56,7 +49,7 @@ AppendString(Vector<T, N, AP>& v, const char (&array)[ArrayLength])
|
||||
|
||||
template <class T, size_t N, class AP>
|
||||
void
|
||||
AppendChars(Vector<T, N, AP>& v, const char c, size_t count)
|
||||
AppendChars(mozilla::Vector<T, N, AP>& v, const char c, size_t count)
|
||||
{
|
||||
size_t vlen = v.length();
|
||||
if (!v.resize(vlen + count))
|
||||
@ -68,7 +61,7 @@ AppendChars(Vector<T, N, AP>& v, const char c, size_t count)
|
||||
|
||||
template <class T, size_t N, class AP>
|
||||
void
|
||||
AppendUInt(Vector<T, N, AP>& v, unsigned n)
|
||||
AppendUInt(mozilla::Vector<T, N, AP>& v, unsigned n)
|
||||
{
|
||||
char array[16];
|
||||
size_t alen = JS_snprintf(array, 16, "%u", n);
|
||||
@ -82,14 +75,14 @@ AppendUInt(Vector<T, N, AP>& v, unsigned n)
|
||||
|
||||
template <class T, size_t N, size_t M, class AP>
|
||||
void
|
||||
AppendString(Vector<T, N, AP>& v, Vector<T, M, AP>& w)
|
||||
AppendString(mozilla::Vector<T, N, AP>& v, mozilla::Vector<T, M, AP>& w)
|
||||
{
|
||||
v.append(w.begin(), w.length());
|
||||
}
|
||||
|
||||
template <size_t N, class AP>
|
||||
void
|
||||
AppendString(Vector<char16_t, N, AP>& v, JSString* str)
|
||||
AppendString(mozilla::Vector<char16_t, N, AP>& v, JSString* str)
|
||||
{
|
||||
MOZ_ASSERT(str);
|
||||
JSLinearString* linear = str->ensureLinear(nullptr);
|
||||
@ -104,7 +97,7 @@ AppendString(Vector<char16_t, N, AP>& v, JSString* str)
|
||||
|
||||
template <size_t N, class AP>
|
||||
void
|
||||
AppendString(Vector<char, N, AP>& v, JSString* str)
|
||||
AppendString(mozilla::Vector<char, N, AP>& v, JSString* str)
|
||||
{
|
||||
MOZ_ASSERT(str);
|
||||
size_t vlen = v.length();
|
||||
@ -130,7 +123,7 @@ AppendString(Vector<char, N, AP>& v, JSString* str)
|
||||
|
||||
template <class T, size_t N, class AP, size_t ArrayLength>
|
||||
void
|
||||
PrependString(Vector<T, N, AP>& v, const char (&array)[ArrayLength])
|
||||
PrependString(mozilla::Vector<T, N, AP>& v, const char (&array)[ArrayLength])
|
||||
{
|
||||
// Don't include the trailing '\0'.
|
||||
size_t alen = ArrayLength - 1;
|
||||
@ -148,7 +141,7 @@ PrependString(Vector<T, N, AP>& v, const char (&array)[ArrayLength])
|
||||
|
||||
template <size_t N, class AP>
|
||||
void
|
||||
PrependString(Vector<char16_t, N, AP>& v, JSString* str)
|
||||
PrependString(mozilla::Vector<char16_t, N, AP>& v, JSString* str)
|
||||
{
|
||||
MOZ_ASSERT(str);
|
||||
size_t vlen = v.length();
|
||||
@ -306,12 +299,12 @@ struct FunctionInfo
|
||||
|
||||
// A fixed array of known parameter types, excluding any variadic
|
||||
// parameters (if mIsVariadic).
|
||||
Array<JS::Heap<JSObject*> > mArgTypes;
|
||||
Vector<JS::Heap<JSObject*>, 0, SystemAllocPolicy> mArgTypes;
|
||||
|
||||
// A variable array of ffi_type*s corresponding to both known parameter
|
||||
// types and dynamic (variadic) parameter types. Longer than mArgTypes
|
||||
// only if mIsVariadic.
|
||||
Array<ffi_type*> mFFITypes;
|
||||
Vector<ffi_type*, 0, SystemAllocPolicy> mFFITypes;
|
||||
|
||||
// Flag indicating whether the function behaves like a C function with
|
||||
// ... as the final formal parameter.
|
||||
|
@ -537,7 +537,7 @@ struct Callback {
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
class CallbackVector : public Vector<Callback<F>, 4, SystemAllocPolicy> {};
|
||||
using CallbackVector = Vector<Callback<F>, 4, SystemAllocPolicy>;
|
||||
|
||||
template <typename T, typename Iter0, typename Iter1>
|
||||
class ChainedIter
|
||||
|
279
mfbt/Vector.h
279
mfbt/Vector.h
@ -31,8 +31,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template<typename T, size_t N, class AllocPolicy, class ThisVector>
|
||||
class VectorBase;
|
||||
template<typename T, size_t N, class AllocPolicy>
|
||||
class Vector;
|
||||
|
||||
namespace detail {
|
||||
|
||||
@ -52,7 +52,7 @@ static bool CapacityHasExcessSpace(size_t aCapacity)
|
||||
* This template class provides a default implementation for vector operations
|
||||
* when the element type is not known to be a POD, as judged by IsPod.
|
||||
*/
|
||||
template<typename T, size_t N, class AP, class ThisVector, bool IsPod>
|
||||
template<typename T, size_t N, class AP, bool IsPod>
|
||||
struct VectorImpl
|
||||
{
|
||||
/*
|
||||
@ -138,7 +138,7 @@ struct VectorImpl
|
||||
* not overflow.
|
||||
*/
|
||||
static inline bool
|
||||
growTo(VectorBase<T, N, AP, ThisVector>& aV, size_t aNewCap)
|
||||
growTo(Vector<T, N, AP>& aV, size_t aNewCap)
|
||||
{
|
||||
MOZ_ASSERT(!aV.usingInlineStorage());
|
||||
MOZ_ASSERT(!CapacityHasExcessSpace<T>(aNewCap));
|
||||
@ -165,8 +165,8 @@ struct VectorImpl
|
||||
* vector operations when the element type is known to be a POD, as judged by
|
||||
* IsPod.
|
||||
*/
|
||||
template<typename T, size_t N, class AP, class ThisVector>
|
||||
struct VectorImpl<T, N, AP, ThisVector, true>
|
||||
template<typename T, size_t N, class AP>
|
||||
struct VectorImpl<T, N, AP, true>
|
||||
{
|
||||
static inline void new_(T* aDst)
|
||||
{
|
||||
@ -229,7 +229,7 @@ struct VectorImpl<T, N, AP, ThisVector, true>
|
||||
}
|
||||
|
||||
static inline bool
|
||||
growTo(VectorBase<T, N, AP, ThisVector>& aV, size_t aNewCap)
|
||||
growTo(Vector<T, N, AP>& aV, size_t aNewCap)
|
||||
{
|
||||
MOZ_ASSERT(!aV.usingInlineStorage());
|
||||
MOZ_ASSERT(!CapacityHasExcessSpace<T>(aNewCap));
|
||||
@ -251,20 +251,33 @@ struct VectorTesting;
|
||||
} // namespace detail
|
||||
|
||||
/*
|
||||
* A CRTP base class for vector-like classes. Unless you really really want
|
||||
* your own vector class -- and you almost certainly don't -- you should use
|
||||
* mozilla::Vector instead!
|
||||
* STL-like container providing a short-lived, dynamic buffer. Vector calls the
|
||||
* constructors/destructors of all elements stored in its internal buffer, so
|
||||
* non-PODs may be safely used. Additionally, Vector will store the first N
|
||||
* elements in-place before resorting to dynamic allocation.
|
||||
*
|
||||
* See mozilla::Vector for interface requirements.
|
||||
* T requirements:
|
||||
* - default and copy constructible, assignable, destructible
|
||||
* - operations do not throw
|
||||
* MinInlineCapacity requirements:
|
||||
* - any value, however, MinInlineCapacity is clamped to min/max values
|
||||
* AllocPolicy:
|
||||
* - see "Allocation policies" in AllocPolicy.h (defaults to
|
||||
* mozilla::MallocAllocPolicy)
|
||||
*
|
||||
* Vector is not reentrant: T member functions called during Vector member
|
||||
* functions must not call back into the same object!
|
||||
*/
|
||||
template<typename T, size_t N, class AllocPolicy, class ThisVector>
|
||||
class VectorBase : private AllocPolicy
|
||||
template<typename T,
|
||||
size_t MinInlineCapacity = 0,
|
||||
class AllocPolicy = MallocAllocPolicy>
|
||||
class Vector final : private AllocPolicy
|
||||
{
|
||||
/* utilities */
|
||||
|
||||
static const bool kElemIsPod = IsPod<T>::value;
|
||||
typedef detail::VectorImpl<T, N, AllocPolicy, ThisVector, kElemIsPod> Impl;
|
||||
friend struct detail::VectorImpl<T, N, AllocPolicy, ThisVector, kElemIsPod>;
|
||||
typedef detail::VectorImpl<T, MinInlineCapacity, AllocPolicy, kElemIsPod> Impl;
|
||||
friend struct detail::VectorImpl<T, MinInlineCapacity, AllocPolicy, kElemIsPod>;
|
||||
|
||||
friend struct detail::VectorTesting;
|
||||
|
||||
@ -298,11 +311,11 @@ class VectorBase : private AllocPolicy
|
||||
};
|
||||
|
||||
static const size_t kInlineCapacity =
|
||||
tl::Min<N, kMaxInlineBytes / ElemSize<N, 0>::value>::value;
|
||||
tl::Min<MinInlineCapacity, kMaxInlineBytes / ElemSize<MinInlineCapacity, 0>::value>::value;
|
||||
|
||||
/* Calculate inline buffer size; avoid 0-sized array. */
|
||||
static const size_t kInlineBytes =
|
||||
tl::Max<1, kInlineCapacity * ElemSize<N, 0>::value>::value;
|
||||
tl::Max<1, kInlineCapacity * ElemSize<MinInlineCapacity, 0>::value>::value;
|
||||
|
||||
/* member data */
|
||||
|
||||
@ -338,7 +351,7 @@ class VectorBase : private AllocPolicy
|
||||
|
||||
bool usingInlineStorage() const
|
||||
{
|
||||
return mBegin == const_cast<VectorBase*>(this)->inlineStorage();
|
||||
return mBegin == const_cast<Vector*>(this)->inlineStorage();
|
||||
}
|
||||
|
||||
T* inlineStorage()
|
||||
@ -379,20 +392,20 @@ class VectorBase : private AllocPolicy
|
||||
|
||||
/* Append operations guaranteed to succeed due to pre-reserved space. */
|
||||
template<typename U> void internalAppend(U&& aU);
|
||||
template<typename U, size_t O, class BP, class UV>
|
||||
void internalAppendAll(const VectorBase<U, O, BP, UV>& aU);
|
||||
template<typename U, size_t O, class BP>
|
||||
void internalAppendAll(const Vector<U, O, BP>& aU);
|
||||
void internalAppendN(const T& aT, size_t aN);
|
||||
template<typename U> void internalAppend(const U* aBegin, size_t aLength);
|
||||
|
||||
public:
|
||||
static const size_t sMaxInlineStorage = N;
|
||||
static const size_t sMaxInlineStorage = MinInlineCapacity;
|
||||
|
||||
typedef T ElementType;
|
||||
|
||||
explicit VectorBase(AllocPolicy = AllocPolicy());
|
||||
explicit VectorBase(ThisVector&&); /* Move constructor. */
|
||||
ThisVector& operator=(ThisVector&&); /* Move assignment. */
|
||||
~VectorBase();
|
||||
explicit Vector(AllocPolicy = AllocPolicy());
|
||||
Vector(Vector&&); /* Move constructor. */
|
||||
Vector& operator=(Vector&&); /* Move assignment. */
|
||||
~Vector();
|
||||
|
||||
/* accessors */
|
||||
|
||||
@ -400,7 +413,7 @@ public:
|
||||
|
||||
AllocPolicy& allocPolicy() { return *this; }
|
||||
|
||||
enum { InlineLength = N };
|
||||
enum { InlineLength = MinInlineCapacity };
|
||||
|
||||
size_t length() const { return mLength; }
|
||||
|
||||
@ -462,7 +475,7 @@ public:
|
||||
|
||||
class Range
|
||||
{
|
||||
friend class VectorBase;
|
||||
friend class Vector;
|
||||
T* mCur;
|
||||
T* mEnd;
|
||||
Range(T* aCur, T* aEnd)
|
||||
@ -482,7 +495,7 @@ public:
|
||||
|
||||
class ConstRange
|
||||
{
|
||||
friend class VectorBase;
|
||||
friend class Vector;
|
||||
const T* mCur;
|
||||
const T* mEnd;
|
||||
ConstRange(const T* aCur, const T* aEnd)
|
||||
@ -576,8 +589,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename U, size_t O, class BP, class UV>
|
||||
bool appendAll(const VectorBase<U, O, BP, UV>& aU);
|
||||
template<typename U, size_t O, class BP>
|
||||
bool appendAll(const Vector<U, O, BP>& aU);
|
||||
bool appendN(const T& aT, size_t aN);
|
||||
template<typename U> bool append(const U* aBegin, const U* aEnd);
|
||||
template<typename U> bool append(const U* aBegin, size_t aLength);
|
||||
@ -678,15 +691,11 @@ public:
|
||||
*/
|
||||
size_t sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
void swap(ThisVector& aOther);
|
||||
void swap(Vector& aOther);
|
||||
|
||||
private:
|
||||
VectorBase(const VectorBase&) = delete;
|
||||
void operator=(const VectorBase&) = delete;
|
||||
|
||||
/* Move-construct/assign only from our derived class, ThisVector. */
|
||||
VectorBase(VectorBase&&) = delete;
|
||||
void operator=(VectorBase&&) = delete;
|
||||
Vector(const Vector&) = delete;
|
||||
void operator=(const Vector&) = delete;
|
||||
};
|
||||
|
||||
/* This does the re-entrancy check plus several other sanity checks. */
|
||||
@ -699,9 +708,9 @@ private:
|
||||
|
||||
/* Vector Implementation */
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE
|
||||
VectorBase<T, N, AP, TV>::VectorBase(AP aAP)
|
||||
Vector<T, N, AP>::Vector(AP aAP)
|
||||
: AP(aAP)
|
||||
, mLength(0)
|
||||
, mCapacity(kInlineCapacity)
|
||||
@ -714,9 +723,9 @@ VectorBase<T, N, AP, TV>::VectorBase(AP aAP)
|
||||
}
|
||||
|
||||
/* Move constructor. */
|
||||
template<typename T, size_t N, class AllocPolicy, class TV>
|
||||
template<typename T, size_t N, class AllocPolicy>
|
||||
MOZ_ALWAYS_INLINE
|
||||
VectorBase<T, N, AllocPolicy, TV>::VectorBase(TV&& aRhs)
|
||||
Vector<T, N, AllocPolicy>::Vector(Vector&& aRhs)
|
||||
: AllocPolicy(Move(aRhs))
|
||||
#ifdef DEBUG
|
||||
, mEntered(false)
|
||||
@ -752,20 +761,19 @@ VectorBase<T, N, AllocPolicy, TV>::VectorBase(TV&& aRhs)
|
||||
}
|
||||
|
||||
/* Move assignment. */
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
MOZ_ALWAYS_INLINE TV&
|
||||
VectorBase<T, N, AP, TV>::operator=(TV&& aRhs)
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE Vector<T, N, AP>&
|
||||
Vector<T, N, AP>::operator=(Vector&& aRhs)
|
||||
{
|
||||
MOZ_ASSERT(this != &aRhs, "self-move assignment is prohibited");
|
||||
TV* tv = static_cast<TV*>(this);
|
||||
tv->~TV();
|
||||
new(tv) TV(Move(aRhs));
|
||||
return *tv;
|
||||
this->~Vector();
|
||||
new(this) Vector(Move(aRhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE
|
||||
VectorBase<T, N, AP, TV>::~VectorBase()
|
||||
Vector<T, N, AP>::~Vector()
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
Impl::destroy(beginNoCheck(), endNoCheck());
|
||||
@ -779,9 +787,9 @@ VectorBase<T, N, AP, TV>::~VectorBase()
|
||||
* move all elements in the inline buffer to this new buffer,
|
||||
* and fail on OOM.
|
||||
*/
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline bool
|
||||
VectorBase<T, N, AP, TV>::convertToHeapStorage(size_t aNewCap)
|
||||
Vector<T, N, AP>::convertToHeapStorage(size_t aNewCap)
|
||||
{
|
||||
MOZ_ASSERT(usingInlineStorage());
|
||||
|
||||
@ -803,9 +811,9 @@ VectorBase<T, N, AP, TV>::convertToHeapStorage(size_t aNewCap)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_NEVER_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::growStorageBy(size_t aIncr)
|
||||
Vector<T, N, AP>::growStorageBy(size_t aIncr)
|
||||
{
|
||||
MOZ_ASSERT(mLength + aIncr > mCapacity);
|
||||
|
||||
@ -885,9 +893,9 @@ grow:
|
||||
return Impl::growTo(*this, newCap);
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline bool
|
||||
VectorBase<T, N, AP, TV>::initCapacity(size_t aRequest)
|
||||
Vector<T, N, AP>::initCapacity(size_t aRequest)
|
||||
{
|
||||
MOZ_ASSERT(empty());
|
||||
MOZ_ASSERT(usingInlineStorage());
|
||||
@ -906,9 +914,9 @@ VectorBase<T, N, AP, TV>::initCapacity(size_t aRequest)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline bool
|
||||
VectorBase<T, N, AP, TV>::reserve(size_t aRequest)
|
||||
Vector<T, N, AP>::reserve(size_t aRequest)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
if (aRequest > mCapacity) {
|
||||
@ -930,9 +938,9 @@ VectorBase<T, N, AP, TV>::reserve(size_t aRequest)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline void
|
||||
VectorBase<T, N, AP, TV>::shrinkBy(size_t aIncr)
|
||||
Vector<T, N, AP>::shrinkBy(size_t aIncr)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
MOZ_ASSERT(aIncr <= mLength);
|
||||
@ -940,9 +948,9 @@ VectorBase<T, N, AP, TV>::shrinkBy(size_t aIncr)
|
||||
mLength -= aIncr;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::growBy(size_t aIncr)
|
||||
Vector<T, N, AP>::growBy(size_t aIncr)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
if (aIncr > mCapacity - mLength) {
|
||||
@ -966,9 +974,9 @@ VectorBase<T, N, AP, TV>::growBy(size_t aIncr)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::growByUninitialized(size_t aIncr)
|
||||
Vector<T, N, AP>::growByUninitialized(size_t aIncr)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
if (aIncr > mCapacity - mLength) {
|
||||
@ -984,9 +992,9 @@ VectorBase<T, N, AP, TV>::growByUninitialized(size_t aIncr)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
VectorBase<T, N, AP, TV>::infallibleGrowByUninitialized(size_t aIncr)
|
||||
Vector<T, N, AP>::infallibleGrowByUninitialized(size_t aIncr)
|
||||
{
|
||||
MOZ_ASSERT(mLength + aIncr <= mCapacity);
|
||||
mLength += aIncr;
|
||||
@ -997,9 +1005,9 @@ VectorBase<T, N, AP, TV>::infallibleGrowByUninitialized(size_t aIncr)
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline bool
|
||||
VectorBase<T, N, AP, TV>::resize(size_t aNewLength)
|
||||
Vector<T, N, AP>::resize(size_t aNewLength)
|
||||
{
|
||||
size_t curLength = mLength;
|
||||
if (aNewLength > curLength) {
|
||||
@ -1009,9 +1017,9 @@ VectorBase<T, N, AP, TV>::resize(size_t aNewLength)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::resizeUninitialized(size_t aNewLength)
|
||||
Vector<T, N, AP>::resizeUninitialized(size_t aNewLength)
|
||||
{
|
||||
size_t curLength = mLength;
|
||||
if (aNewLength > curLength) {
|
||||
@ -1021,18 +1029,18 @@ VectorBase<T, N, AP, TV>::resizeUninitialized(size_t aNewLength)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline void
|
||||
VectorBase<T, N, AP, TV>::clear()
|
||||
Vector<T, N, AP>::clear()
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
Impl::destroy(beginNoCheck(), endNoCheck());
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline void
|
||||
VectorBase<T, N, AP, TV>::clearAndFree()
|
||||
Vector<T, N, AP>::clearAndFree()
|
||||
{
|
||||
clear();
|
||||
|
||||
@ -1047,26 +1055,25 @@ VectorBase<T, N, AP, TV>::clearAndFree()
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline bool
|
||||
VectorBase<T, N, AP, TV>::canAppendWithoutRealloc(size_t aNeeded) const
|
||||
Vector<T, N, AP>::canAppendWithoutRealloc(size_t aNeeded) const
|
||||
{
|
||||
return mLength + aNeeded <= mCapacity;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename U, size_t O, class BP, class UV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<typename U, size_t O, class BP>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
VectorBase<T, N, AP, TV>::internalAppendAll(
|
||||
const VectorBase<U, O, BP, UV>& aOther)
|
||||
Vector<T, N, AP>::internalAppendAll(const Vector<U, O, BP>& aOther)
|
||||
{
|
||||
internalAppend(aOther.begin(), aOther.length());
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<typename U>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
VectorBase<T, N, AP, TV>::internalAppend(U&& aU)
|
||||
Vector<T, N, AP>::internalAppend(U&& aU)
|
||||
{
|
||||
MOZ_ASSERT(mLength + 1 <= mReserved);
|
||||
MOZ_ASSERT(mReserved <= mCapacity);
|
||||
@ -1074,9 +1081,9 @@ VectorBase<T, N, AP, TV>::internalAppend(U&& aU)
|
||||
++mLength;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::appendN(const T& aT, size_t aNeeded)
|
||||
Vector<T, N, AP>::appendN(const T& aT, size_t aNeeded)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
if (mLength + aNeeded > mCapacity) {
|
||||
@ -1096,9 +1103,9 @@ VectorBase<T, N, AP, TV>::appendN(const T& aT, size_t aNeeded)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
VectorBase<T, N, AP, TV>::internalAppendN(const T& aT, size_t aNeeded)
|
||||
Vector<T, N, AP>::internalAppendN(const T& aT, size_t aNeeded)
|
||||
{
|
||||
MOZ_ASSERT(mLength + aNeeded <= mReserved);
|
||||
MOZ_ASSERT(mReserved <= mCapacity);
|
||||
@ -1106,10 +1113,10 @@ VectorBase<T, N, AP, TV>::internalAppendN(const T& aT, size_t aNeeded)
|
||||
mLength += aNeeded;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<typename U>
|
||||
inline T*
|
||||
VectorBase<T, N, AP, TV>::insert(T* aP, U&& aVal)
|
||||
Vector<T, N, AP>::insert(T* aP, U&& aVal)
|
||||
{
|
||||
MOZ_ASSERT(begin() <= aP);
|
||||
MOZ_ASSERT(aP <= end());
|
||||
@ -1133,9 +1140,9 @@ VectorBase<T, N, AP, TV>::insert(T* aP, U&& aVal)
|
||||
return begin() + pos;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline void
|
||||
VectorBase<T, N, AP, TV>::erase(T* aIt)
|
||||
Vector<T, N, AP>::erase(T* aIt)
|
||||
{
|
||||
MOZ_ASSERT(begin() <= aIt);
|
||||
MOZ_ASSERT(aIt < end());
|
||||
@ -1146,9 +1153,9 @@ VectorBase<T, N, AP, TV>::erase(T* aIt)
|
||||
popBack();
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline void
|
||||
VectorBase<T, N, AP, TV>::erase(T* aBegin, T* aEnd)
|
||||
Vector<T, N, AP>::erase(T* aBegin, T* aEnd)
|
||||
{
|
||||
MOZ_ASSERT(begin() <= aBegin);
|
||||
MOZ_ASSERT(aBegin <= aEnd);
|
||||
@ -1159,10 +1166,10 @@ VectorBase<T, N, AP, TV>::erase(T* aBegin, T* aEnd)
|
||||
shrinkBy(aEnd - aBegin);
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<typename U>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::append(const U* aInsBegin, const U* aInsEnd)
|
||||
Vector<T, N, AP>::append(const U* aInsBegin, const U* aInsEnd)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
size_t aNeeded = PointerRangeSize(aInsBegin, aInsEnd);
|
||||
@ -1183,10 +1190,10 @@ VectorBase<T, N, AP, TV>::append(const U* aInsBegin, const U* aInsEnd)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<typename U>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
VectorBase<T, N, AP, TV>::internalAppend(const U* aInsBegin, size_t aInsLength)
|
||||
Vector<T, N, AP>::internalAppend(const U* aInsBegin, size_t aInsLength)
|
||||
{
|
||||
MOZ_ASSERT(mLength + aInsLength <= mReserved);
|
||||
MOZ_ASSERT(mReserved <= mCapacity);
|
||||
@ -1194,10 +1201,10 @@ VectorBase<T, N, AP, TV>::internalAppend(const U* aInsBegin, size_t aInsLength)
|
||||
mLength += aInsLength;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<typename U>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::append(U&& aU)
|
||||
Vector<T, N, AP>::append(U&& aU)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
if (mLength == mCapacity) {
|
||||
@ -1217,25 +1224,25 @@ VectorBase<T, N, AP, TV>::append(U&& aU)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename U, size_t O, class BP, class UV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<typename U, size_t O, class BP>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::appendAll(const VectorBase<U, O, BP, UV>& aOther)
|
||||
Vector<T, N, AP>::appendAll(const Vector<U, O, BP>& aOther)
|
||||
{
|
||||
return append(aOther.begin(), aOther.length());
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
template<class U>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
VectorBase<T, N, AP, TV>::append(const U* aInsBegin, size_t aInsLength)
|
||||
Vector<T, N, AP>::append(const U* aInsBegin, size_t aInsLength)
|
||||
{
|
||||
return append(aInsBegin, aInsBegin + aInsLength);
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE void
|
||||
VectorBase<T, N, AP, TV>::popBack()
|
||||
Vector<T, N, AP>::popBack()
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
MOZ_ASSERT(!empty());
|
||||
@ -1243,18 +1250,18 @@ VectorBase<T, N, AP, TV>::popBack()
|
||||
endNoCheck()->~T();
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
MOZ_ALWAYS_INLINE T
|
||||
VectorBase<T, N, AP, TV>::popCopy()
|
||||
Vector<T, N, AP>::popCopy()
|
||||
{
|
||||
T ret = back();
|
||||
popBack();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline T*
|
||||
VectorBase<T, N, AP, TV>::extractRawBuffer()
|
||||
Vector<T, N, AP>::extractRawBuffer()
|
||||
{
|
||||
T* ret;
|
||||
if (usingInlineStorage()) {
|
||||
@ -1278,9 +1285,9 @@ VectorBase<T, N, AP, TV>::extractRawBuffer()
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline void
|
||||
VectorBase<T, N, AP, TV>::replaceRawBuffer(T* aP, size_t aLength)
|
||||
Vector<T, N, AP>::replaceRawBuffer(T* aP, size_t aLength)
|
||||
{
|
||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||
|
||||
@ -1313,23 +1320,23 @@ VectorBase<T, N, AP, TV>::replaceRawBuffer(T* aP, size_t aLength)
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline size_t
|
||||
VectorBase<T, N, AP, TV>::sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
Vector<T, N, AP>::sizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return usingInlineStorage() ? 0 : aMallocSizeOf(beginNoCheck());
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline size_t
|
||||
VectorBase<T, N, AP, TV>::sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
Vector<T, N, AP>::sizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
template<typename T, size_t N, class AP, class TV>
|
||||
template<typename T, size_t N, class AP>
|
||||
inline void
|
||||
VectorBase<T, N, AP, TV>::swap(TV& aOther)
|
||||
Vector<T, N, AP>::swap(Vector& aOther)
|
||||
{
|
||||
static_assert(N == 0,
|
||||
"still need to implement this for N != 0");
|
||||
@ -1354,44 +1361,6 @@ VectorBase<T, N, AP, TV>::swap(TV& aOther)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* STL-like container providing a short-lived, dynamic buffer. Vector calls the
|
||||
* constructors/destructors of all elements stored in its internal buffer, so
|
||||
* non-PODs may be safely used. Additionally, Vector will store the first N
|
||||
* elements in-place before resorting to dynamic allocation.
|
||||
*
|
||||
* T requirements:
|
||||
* - default and copy constructible, assignable, destructible
|
||||
* - operations do not throw
|
||||
* N requirements:
|
||||
* - any value, however, N is clamped to min/max values
|
||||
* AllocPolicy:
|
||||
* - see "Allocation policies" in AllocPolicy.h (defaults to
|
||||
* mozilla::MallocAllocPolicy)
|
||||
*
|
||||
* Vector is not reentrant: T member functions called during Vector member
|
||||
* functions must not call back into the same object!
|
||||
*/
|
||||
template<typename T,
|
||||
size_t MinInlineCapacity = 0,
|
||||
class AllocPolicy = MallocAllocPolicy>
|
||||
class Vector
|
||||
: public VectorBase<T,
|
||||
MinInlineCapacity,
|
||||
AllocPolicy,
|
||||
Vector<T, MinInlineCapacity, AllocPolicy> >
|
||||
{
|
||||
typedef VectorBase<T, MinInlineCapacity, AllocPolicy, Vector> Base;
|
||||
|
||||
public:
|
||||
explicit Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {}
|
||||
Vector(Vector&& vec) : Base(Move(vec)) {}
|
||||
Vector& operator=(Vector&& aOther)
|
||||
{
|
||||
return Base::operator=(Move(aOther));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -47,10 +47,14 @@ public:
|
||||
|
||||
/* HangStack stores an array of const char pointers,
|
||||
with optional internal storage for strings. */
|
||||
class HangStack : public mozilla::Vector<const char*, 8>
|
||||
class HangStack
|
||||
{
|
||||
public:
|
||||
static const size_t sMaxInlineStorage = 8;
|
||||
|
||||
private:
|
||||
typedef mozilla::Vector<const char*, 8> Base;
|
||||
typedef mozilla::Vector<const char*, sMaxInlineStorage> Impl;
|
||||
Impl mImpl;
|
||||
|
||||
// Stack entries can either be a static const char*
|
||||
// or a pointer to within this buffer.
|
||||
@ -60,7 +64,7 @@ public:
|
||||
HangStack() { }
|
||||
|
||||
HangStack(HangStack&& aOther)
|
||||
: Base(mozilla::Move(aOther))
|
||||
: mImpl(mozilla::Move(aOther.mImpl))
|
||||
, mBuffer(mozilla::Move(aOther.mBuffer))
|
||||
{
|
||||
}
|
||||
@ -78,8 +82,34 @@ public:
|
||||
return !operator==(aOther);
|
||||
}
|
||||
|
||||
const char*& operator[](size_t aIndex) {
|
||||
return mImpl[aIndex];
|
||||
}
|
||||
|
||||
const char* const& operator[](size_t aIndex) const {
|
||||
return mImpl[aIndex];
|
||||
}
|
||||
|
||||
size_t capacity() const { return mImpl.capacity(); }
|
||||
size_t length() const { return mImpl.length(); }
|
||||
bool empty() const { return mImpl.empty(); }
|
||||
bool canAppendWithoutRealloc(size_t aNeeded) const {
|
||||
return mImpl.canAppendWithoutRealloc(aNeeded);
|
||||
}
|
||||
void infallibleAppend(const char* aEntry) { mImpl.infallibleAppend(aEntry); }
|
||||
bool reserve(size_t aRequest) { return mImpl.reserve(aRequest); }
|
||||
const char** begin() { return mImpl.begin(); }
|
||||
const char* const* begin() const { return mImpl.begin(); }
|
||||
const char** end() { return mImpl.end(); }
|
||||
const char* const* end() const { return mImpl.end(); }
|
||||
const char*& back() { return mImpl.back(); }
|
||||
void erase(const char** aEntry) { mImpl.erase(aEntry); }
|
||||
void erase(const char** aBegin, const char** aEnd) {
|
||||
mImpl.erase(aBegin, aEnd);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
Base::clear();
|
||||
mImpl.clear();
|
||||
mBuffer.clear();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user