Chromium Code Reviews| Index: Source/wtf/Vector.h |
| diff --git a/Source/wtf/Vector.h b/Source/wtf/Vector.h |
| index 8833e499b2eb63cdb3173454dd103e161b32f962..bbaf5c48bc48c7a3c2c31ff1418be592e8fd3981 100644 |
| --- a/Source/wtf/Vector.h |
| +++ b/Source/wtf/Vector.h |
| @@ -311,6 +311,8 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| } |
| protected: |
| + static const size_t sizeFieldSize = sizeof(unsigned) * 2 > sizeof(double) ? sizeof(unsigned) * 2 : sizeof(double); |
| + |
| VectorBufferBase() |
| : m_buffer(0) |
| , m_capacity(0) |
| @@ -323,9 +325,41 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| { |
| } |
| + // Ends are exclusive and if they point at the same element as their |
| + // start then the range is empty. The end can point one above the last |
| + // element in the capacity (this only happens for Vector, not for |
| + // Deque). |
| + struct Range { |
| + Range(unsigned s = 0, unsigned e = 0) |
| + : start(s) |
| + , end(e) |
| + { |
| + } |
| + |
| + bool IsEmpty() { return start == end; } |
| + |
| + unsigned start; |
| + unsigned end; |
| + }; |
| + |
| + // Takes a range, which may wrap around at capacity and |
| + // decomposes it into 0, 1, or 2 ranges, returning a pointer to the |
| + // element past the last one. |
| + Range* findRanges(Range* buffer, const Range in, unsigned capacity) |
| + { |
| + if (in.end > in.start) { |
| + *buffer++ = in; |
| + } else if (in.end < in.start) { |
| + if (in.end) |
| + *buffer++ = Range(0, in.end); |
| + ASSERT(in.start != capacity); |
| + *buffer++ = Range(in.start, capacity); |
| + } |
| + return buffer; |
| + } |
| + |
| T* m_buffer; |
| unsigned m_capacity; |
| - unsigned m_size; |
| }; |
| template<typename T, size_t inlineCapacity, typename Allocator = DefaultAllocator> |
| @@ -335,6 +369,10 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocator> { |
| private: |
| typedef VectorBufferBase<T, Allocator> Base; |
| + |
| + protected: |
| + typedef typename Base::Range Range; |
| + |
| public: |
| VectorBuffer() |
| { |
| @@ -365,7 +403,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| m_capacity = 0; |
| } |
| - void swapVectorBuffer(VectorBuffer<T, 0, Allocator>& other) |
| + void swapVectorBuffer(VectorBuffer<T, 0, Allocator>& other, Range, Range) |
| { |
| std::swap(m_buffer, other.m_buffer); |
| std::swap(m_capacity, other.m_capacity); |
| @@ -376,6 +414,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| using Base::buffer; |
| using Base::capacity; |
| + using Base::findRanges; |
| using Base::clearUnusedSlots; |
| @@ -385,9 +424,6 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| return buffer(); |
| } |
| - protected: |
| - using Base::m_size; |
| - |
| private: |
| using Base::m_buffer; |
| using Base::m_capacity; |
| @@ -398,6 +434,10 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| WTF_MAKE_NONCOPYABLE(VectorBuffer); |
| private: |
| typedef VectorBufferBase<T, Allocator> Base; |
| + |
| + protected: |
| + typedef typename Base::Range Range; |
| + |
| public: |
| VectorBuffer() |
| : Base(inlineBuffer(), inlineCapacity) |
| @@ -450,46 +490,93 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| return Base::allocationSize(capacity); |
| } |
| - void swapVectorBuffer(VectorBuffer<T, inlineCapacity, Allocator>& other) |
| + void swapVectorBuffer(VectorBuffer<T, inlineCapacity, Allocator>& other, Range thisRange, Range otherRange) |
|
Ken Russell (switch to Gerrit)
2014/07/16 07:38:42
Are the changes to this method tested sufficiently
Erik Corry
2014/07/17 14:44:33
More tests added
|
| { |
| typedef VectorTypeOperations<T> TypeOperations; |
| - if (buffer() == inlineBuffer() && other.buffer() == other.inlineBuffer()) { |
| - ASSERT(m_capacity == other.m_capacity); |
| - if (m_size > other.m_size) { |
| - TypeOperations::swap(inlineBuffer(), inlineBuffer() + other.m_size, other.inlineBuffer()); |
| - TypeOperations::move(inlineBuffer() + other.m_size, inlineBuffer() + m_size, other.inlineBuffer() + other.m_size); |
| + Range thisRanges[2]; |
| + Range otherRanges[2]; |
| + Range* thisRangePtr = thisRanges; |
| + Range* otherRangePtr = otherRanges; |
| + |
| + std::swap(m_capacity, other.m_capacity); |
| + if (buffer() != inlineBuffer() && other.buffer() != other.inlineBuffer()) { |
| + std::swap(m_buffer, other.m_buffer); |
| + } else { |
| + T* otherBuffer = other.m_buffer; |
| + if (buffer() == inlineBuffer()) { |
| + thisRangePtr = findRanges(thisRanges, thisRange, inlineCapacity); |
| } else { |
| - TypeOperations::swap(inlineBuffer(), inlineBuffer() + m_size, other.inlineBuffer()); |
| - TypeOperations::move(other.inlineBuffer() + m_size, other.inlineBuffer() + other.m_size, inlineBuffer() + m_size); |
| + other.m_buffer = m_buffer; |
| + m_buffer = inlineBuffer(); |
| + } |
| + if (otherBuffer == other.inlineBuffer()) { |
| + otherRangePtr = findRanges(otherRanges, otherRange, inlineCapacity); |
| + } else { |
| + m_buffer = otherBuffer; |
| + other.m_buffer = other.inlineBuffer(); |
| } |
| - } else if (buffer() == inlineBuffer()) { |
| - m_buffer = other.m_buffer; |
| - other.m_buffer = other.inlineBuffer(); |
| - TypeOperations::move(inlineBuffer(), inlineBuffer() + m_size, other.inlineBuffer()); |
| - std::swap(m_capacity, other.m_capacity); |
| - } else if (other.buffer() == other.inlineBuffer()) { |
| - other.m_buffer = m_buffer; |
| - m_buffer = inlineBuffer(); |
| - TypeOperations::move(other.inlineBuffer(), other.inlineBuffer() + other.m_size, inlineBuffer()); |
| - std::swap(m_capacity, other.m_capacity); |
| - } else { |
| - std::swap(m_buffer, other.m_buffer); |
| - std::swap(m_capacity, other.m_capacity); |
| + } |
| + |
| + while (thisRangePtr != thisRanges || otherRangePtr != otherRanges) { |
| + if (thisRangePtr == thisRanges) { |
| + // Ran out of ranges in this: process a range in the other. |
| + Range otherRange = *--otherRangePtr; |
| + TypeOperations::move(other.inlineBuffer() + otherRange.start, other.inlineBuffer() + otherRange.end, inlineBuffer() + otherRange.start); |
| + continue; |
| + } |
| + if (otherRangePtr == otherRanges) { |
| + // Ran out of ranges in the other: process a range in this. |
| + Range thisRange = *--thisRangePtr; |
| + TypeOperations::move(inlineBuffer() + thisRange.start, inlineBuffer() + thisRange.end, other.inlineBuffer() + thisRange.start); |
| + continue; |
| + } |
| + // We have a rightmost range in both. Find out which extends furthest to the right. |
| + Range otherRange = *--otherRangePtr; |
| + Range thisRange = *--thisRangePtr; |
| + if (otherRange.end == thisRange.end) { |
| + // They end together: Find the start of the overlap. |
| + unsigned startOfOverlap = std::max(thisRange.start, otherRange.start); |
| + TypeOperations::swap(inlineBuffer() + startOfOverlap, inlineBuffer() + thisRange.end, other.inlineBuffer() + startOfOverlap); |
| + if (otherRange.start == thisRange.start) |
| + continue; // Common left edge - we are done with these entries. |
| + if (otherRange.start < thisRange.start) { |
| + // The other extends further to the left, make a new range. |
| + *otherRangePtr++ = Range(otherRange.start, thisRange.start); |
| + continue; |
| + } |
| + // This extends further to the left, make a new range. |
| + *thisRangePtr++ = Range(thisRange.start, otherRange.start); |
| + continue; |
| + } |
| + if (otherRange.end > thisRange.end) { |
| + // Other one hangs over the edge. |
| + unsigned startOfOverhang = std::max(otherRange.start, thisRange.end); |
| + TypeOperations::move(other.inlineBuffer() + startOfOverhang, other.inlineBuffer() + otherRange.end, inlineBuffer() + startOfOverhang); |
| + if (otherRange.start != startOfOverhang) |
| + *otherRangePtr++ = Range(otherRange.start, startOfOverhang); |
| + *thisRangePtr++ = thisRange; |
| + continue; |
| + } |
| + ASSERT(thisRange.end > otherRange.end); |
| + // This one hangs over the edge. |
| + unsigned startOfOverhang = std::max(thisRange.start, otherRange.end); |
| + TypeOperations::move(inlineBuffer() + startOfOverhang, inlineBuffer() + thisRange.end, other.inlineBuffer() + startOfOverhang); |
| + if (thisRange.start != startOfOverhang) |
| + *thisRangePtr++ = Range(thisRange.start, startOfOverhang); |
| + *otherRangePtr++ = otherRange; |
| } |
| } |
| using Base::buffer; |
| using Base::capacity; |
| + using Base::findRanges; |
| bool hasOutOfLineBuffer() const |
| { |
| return buffer() && buffer() != inlineBuffer(); |
| } |
| - protected: |
| - using Base::m_size; |
| - |
| private: |
| using Base::m_buffer; |
| using Base::m_capacity; |
| @@ -550,6 +637,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| private: |
| typedef VectorBuffer<T, inlineCapacity, Allocator> Base; |
| typedef VectorTypeOperations<T> TypeOperations; |
| + typedef typename Base::Range Range; |
| public: |
| typedef T ValueType; |
| @@ -560,6 +648,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
| Vector() |
| + : m_size(0) |
| { |
| // Unused slots are initialized to zero so that the visitor and the |
| // finalizer can visit them safely. canInitializeWithMemset tells us |
| @@ -567,18 +656,17 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| // destructor calls as long as the memory is zeroed. |
| COMPILE_ASSERT(!Allocator::isGarbageCollected || !VectorTraits<T>::needsDestruction || VectorTraits<T>::canInitializeWithMemset, ClassHasProblemsWithFinalizersCalledOnClearedMemory); |
| COMPILE_ASSERT(!WTF::IsPolymorphic<T>::value || !VectorTraits<T>::canInitializeWithMemset, CantInitializeWithMemsetIfThereIsAVtable); |
| - m_size = 0; |
| } |
| explicit Vector(size_t size) |
| : Base(size) |
| { |
| + setSize(size); |
| // Unused slots are initialized to zero so that the visitor and the |
| // finalizer can visit them safely. canInitializeWithMemset tells us |
| // that the class does not expect matching constructor and |
| // destructor calls as long as the memory is zeroed. |
| COMPILE_ASSERT(!Allocator::isGarbageCollected || !VectorTraits<T>::needsDestruction || VectorTraits<T>::canInitializeWithMemset, ClassHasProblemsWithFinalizersCalledOnClearedMemory); |
| - m_size = size; |
| TypeOperations::initialize(begin(), end()); |
| } |
| @@ -592,9 +680,9 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| if (LIKELY(!Base::buffer())) |
| return; |
| } |
| - if (LIKELY(m_size) && !(Allocator::isGarbageCollected && this->hasOutOfLineBuffer())) { |
| + if (LIKELY(size()) && !(Allocator::isGarbageCollected && this->hasOutOfLineBuffer())) { |
| TypeOperations::destruct(begin(), end()); |
| - m_size = 0; // Partial protection against use-after-free. |
| + setSize(0); // Partial protection against use-after-free. |
| } |
| Base::destruct(); |
| @@ -606,19 +694,18 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| } |
| Vector(const Vector&); |
| - template<size_t otherCapacity> |
| - explicit Vector(const Vector<T, otherCapacity, Allocator>&); |
| + template<size_t otherInlineCapacity> |
| + explicit Vector(const Vector<T, otherInlineCapacity, Allocator>&); |
| Vector& operator=(const Vector&); |
| - template<size_t otherCapacity> |
| - Vector& operator=(const Vector<T, otherCapacity, Allocator>&); |
| + template<size_t otherInlineCapacity> |
| + Vector& operator=(const Vector<T, otherInlineCapacity, Allocator>&); |
| #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) |
| Vector(Vector&&); |
| Vector& operator=(Vector&&); |
| #endif |
| - size_t size() const { return m_size; } |
| size_t capacity() const { return Base::capacity(); } |
| bool isEmpty() const { return !size(); } |
| @@ -640,9 +727,9 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| const T* data() const { return Base::buffer(); } |
| iterator begin() { return data(); } |
| - iterator end() { return begin() + m_size; } |
| + iterator end() { return begin() + size(); } |
| const_iterator begin() const { return data(); } |
| - const_iterator end() const { return begin() + m_size; } |
| + const_iterator end() const { return begin() + size(); } |
| reverse_iterator rbegin() { return reverse_iterator(end()); } |
| reverse_iterator rend() { return reverse_iterator(begin()); } |
| @@ -675,7 +762,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| template<typename U> void append(const U*, size_t); |
| template<typename U> void append(const U&); |
| template<typename U> void uncheckedAppend(const U& val); |
| - template<typename U, size_t otherCapacity, typename V> void appendVector(const Vector<U, otherCapacity, V>&); |
| + template<typename U, size_t otherInlineCapacity, typename V> void appendVector(const Vector<U, otherInlineCapacity, V>&); |
| template<typename U> void insert(size_t position, const U*, size_t); |
| template<typename U> void insert(size_t position, const U&); |
| @@ -697,7 +784,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| Vector(size_t size, const T& val) |
| : Base(size) |
| { |
| - m_size = size; |
| + setSize(size); |
| TypeOperations::uninitializedFill(begin(), end(), val); |
| } |
| @@ -706,16 +793,13 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| template<typename Iterator> void appendRange(Iterator start, Iterator end); |
| - void swap(Vector& other) |
| - { |
| - Base::swapVectorBuffer(other); |
| - std::swap(m_size, other.m_size); |
| - } |
| + void swap(Vector& other); |
| void reverse(); |
| void trace(typename Allocator::Visitor*); |
| + size_t size() const { return m_size; } |
| private: |
| void expandCapacity(size_t newMinCapacity); |
| const T* expandCapacity(size_t newMinCapacity, const T*); |
| @@ -723,29 +807,44 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| void shrinkCapacity(size_t newCapacity); |
| template<typename U> void appendSlowCase(const U&); |
| - using Base::m_size; |
| + void setSize(unsigned size) |
| + { |
| + m_size = size; |
| + } |
| + |
| + unsigned m_size; |
| + |
| using Base::buffer; |
| using Base::capacity; |
| - using Base::swapVectorBuffer; |
| using Base::allocateBuffer; |
| using Base::allocationSize; |
| using Base::clearUnusedSlots; |
| + using Base::hasOutOfLineBuffer; |
| + |
| + friend class VectorBuffer<T, inlineCapacity, Allocator>; |
| }; |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| + void Vector<T, inlineCapacity, Allocator>::swap(Vector<T, inlineCapacity, Allocator>& other) |
| + { |
| + Base::swapVectorBuffer(other, Range(0, m_size), Range(0, other.m_size)); |
| + std::swap(m_size, other.m_size); |
| + } |
| + |
| + template<typename T, size_t inlineCapacity, typename Allocator> |
| Vector<T, inlineCapacity, Allocator>::Vector(const Vector& other) |
| : Base(other.capacity()) |
| { |
| - m_size = other.size(); |
| + setSize(other.size()); |
| TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| - template<size_t otherCapacity> |
| - Vector<T, inlineCapacity, Allocator>::Vector(const Vector<T, otherCapacity, Allocator>& other) |
| + template<size_t otherInlineCapacity> |
| + Vector<T, inlineCapacity, Allocator>::Vector(const Vector<T, otherInlineCapacity, Allocator>& other) |
| : Base(other.capacity()) |
| { |
| - m_size = other.size(); |
| + setSize(other.size()); |
| TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); |
| } |
| @@ -771,7 +870,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| std::copy(other.begin(), other.begin() + size(), begin()); |
| TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); |
| - m_size = other.size(); |
| + setSize(other.size()); |
| return *this; |
| } |
| @@ -779,8 +878,8 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| inline bool typelessPointersAreEqual(const void* a, const void* b) { return a == b; } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| - template<size_t otherCapacity> |
| - Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>::operator=(const Vector<T, otherCapacity, Allocator>& other) |
| + template<size_t otherInlineCapacity> |
| + Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>::operator=(const Vector<T, otherInlineCapacity, Allocator>& other) |
| { |
| // If the inline capacities match, we should call the more specific |
| // template. If the inline capacities don't match, the two objects |
| @@ -803,7 +902,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| std::copy(other.begin(), other.begin() + size(), begin()); |
| TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); |
| - m_size = other.size(); |
| + setSize(other.size()); |
| return *this; |
| } |
| @@ -812,7 +911,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| Vector<T, inlineCapacity, Allocator>::Vector(Vector<T, inlineCapacity, Allocator>&& other) |
| { |
| - m_size = 0; |
| + setSize(0); |
| // It's a little weird to implement a move constructor using swap but this way we |
| // don't have to add a move constructor to VectorBuffer. |
| swap(other); |
| @@ -873,7 +972,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| std::fill(begin(), end(), val); |
| TypeOperations::uninitializedFill(end(), begin() + newSize, val); |
| - m_size = newSize; |
| + setSize(newSize); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| @@ -926,36 +1025,36 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| - inline void Vector<T, inlineCapacity, Allocator>::resize(size_t size) |
| + inline void Vector<T, inlineCapacity, Allocator>::resize(size_t sizeArg) |
| { |
| - if (size <= m_size) |
| - TypeOperations::destruct(begin() + size, end()); |
| + if (sizeArg <= size()) |
| + TypeOperations::destruct(begin() + sizeArg, end()); |
| else { |
| - if (size > capacity()) |
| - expandCapacity(size); |
| - TypeOperations::initialize(end(), begin() + size); |
| + if (sizeArg > capacity()) |
| + expandCapacity(sizeArg); |
| + TypeOperations::initialize(end(), begin() + sizeArg); |
| } |
| - m_size = size; |
| + setSize(sizeArg); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| - void Vector<T, inlineCapacity, Allocator>::shrink(size_t size) |
| + void Vector<T, inlineCapacity, Allocator>::shrink(size_t sizeArg) |
| { |
| - ASSERT(size <= m_size); |
| - TypeOperations::destruct(begin() + size, end()); |
| - clearUnusedSlots(begin() + size, end()); |
| - m_size = size; |
| + ASSERT(sizeArg <= size()); |
| + TypeOperations::destruct(begin() + sizeArg, end()); |
| + clearUnusedSlots(begin() + sizeArg, end()); |
| + setSize(sizeArg); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| - void Vector<T, inlineCapacity, Allocator>::grow(size_t size) |
| + void Vector<T, inlineCapacity, Allocator>::grow(size_t sizeArg) |
| { |
| - ASSERT(size >= m_size); |
| - if (size > capacity()) |
| - expandCapacity(size); |
| - TypeOperations::initialize(end(), begin() + size); |
| - m_size = size; |
| + ASSERT(sizeArg >= size()); |
| + if (sizeArg > capacity()) |
| + expandCapacity(sizeArg); |
| + TypeOperations::initialize(end(), begin() + sizeArg); |
| + setSize(sizeArg); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| @@ -973,7 +1072,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| inline void Vector<T, inlineCapacity, Allocator>::reserveInitialCapacity(size_t initialCapacity) |
| { |
| - ASSERT(!m_size); |
| + ASSERT(!size()); |
| ASSERT(capacity() == inlineCapacity); |
| if (initialCapacity > inlineCapacity) |
| Base::allocateBuffer(initialCapacity); |
| @@ -1012,15 +1111,15 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| template<typename T, size_t inlineCapacity, typename Allocator> template<typename U> |
| void Vector<T, inlineCapacity, Allocator>::append(const U* data, size_t dataSize) |
| { |
| - size_t newSize = m_size + dataSize; |
| + size_t newSize = size() + dataSize; |
| if (newSize > capacity()) { |
| data = expandCapacity(newSize, data); |
| ASSERT(begin()); |
| } |
| - RELEASE_ASSERT(newSize >= m_size); |
| + RELEASE_ASSERT(newSize >= size()); |
| T* dest = end(); |
| VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(data, &data[dataSize], dest); |
| - m_size = newSize; |
| + setSize(newSize); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> template<typename U> |
| @@ -1028,7 +1127,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| { |
| if (LIKELY(size() != capacity())) { |
| new (NotNull, end()) T(val); |
| - ++m_size; |
| + setSize(size() + 1); |
| return; |
| } |
| @@ -1045,7 +1144,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| ASSERT(begin()); |
| new (NotNull, end()) T(*ptr); |
| - ++m_size; |
| + setSize(size() + 1); |
| } |
| // This version of append saves a branch in the case where you know that the |
| @@ -1057,11 +1156,11 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| ASSERT(size() < capacity()); |
| const U* ptr = &val; |
| new (NotNull, end()) T(*ptr); |
| - ++m_size; |
| + setSize(size() + 1); |
| } |
| - template<typename T, size_t inlineCapacity, typename Allocator> template<typename U, size_t otherCapacity, typename OtherAllocator> |
| - inline void Vector<T, inlineCapacity, Allocator>::appendVector(const Vector<U, otherCapacity, OtherAllocator>& val) |
| + template<typename T, size_t inlineCapacity, typename Allocator> template<typename U, size_t otherInlineCapacity, typename OtherAllocator> |
| + inline void Vector<T, inlineCapacity, Allocator>::appendVector(const Vector<U, otherInlineCapacity, OtherAllocator>& val) |
| { |
| append(val.begin(), val.size()); |
| } |
| @@ -1070,16 +1169,16 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| void Vector<T, inlineCapacity, Allocator>::insert(size_t position, const U* data, size_t dataSize) |
| { |
| RELEASE_ASSERT(position <= size()); |
| - size_t newSize = m_size + dataSize; |
| + size_t newSize = size() + dataSize; |
| if (newSize > capacity()) { |
| data = expandCapacity(newSize, data); |
| ASSERT(begin()); |
| } |
| - RELEASE_ASSERT(newSize >= m_size); |
| + RELEASE_ASSERT(newSize >= size()); |
| T* spot = begin() + position; |
| TypeOperations::moveOverlapping(spot, end(), spot + dataSize); |
| VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(data, &data[dataSize], spot); |
| - m_size = newSize; |
| + setSize(newSize); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> template<typename U> |
| @@ -1094,7 +1193,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| T* spot = begin() + position; |
| TypeOperations::moveOverlapping(spot, end(), spot + 1); |
| new (NotNull, spot) T(*data); |
| - ++m_size; |
| + setSize(size() + 1); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> template<typename U, size_t c, typename OtherAllocator> |
| @@ -1129,7 +1228,7 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| spot->~T(); |
| TypeOperations::moveOverlapping(spot + 1, end(), spot); |
| clearUnusedSlots(end() - 1, end()); |
| - --m_size; |
| + setSize(size() - 1); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| @@ -1142,14 +1241,14 @@ static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE; |
| TypeOperations::destruct(beginSpot, endSpot); |
| TypeOperations::moveOverlapping(endSpot, end(), beginSpot); |
| clearUnusedSlots(end() - length, end()); |
| - m_size -= length; |
| + setSize(size() - length); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |
| inline void Vector<T, inlineCapacity, Allocator>::reverse() |
| { |
| - for (size_t i = 0; i < m_size / 2; ++i) |
| - std::swap(at(i), at(m_size - 1 - i)); |
| + for (size_t i = 0; i < size() / 2; ++i) |
| + std::swap(at(i), at(size() - 1 - i)); |
| } |
| template<typename T, size_t inlineCapacity, typename Allocator> |