📄 stl_vector.h
字号:
// Vector implementation -*- C++ -*-// Copyright (C) 2001, 2002 Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library. This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING. If not, write to the Free// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,// USA.// As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License./* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. *//** @file stl_vector.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. */#ifndef __GLIBCPP_INTERNAL_VECTOR_H#define __GLIBCPP_INTERNAL_VECTOR_H#include <bits/stl_iterator_base_funcs.h>#include <bits/functexcept.h>#include <bits/concept_check.h>namespace std{// The vector base class serves two purposes. First, its constructor// and destructor allocate (but don't initialize) storage. This makes// exception safety easier. Second, the base class encapsulates all of// the differences between SGI-style allocators and standard-conforming// allocators.// Base class for ordinary allocators.template <class _Tp, class _Allocator, bool _IsStatic>class _Vector_alloc_base {public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return _M_data_allocator; } _Vector_alloc_base(const allocator_type& __a) : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) {}protected: allocator_type _M_data_allocator; _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; _Tp* _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { if (__p) _M_data_allocator.deallocate(__p, __n); }};// Specialization for allocators that have the property that we don't// actually have to store an allocator object.template <class _Tp, class _Allocator>class _Vector_alloc_base<_Tp, _Allocator, true> {public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; allocator_type get_allocator() const { return allocator_type(); } _Vector_alloc_base(const allocator_type&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) {}protected: _Tp* _M_start; _Tp* _M_finish; _Tp* _M_end_of_storage; typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type; _Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);}};template <class _Tp, class _Alloc>struct _Vector_base : public _Vector_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless>{ typedef _Vector_alloc_base<_Tp, _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; typedef typename _Base::allocator_type allocator_type; _Vector_base(const allocator_type& __a) : _Base(__a) {} _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) { _M_start = _M_allocate(__n); _M_finish = _M_start; _M_end_of_storage = _M_start + __n; } ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }};/** * @brief A standard container which offers fixed time access to individual * elements in any order. * * @ingroup Containers * @ingroup Sequences * * Meets the requirements of a <a href="tables.html#65">container</a>, a * <a href="tables.html#66">reversible container</a>, and a * <a href="tables.html#67">sequence</a>, including the * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c push_front and @c pop_front. * * In some terminology a vector can be described as a dynamic C-style array, * it offers fast and efficient access to individual elements in any order * and saves the user from worrying about memory and size allocation. * Subscripting ( [] ) access is also provided as with C-style arrays.*/template <class _Tp, class _Alloc = allocator<_Tp> >class vector : protected _Vector_base<_Tp, _Alloc>{ // concept requirements __glibcpp_class_requires(_Tp, _SGIAssignableConcept)private: typedef _Vector_base<_Tp, _Alloc> _Base; typedef vector<_Tp, _Alloc> vector_type;public: typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator; typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type> const_iterator; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef typename _Base::allocator_type allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } typedef reverse_iterator<const_iterator> const_reverse_iterator; typedef reverse_iterator<iterator> reverse_iterator;protected: using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_M_start; using _Base::_M_finish; using _Base::_M_end_of_storage;protected: void _M_insert_aux(iterator __position, const _Tp& __x); void _M_insert_aux(iterator __position);public: /** * Returns a read/write iterator that points to the first element in the * vector. Iteration is done in ordinary element order. */ iterator begin() { return iterator (_M_start); } /** * Returns a read-only (constant) iterator that points to the first element * in the vector. Iteration is done in ordinary element order. */ const_iterator begin() const { return const_iterator (_M_start); } /** * Returns a read/write iterator that points one past the last element in * the vector. Iteration is done in ordinary element order. */ iterator end() { return iterator (_M_finish); } /** * Returns a read-only (constant) iterator that points one past the last * element in the vector. Iteration is done in ordinary element order. */ const_iterator end() const { return const_iterator (_M_finish); } /** * Returns a read/write reverse iterator that points to the last element in * the vector. Iteration is done in reverse element order. */ reverse_iterator rbegin() { return reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points to the last * element in the vector. Iteration is done in reverse element order. */ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } /** * Returns a read/write reverse iterator that points to one before the * first element in the vector. Iteration is done in reverse element * order. */ reverse_iterator rend() { return reverse_iterator(begin()); } /** * Returns a read-only (constant) reverse iterator that points to one * before the first element in the vector. Iteration is done in reverse * element order. */ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } /** Returns the number of elements in the vector. */ size_type size() const { return size_type(end() - begin()); } /** Returns the size of the largest possible vector. */ size_type max_size() const { return size_type(-1) / sizeof(_Tp); } /** * Returns the amount of memory that has been alocated for the current * elements (?). */ size_type capacity() const { return size_type(const_iterator(_M_end_of_storage) - begin()); } /** * Returns true if the vector is empty. (Thus begin() would equal end().) */ bool empty() const { return begin() == end(); } /** * @brief Subscript access to the data contained in the vector. * @param n The element for which data should be accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and out_of_range * lookups are not defined. (For checked lookups see at().) */ reference operator[](size_type __n) { return *(begin() + __n); } /** * @brief Subscript access to the data contained in the vector. * @param n The element for which data should be accessed. * @return Read-only (constant) reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and out_of_range * lookups are not defined. (For checked lookups see at().) */ const_reference operator[](size_type __n) const { return *(begin() + __n); } void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range("vector"); } /** * @brief Provides access to the data contained in the vector. * @param n The element for which data should be accessed. * @return Read/write reference to data. * * This function provides for safer data access. The parameter is first * checked that it is in the range of the vector. The function throws * out_of_range if the check fails. */ reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } /** * @brief Provides access to the data contained in the vector. * @param n The element for which data should be accessed. * @return Read-only (constant) reference to data. * * This function provides for safer data access. The parameter is first * checked that it is in the range of the vector. The function throws * out_of_range if the check fails. */ const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } 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); } // Check whether it's an integral type. If so, it's not an 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -