📄 vector.h
字号:
ASSERT(i < size()); return m_buffer.buffer()[i]; } T& operator[](size_t i) { return at(i); } const T& operator[](size_t i) const { return at(i); } T* data() { return m_buffer.buffer(); } const T* data() const { return m_buffer.buffer(); } T** dataSlot() { return m_buffer.bufferSlot(); } iterator begin() { return data(); } iterator end() { return begin() + m_size; } const_iterator begin() const { return data(); } const_iterator end() const { return begin() + m_size; } T& first() { return at(0); } const T& first() const { return at(0); } T& last() { return at(size() - 1); } const T& last() const { return at(size() - 1); } template<typename U> size_t find(const U&) const; void shrink(size_t size); void grow(size_t size); void resize(size_t size); void reserveCapacity(size_t newCapacity); void reserveInitialCapacity(size_t initialCapacity); void shrinkCapacity(size_t newCapacity); void shrinkToFit() { shrinkCapacity(size()); } void clear() { shrinkCapacity(0); } 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<size_t otherCapacity> void append(const Vector<T, otherCapacity>&); template<typename U> void insert(size_t position, const U*, size_t); template<typename U> void insert(size_t position, const U&); template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&); template<typename U> void prepend(const U*, size_t); template<typename U> void prepend(const U&); template<typename U, size_t c> void prepend(const Vector<U, c>&); void remove(size_t position); void remove(size_t position, size_t length); void removeLast() { ASSERT(!isEmpty()); shrink(size() - 1); } Vector(size_t size, const T& val) : m_size(size) , m_buffer(size) { if (begin()) TypeOperations::uninitializedFill(begin(), end(), val); } void fill(const T&, size_t); void fill(const T& val) { fill(val, size()); } template<typename Iterator> void appendRange(Iterator start, Iterator end); T* releaseBuffer(); void swap(Vector<T, inlineCapacity>& other) { std::swap(m_size, other.m_size); m_buffer.swap(other.m_buffer); } private: void expandCapacity(size_t newMinCapacity); const T* expandCapacity(size_t newMinCapacity, const T*); template<typename U> U* expandCapacity(size_t newMinCapacity, U*); size_t m_size; Buffer m_buffer; }; template<typename T, size_t inlineCapacity> Vector<T, inlineCapacity>::Vector(const Vector& other) : m_size(other.size()) , m_buffer(other.capacity()) { if (begin()) TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); } template<typename T, size_t inlineCapacity> template<size_t otherCapacity> Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other) : m_size(other.size()) , m_buffer(other.capacity()) { if (begin()) TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); } template<typename T, size_t inlineCapacity> Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other) { if (&other == this) return *this; if (size() > other.size()) shrink(other.size()); else if (other.size() > capacity()) { clear(); reserveCapacity(other.size()); if (!begin()) return *this; } std::copy(other.begin(), other.begin() + size(), begin()); TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); m_size = other.size(); return *this; } template<typename T, size_t inlineCapacity> template<size_t otherCapacity> Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other) { if (&other == this) return *this; if (size() > other.size()) shrink(other.size()); else if (other.size() > capacity()) { clear(); reserveCapacity(other.size()); if (!begin()) return *this; } std::copy(other.begin(), other.begin() + size(), begin()); TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); m_size = other.size(); return *this; } template<typename T, size_t inlineCapacity> template<typename U> size_t Vector<T, inlineCapacity>::find(const U& value) const { for (size_t i = 0; i < size(); ++i) { if (at(i) == value) return i; } return notFound; } template<typename T, size_t inlineCapacity> void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize) { if (size() > newSize) shrink(newSize); else if (newSize > capacity()) { clear(); reserveCapacity(newSize); if (!begin()) return; } std::fill(begin(), end(), val); TypeOperations::uninitializedFill(end(), begin() + newSize, val); m_size = newSize; } template<typename T, size_t inlineCapacity> template<typename Iterator> void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end) { for (Iterator it = start; it != end; ++it) append(*it); } template<typename T, size_t inlineCapacity> void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity) { reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1))); } template<typename T, size_t inlineCapacity> const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr) { if (ptr < begin() || ptr >= end()) { expandCapacity(newMinCapacity); return ptr; } size_t index = ptr - begin(); expandCapacity(newMinCapacity); return begin() + index; } template<typename T, size_t inlineCapacity> template<typename U> inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr) { expandCapacity(newMinCapacity); return ptr; } template<typename T, size_t inlineCapacity> void Vector<T, inlineCapacity>::resize(size_t size) { if (size <= m_size) TypeOperations::destruct(begin() + size, end()); else { if (size > capacity()) expandCapacity(size); if (begin()) TypeOperations::initialize(end(), begin() + size); } m_size = size; } template<typename T, size_t inlineCapacity> void Vector<T, inlineCapacity>::shrink(size_t size) { ASSERT(size <= m_size); TypeOperations::destruct(begin() + size, end()); m_size = size; } template<typename T, size_t inlineCapacity> void Vector<T, inlineCapacity>::grow(size_t size) { ASSERT(size >= m_size); if (size > capacity()) expandCapacity(size); if (begin()) TypeOperations::initialize(end(), begin() + size); m_size = size; } template<typename T, size_t inlineCapacity> void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity) { if (newCapacity <= capacity()) return; T* oldBuffer = begin(); T* oldEnd = end(); m_buffer.allocateBuffer(newCapacity); if (begin()) TypeOperations::move(oldBuffer, oldEnd, begin()); m_buffer.deallocateBuffer(oldBuffer); } template<typename T, size_t inlineCapacity> inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity) { ASSERT(!m_size); ASSERT(capacity() == inlineCapacity); if (initialCapacity > inlineCapacity) m_buffer.allocateBuffer(initialCapacity); } template<typename T, size_t inlineCapacity> void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity) { if (newCapacity >= capacity()) return; if (newCapacity < size()) shrink(newCapacity); T* oldBuffer = begin(); if (newCapacity > 0) { T* oldEnd = end(); m_buffer.allocateBuffer(newCapacity); if (begin() != oldBuffer) TypeOperations::move(oldBuffer, oldEnd, begin()); } m_buffer.deallocateBuffer(oldBuffer); m_buffer.restoreInlineBufferIfNeeded(); } // Templatizing these is better than just letting the conversion happen implicitly, // because for instance it allows a PassRefPtr to be appended to a RefPtr vector // without refcount thrash. template<typename T, size_t inlineCapacity> template<typename U> void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize) { size_t newSize = m_size + dataSize; if (newSize > capacity()) { data = expandCapacity(newSize, data); if (!begin()) return; } T* dest = end(); for (size_t i = 0; i < dataSize; ++i) new (&dest[i]) T(data[i]); m_size = newSize; } template<typename T, size_t inlineCapacity> template<typename U> inline void Vector<T, inlineCapacity>::append(const U& val) { const U* ptr = &val; if (size() == capacity()) { ptr = expandCapacity(size() + 1, ptr); if (!begin()) return; } #if COMPILER(MSVC7) // FIXME: MSVC7 generates compilation errors when trying to assign // a pointer to a Vector of its base class (i.e. can't downcast). So far // I've been unable to determine any logical reason for this, so I can // only assume it is a bug with the compiler. Casting is a bad solution, // however, because it subverts implicit conversions, so a better // one is needed. new (end()) T(static_cast<T>(*ptr));#else new (end()) T(*ptr);#endif ++m_size; } // This version of append saves a branch in the case where you know that the // vector's capacity is large enough for the append to succeed. template<typename T, size_t inlineCapacity> template<typename U> inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val) { ASSERT(size() < capacity()); const U* ptr = &val; new (end()) T(*ptr); ++m_size; } // This method should not be called append, a better name would be appendElements. // It could also be eliminated entirely, and call sites could just use // appendRange(val.begin(), val.end()). template<typename T, size_t inlineCapacity> template<size_t otherCapacity> inline void Vector<T, inlineCapacity>::append(const Vector<T, otherCapacity>& val) { append(val.begin(), val.size()); } template<typename T, size_t inlineCapacity> template<typename U> void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize) { ASSERT(position <= size()); size_t newSize = m_size + dataSize; if (newSize > capacity()) { data = expandCapacity(newSize, data); if (!begin()) return; } T* spot = begin() + position; TypeOperations::moveOverlapping(spot, end(), spot + dataSize); for (size_t i = 0; i < dataSize; ++i) new (&spot[i]) T(data[i]); m_size = newSize; } template<typename T, size_t inlineCapacity> template<typename U> inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val) { ASSERT(position <= size()); const U* data = &val; if (size() == capacity()) { data = expandCapacity(size() + 1, data); if (!begin()) return; } T* spot = begin() + position; TypeOperations::moveOverlapping(spot, end(), spot + 1); new (spot) T(*data); ++m_size; } template<typename T, size_t inlineCapacity> template<typename U, size_t c> inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val) { insert(position, val.begin(), val.size()); } template<typename T, size_t inlineCapacity> template<typename U> void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize) { insert(0, data, dataSize); } template<typename T, size_t inlineCapacity> template<typename U> inline void Vector<T, inlineCapacity>::prepend(const U& val) { insert(0, val); } template<typename T, size_t inlineCapacity> template<typename U, size_t c> inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val) { insert(0, val.begin(), val.size()); } template<typename T, size_t inlineCapacity> inline void Vector<T, inlineCapacity>::remove(size_t position) { ASSERT(position < size()); T* spot = begin() + position; spot->~T(); TypeOperations::moveOverlapping(spot + 1, end(), spot); --m_size; } template<typename T, size_t inlineCapacity> inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length) { ASSERT(position < size()); ASSERT(position + length < size()); T* beginSpot = begin() + position; T* endSpot = beginSpot + length; TypeOperations::destruct(beginSpot, endSpot); TypeOperations::moveOverlapping(endSpot, end(), beginSpot); m_size -= length; } template<typename T, size_t inlineCapacity> inline T* Vector<T, inlineCapacity>::releaseBuffer() { T* buffer = m_buffer.releaseBuffer(); if (inlineCapacity && !buffer && m_size) { // If the vector had some data, but no buffer to release, // that means it was using the inline buffer. In that case, // we create a brand new buffer so the caller always gets one. size_t bytes = m_size * sizeof(T); buffer = static_cast<T*>(fastMalloc(bytes)); memcpy(buffer, data(), bytes); } m_size = 0; return buffer; } template<typename T, size_t inlineCapacity> void deleteAllValues(const Vector<T, inlineCapacity>& collection) { typedef typename Vector<T, inlineCapacity>::const_iterator iterator; iterator end = collection.end(); for (iterator it = collection.begin(); it != end; ++it) delete *it; } template<typename T, size_t inlineCapacity> inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b) { a.swap(b); } template<typename T, size_t inlineCapacity> bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b) { if (a.size() != b.size()) return false; return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size()); } template<typename T, size_t inlineCapacity> inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b) { return !(a == b); }} // namespace WTFusing WTF::Vector;#endif // WTF_Vector_h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -