Vector data structure
The vector data structure is linear continuous space , there are two iterator start and finish, pointing to the currently used range in the configured continuous space, and the iterator end_of_storage points to the end of the whole contiguous space (including the spare space).
To reduce the speed cost of space configuration, the actual size of the vector may be larger than the client requirements for future expansion. That is the capacity. The capacity of a vector is always greater than or equal to its size. Once the capacity is equal to the size, it is loaded, and the next time a new element is added, the whole vector needs another space. With Start,finish,end_of_storage three iterators, you can easily provide the first and last signs, size, capacity, empty container judgments, label operators ([]), front-end elements, and finally end elements.
Vector expansion principle: If it exceeds the current capacity, then the capacity will be expanded to twice times, if twice times the capacity is still insufficient, the expansion to large enough capacity .
Vector Source Analysis
Vector class definition Template <class _tp, class _alloc = __stl_default_allocator (_TP) >class vector:protected _vector_base& LT;_TP, _alloc> {///requirements: __stl_class_requires (_TP, _assignable);p rivate:typedef _vector_base<_tp, _All Oc> _base;public://vector nested type definition typedef _TP VALUE_TYPE; Vector element type typedef value_type* pointer; Vector pointer typedef const VALUE_TYPE* Const_pointer; Vector static pointer typedef value_type* iterator; Vector iterator is a normal pointer typedef const VALUE_TYPE* CONST_ITERATOR; Vector iterator static pointer typedef value_type& reference; Vector referencing typedef const value_type& Const_reference; Vector static reference typedef size_t SIZE_TYPE; Vector size typedef ptrdiff_t DIFFERENCE_TYPE; Vector type typedef typename _BASE::ALLOCATOR_TYPE Allocator_type; Allocator_type Get_allocator () const {return _base::get_allocator ();} PROTECTED://is a simple space configurator #ifdEF __stl_has_namespaces using _base::_m_allocate; Using _base::_m_deallocate; Using _base::_m_start; A head using _base::_m_finish that represents the current use of space; Indicates the trailing using _base::_m_end_of_storage of the currently used space; Indicates the current space available tail #endif/* __stl_has_namespaces */protected://Insert auxiliary function void _m_insert_aux (iterator __position, const _TP& ; __X); void _m_insert_aux (iterator __position);p ublic://Vector head node element iterator begin () {return _m_start;} Const_iterator begin () const {return _m_start;} Vector tail node element iterator end () {return _m_finish;} Const_iterator End () const {return _m_finish;} The head node after vector reversal Reverse_iterator Rbegin () {return reverse_iterator (end ());} Const_reverse_iterator Rbegin () const {return const_reverse_iterator (end ());} Tail node after vector reversal Reverse_iterator rend () {return reverse_iterator (begin ());} Const_reverse_iterator rend () const {return const_reverse_iterator (begin ());} Returns the number of current objects Size_type size () const {return sizE_type (end ()-begin ()); }//Returns the maximum size Size_type max_size () const {return size_type ( -1)/sizeof (_TP);} Returns the maximum number of objects that can be stored in the reallocation Memory Size_type capacity () const {return size_type (_m_end_of_storage-begin ());} Determines whether the NULL function bool empty () const {return begin () = = End ();} Vector value Manipulation reference operator[] (Size_type __n) {return * (begin () + __n);} Const_reference operator[] (size_type __n) const {return * (begin () + __n);} Vector constructor, which allows to specify vector size n and initial value explicit vector (const allocator_type& __a = Allocator_type ()): _base (__a) {} Vector (Size_type __n, const _tp& __value, const allocator_type& __a = Allocator_type ()): _base (__n, __a) {_m_finish = Uninitialized_fill_n (_m_start, __n, __value);} Explicit vector (Size_type __n): _base (__n, Allocator_type ()) {_m_finish = Uninitialized_fill_n (_m_start, __n, _TP ( )); } vector (const VECTOR<_TP, _alloc>& __x): _base (__x.size (), __x.get_allocator ()) {_m_finish = UnInitIalized_copy (__x.begin (), __x.end (), _m_start); }//For integral type, do not use iterator template <class _inputiterator> vector (_inputiterator __first, _inputiterator __last, Const allocator_type& __a = Allocator_type ()): _base (__a) {typedef typename _IS_INTEGER<_INPUTITERATOR> ;:: _integral _integral; _m_initialize_aux (__first, __last, _integral ()); } template <class _integer> void _m_initialize_aux (_integer __n, _integer __value, __true_type) {_M_start = _M _allocate (__n); _m_end_of_storage = _m_start + __n; _m_finish = Uninitialized_fill_n (_m_start, __n, __value); }//Vector initialization auxiliary function template <class _inputiterator> void _m_initialize_aux (_inputiterator __first, _inputiterator __last, __false_type) {_m_range_initialize (__first, __last, __iterator_category (__first)); }vector (const _tp* __first, const _tp* __last, const allocator_type& __a = Allocator_type ()): _base (__last -__first, __a) {_m_fInish = Uninitialized_copy (__first, __last, _m_start); }//destructor ~vector () {Destroy (_m_start, _m_finish);} ...//Configure space and fill #ifdef __stl_member_templates template <class _forwarditerator> iterator _m_allocate_and_copy (size _type __n, _forwarditerator __first, _forwarditerator __last) {iterator __result = _m_allocate (__n); __stl_try {uninitialized_copy (__first, __last, __result); return __result; } __stl_unwind (_m_deallocate (__result, __n)); } #else/* __stl_member_templates */iterator _m_allocate_and_copy (size_type __n, Const_iterator __first, Const_iterator __last) {iterator __result = _m_allocate (__n); __stl_try {uninitialized_copy (__first, __last, __result); return __result; } __stl_unwind (_m_deallocate (__result, __n)); } #endif/* __stl_member_templates */... reference front () {return *begin ();} The first element of Const_referenCE Front () const {return *begin ();} Reference back () {return * (end ()-1);} The last element const_reference back () const {return * (end ()-1);} void push_back (const _tp& __x) {//Inserts an element into the end of the value if (_m_finish! = _m_end_of_storage) {//also has spare space con struct (_m_finish, __x); global function ++_m_finish; Adjust the height of the water level} else//No spare space _m_insert_aux (end (), __x); The function is a member function of the vector} void Push_back () {if (_m_finish! = _m_end_of_storage) {construct (_m_finish); ++_m_finish; } else _m_insert_aux (end ()); } ...//starting from position, insert n elements, element initial value is x void Insert (iterator __pos, size_type __n, const _tp& __x) {_m_fill_insert (__p OS, __n, __x); } void _m_fill_insert (iterator __pos, size_type __n, const _tp& __x); See below analysis//Take off the tail element and resize void Pop_back () {//Remove the tail element--_m_finish; The trailing end is marked forward with a lattice, indicating that the trailing element destroy (_m_finish) will be discarded; Destroy is the global function}//Clears the element at a location iterator erase (iterator __position) {//Clears the element at a location if (__position + 1!). = End ()) copy (__position + 1, _m_finish, __position); The subsequent elements move forward--_m_finish; Destroy (_m_finish); return __position; }//Clears all elements in [first,last] iterator erase (iterator __first, iterator __last) {iterator __i = copy (__last, _m_finish, __first); Copy is the global function destroy (__i, _m_finish); _m_finish = _m_finish-(__last-__first); return __first; }//adjust vector size void resize (size_type __new_size, const _tp& __x) {if (__new_size < size ()) Erase (begin () + __new_size, End ()); else Insert (end (), __new_size-size (), __x); } void Resize (Size_type __new_size) {Resize (__new_size, _TP ());} Clears the vector element void clear () {Erase (Begin (), end ());} ... template <class _tp, class _alloc>void vector<_tp, _alloc>::_m_insert_aux (iTerator __position, const _tp& __x) {if (_m_finish! = _m_end_of_storage) {//also has spare space constru CT (_m_finish, * (_m_finish-1)); Constructs an element at the beginning of the alternate space and initializes the ++_m_finish with the last element value of the vector; Adjust the water level _tp __x_copy = __x; Copy_backward (__position, _m_finish-2, _m_finish-1); *__position = __x_copy; } else {//No spare space const SIZE_TYPE __old_size = size (); Const Size_type __len = __old_size! = 0? 2 * __OLD_SIZE:1; The above configuration principle: If the original size is 0, then configure 1 (element size);//If the original size is not 0, then configure twice times the original size,//The first half is used to place the original data, the second half is ready to be used to place the new data iterator __new_start = _m_alloca Te (__len); Actual configuration iterator __new_finish = __new_start; __stl_try {__new_finish = Uninitialized_copy (_m_start, __position, __new_start); Copy the contents of the original vector to the new vector construct (__new_finish, __x); Set the initial value x ++__new_finish for the new element; Adjust the water level __new_finish = Uninitialized_copy (__position, _m_fi Nish, __new_finish); Copy the original contents of the placement site} __stl_unwind (Destroy (__new_start,__new_finish), _m_deallocate (__new_start,__le n))); Destroy (Begin (), end ()); Destruction and release of the original Vector _m_deallocate (_m_start, _m_end_of_storage-_m_start); _m_start = __new_start; Adjust the iterator, pointing to the new vector _m_finish = __new_finish; _m_end_of_storage = __new_start + __len; }}//starts with position, inserts n elements, the initial value of the element is Xtemplate <class _TP, Class _alloc>void vector<_tp, _alloc>::_m_fill_insert ( Iterator __position, Size_type __n, const _tp& __x) {if (__n! = 0) { When N!=0 does all of the following actions if (Size_type (_m_end_of_storage-_m_finish) >= __n ) {//spare space greater than or equal to the number of new elements _Tp __x_copy = __x; Const Size_type __elems_after = _m_finish-__position; Calculates the number of existing elements after the insertion point iterator __old_finish = _m_finish; The number of existing elements after the IF (__elems_after > __n) {//insertion point is greater than the number of new elements uninitialized_copy (_m_ Finish-__n, _m_finish, _m_finish); _m_finish + = __n; Mark the tail end of the vector and move the Copy_backward (__position, __old_finish-__n, __old_finish); Fill (__position, __position + __n, __x_copy); Start filling new value after insertion point} else {//insertion point after the number of existing elements is less than or equal to the number of new elements Uninitialized_fill_n (_m_finish, __n-__elems_after, __x_co PY); _m_finish + = __n-__elems_after; Uninitialized_copy (__position, __old_finish, _m_finish); _m_finish + = __elems_after Fill (__position, __old_finish, __x_copy); }} else {//spare space is less than the number of new elements (additional memory must be configured), first determine the new length: twice times the old length, or the old length + the number of new elements const Size_type __old_size = size (); Const Size_type __len = __old_size + Max (__old_size, __n); The following configuration of the new vector space iterator __new_start = _m_allocate (__len); Iterator __new_finish = __new_start; __stl_try {//below first copies the elements before the insertion point of the old vector to the new space __new_finish = Uninitialized_copy (_m_start, __position, __new_st ART); The following will add new elements (the initial value is N) to fill in the space __new_finish = Uninitialized_fill_n (__new_finish, __n, __x); The following then copies the elements after the insertion point of the old vector into the new space __new_finish = Uninitialized_copy (__position, _m_finish, __new_finish); } __stl_unwind ((Destroy (__new_start,__new_finish), _m_deallocate (__new_start,__len))); The following clears and releases the old vector destroy (_m_start, _m_finish); _m_deallocate (_m_start, _m_end_of_storage-_m_start); The following adjustment water level mark _m_start = __new_start; _m_finish = __new_finish; _m_end_of_storage = __new_start + __len; }}}//vector reversal function void Reserve (Size_type __n) {if (Capacity () < __n) {Const Size_type __old_size = size (); Iterator __tmp = _m_allocate_and_copy (__n, _m_start, _m_finish); Destroy (_m_start, _m_finish); _m_deallocate (_m_start, _m_end_of_storage-_m_start); _m_start = __tmp; _m_finish = __tmp + __old_size; _m_end_of_storage = _m_start + __n; }}