📄 vector.h
字号:
unsigned int destroyed = (last-first); // Shift all elements from the erase point to the last filled element one // position towards the start of the container while ( last < end() ) { *first = *last; ++first; ++last; } // Destroy what was the last element in the container, which is now dupli- // cated one position towards the start of the container while ( first < end() ) { first->~T(); ++first; } // Decrement count of elements in the container size_ -= destroyed; return next; } // }}} /** * expand - Although this implementation does not support automatic * resizing or reallocation, the interface is extended beyond that of * standard STL with this method that allows the maximum storage size * to be increased. This is an expensive operation, and involves the * use of the copy constructor, and Swap. Accordingly, in the event of * an allocation failure, the object will remain untouched, and a debug * ASSERT will be raised. * @param maxSize is a size_type that describes the number of objects * that we wish storage to be reserved for. If the max_size() of 'other' * is greater, then this size will be requested instead. The result will * be reflected by max_size(), and this should be checked against the * requested size and/or other.max_size() **BEFORE THE OBJECT IS USED**. * An assert is also included to trap memory allocation failure in debug * builds. */ template<typename T, typename Allocator, bool bUseCtor> void Vector<T, Allocator, bUseCtor>::expand(size_type maxSize) // {{{ { if (maxSize > max_size()) { Vector<T, Allocator, bUseCtor> temp(*this, maxSize); if ( temp.max_size() == maxSize ) { Swap(temp); } else { TRACE("$R** Vector expansion FAILED when expanding from 0x%08x to 0x%08x **\n", max_size(), maxSize ); } } } // }}} /** * resize is a method that allows the 'size()' of the object to be altered. * It achieves this in two ways. If the size is greater than size_, the * elements upto size are constructed, and size is set accordingly. If * the newSize is less than size_, the elemnts between newSize and size_ are * destroyed, and the size_ is trimmed back. THIS OPERATION DOES NOT * RANGE CHECK MAX_SIZE - it is required that the user observes max_size. * @param newSize is a size_type that specifies the new size_ of the * object. */ template<typename T, typename Allocator, bool bUseCtor> inline void Vector<T, Allocator, bUseCtor>::resize( size_type newSize ) // {{{ { // fill with default ctor value. resize( newSize, value_type() ); } // }}} /** * resize is a method that allows the 'size()' of the object to be altered. * It achieves this in two ways. If the size is greater than size_, the * elements upto size are constructed, and size is set accordingly. If * the newSize is less than size_, the elemnts between newSize and size_ are * destroyed, and the size_ is trimmed back. THIS OPERATION DOES NOT * RANGE CHECK MAX_SIZE - it is required that the user observes max_size. * @param newSize is a size_type that specifies the new size_ of the * object. * @param fill_value is a value_type that describes the value which should * be copied into the slots when size_ is increased. */ template<typename T, typename Allocator, bool bUseCtor> void Vector<T, Allocator, bUseCtor>::resize( size_type newSize, value_type fill_value ) // {{{ { ASSERT( newSize <= max_size() ); if ( newSize > size() ) { // then we want to fill the new slots... unsigned long iCount = newSize - size(); iterator pEntry = end(); do { new (pEntry) T(fill_value); ++pEntry; } while ( --iCount ); } else if ( newSize < size() ) { // then we want to destroy the old slots... unsigned long iCount = size() - newSize; iterator pEntry = end(); do { // destroy... (--pEntry)->~T(); } while ( --iCount ); } size_ = newSize; } // }}} template<typename T, typename Allocator, bool bUseCtor> inline typename Vector<T, Allocator, bUseCtor>::iterator Vector<T, Allocator, bUseCtor>::insert( iterator position, const_reference value) // {{{ { ASSERT( size() < max_size() ); ASSERT( position >= begin() ); ASSERT( position <= end() ); if (position != end()) { // Get an iterator pointing to the currently last element in the // container iterator last = end() - 1; // Copy construct a new element one past the current end of the // container from the currently last element new (end()) T(*last); // Shift elements from the position pointed to by the iterator upto the last // in the container inclusive one position towards the end of // the container while (--last >= position) { *(last + 1) = *last; } // Destroy the existing element in the insertion position position->~T(); } // Construct new object at the insertion position new (position) T(value); // Increment count of elements in the container ++size_; return position; } // }}} template<typename T, typename Allocator, bool bUseCtor> inline typename Vector<T, Allocator, bUseCtor>::size_type Vector<T, Allocator, bUseCtor>::max_size() const // {{{ { return maxSize_; } // }}} template<typename T, typename Allocator, bool bUseCtor> inline void Vector<T, Allocator, bUseCtor>::push_back(const_reference value) // {{{ { ASSERT( size() < max_size() ); // Construct new object in memory one position past current last element new (end()) T(value); // Increment count of elements in the container ++size_; } // }}} template<typename T, typename Allocator, bool bUseCtor> inline void Vector<T, Allocator, bUseCtor>::pop_back() // {{{ { ASSERT( size() ); iterator last = end() - 1; last->~T(); // Decrement count of elements in the container --size_; } // }}} template<typename T, typename Allocator, bool bUseCtor> inline typename Vector<T, Allocator, bUseCtor>::reverse_iterator Vector<T, Allocator, bUseCtor>::rbegin() // {{{ { return reverse_iterator(end()); } // }}} template<typename T, typename Allocator, bool bUseCtor> inline typename Vector<T, Allocator, bUseCtor>::const_reverse_iterator Vector<T, Allocator, bUseCtor>::rbegin() const // {{{ { return const_reverse_iterator(end()); } // }}} template<typename T, typename Allocator, bool bUseCtor> inline typename Vector<T, Allocator, bUseCtor>::reverse_iterator Vector<T, Allocator, bUseCtor>::rend() // {{{ { return reverse_iterator(begin()); } // }}} template<typename T, typename Allocator, bool bUseCtor> inline typename Vector<T, Allocator, bUseCtor>::const_reverse_iterator Vector<T, Allocator, bUseCtor>::rend() const // {{{ { return const_reverse_iterator(begin()); } // }}} template<typename T, typename Allocator, bool bUseCtor> inline typename Vector<T, Allocator, bUseCtor>::size_type Vector<T, Allocator, bUseCtor>::size() const // {{{ { return size_; } // }}} template<typename T, typename Allocator, bool bUseCtor> inline void Vector<T, Allocator, bUseCtor>::Swap(Vector<T, Allocator, bUseCtor>& other) // {{{ { size_type temp = maxSize_; maxSize_ = other.maxSize_; other.maxSize_ = temp; temp = size_; size_ = other.size_; other.size_ = temp; T* tempBuffer = buffer_; buffer_ = other.buffer_; other.buffer_ = tempBuffer; } // }}} // ========================================================================= // ========================================================================= // ========================================================================= // ========================================================================= // Implementation for no ctor specialisation /** * @ctor * creates a lightweight vector style object with space reserved for * maxSize elements. * @param maxSize is a size_type that describes the number of objects * that we wish storage to be reserved for. This will be reflected by * max_size(), and this should be checked against the requested size * *BEFORE THE OBJECT IS USED**. An assert is also included to trap * memory allocation failure in debug builds. */ template<typename T, typename Allocator> Vector<T, Allocator, false>::Vector(size_type maxSize) : maxSize_(maxSize), size_(0), buffer_(0) // {{{ { if ( maxSize_ && !(buffer_ = Allocator::allocate( maxSize_ ) ) ) { TRACE("$R** Vector allocation FAILURE, trying to allocate 0x%08x bytes**\n", maxSize);// ASSERT(0); maxSize_ = 0; } } // }}} /** * @ctor * creates a lightweight vector style object with space reserved for * the larger of maxSize and other.max_size() elements. The body of * the construction in the event of successsful allocation will then * duplicate the data of 'other' in the new object. * @param other is the object from which data will be copied when the * vector is established. * @param maxSize is a size_type that describes the number of objects * that we wish storage to be reserved for. If the max_size() of 'other' * is greater, then this size will be requested instead. The result will * be reflected by max_size(), and this should be checked against the * requested size and/or other.max_size() * *BEFORE THE OBJECT IS USED**. * An assert is also included to trap memory allocation failure in debug * builds. */ template<typename T, typename Allocator> Vector<T, Allocator, false>::Vector(const Vector<T, Allocator, false>& other, size_type maxSize) : maxSize_(other.max_size() > maxSize ? other.max_size() : maxSize), size_(0), buffer_(0) // {{{ { if ( maxSize_ && !(buffer_ = Allocator::allocate( maxSize_ ) ) ) { TRACE("$R** Vector allocation FAILURE, trying to allocate 0x%08x bytes**\n", maxSize);// ASSERT(0); maxSize_ = 0; } else { // not overlapping here, so memcpy is ok. std::memcpy( reinterpret_cast<char*>(buffer_), reinterpret_cast<char*>(other.buffer_), other.size() * sizeof(T) ); size_ = other.size(); } } // }}} template<typename T, typename Allocator> Vector<T, Allocator, false>& Vector<T, Allocator, false>::operator=(const Vector<T, Allocator, false>& other) // {{{ { if ( &other != this ) { Vector<T, Allocator, false> temp(other); Swap(temp); } return *this; } // }}} template<typename T, typename Allocator> Vector<T, Allocator, false>::~Vector() // {{{ { Allocator::deallocate(buffer_); } // }}} template<typename T, typename Allocator> inline typename Vector<T, Allocator, false>::reference Vector<T, Allocator, false>::operator[](size_type index) // {{{ { ASSERT( index < max_size() ); if (index >= size()) { ASSERT( index < max_size() );//TRACE("$R BLIND no ctor VECTOR EXPANSION %ux%u (%u::%u)\n",sizeof(T),index-size()+1,index,max_size()); size_ = index+1; } return buffer_[index]; } // }}} template<typename T, typename Allocator> inline typename Vector<T, Allocator, false>::const_reference Vector<T, Allocator, false>::operator[](size_type index) const // {{{ { ASSERT( index < size() ); return buffer_[index]; } // }}} template<typename T, typename Allocator> inline typename Vector<T, Allocator, false>::reference Vector<T, Allocator, false>::at(size_type index) // {{{ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -