138fd1498Szrj // Vector implementation -*- C++ -*- 238fd1498Szrj 338fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc. 438fd1498Szrj // 538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 638fd1498Szrj // software; you can redistribute it and/or modify it under the 738fd1498Szrj // terms of the GNU General Public License as published by the 838fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj // any later version. 1038fd1498Szrj 1138fd1498Szrj // This library is distributed in the hope that it will be useful, 1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj // GNU General Public License for more details. 1538fd1498Szrj 1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 1838fd1498Szrj // 3.1, as published by the Free Software Foundation. 1938fd1498Szrj 2038fd1498Szrj // You should have received a copy of the GNU General Public License and 2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2338fd1498Szrj // <http://www.gnu.org/licenses/>. 2438fd1498Szrj 2538fd1498Szrj /* 2638fd1498Szrj * 2738fd1498Szrj * Copyright (c) 1994 2838fd1498Szrj * Hewlett-Packard Company 2938fd1498Szrj * 3038fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 3138fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 3238fd1498Szrj * provided that the above copyright notice appear in all copies and 3338fd1498Szrj * that both that copyright notice and this permission notice appear 3438fd1498Szrj * in supporting documentation. Hewlett-Packard Company makes no 3538fd1498Szrj * representations about the suitability of this software for any 3638fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 3738fd1498Szrj * 3838fd1498Szrj * 3938fd1498Szrj * Copyright (c) 1996 4038fd1498Szrj * Silicon Graphics Computer Systems, Inc. 4138fd1498Szrj * 4238fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 4338fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 4438fd1498Szrj * provided that the above copyright notice appear in all copies and 4538fd1498Szrj * that both that copyright notice and this permission notice appear 4638fd1498Szrj * in supporting documentation. Silicon Graphics makes no 4738fd1498Szrj * representations about the suitability of this software for any 4838fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 4938fd1498Szrj */ 5038fd1498Szrj 5138fd1498Szrj /** @file bits/stl_vector.h 5238fd1498Szrj * This is an internal header file, included by other library headers. 5338fd1498Szrj * Do not attempt to use it directly. @headername{vector} 5438fd1498Szrj */ 5538fd1498Szrj 5638fd1498Szrj #ifndef _STL_VECTOR_H 5738fd1498Szrj #define _STL_VECTOR_H 1 5838fd1498Szrj 5938fd1498Szrj #include <bits/stl_iterator_base_funcs.h> 6038fd1498Szrj #include <bits/functexcept.h> 6138fd1498Szrj #include <bits/concept_check.h> 6238fd1498Szrj #if __cplusplus >= 201103L 6338fd1498Szrj #include <initializer_list> 6438fd1498Szrj #endif 6538fd1498Szrj 6638fd1498Szrj #include <debug/assertions.h> 6738fd1498Szrj 6838fd1498Szrj #if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR 6938fd1498Szrj extern "C" void 7038fd1498Szrj __sanitizer_annotate_contiguous_container(const void*, const void*, 7138fd1498Szrj const void*, const void*); 7238fd1498Szrj #endif 7338fd1498Szrj 7438fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 7538fd1498Szrj { 7638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 7738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 7838fd1498Szrj 7938fd1498Szrj /// See bits/stl_deque.h's _Deque_base for an explanation. 8038fd1498Szrj template<typename _Tp, typename _Alloc> 8138fd1498Szrj struct _Vector_base 8238fd1498Szrj { 8338fd1498Szrj typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template 8438fd1498Szrj rebind<_Tp>::other _Tp_alloc_type; 8538fd1498Szrj typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer 8638fd1498Szrj pointer; 8738fd1498Szrj 8838fd1498Szrj struct _Vector_impl 8938fd1498Szrj : public _Tp_alloc_type 9038fd1498Szrj { 9138fd1498Szrj pointer _M_start; 9238fd1498Szrj pointer _M_finish; 9338fd1498Szrj pointer _M_end_of_storage; 9438fd1498Szrj 9538fd1498Szrj _Vector_impl() 9638fd1498Szrj : _Tp_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage() 9738fd1498Szrj { } 9838fd1498Szrj 9938fd1498Szrj _Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT 10038fd1498Szrj : _Tp_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage() 10138fd1498Szrj { } 10238fd1498Szrj 10338fd1498Szrj #if __cplusplus >= 201103L 10438fd1498Szrj _Vector_impl(_Tp_alloc_type&& __a) noexcept 10538fd1498Szrj : _Tp_alloc_type(std::move(__a)), 10638fd1498Szrj _M_start(), _M_finish(), _M_end_of_storage() 10738fd1498Szrj { } 10838fd1498Szrj #endif 10938fd1498Szrj 11038fd1498Szrj void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT 11138fd1498Szrj { 11238fd1498Szrj std::swap(_M_start, __x._M_start); 11338fd1498Szrj std::swap(_M_finish, __x._M_finish); 11438fd1498Szrj std::swap(_M_end_of_storage, __x._M_end_of_storage); 11538fd1498Szrj } 11638fd1498Szrj 11738fd1498Szrj #if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR 11838fd1498Szrj template<typename = _Tp_alloc_type> 11938fd1498Szrj struct _Asan 12038fd1498Szrj { 12138fd1498Szrj typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type> 12238fd1498Szrj ::size_type size_type; 12338fd1498Szrj 12438fd1498Szrj static void _S_shrink(_Vector_impl&, size_type) { } 12538fd1498Szrj static void _S_on_dealloc(_Vector_impl&) { } 12638fd1498Szrj 12738fd1498Szrj typedef _Vector_impl& _Reinit; 12838fd1498Szrj 12938fd1498Szrj struct _Grow 13038fd1498Szrj { 13138fd1498Szrj _Grow(_Vector_impl&, size_type) { } 13238fd1498Szrj void _M_grew(size_type) { } 13338fd1498Szrj }; 13438fd1498Szrj }; 13538fd1498Szrj 13638fd1498Szrj // Enable ASan annotations for memory obtained from std::allocator. 13738fd1498Szrj template<typename _Up> 13838fd1498Szrj struct _Asan<allocator<_Up> > 13938fd1498Szrj { 14038fd1498Szrj typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type> 14138fd1498Szrj ::size_type size_type; 14238fd1498Szrj 14338fd1498Szrj // Adjust ASan annotation for [_M_start, _M_end_of_storage) to 14438fd1498Szrj // mark end of valid region as __curr instead of __prev. 14538fd1498Szrj static void 14638fd1498Szrj _S_adjust(_Vector_impl& __impl, pointer __prev, pointer __curr) 14738fd1498Szrj { 14838fd1498Szrj __sanitizer_annotate_contiguous_container(__impl._M_start, 14938fd1498Szrj __impl._M_end_of_storage, __prev, __curr); 15038fd1498Szrj } 15138fd1498Szrj 15238fd1498Szrj static void 15338fd1498Szrj _S_grow(_Vector_impl& __impl, size_type __n) 15438fd1498Szrj { _S_adjust(__impl, __impl._M_finish, __impl._M_finish + __n); } 15538fd1498Szrj 15638fd1498Szrj static void 15738fd1498Szrj _S_shrink(_Vector_impl& __impl, size_type __n) 15838fd1498Szrj { _S_adjust(__impl, __impl._M_finish + __n, __impl._M_finish); } 15938fd1498Szrj 16038fd1498Szrj static void 16138fd1498Szrj _S_on_dealloc(_Vector_impl& __impl) 16238fd1498Szrj { 16338fd1498Szrj if (__impl._M_start) 16438fd1498Szrj _S_adjust(__impl, __impl._M_finish, __impl._M_end_of_storage); 16538fd1498Szrj } 16638fd1498Szrj 16738fd1498Szrj // Used on reallocation to tell ASan unused capacity is invalid. 16838fd1498Szrj struct _Reinit 16938fd1498Szrj { 17038fd1498Szrj explicit _Reinit(_Vector_impl& __impl) : _M_impl(__impl) 17138fd1498Szrj { 17238fd1498Szrj // Mark unused capacity as valid again before deallocating it. 17338fd1498Szrj _S_on_dealloc(_M_impl); 17438fd1498Szrj } 17538fd1498Szrj 17638fd1498Szrj ~_Reinit() 17738fd1498Szrj { 17838fd1498Szrj // Mark unused capacity as invalid after reallocation. 17938fd1498Szrj if (_M_impl._M_start) 18038fd1498Szrj _S_adjust(_M_impl, _M_impl._M_end_of_storage, 18138fd1498Szrj _M_impl._M_finish); 18238fd1498Szrj } 18338fd1498Szrj 18438fd1498Szrj _Vector_impl& _M_impl; 18538fd1498Szrj 18638fd1498Szrj #if __cplusplus >= 201103L 18738fd1498Szrj _Reinit(const _Reinit&) = delete; 18838fd1498Szrj _Reinit& operator=(const _Reinit&) = delete; 18938fd1498Szrj #endif 19038fd1498Szrj }; 19138fd1498Szrj 19238fd1498Szrj // Tell ASan when unused capacity is initialized to be valid. 19338fd1498Szrj struct _Grow 19438fd1498Szrj { 19538fd1498Szrj _Grow(_Vector_impl& __impl, size_type __n) 19638fd1498Szrj : _M_impl(__impl), _M_n(__n) 19738fd1498Szrj { _S_grow(_M_impl, __n); } 19838fd1498Szrj 19938fd1498Szrj ~_Grow() { if (_M_n) _S_shrink(_M_impl, _M_n); } 20038fd1498Szrj 20138fd1498Szrj void _M_grew(size_type __n) { _M_n -= __n; } 20238fd1498Szrj 20338fd1498Szrj #if __cplusplus >= 201103L 20438fd1498Szrj _Grow(const _Grow&) = delete; 20538fd1498Szrj _Grow& operator=(const _Grow&) = delete; 20638fd1498Szrj #endif 20738fd1498Szrj private: 20838fd1498Szrj _Vector_impl& _M_impl; 20938fd1498Szrj size_type _M_n; 21038fd1498Szrj }; 21138fd1498Szrj }; 21238fd1498Szrj 21338fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_REINIT \ 21438fd1498Szrj typename _Base::_Vector_impl::template _Asan<>::_Reinit const \ 21538fd1498Szrj __attribute__((__unused__)) __reinit_guard(this->_M_impl) 21638fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GROW(n) \ 21738fd1498Szrj typename _Base::_Vector_impl::template _Asan<>::_Grow \ 21838fd1498Szrj __attribute__((__unused__)) __grow_guard(this->_M_impl, (n)) 21938fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GREW(n) __grow_guard._M_grew(n) 22038fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) \ 22138fd1498Szrj _Base::_Vector_impl::template _Asan<>::_S_shrink(this->_M_impl, n) 22238fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC \ 22338fd1498Szrj _Base::_Vector_impl::template _Asan<>::_S_on_dealloc(this->_M_impl) 22438fd1498Szrj #else // ! (_GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR) 22538fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_REINIT 22638fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GROW(n) 22738fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GREW(n) 22838fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) 22938fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC 23038fd1498Szrj #endif // _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR 23138fd1498Szrj }; 23238fd1498Szrj 23338fd1498Szrj public: 23438fd1498Szrj typedef _Alloc allocator_type; 23538fd1498Szrj 23638fd1498Szrj _Tp_alloc_type& 23738fd1498Szrj _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT 23838fd1498Szrj { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } 23938fd1498Szrj 24038fd1498Szrj const _Tp_alloc_type& 24138fd1498Szrj _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT 24238fd1498Szrj { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } 24338fd1498Szrj 24438fd1498Szrj allocator_type 24538fd1498Szrj get_allocator() const _GLIBCXX_NOEXCEPT 24638fd1498Szrj { return allocator_type(_M_get_Tp_allocator()); } 24738fd1498Szrj 24838fd1498Szrj _Vector_base() 24938fd1498Szrj : _M_impl() { } 25038fd1498Szrj 25138fd1498Szrj _Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPT 25238fd1498Szrj : _M_impl(__a) { } 25338fd1498Szrj 25438fd1498Szrj _Vector_base(size_t __n) 25538fd1498Szrj : _M_impl() 25638fd1498Szrj { _M_create_storage(__n); } 25738fd1498Szrj 25838fd1498Szrj _Vector_base(size_t __n, const allocator_type& __a) 25938fd1498Szrj : _M_impl(__a) 26038fd1498Szrj { _M_create_storage(__n); } 26138fd1498Szrj 26238fd1498Szrj #if __cplusplus >= 201103L 26338fd1498Szrj _Vector_base(_Tp_alloc_type&& __a) noexcept 26438fd1498Szrj : _M_impl(std::move(__a)) { } 26538fd1498Szrj 26638fd1498Szrj _Vector_base(_Vector_base&& __x) noexcept 26738fd1498Szrj : _M_impl(std::move(__x._M_get_Tp_allocator())) 26838fd1498Szrj { this->_M_impl._M_swap_data(__x._M_impl); } 26938fd1498Szrj 27038fd1498Szrj _Vector_base(_Vector_base&& __x, const allocator_type& __a) 27138fd1498Szrj : _M_impl(__a) 27238fd1498Szrj { 27338fd1498Szrj if (__x.get_allocator() == __a) 27438fd1498Szrj this->_M_impl._M_swap_data(__x._M_impl); 27538fd1498Szrj else 27638fd1498Szrj { 27738fd1498Szrj size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start; 27838fd1498Szrj _M_create_storage(__n); 27938fd1498Szrj } 28038fd1498Szrj } 28138fd1498Szrj #endif 28238fd1498Szrj 28338fd1498Szrj ~_Vector_base() _GLIBCXX_NOEXCEPT 28438fd1498Szrj { 28538fd1498Szrj _M_deallocate(_M_impl._M_start, 28638fd1498Szrj _M_impl._M_end_of_storage - _M_impl._M_start); 28738fd1498Szrj } 28838fd1498Szrj 28938fd1498Szrj public: 29038fd1498Szrj _Vector_impl _M_impl; 29138fd1498Szrj 29238fd1498Szrj pointer 29338fd1498Szrj _M_allocate(size_t __n) 29438fd1498Szrj { 29538fd1498Szrj typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr; 29638fd1498Szrj return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer(); 29738fd1498Szrj } 29838fd1498Szrj 29938fd1498Szrj void 30038fd1498Szrj _M_deallocate(pointer __p, size_t __n) 30138fd1498Szrj { 30238fd1498Szrj typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr; 30338fd1498Szrj if (__p) 30438fd1498Szrj _Tr::deallocate(_M_impl, __p, __n); 30538fd1498Szrj } 30638fd1498Szrj 30738fd1498Szrj private: 30838fd1498Szrj void 30938fd1498Szrj _M_create_storage(size_t __n) 31038fd1498Szrj { 31138fd1498Szrj this->_M_impl._M_start = this->_M_allocate(__n); 31238fd1498Szrj this->_M_impl._M_finish = this->_M_impl._M_start; 31338fd1498Szrj this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; 31438fd1498Szrj } 31538fd1498Szrj }; 31638fd1498Szrj 31738fd1498Szrj /** 31838fd1498Szrj * @brief A standard container which offers fixed time access to 31938fd1498Szrj * individual elements in any order. 32038fd1498Szrj * 32138fd1498Szrj * @ingroup sequences 32238fd1498Szrj * 32338fd1498Szrj * @tparam _Tp Type of element. 32438fd1498Szrj * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. 32538fd1498Szrj * 32638fd1498Szrj * Meets the requirements of a <a href="tables.html#65">container</a>, a 32738fd1498Szrj * <a href="tables.html#66">reversible container</a>, and a 32838fd1498Szrj * <a href="tables.html#67">sequence</a>, including the 32938fd1498Szrj * <a href="tables.html#68">optional sequence requirements</a> with the 33038fd1498Szrj * %exception of @c push_front and @c pop_front. 33138fd1498Szrj * 33238fd1498Szrj * In some terminology a %vector can be described as a dynamic 33338fd1498Szrj * C-style array, it offers fast and efficient access to individual 33438fd1498Szrj * elements in any order and saves the user from worrying about 33538fd1498Szrj * memory and size allocation. Subscripting ( @c [] ) access is 33638fd1498Szrj * also provided as with C-style arrays. 33738fd1498Szrj */ 33838fd1498Szrj template<typename _Tp, typename _Alloc = std::allocator<_Tp> > 33938fd1498Szrj class vector : protected _Vector_base<_Tp, _Alloc> 34038fd1498Szrj { 34138fd1498Szrj #ifdef _GLIBCXX_CONCEPT_CHECKS 34238fd1498Szrj // Concept requirements. 34338fd1498Szrj typedef typename _Alloc::value_type _Alloc_value_type; 34438fd1498Szrj # if __cplusplus < 201103L 34538fd1498Szrj __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 34638fd1498Szrj # endif 34738fd1498Szrj __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) 34838fd1498Szrj #endif 34938fd1498Szrj 35038fd1498Szrj #if __cplusplus >= 201103L 35138fd1498Szrj static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value, 35238fd1498Szrj "std::vector must have a non-const, non-volatile value_type"); 35338fd1498Szrj # ifdef __STRICT_ANSI__ 35438fd1498Szrj static_assert(is_same<typename _Alloc::value_type, _Tp>::value, 35538fd1498Szrj "std::vector must have the same value_type as its allocator"); 35638fd1498Szrj # endif 35738fd1498Szrj #endif 35838fd1498Szrj 35938fd1498Szrj typedef _Vector_base<_Tp, _Alloc> _Base; 36038fd1498Szrj typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; 36138fd1498Szrj typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits; 36238fd1498Szrj 36338fd1498Szrj public: 36438fd1498Szrj typedef _Tp value_type; 36538fd1498Szrj typedef typename _Base::pointer pointer; 36638fd1498Szrj typedef typename _Alloc_traits::const_pointer const_pointer; 36738fd1498Szrj typedef typename _Alloc_traits::reference reference; 36838fd1498Szrj typedef typename _Alloc_traits::const_reference const_reference; 36938fd1498Szrj typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator; 37038fd1498Szrj typedef __gnu_cxx::__normal_iterator<const_pointer, vector> 37138fd1498Szrj const_iterator; 37238fd1498Szrj typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 37338fd1498Szrj typedef std::reverse_iterator<iterator> reverse_iterator; 37438fd1498Szrj typedef size_t size_type; 37538fd1498Szrj typedef ptrdiff_t difference_type; 37638fd1498Szrj typedef _Alloc allocator_type; 37738fd1498Szrj 37838fd1498Szrj protected: 37938fd1498Szrj using _Base::_M_allocate; 38038fd1498Szrj using _Base::_M_deallocate; 38138fd1498Szrj using _Base::_M_impl; 38238fd1498Szrj using _Base::_M_get_Tp_allocator; 38338fd1498Szrj 38438fd1498Szrj public: 38538fd1498Szrj // [23.2.4.1] construct/copy/destroy 38638fd1498Szrj // (assign() and get_allocator() are also listed in this section) 38738fd1498Szrj 38838fd1498Szrj /** 38938fd1498Szrj * @brief Creates a %vector with no elements. 39038fd1498Szrj */ 39138fd1498Szrj vector() 39238fd1498Szrj #if __cplusplus >= 201103L 39338fd1498Szrj noexcept(is_nothrow_default_constructible<_Alloc>::value) 39438fd1498Szrj #endif 39538fd1498Szrj : _Base() { } 39638fd1498Szrj 39738fd1498Szrj /** 39838fd1498Szrj * @brief Creates a %vector with no elements. 39938fd1498Szrj * @param __a An allocator object. 40038fd1498Szrj */ 40138fd1498Szrj explicit 40238fd1498Szrj vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT 40338fd1498Szrj : _Base(__a) { } 40438fd1498Szrj 40538fd1498Szrj #if __cplusplus >= 201103L 40638fd1498Szrj /** 40738fd1498Szrj * @brief Creates a %vector with default constructed elements. 40838fd1498Szrj * @param __n The number of elements to initially create. 40938fd1498Szrj * @param __a An allocator. 41038fd1498Szrj * 41138fd1498Szrj * This constructor fills the %vector with @a __n default 41238fd1498Szrj * constructed elements. 41338fd1498Szrj */ 41438fd1498Szrj explicit 41538fd1498Szrj vector(size_type __n, const allocator_type& __a = allocator_type()) 41638fd1498Szrj : _Base(__n, __a) 41738fd1498Szrj { _M_default_initialize(__n); } 41838fd1498Szrj 41938fd1498Szrj /** 42038fd1498Szrj * @brief Creates a %vector with copies of an exemplar element. 42138fd1498Szrj * @param __n The number of elements to initially create. 42238fd1498Szrj * @param __value An element to copy. 42338fd1498Szrj * @param __a An allocator. 42438fd1498Szrj * 42538fd1498Szrj * This constructor fills the %vector with @a __n copies of @a __value. 42638fd1498Szrj */ 42738fd1498Szrj vector(size_type __n, const value_type& __value, 42838fd1498Szrj const allocator_type& __a = allocator_type()) 42938fd1498Szrj : _Base(__n, __a) 43038fd1498Szrj { _M_fill_initialize(__n, __value); } 43138fd1498Szrj #else 43238fd1498Szrj /** 43338fd1498Szrj * @brief Creates a %vector with copies of an exemplar element. 43438fd1498Szrj * @param __n The number of elements to initially create. 43538fd1498Szrj * @param __value An element to copy. 43638fd1498Szrj * @param __a An allocator. 43738fd1498Szrj * 43838fd1498Szrj * This constructor fills the %vector with @a __n copies of @a __value. 43938fd1498Szrj */ 44038fd1498Szrj explicit 44138fd1498Szrj vector(size_type __n, const value_type& __value = value_type(), 44238fd1498Szrj const allocator_type& __a = allocator_type()) 44338fd1498Szrj : _Base(__n, __a) 44438fd1498Szrj { _M_fill_initialize(__n, __value); } 44538fd1498Szrj #endif 44638fd1498Szrj 44738fd1498Szrj /** 44838fd1498Szrj * @brief %Vector copy constructor. 44938fd1498Szrj * @param __x A %vector of identical element and allocator types. 45038fd1498Szrj * 45138fd1498Szrj * All the elements of @a __x are copied, but any unused capacity in 45238fd1498Szrj * @a __x will not be copied 45338fd1498Szrj * (i.e. capacity() == size() in the new %vector). 45438fd1498Szrj * 45538fd1498Szrj * The newly-created %vector uses a copy of the allocator object used 45638fd1498Szrj * by @a __x (unless the allocator traits dictate a different object). 45738fd1498Szrj */ 45838fd1498Szrj vector(const vector& __x) 45938fd1498Szrj : _Base(__x.size(), 46038fd1498Szrj _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator())) 46138fd1498Szrj { 46238fd1498Szrj this->_M_impl._M_finish = 46338fd1498Szrj std::__uninitialized_copy_a(__x.begin(), __x.end(), 46438fd1498Szrj this->_M_impl._M_start, 46538fd1498Szrj _M_get_Tp_allocator()); 46638fd1498Szrj } 46738fd1498Szrj 46838fd1498Szrj #if __cplusplus >= 201103L 46938fd1498Szrj /** 47038fd1498Szrj * @brief %Vector move constructor. 47138fd1498Szrj * @param __x A %vector of identical element and allocator types. 47238fd1498Szrj * 47338fd1498Szrj * The newly-created %vector contains the exact contents of @a __x. 47438fd1498Szrj * The contents of @a __x are a valid, but unspecified %vector. 47538fd1498Szrj */ 47638fd1498Szrj vector(vector&& __x) noexcept 47738fd1498Szrj : _Base(std::move(__x)) { } 47838fd1498Szrj 47938fd1498Szrj /// Copy constructor with alternative allocator 48038fd1498Szrj vector(const vector& __x, const allocator_type& __a) 48138fd1498Szrj : _Base(__x.size(), __a) 48238fd1498Szrj { 48338fd1498Szrj this->_M_impl._M_finish = 48438fd1498Szrj std::__uninitialized_copy_a(__x.begin(), __x.end(), 48538fd1498Szrj this->_M_impl._M_start, 48638fd1498Szrj _M_get_Tp_allocator()); 48738fd1498Szrj } 48838fd1498Szrj 48938fd1498Szrj /// Move constructor with alternative allocator 49038fd1498Szrj vector(vector&& __rv, const allocator_type& __m) 49138fd1498Szrj noexcept(_Alloc_traits::_S_always_equal()) 49238fd1498Szrj : _Base(std::move(__rv), __m) 49338fd1498Szrj { 49438fd1498Szrj if (__rv.get_allocator() != __m) 49538fd1498Szrj { 49638fd1498Szrj this->_M_impl._M_finish = 49738fd1498Szrj std::__uninitialized_move_a(__rv.begin(), __rv.end(), 49838fd1498Szrj this->_M_impl._M_start, 49938fd1498Szrj _M_get_Tp_allocator()); 50038fd1498Szrj __rv.clear(); 50138fd1498Szrj } 50238fd1498Szrj } 50338fd1498Szrj 50438fd1498Szrj /** 50538fd1498Szrj * @brief Builds a %vector from an initializer list. 50638fd1498Szrj * @param __l An initializer_list. 50738fd1498Szrj * @param __a An allocator. 50838fd1498Szrj * 50938fd1498Szrj * Create a %vector consisting of copies of the elements in the 51038fd1498Szrj * initializer_list @a __l. 51138fd1498Szrj * 51238fd1498Szrj * This will call the element type's copy constructor N times 51338fd1498Szrj * (where N is @a __l.size()) and do no memory reallocation. 51438fd1498Szrj */ 51538fd1498Szrj vector(initializer_list<value_type> __l, 51638fd1498Szrj const allocator_type& __a = allocator_type()) 51738fd1498Szrj : _Base(__a) 51838fd1498Szrj { 51938fd1498Szrj _M_range_initialize(__l.begin(), __l.end(), 52038fd1498Szrj random_access_iterator_tag()); 52138fd1498Szrj } 52238fd1498Szrj #endif 52338fd1498Szrj 52438fd1498Szrj /** 52538fd1498Szrj * @brief Builds a %vector from a range. 52638fd1498Szrj * @param __first An input iterator. 52738fd1498Szrj * @param __last An input iterator. 52838fd1498Szrj * @param __a An allocator. 52938fd1498Szrj * 53038fd1498Szrj * Create a %vector consisting of copies of the elements from 53138fd1498Szrj * [first,last). 53238fd1498Szrj * 53338fd1498Szrj * If the iterators are forward, bidirectional, or 53438fd1498Szrj * random-access, then this will call the elements' copy 53538fd1498Szrj * constructor N times (where N is distance(first,last)) and do 53638fd1498Szrj * no memory reallocation. But if only input iterators are 53738fd1498Szrj * used, then this will do at most 2N calls to the copy 53838fd1498Szrj * constructor, and logN memory reallocations. 53938fd1498Szrj */ 54038fd1498Szrj #if __cplusplus >= 201103L 54138fd1498Szrj template<typename _InputIterator, 54238fd1498Szrj typename = std::_RequireInputIter<_InputIterator>> 54338fd1498Szrj vector(_InputIterator __first, _InputIterator __last, 54438fd1498Szrj const allocator_type& __a = allocator_type()) 54538fd1498Szrj : _Base(__a) 54638fd1498Szrj { _M_initialize_dispatch(__first, __last, __false_type()); } 54738fd1498Szrj #else 54838fd1498Szrj template<typename _InputIterator> 54938fd1498Szrj vector(_InputIterator __first, _InputIterator __last, 55038fd1498Szrj const allocator_type& __a = allocator_type()) 55138fd1498Szrj : _Base(__a) 55238fd1498Szrj { 55338fd1498Szrj // Check whether it's an integral type. If so, it's not an iterator. 55438fd1498Szrj typedef typename std::__is_integer<_InputIterator>::__type _Integral; 55538fd1498Szrj _M_initialize_dispatch(__first, __last, _Integral()); 55638fd1498Szrj } 55738fd1498Szrj #endif 55838fd1498Szrj 55938fd1498Szrj /** 56038fd1498Szrj * The dtor only erases the elements, and note that if the 56138fd1498Szrj * elements themselves are pointers, the pointed-to memory is 56238fd1498Szrj * not touched in any way. Managing the pointer is the user's 56338fd1498Szrj * responsibility. 56438fd1498Szrj */ 56538fd1498Szrj ~vector() _GLIBCXX_NOEXCEPT 56638fd1498Szrj { 56738fd1498Szrj std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 56838fd1498Szrj _M_get_Tp_allocator()); 56938fd1498Szrj _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC; 57038fd1498Szrj } 57138fd1498Szrj 57238fd1498Szrj /** 57338fd1498Szrj * @brief %Vector assignment operator. 57438fd1498Szrj * @param __x A %vector of identical element and allocator types. 57538fd1498Szrj * 57638fd1498Szrj * All the elements of @a __x are copied, but any unused capacity in 57738fd1498Szrj * @a __x will not be copied. 57838fd1498Szrj * 57938fd1498Szrj * Whether the allocator is copied depends on the allocator traits. 58038fd1498Szrj */ 58138fd1498Szrj vector& 58238fd1498Szrj operator=(const vector& __x); 58338fd1498Szrj 58438fd1498Szrj #if __cplusplus >= 201103L 58538fd1498Szrj /** 58638fd1498Szrj * @brief %Vector move assignment operator. 58738fd1498Szrj * @param __x A %vector of identical element and allocator types. 58838fd1498Szrj * 58938fd1498Szrj * The contents of @a __x are moved into this %vector (without copying, 59038fd1498Szrj * if the allocators permit it). 59138fd1498Szrj * Afterwards @a __x is a valid, but unspecified %vector. 59238fd1498Szrj * 59338fd1498Szrj * Whether the allocator is moved depends on the allocator traits. 59438fd1498Szrj */ 59538fd1498Szrj vector& 59638fd1498Szrj operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) 59738fd1498Szrj { 59838fd1498Szrj constexpr bool __move_storage = 59938fd1498Szrj _Alloc_traits::_S_propagate_on_move_assign() 60038fd1498Szrj || _Alloc_traits::_S_always_equal(); 60138fd1498Szrj _M_move_assign(std::move(__x), __bool_constant<__move_storage>()); 60238fd1498Szrj return *this; 60338fd1498Szrj } 60438fd1498Szrj 60538fd1498Szrj /** 60638fd1498Szrj * @brief %Vector list assignment operator. 60738fd1498Szrj * @param __l An initializer_list. 60838fd1498Szrj * 60938fd1498Szrj * This function fills a %vector with copies of the elements in the 61038fd1498Szrj * initializer list @a __l. 61138fd1498Szrj * 61238fd1498Szrj * Note that the assignment completely changes the %vector and 61338fd1498Szrj * that the resulting %vector's size is the same as the number 61438fd1498Szrj * of elements assigned. 61538fd1498Szrj */ 61638fd1498Szrj vector& 61738fd1498Szrj operator=(initializer_list<value_type> __l) 61838fd1498Szrj { 61938fd1498Szrj this->_M_assign_aux(__l.begin(), __l.end(), 62038fd1498Szrj random_access_iterator_tag()); 62138fd1498Szrj return *this; 62238fd1498Szrj } 62338fd1498Szrj #endif 62438fd1498Szrj 62538fd1498Szrj /** 62638fd1498Szrj * @brief Assigns a given value to a %vector. 62738fd1498Szrj * @param __n Number of elements to be assigned. 62838fd1498Szrj * @param __val Value to be assigned. 62938fd1498Szrj * 63038fd1498Szrj * This function fills a %vector with @a __n copies of the given 63138fd1498Szrj * value. Note that the assignment completely changes the 63238fd1498Szrj * %vector and that the resulting %vector's size is the same as 63338fd1498Szrj * the number of elements assigned. 63438fd1498Szrj */ 63538fd1498Szrj void 63638fd1498Szrj assign(size_type __n, const value_type& __val) 63738fd1498Szrj { _M_fill_assign(__n, __val); } 63838fd1498Szrj 63938fd1498Szrj /** 64038fd1498Szrj * @brief Assigns a range to a %vector. 64138fd1498Szrj * @param __first An input iterator. 64238fd1498Szrj * @param __last An input iterator. 64338fd1498Szrj * 64438fd1498Szrj * This function fills a %vector with copies of the elements in the 64538fd1498Szrj * range [__first,__last). 64638fd1498Szrj * 64738fd1498Szrj * Note that the assignment completely changes the %vector and 64838fd1498Szrj * that the resulting %vector's size is the same as the number 64938fd1498Szrj * of elements assigned. 65038fd1498Szrj */ 65138fd1498Szrj #if __cplusplus >= 201103L 65238fd1498Szrj template<typename _InputIterator, 65338fd1498Szrj typename = std::_RequireInputIter<_InputIterator>> 65438fd1498Szrj void 65538fd1498Szrj assign(_InputIterator __first, _InputIterator __last) 65638fd1498Szrj { _M_assign_dispatch(__first, __last, __false_type()); } 65738fd1498Szrj #else 65838fd1498Szrj template<typename _InputIterator> 65938fd1498Szrj void 66038fd1498Szrj assign(_InputIterator __first, _InputIterator __last) 66138fd1498Szrj { 66238fd1498Szrj // Check whether it's an integral type. If so, it's not an iterator. 66338fd1498Szrj typedef typename std::__is_integer<_InputIterator>::__type _Integral; 66438fd1498Szrj _M_assign_dispatch(__first, __last, _Integral()); 66538fd1498Szrj } 66638fd1498Szrj #endif 66738fd1498Szrj 66838fd1498Szrj #if __cplusplus >= 201103L 66938fd1498Szrj /** 67038fd1498Szrj * @brief Assigns an initializer list to a %vector. 67138fd1498Szrj * @param __l An initializer_list. 67238fd1498Szrj * 67338fd1498Szrj * This function fills a %vector with copies of the elements in the 67438fd1498Szrj * initializer list @a __l. 67538fd1498Szrj * 67638fd1498Szrj * Note that the assignment completely changes the %vector and 67738fd1498Szrj * that the resulting %vector's size is the same as the number 67838fd1498Szrj * of elements assigned. 67938fd1498Szrj */ 68038fd1498Szrj void 68138fd1498Szrj assign(initializer_list<value_type> __l) 68238fd1498Szrj { 68338fd1498Szrj this->_M_assign_aux(__l.begin(), __l.end(), 68438fd1498Szrj random_access_iterator_tag()); 68538fd1498Szrj } 68638fd1498Szrj #endif 68738fd1498Szrj 68838fd1498Szrj /// Get a copy of the memory allocation object. 68938fd1498Szrj using _Base::get_allocator; 69038fd1498Szrj 69138fd1498Szrj // iterators 69238fd1498Szrj /** 69338fd1498Szrj * Returns a read/write iterator that points to the first 69438fd1498Szrj * element in the %vector. Iteration is done in ordinary 69538fd1498Szrj * element order. 69638fd1498Szrj */ 69738fd1498Szrj iterator 69838fd1498Szrj begin() _GLIBCXX_NOEXCEPT 69938fd1498Szrj { return iterator(this->_M_impl._M_start); } 70038fd1498Szrj 70138fd1498Szrj /** 70238fd1498Szrj * Returns a read-only (constant) iterator that points to the 70338fd1498Szrj * first element in the %vector. Iteration is done in ordinary 70438fd1498Szrj * element order. 70538fd1498Szrj */ 70638fd1498Szrj const_iterator 70738fd1498Szrj begin() const _GLIBCXX_NOEXCEPT 70838fd1498Szrj { return const_iterator(this->_M_impl._M_start); } 70938fd1498Szrj 71038fd1498Szrj /** 71138fd1498Szrj * Returns a read/write iterator that points one past the last 71238fd1498Szrj * element in the %vector. Iteration is done in ordinary 71338fd1498Szrj * element order. 71438fd1498Szrj */ 71538fd1498Szrj iterator 71638fd1498Szrj end() _GLIBCXX_NOEXCEPT 71738fd1498Szrj { return iterator(this->_M_impl._M_finish); } 71838fd1498Szrj 71938fd1498Szrj /** 72038fd1498Szrj * Returns a read-only (constant) iterator that points one past 72138fd1498Szrj * the last element in the %vector. Iteration is done in 72238fd1498Szrj * ordinary element order. 72338fd1498Szrj */ 72438fd1498Szrj const_iterator 72538fd1498Szrj end() const _GLIBCXX_NOEXCEPT 72638fd1498Szrj { return const_iterator(this->_M_impl._M_finish); } 72738fd1498Szrj 72838fd1498Szrj /** 72938fd1498Szrj * Returns a read/write reverse iterator that points to the 73038fd1498Szrj * last element in the %vector. Iteration is done in reverse 73138fd1498Szrj * element order. 73238fd1498Szrj */ 73338fd1498Szrj reverse_iterator 73438fd1498Szrj rbegin() _GLIBCXX_NOEXCEPT 73538fd1498Szrj { return reverse_iterator(end()); } 73638fd1498Szrj 73738fd1498Szrj /** 73838fd1498Szrj * Returns a read-only (constant) reverse iterator that points 73938fd1498Szrj * to the last element in the %vector. Iteration is done in 74038fd1498Szrj * reverse element order. 74138fd1498Szrj */ 74238fd1498Szrj const_reverse_iterator 74338fd1498Szrj rbegin() const _GLIBCXX_NOEXCEPT 74438fd1498Szrj { return const_reverse_iterator(end()); } 74538fd1498Szrj 74638fd1498Szrj /** 74738fd1498Szrj * Returns a read/write reverse iterator that points to one 74838fd1498Szrj * before the first element in the %vector. Iteration is done 74938fd1498Szrj * in reverse element order. 75038fd1498Szrj */ 75138fd1498Szrj reverse_iterator 75238fd1498Szrj rend() _GLIBCXX_NOEXCEPT 75338fd1498Szrj { return reverse_iterator(begin()); } 75438fd1498Szrj 75538fd1498Szrj /** 75638fd1498Szrj * Returns a read-only (constant) reverse iterator that points 75738fd1498Szrj * to one before the first element in the %vector. Iteration 75838fd1498Szrj * is done in reverse element order. 75938fd1498Szrj */ 76038fd1498Szrj const_reverse_iterator 76138fd1498Szrj rend() const _GLIBCXX_NOEXCEPT 76238fd1498Szrj { return const_reverse_iterator(begin()); } 76338fd1498Szrj 76438fd1498Szrj #if __cplusplus >= 201103L 76538fd1498Szrj /** 76638fd1498Szrj * Returns a read-only (constant) iterator that points to the 76738fd1498Szrj * first element in the %vector. Iteration is done in ordinary 76838fd1498Szrj * element order. 76938fd1498Szrj */ 77038fd1498Szrj const_iterator 77138fd1498Szrj cbegin() const noexcept 77238fd1498Szrj { return const_iterator(this->_M_impl._M_start); } 77338fd1498Szrj 77438fd1498Szrj /** 77538fd1498Szrj * Returns a read-only (constant) iterator that points one past 77638fd1498Szrj * the last element in the %vector. Iteration is done in 77738fd1498Szrj * ordinary element order. 77838fd1498Szrj */ 77938fd1498Szrj const_iterator 78038fd1498Szrj cend() const noexcept 78138fd1498Szrj { return const_iterator(this->_M_impl._M_finish); } 78238fd1498Szrj 78338fd1498Szrj /** 78438fd1498Szrj * Returns a read-only (constant) reverse iterator that points 78538fd1498Szrj * to the last element in the %vector. Iteration is done in 78638fd1498Szrj * reverse element order. 78738fd1498Szrj */ 78838fd1498Szrj const_reverse_iterator 78938fd1498Szrj crbegin() const noexcept 79038fd1498Szrj { return const_reverse_iterator(end()); } 79138fd1498Szrj 79238fd1498Szrj /** 79338fd1498Szrj * Returns a read-only (constant) reverse iterator that points 79438fd1498Szrj * to one before the first element in the %vector. Iteration 79538fd1498Szrj * is done in reverse element order. 79638fd1498Szrj */ 79738fd1498Szrj const_reverse_iterator 79838fd1498Szrj crend() const noexcept 79938fd1498Szrj { return const_reverse_iterator(begin()); } 80038fd1498Szrj #endif 80138fd1498Szrj 80238fd1498Szrj // [23.2.4.2] capacity 80338fd1498Szrj /** Returns the number of elements in the %vector. */ 80438fd1498Szrj size_type 80538fd1498Szrj size() const _GLIBCXX_NOEXCEPT 80638fd1498Szrj { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } 80738fd1498Szrj 80838fd1498Szrj /** Returns the size() of the largest possible %vector. */ 80938fd1498Szrj size_type 81038fd1498Szrj max_size() const _GLIBCXX_NOEXCEPT 81138fd1498Szrj { return _Alloc_traits::max_size(_M_get_Tp_allocator()); } 81238fd1498Szrj 81338fd1498Szrj #if __cplusplus >= 201103L 81438fd1498Szrj /** 81538fd1498Szrj * @brief Resizes the %vector to the specified number of elements. 81638fd1498Szrj * @param __new_size Number of elements the %vector should contain. 81738fd1498Szrj * 81838fd1498Szrj * This function will %resize the %vector to the specified 81938fd1498Szrj * number of elements. If the number is smaller than the 82038fd1498Szrj * %vector's current size the %vector is truncated, otherwise 82138fd1498Szrj * default constructed elements are appended. 82238fd1498Szrj */ 82338fd1498Szrj void 82438fd1498Szrj resize(size_type __new_size) 82538fd1498Szrj { 82638fd1498Szrj if (__new_size > size()) 82738fd1498Szrj _M_default_append(__new_size - size()); 82838fd1498Szrj else if (__new_size < size()) 82938fd1498Szrj _M_erase_at_end(this->_M_impl._M_start + __new_size); 83038fd1498Szrj } 83138fd1498Szrj 83238fd1498Szrj /** 83338fd1498Szrj * @brief Resizes the %vector to the specified number of elements. 83438fd1498Szrj * @param __new_size Number of elements the %vector should contain. 83538fd1498Szrj * @param __x Data with which new elements should be populated. 83638fd1498Szrj * 83738fd1498Szrj * This function will %resize the %vector to the specified 83838fd1498Szrj * number of elements. If the number is smaller than the 83938fd1498Szrj * %vector's current size the %vector is truncated, otherwise 84038fd1498Szrj * the %vector is extended and new elements are populated with 84138fd1498Szrj * given data. 84238fd1498Szrj */ 84338fd1498Szrj void 84438fd1498Szrj resize(size_type __new_size, const value_type& __x) 84538fd1498Szrj { 84638fd1498Szrj if (__new_size > size()) 84738fd1498Szrj _M_fill_insert(end(), __new_size - size(), __x); 84838fd1498Szrj else if (__new_size < size()) 84938fd1498Szrj _M_erase_at_end(this->_M_impl._M_start + __new_size); 85038fd1498Szrj } 85138fd1498Szrj #else 85238fd1498Szrj /** 85338fd1498Szrj * @brief Resizes the %vector to the specified number of elements. 85438fd1498Szrj * @param __new_size Number of elements the %vector should contain. 85538fd1498Szrj * @param __x Data with which new elements should be populated. 85638fd1498Szrj * 85738fd1498Szrj * This function will %resize the %vector to the specified 85838fd1498Szrj * number of elements. If the number is smaller than the 85938fd1498Szrj * %vector's current size the %vector is truncated, otherwise 86038fd1498Szrj * the %vector is extended and new elements are populated with 86138fd1498Szrj * given data. 86238fd1498Szrj */ 86338fd1498Szrj void 86438fd1498Szrj resize(size_type __new_size, value_type __x = value_type()) 86538fd1498Szrj { 86638fd1498Szrj if (__new_size > size()) 86738fd1498Szrj _M_fill_insert(end(), __new_size - size(), __x); 86838fd1498Szrj else if (__new_size < size()) 86938fd1498Szrj _M_erase_at_end(this->_M_impl._M_start + __new_size); 87038fd1498Szrj } 87138fd1498Szrj #endif 87238fd1498Szrj 87338fd1498Szrj #if __cplusplus >= 201103L 87438fd1498Szrj /** A non-binding request to reduce capacity() to size(). */ 87538fd1498Szrj void 87638fd1498Szrj shrink_to_fit() 87738fd1498Szrj { _M_shrink_to_fit(); } 87838fd1498Szrj #endif 87938fd1498Szrj 88038fd1498Szrj /** 88138fd1498Szrj * Returns the total number of elements that the %vector can 88238fd1498Szrj * hold before needing to allocate more memory. 88338fd1498Szrj */ 88438fd1498Szrj size_type 88538fd1498Szrj capacity() const _GLIBCXX_NOEXCEPT 88638fd1498Szrj { return size_type(this->_M_impl._M_end_of_storage 88738fd1498Szrj - this->_M_impl._M_start); } 88838fd1498Szrj 88938fd1498Szrj /** 89038fd1498Szrj * Returns true if the %vector is empty. (Thus begin() would 89138fd1498Szrj * equal end().) 89238fd1498Szrj */ 89338fd1498Szrj bool 89438fd1498Szrj empty() const _GLIBCXX_NOEXCEPT 89538fd1498Szrj { return begin() == end(); } 89638fd1498Szrj 89738fd1498Szrj /** 89838fd1498Szrj * @brief Attempt to preallocate enough memory for specified number of 89938fd1498Szrj * elements. 90038fd1498Szrj * @param __n Number of elements required. 90138fd1498Szrj * @throw std::length_error If @a n exceeds @c max_size(). 90238fd1498Szrj * 90338fd1498Szrj * This function attempts to reserve enough memory for the 90438fd1498Szrj * %vector to hold the specified number of elements. If the 90538fd1498Szrj * number requested is more than max_size(), length_error is 90638fd1498Szrj * thrown. 90738fd1498Szrj * 90838fd1498Szrj * The advantage of this function is that if optimal code is a 90938fd1498Szrj * necessity and the user can determine the number of elements 91038fd1498Szrj * that will be required, the user can reserve the memory in 91138fd1498Szrj * %advance, and thus prevent a possible reallocation of memory 91238fd1498Szrj * and copying of %vector data. 91338fd1498Szrj */ 91438fd1498Szrj void 91538fd1498Szrj reserve(size_type __n); 91638fd1498Szrj 91738fd1498Szrj // element access 91838fd1498Szrj /** 91938fd1498Szrj * @brief Subscript access to the data contained in the %vector. 92038fd1498Szrj * @param __n The index of the element for which data should be 92138fd1498Szrj * accessed. 92238fd1498Szrj * @return Read/write reference to data. 92338fd1498Szrj * 92438fd1498Szrj * This operator allows for easy, array-style, data access. 92538fd1498Szrj * Note that data access with this operator is unchecked and 92638fd1498Szrj * out_of_range lookups are not defined. (For checked lookups 92738fd1498Szrj * see at().) 92838fd1498Szrj */ 92938fd1498Szrj reference 93038fd1498Szrj operator[](size_type __n) _GLIBCXX_NOEXCEPT 93138fd1498Szrj { 93238fd1498Szrj __glibcxx_requires_subscript(__n); 93338fd1498Szrj return *(this->_M_impl._M_start + __n); 93438fd1498Szrj } 93538fd1498Szrj 93638fd1498Szrj /** 93738fd1498Szrj * @brief Subscript access to the data contained in the %vector. 93838fd1498Szrj * @param __n The index of the element for which data should be 93938fd1498Szrj * accessed. 94038fd1498Szrj * @return Read-only (constant) reference to data. 94138fd1498Szrj * 94238fd1498Szrj * This operator allows for easy, array-style, data access. 94338fd1498Szrj * Note that data access with this operator is unchecked and 94438fd1498Szrj * out_of_range lookups are not defined. (For checked lookups 94538fd1498Szrj * see at().) 94638fd1498Szrj */ 94738fd1498Szrj const_reference 94838fd1498Szrj operator[](size_type __n) const _GLIBCXX_NOEXCEPT 94938fd1498Szrj { 95038fd1498Szrj __glibcxx_requires_subscript(__n); 95138fd1498Szrj return *(this->_M_impl._M_start + __n); 95238fd1498Szrj } 95338fd1498Szrj 95438fd1498Szrj protected: 95538fd1498Szrj /// Safety check used only from at(). 95638fd1498Szrj void 95738fd1498Szrj _M_range_check(size_type __n) const 95838fd1498Szrj { 95938fd1498Szrj if (__n >= this->size()) 96038fd1498Szrj __throw_out_of_range_fmt(__N("vector::_M_range_check: __n " 96138fd1498Szrj "(which is %zu) >= this->size() " 96238fd1498Szrj "(which is %zu)"), 96338fd1498Szrj __n, this->size()); 96438fd1498Szrj } 96538fd1498Szrj 96638fd1498Szrj public: 96738fd1498Szrj /** 96838fd1498Szrj * @brief Provides access to the data contained in the %vector. 96938fd1498Szrj * @param __n The index of the element for which data should be 97038fd1498Szrj * accessed. 97138fd1498Szrj * @return Read/write reference to data. 97238fd1498Szrj * @throw std::out_of_range If @a __n is an invalid index. 97338fd1498Szrj * 97438fd1498Szrj * This function provides for safer data access. The parameter 97538fd1498Szrj * is first checked that it is in the range of the vector. The 97638fd1498Szrj * function throws out_of_range if the check fails. 97738fd1498Szrj */ 97838fd1498Szrj reference 97938fd1498Szrj at(size_type __n) 98038fd1498Szrj { 98138fd1498Szrj _M_range_check(__n); 98238fd1498Szrj return (*this)[__n]; 98338fd1498Szrj } 98438fd1498Szrj 98538fd1498Szrj /** 98638fd1498Szrj * @brief Provides access to the data contained in the %vector. 98738fd1498Szrj * @param __n The index of the element for which data should be 98838fd1498Szrj * accessed. 98938fd1498Szrj * @return Read-only (constant) reference to data. 99038fd1498Szrj * @throw std::out_of_range If @a __n is an invalid index. 99138fd1498Szrj * 99238fd1498Szrj * This function provides for safer data access. The parameter 99338fd1498Szrj * is first checked that it is in the range of the vector. The 99438fd1498Szrj * function throws out_of_range if the check fails. 99538fd1498Szrj */ 99638fd1498Szrj const_reference 99738fd1498Szrj at(size_type __n) const 99838fd1498Szrj { 99938fd1498Szrj _M_range_check(__n); 100038fd1498Szrj return (*this)[__n]; 100138fd1498Szrj } 100238fd1498Szrj 100338fd1498Szrj /** 100438fd1498Szrj * Returns a read/write reference to the data at the first 100538fd1498Szrj * element of the %vector. 100638fd1498Szrj */ 100738fd1498Szrj reference 100838fd1498Szrj front() _GLIBCXX_NOEXCEPT 100938fd1498Szrj { 101038fd1498Szrj __glibcxx_requires_nonempty(); 101138fd1498Szrj return *begin(); 101238fd1498Szrj } 101338fd1498Szrj 101438fd1498Szrj /** 101538fd1498Szrj * Returns a read-only (constant) reference to the data at the first 101638fd1498Szrj * element of the %vector. 101738fd1498Szrj */ 101838fd1498Szrj const_reference 101938fd1498Szrj front() const _GLIBCXX_NOEXCEPT 102038fd1498Szrj { 102138fd1498Szrj __glibcxx_requires_nonempty(); 102238fd1498Szrj return *begin(); 102338fd1498Szrj } 102438fd1498Szrj 102538fd1498Szrj /** 102638fd1498Szrj * Returns a read/write reference to the data at the last 102738fd1498Szrj * element of the %vector. 102838fd1498Szrj */ 102938fd1498Szrj reference 103038fd1498Szrj back() _GLIBCXX_NOEXCEPT 103138fd1498Szrj { 103238fd1498Szrj __glibcxx_requires_nonempty(); 103338fd1498Szrj return *(end() - 1); 103438fd1498Szrj } 103538fd1498Szrj 103638fd1498Szrj /** 103738fd1498Szrj * Returns a read-only (constant) reference to the data at the 103838fd1498Szrj * last element of the %vector. 103938fd1498Szrj */ 104038fd1498Szrj const_reference 104138fd1498Szrj back() const _GLIBCXX_NOEXCEPT 104238fd1498Szrj { 104338fd1498Szrj __glibcxx_requires_nonempty(); 104438fd1498Szrj return *(end() - 1); 104538fd1498Szrj } 104638fd1498Szrj 104738fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 104838fd1498Szrj // DR 464. Suggestion for new member functions in standard containers. 104938fd1498Szrj // data access 105038fd1498Szrj /** 105138fd1498Szrj * Returns a pointer such that [data(), data() + size()) is a valid 105238fd1498Szrj * range. For a non-empty %vector, data() == &front(). 105338fd1498Szrj */ 105438fd1498Szrj _Tp* 105538fd1498Szrj data() _GLIBCXX_NOEXCEPT 105638fd1498Szrj { return _M_data_ptr(this->_M_impl._M_start); } 105738fd1498Szrj 105838fd1498Szrj const _Tp* 105938fd1498Szrj data() const _GLIBCXX_NOEXCEPT 106038fd1498Szrj { return _M_data_ptr(this->_M_impl._M_start); } 106138fd1498Szrj 106238fd1498Szrj // [23.2.4.3] modifiers 106338fd1498Szrj /** 106438fd1498Szrj * @brief Add data to the end of the %vector. 106538fd1498Szrj * @param __x Data to be added. 106638fd1498Szrj * 106738fd1498Szrj * This is a typical stack operation. The function creates an 106838fd1498Szrj * element at the end of the %vector and assigns the given data 106938fd1498Szrj * to it. Due to the nature of a %vector this operation can be 107038fd1498Szrj * done in constant time if the %vector has preallocated space 107138fd1498Szrj * available. 107238fd1498Szrj */ 107338fd1498Szrj void 107438fd1498Szrj push_back(const value_type& __x) 107538fd1498Szrj { 107638fd1498Szrj if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 107738fd1498Szrj { 107838fd1498Szrj _GLIBCXX_ASAN_ANNOTATE_GROW(1); 107938fd1498Szrj _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 108038fd1498Szrj __x); 108138fd1498Szrj ++this->_M_impl._M_finish; 108238fd1498Szrj _GLIBCXX_ASAN_ANNOTATE_GREW(1); 108338fd1498Szrj } 108438fd1498Szrj else 108538fd1498Szrj _M_realloc_insert(end(), __x); 108638fd1498Szrj } 108738fd1498Szrj 108838fd1498Szrj #if __cplusplus >= 201103L 108938fd1498Szrj void 109038fd1498Szrj push_back(value_type&& __x) 109138fd1498Szrj { emplace_back(std::move(__x)); } 109238fd1498Szrj 109338fd1498Szrj template<typename... _Args> 109438fd1498Szrj #if __cplusplus > 201402L 109538fd1498Szrj reference 109638fd1498Szrj #else 109738fd1498Szrj void 109838fd1498Szrj #endif 109938fd1498Szrj emplace_back(_Args&&... __args); 110038fd1498Szrj #endif 110138fd1498Szrj 110238fd1498Szrj /** 110338fd1498Szrj * @brief Removes last element. 110438fd1498Szrj * 110538fd1498Szrj * This is a typical stack operation. It shrinks the %vector by one. 110638fd1498Szrj * 110738fd1498Szrj * Note that no data is returned, and if the last element's 110838fd1498Szrj * data is needed, it should be retrieved before pop_back() is 110938fd1498Szrj * called. 111038fd1498Szrj */ 111138fd1498Szrj void 111238fd1498Szrj pop_back() _GLIBCXX_NOEXCEPT 111338fd1498Szrj { 111438fd1498Szrj __glibcxx_requires_nonempty(); 111538fd1498Szrj --this->_M_impl._M_finish; 111638fd1498Szrj _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); 111738fd1498Szrj _GLIBCXX_ASAN_ANNOTATE_SHRINK(1); 111838fd1498Szrj } 111938fd1498Szrj 112038fd1498Szrj #if __cplusplus >= 201103L 112138fd1498Szrj /** 112238fd1498Szrj * @brief Inserts an object in %vector before specified iterator. 112338fd1498Szrj * @param __position A const_iterator into the %vector. 112438fd1498Szrj * @param __args Arguments. 112538fd1498Szrj * @return An iterator that points to the inserted data. 112638fd1498Szrj * 112738fd1498Szrj * This function will insert an object of type T constructed 112838fd1498Szrj * with T(std::forward<Args>(args)...) before the specified location. 112938fd1498Szrj * Note that this kind of operation could be expensive for a %vector 113038fd1498Szrj * and if it is frequently used the user should consider using 113138fd1498Szrj * std::list. 113238fd1498Szrj */ 113338fd1498Szrj template<typename... _Args> 113438fd1498Szrj iterator 113538fd1498Szrj emplace(const_iterator __position, _Args&&... __args) 113638fd1498Szrj { return _M_emplace_aux(__position, std::forward<_Args>(__args)...); } 113738fd1498Szrj 113838fd1498Szrj /** 113938fd1498Szrj * @brief Inserts given value into %vector before specified iterator. 114038fd1498Szrj * @param __position A const_iterator into the %vector. 114138fd1498Szrj * @param __x Data to be inserted. 114238fd1498Szrj * @return An iterator that points to the inserted data. 114338fd1498Szrj * 114438fd1498Szrj * This function will insert a copy of the given value before 114538fd1498Szrj * the specified location. Note that this kind of operation 114638fd1498Szrj * could be expensive for a %vector and if it is frequently 114738fd1498Szrj * used the user should consider using std::list. 114838fd1498Szrj */ 114938fd1498Szrj iterator 115038fd1498Szrj insert(const_iterator __position, const value_type& __x); 115138fd1498Szrj #else 115238fd1498Szrj /** 115338fd1498Szrj * @brief Inserts given value into %vector before specified iterator. 115438fd1498Szrj * @param __position An iterator into the %vector. 115538fd1498Szrj * @param __x Data to be inserted. 115638fd1498Szrj * @return An iterator that points to the inserted data. 115738fd1498Szrj * 115838fd1498Szrj * This function will insert a copy of the given value before 115938fd1498Szrj * the specified location. Note that this kind of operation 116038fd1498Szrj * could be expensive for a %vector and if it is frequently 116138fd1498Szrj * used the user should consider using std::list. 116238fd1498Szrj */ 116338fd1498Szrj iterator 116438fd1498Szrj insert(iterator __position, const value_type& __x); 116538fd1498Szrj #endif 116638fd1498Szrj 116738fd1498Szrj #if __cplusplus >= 201103L 116838fd1498Szrj /** 116938fd1498Szrj * @brief Inserts given rvalue into %vector before specified iterator. 117038fd1498Szrj * @param __position A const_iterator into the %vector. 117138fd1498Szrj * @param __x Data to be inserted. 117238fd1498Szrj * @return An iterator that points to the inserted data. 117338fd1498Szrj * 117438fd1498Szrj * This function will insert a copy of the given rvalue before 117538fd1498Szrj * the specified location. Note that this kind of operation 117638fd1498Szrj * could be expensive for a %vector and if it is frequently 117738fd1498Szrj * used the user should consider using std::list. 117838fd1498Szrj */ 117938fd1498Szrj iterator 118038fd1498Szrj insert(const_iterator __position, value_type&& __x) 118138fd1498Szrj { return _M_insert_rval(__position, std::move(__x)); } 118238fd1498Szrj 118338fd1498Szrj /** 118438fd1498Szrj * @brief Inserts an initializer_list into the %vector. 118538fd1498Szrj * @param __position An iterator into the %vector. 118638fd1498Szrj * @param __l An initializer_list. 118738fd1498Szrj * 118838fd1498Szrj * This function will insert copies of the data in the 118938fd1498Szrj * initializer_list @a l into the %vector before the location 119038fd1498Szrj * specified by @a position. 119138fd1498Szrj * 119238fd1498Szrj * Note that this kind of operation could be expensive for a 119338fd1498Szrj * %vector and if it is frequently used the user should 119438fd1498Szrj * consider using std::list. 119538fd1498Szrj */ 119638fd1498Szrj iterator 119738fd1498Szrj insert(const_iterator __position, initializer_list<value_type> __l) 119838fd1498Szrj { 119938fd1498Szrj auto __offset = __position - cbegin(); 120038fd1498Szrj _M_range_insert(begin() + __offset, __l.begin(), __l.end(), 120138fd1498Szrj std::random_access_iterator_tag()); 120238fd1498Szrj return begin() + __offset; 120338fd1498Szrj } 120438fd1498Szrj #endif 120538fd1498Szrj 120638fd1498Szrj #if __cplusplus >= 201103L 120738fd1498Szrj /** 120838fd1498Szrj * @brief Inserts a number of copies of given data into the %vector. 120938fd1498Szrj * @param __position A const_iterator into the %vector. 121038fd1498Szrj * @param __n Number of elements to be inserted. 121138fd1498Szrj * @param __x Data to be inserted. 121238fd1498Szrj * @return An iterator that points to the inserted data. 121338fd1498Szrj * 121438fd1498Szrj * This function will insert a specified number of copies of 121538fd1498Szrj * the given data before the location specified by @a position. 121638fd1498Szrj * 121738fd1498Szrj * Note that this kind of operation could be expensive for a 121838fd1498Szrj * %vector and if it is frequently used the user should 121938fd1498Szrj * consider using std::list. 122038fd1498Szrj */ 122138fd1498Szrj iterator 122238fd1498Szrj insert(const_iterator __position, size_type __n, const value_type& __x) 122338fd1498Szrj { 122438fd1498Szrj difference_type __offset = __position - cbegin(); 122538fd1498Szrj _M_fill_insert(begin() + __offset, __n, __x); 122638fd1498Szrj return begin() + __offset; 122738fd1498Szrj } 122838fd1498Szrj #else 122938fd1498Szrj /** 123038fd1498Szrj * @brief Inserts a number of copies of given data into the %vector. 123138fd1498Szrj * @param __position An iterator into the %vector. 123238fd1498Szrj * @param __n Number of elements to be inserted. 123338fd1498Szrj * @param __x Data to be inserted. 123438fd1498Szrj * 123538fd1498Szrj * This function will insert a specified number of copies of 123638fd1498Szrj * the given data before the location specified by @a position. 123738fd1498Szrj * 123838fd1498Szrj * Note that this kind of operation could be expensive for a 123938fd1498Szrj * %vector and if it is frequently used the user should 124038fd1498Szrj * consider using std::list. 124138fd1498Szrj */ 124238fd1498Szrj void 124338fd1498Szrj insert(iterator __position, size_type __n, const value_type& __x) 124438fd1498Szrj { _M_fill_insert(__position, __n, __x); } 124538fd1498Szrj #endif 124638fd1498Szrj 124738fd1498Szrj #if __cplusplus >= 201103L 124838fd1498Szrj /** 124938fd1498Szrj * @brief Inserts a range into the %vector. 125038fd1498Szrj * @param __position A const_iterator into the %vector. 125138fd1498Szrj * @param __first An input iterator. 125238fd1498Szrj * @param __last An input iterator. 125338fd1498Szrj * @return An iterator that points to the inserted data. 125438fd1498Szrj * 125538fd1498Szrj * This function will insert copies of the data in the range 125638fd1498Szrj * [__first,__last) into the %vector before the location specified 125738fd1498Szrj * by @a pos. 125838fd1498Szrj * 125938fd1498Szrj * Note that this kind of operation could be expensive for a 126038fd1498Szrj * %vector and if it is frequently used the user should 126138fd1498Szrj * consider using std::list. 126238fd1498Szrj */ 126338fd1498Szrj template<typename _InputIterator, 126438fd1498Szrj typename = std::_RequireInputIter<_InputIterator>> 126538fd1498Szrj iterator 126638fd1498Szrj insert(const_iterator __position, _InputIterator __first, 126738fd1498Szrj _InputIterator __last) 126838fd1498Szrj { 126938fd1498Szrj difference_type __offset = __position - cbegin(); 127038fd1498Szrj _M_insert_dispatch(begin() + __offset, 127138fd1498Szrj __first, __last, __false_type()); 127238fd1498Szrj return begin() + __offset; 127338fd1498Szrj } 127438fd1498Szrj #else 127538fd1498Szrj /** 127638fd1498Szrj * @brief Inserts a range into the %vector. 127738fd1498Szrj * @param __position An iterator into the %vector. 127838fd1498Szrj * @param __first An input iterator. 127938fd1498Szrj * @param __last An input iterator. 128038fd1498Szrj * 128138fd1498Szrj * This function will insert copies of the data in the range 128238fd1498Szrj * [__first,__last) into the %vector before the location specified 128338fd1498Szrj * by @a pos. 128438fd1498Szrj * 128538fd1498Szrj * Note that this kind of operation could be expensive for a 128638fd1498Szrj * %vector and if it is frequently used the user should 128738fd1498Szrj * consider using std::list. 128838fd1498Szrj */ 128938fd1498Szrj template<typename _InputIterator> 129038fd1498Szrj void 129138fd1498Szrj insert(iterator __position, _InputIterator __first, 129238fd1498Szrj _InputIterator __last) 129338fd1498Szrj { 129438fd1498Szrj // Check whether it's an integral type. If so, it's not an iterator. 129538fd1498Szrj typedef typename std::__is_integer<_InputIterator>::__type _Integral; 129638fd1498Szrj _M_insert_dispatch(__position, __first, __last, _Integral()); 129738fd1498Szrj } 129838fd1498Szrj #endif 129938fd1498Szrj 130038fd1498Szrj /** 130138fd1498Szrj * @brief Remove element at given position. 130238fd1498Szrj * @param __position Iterator pointing to element to be erased. 130338fd1498Szrj * @return An iterator pointing to the next element (or end()). 130438fd1498Szrj * 130538fd1498Szrj * This function will erase the element at the given position and thus 130638fd1498Szrj * shorten the %vector by one. 130738fd1498Szrj * 130838fd1498Szrj * Note This operation could be expensive and if it is 130938fd1498Szrj * frequently used the user should consider using std::list. 131038fd1498Szrj * The user is also cautioned that this function only erases 131138fd1498Szrj * the element, and that if the element is itself a pointer, 131238fd1498Szrj * the pointed-to memory is not touched in any way. Managing 131338fd1498Szrj * the pointer is the user's responsibility. 131438fd1498Szrj */ 131538fd1498Szrj iterator 131638fd1498Szrj #if __cplusplus >= 201103L 131738fd1498Szrj erase(const_iterator __position) 131838fd1498Szrj { return _M_erase(begin() + (__position - cbegin())); } 131938fd1498Szrj #else 132038fd1498Szrj erase(iterator __position) 132138fd1498Szrj { return _M_erase(__position); } 132238fd1498Szrj #endif 132338fd1498Szrj 132438fd1498Szrj /** 132538fd1498Szrj * @brief Remove a range of elements. 132638fd1498Szrj * @param __first Iterator pointing to the first element to be erased. 132738fd1498Szrj * @param __last Iterator pointing to one past the last element to be 132838fd1498Szrj * erased. 132938fd1498Szrj * @return An iterator pointing to the element pointed to by @a __last 133038fd1498Szrj * prior to erasing (or end()). 133138fd1498Szrj * 133238fd1498Szrj * This function will erase the elements in the range 133338fd1498Szrj * [__first,__last) and shorten the %vector accordingly. 133438fd1498Szrj * 133538fd1498Szrj * Note This operation could be expensive and if it is 133638fd1498Szrj * frequently used the user should consider using std::list. 133738fd1498Szrj * The user is also cautioned that this function only erases 133838fd1498Szrj * the elements, and that if the elements themselves are 133938fd1498Szrj * pointers, the pointed-to memory is not touched in any way. 134038fd1498Szrj * Managing the pointer is the user's responsibility. 134138fd1498Szrj */ 134238fd1498Szrj iterator 134338fd1498Szrj #if __cplusplus >= 201103L 134438fd1498Szrj erase(const_iterator __first, const_iterator __last) 134538fd1498Szrj { 134638fd1498Szrj const auto __beg = begin(); 134738fd1498Szrj const auto __cbeg = cbegin(); 134838fd1498Szrj return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg)); 134938fd1498Szrj } 135038fd1498Szrj #else 135138fd1498Szrj erase(iterator __first, iterator __last) 135238fd1498Szrj { return _M_erase(__first, __last); } 135338fd1498Szrj #endif 135438fd1498Szrj 135538fd1498Szrj /** 135638fd1498Szrj * @brief Swaps data with another %vector. 135738fd1498Szrj * @param __x A %vector of the same element and allocator types. 135838fd1498Szrj * 135938fd1498Szrj * This exchanges the elements between two vectors in constant time. 136038fd1498Szrj * (Three pointers, so it should be quite fast.) 136138fd1498Szrj * Note that the global std::swap() function is specialized such that 136238fd1498Szrj * std::swap(v1,v2) will feed to this function. 136338fd1498Szrj * 136438fd1498Szrj * Whether the allocators are swapped depends on the allocator traits. 136538fd1498Szrj */ 136638fd1498Szrj void 136738fd1498Szrj swap(vector& __x) _GLIBCXX_NOEXCEPT 136838fd1498Szrj { 136938fd1498Szrj #if __cplusplus >= 201103L 137038fd1498Szrj __glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value 137138fd1498Szrj || _M_get_Tp_allocator() == __x._M_get_Tp_allocator()); 137238fd1498Szrj #endif 137338fd1498Szrj this->_M_impl._M_swap_data(__x._M_impl); 137438fd1498Szrj _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(), 137538fd1498Szrj __x._M_get_Tp_allocator()); 137638fd1498Szrj } 137738fd1498Szrj 137838fd1498Szrj /** 137938fd1498Szrj * Erases all the elements. Note that this function only erases the 138038fd1498Szrj * elements, and that if the elements themselves are pointers, the 138138fd1498Szrj * pointed-to memory is not touched in any way. Managing the pointer is 138238fd1498Szrj * the user's responsibility. 138338fd1498Szrj */ 138438fd1498Szrj void 138538fd1498Szrj clear() _GLIBCXX_NOEXCEPT 138638fd1498Szrj { _M_erase_at_end(this->_M_impl._M_start); } 138738fd1498Szrj 138838fd1498Szrj protected: 138938fd1498Szrj /** 139038fd1498Szrj * Memory expansion handler. Uses the member allocation function to 139138fd1498Szrj * obtain @a n bytes of memory, and then copies [first,last) into it. 139238fd1498Szrj */ 139338fd1498Szrj template<typename _ForwardIterator> 139438fd1498Szrj pointer 139538fd1498Szrj _M_allocate_and_copy(size_type __n, 139638fd1498Szrj _ForwardIterator __first, _ForwardIterator __last) 139738fd1498Szrj { 139838fd1498Szrj pointer __result = this->_M_allocate(__n); 139938fd1498Szrj __try 140038fd1498Szrj { 140138fd1498Szrj std::__uninitialized_copy_a(__first, __last, __result, 140238fd1498Szrj _M_get_Tp_allocator()); 140338fd1498Szrj return __result; 140438fd1498Szrj } 140538fd1498Szrj __catch(...) 140638fd1498Szrj { 140738fd1498Szrj _M_deallocate(__result, __n); 140838fd1498Szrj __throw_exception_again; 140938fd1498Szrj } 141038fd1498Szrj } 141138fd1498Szrj 141238fd1498Szrj 141338fd1498Szrj // Internal constructor functions follow. 141438fd1498Szrj 141538fd1498Szrj // Called by the range constructor to implement [23.1.1]/9 141638fd1498Szrj 141738fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 141838fd1498Szrj // 438. Ambiguity in the "do the right thing" clause 141938fd1498Szrj template<typename _Integer> 142038fd1498Szrj void 142138fd1498Szrj _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) 142238fd1498Szrj { 142338fd1498Szrj this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n)); 142438fd1498Szrj this->_M_impl._M_end_of_storage = 142538fd1498Szrj this->_M_impl._M_start + static_cast<size_type>(__n); 142638fd1498Szrj _M_fill_initialize(static_cast<size_type>(__n), __value); 142738fd1498Szrj } 142838fd1498Szrj 142938fd1498Szrj // Called by the range constructor to implement [23.1.1]/9 143038fd1498Szrj template<typename _InputIterator> 143138fd1498Szrj void 143238fd1498Szrj _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, 143338fd1498Szrj __false_type) 143438fd1498Szrj { 143538fd1498Szrj typedef typename std::iterator_traits<_InputIterator>:: 143638fd1498Szrj iterator_category _IterCategory; 143738fd1498Szrj _M_range_initialize(__first, __last, _IterCategory()); 143838fd1498Szrj } 143938fd1498Szrj 144038fd1498Szrj // Called by the second initialize_dispatch above 144138fd1498Szrj template<typename _InputIterator> 144238fd1498Szrj void 1443*58e805e6Szrj _M_range_initialize(_InputIterator __first, _InputIterator __last, 1444*58e805e6Szrj std::input_iterator_tag) 144538fd1498Szrj { 1446*58e805e6Szrj __try { 144738fd1498Szrj for (; __first != __last; ++__first) 144838fd1498Szrj #if __cplusplus >= 201103L 144938fd1498Szrj emplace_back(*__first); 145038fd1498Szrj #else 145138fd1498Szrj push_back(*__first); 145238fd1498Szrj #endif 1453*58e805e6Szrj } __catch(...) { 1454*58e805e6Szrj clear(); 1455*58e805e6Szrj __throw_exception_again; 1456*58e805e6Szrj } 145738fd1498Szrj } 145838fd1498Szrj 145938fd1498Szrj // Called by the second initialize_dispatch above 146038fd1498Szrj template<typename _ForwardIterator> 146138fd1498Szrj void 1462*58e805e6Szrj _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, 1463*58e805e6Szrj std::forward_iterator_tag) 146438fd1498Szrj { 146538fd1498Szrj const size_type __n = std::distance(__first, __last); 146638fd1498Szrj this->_M_impl._M_start = this->_M_allocate(__n); 146738fd1498Szrj this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; 146838fd1498Szrj this->_M_impl._M_finish = 146938fd1498Szrj std::__uninitialized_copy_a(__first, __last, 147038fd1498Szrj this->_M_impl._M_start, 147138fd1498Szrj _M_get_Tp_allocator()); 147238fd1498Szrj } 147338fd1498Szrj 147438fd1498Szrj // Called by the first initialize_dispatch above and by the 147538fd1498Szrj // vector(n,value,a) constructor. 147638fd1498Szrj void 147738fd1498Szrj _M_fill_initialize(size_type __n, const value_type& __value) 147838fd1498Szrj { 147938fd1498Szrj this->_M_impl._M_finish = 148038fd1498Szrj std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, 148138fd1498Szrj _M_get_Tp_allocator()); 148238fd1498Szrj } 148338fd1498Szrj 148438fd1498Szrj #if __cplusplus >= 201103L 148538fd1498Szrj // Called by the vector(n) constructor. 148638fd1498Szrj void 148738fd1498Szrj _M_default_initialize(size_type __n) 148838fd1498Szrj { 148938fd1498Szrj this->_M_impl._M_finish = 149038fd1498Szrj std::__uninitialized_default_n_a(this->_M_impl._M_start, __n, 149138fd1498Szrj _M_get_Tp_allocator()); 149238fd1498Szrj } 149338fd1498Szrj #endif 149438fd1498Szrj 149538fd1498Szrj // Internal assign functions follow. The *_aux functions do the actual 149638fd1498Szrj // assignment work for the range versions. 149738fd1498Szrj 149838fd1498Szrj // Called by the range assign to implement [23.1.1]/9 149938fd1498Szrj 150038fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 150138fd1498Szrj // 438. Ambiguity in the "do the right thing" clause 150238fd1498Szrj template<typename _Integer> 150338fd1498Szrj void 150438fd1498Szrj _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) 150538fd1498Szrj { _M_fill_assign(__n, __val); } 150638fd1498Szrj 150738fd1498Szrj // Called by the range assign to implement [23.1.1]/9 150838fd1498Szrj template<typename _InputIterator> 150938fd1498Szrj void 151038fd1498Szrj _M_assign_dispatch(_InputIterator __first, _InputIterator __last, 151138fd1498Szrj __false_type) 151238fd1498Szrj { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } 151338fd1498Szrj 151438fd1498Szrj // Called by the second assign_dispatch above 151538fd1498Szrj template<typename _InputIterator> 151638fd1498Szrj void 151738fd1498Szrj _M_assign_aux(_InputIterator __first, _InputIterator __last, 151838fd1498Szrj std::input_iterator_tag); 151938fd1498Szrj 152038fd1498Szrj // Called by the second assign_dispatch above 152138fd1498Szrj template<typename _ForwardIterator> 152238fd1498Szrj void 152338fd1498Szrj _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 152438fd1498Szrj std::forward_iterator_tag); 152538fd1498Szrj 152638fd1498Szrj // Called by assign(n,t), and the range assign when it turns out 152738fd1498Szrj // to be the same thing. 152838fd1498Szrj void 152938fd1498Szrj _M_fill_assign(size_type __n, const value_type& __val); 153038fd1498Szrj 153138fd1498Szrj // Internal insert functions follow. 153238fd1498Szrj 153338fd1498Szrj // Called by the range insert to implement [23.1.1]/9 153438fd1498Szrj 153538fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 153638fd1498Szrj // 438. Ambiguity in the "do the right thing" clause 153738fd1498Szrj template<typename _Integer> 153838fd1498Szrj void 153938fd1498Szrj _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, 154038fd1498Szrj __true_type) 154138fd1498Szrj { _M_fill_insert(__pos, __n, __val); } 154238fd1498Szrj 154338fd1498Szrj // Called by the range insert to implement [23.1.1]/9 154438fd1498Szrj template<typename _InputIterator> 154538fd1498Szrj void 154638fd1498Szrj _M_insert_dispatch(iterator __pos, _InputIterator __first, 154738fd1498Szrj _InputIterator __last, __false_type) 154838fd1498Szrj { 154938fd1498Szrj _M_range_insert(__pos, __first, __last, 155038fd1498Szrj std::__iterator_category(__first)); 155138fd1498Szrj } 155238fd1498Szrj 155338fd1498Szrj // Called by the second insert_dispatch above 155438fd1498Szrj template<typename _InputIterator> 155538fd1498Szrj void 155638fd1498Szrj _M_range_insert(iterator __pos, _InputIterator __first, 155738fd1498Szrj _InputIterator __last, std::input_iterator_tag); 155838fd1498Szrj 155938fd1498Szrj // Called by the second insert_dispatch above 156038fd1498Szrj template<typename _ForwardIterator> 156138fd1498Szrj void 156238fd1498Szrj _M_range_insert(iterator __pos, _ForwardIterator __first, 156338fd1498Szrj _ForwardIterator __last, std::forward_iterator_tag); 156438fd1498Szrj 156538fd1498Szrj // Called by insert(p,n,x), and the range insert when it turns out to be 156638fd1498Szrj // the same thing. 156738fd1498Szrj void 156838fd1498Szrj _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 156938fd1498Szrj 157038fd1498Szrj #if __cplusplus >= 201103L 157138fd1498Szrj // Called by resize(n). 157238fd1498Szrj void 157338fd1498Szrj _M_default_append(size_type __n); 157438fd1498Szrj 157538fd1498Szrj bool 157638fd1498Szrj _M_shrink_to_fit(); 157738fd1498Szrj #endif 157838fd1498Szrj 157938fd1498Szrj #if __cplusplus < 201103L 158038fd1498Szrj // Called by insert(p,x) 158138fd1498Szrj void 158238fd1498Szrj _M_insert_aux(iterator __position, const value_type& __x); 158338fd1498Szrj 158438fd1498Szrj void 158538fd1498Szrj _M_realloc_insert(iterator __position, const value_type& __x); 158638fd1498Szrj #else 158738fd1498Szrj // A value_type object constructed with _Alloc_traits::construct() 158838fd1498Szrj // and destroyed with _Alloc_traits::destroy(). 158938fd1498Szrj struct _Temporary_value 159038fd1498Szrj { 159138fd1498Szrj template<typename... _Args> 159238fd1498Szrj explicit 159338fd1498Szrj _Temporary_value(vector* __vec, _Args&&... __args) : _M_this(__vec) 159438fd1498Szrj { 159538fd1498Szrj _Alloc_traits::construct(_M_this->_M_impl, _M_ptr(), 159638fd1498Szrj std::forward<_Args>(__args)...); 159738fd1498Szrj } 159838fd1498Szrj 159938fd1498Szrj ~_Temporary_value() 160038fd1498Szrj { _Alloc_traits::destroy(_M_this->_M_impl, _M_ptr()); } 160138fd1498Szrj 160238fd1498Szrj value_type& 160338fd1498Szrj _M_val() { return *reinterpret_cast<_Tp*>(&__buf); } 160438fd1498Szrj 160538fd1498Szrj private: 160638fd1498Szrj pointer 160738fd1498Szrj _M_ptr() { return pointer_traits<pointer>::pointer_to(_M_val()); } 160838fd1498Szrj 160938fd1498Szrj vector* _M_this; 161038fd1498Szrj typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __buf; 161138fd1498Szrj }; 161238fd1498Szrj 161338fd1498Szrj // Called by insert(p,x) and other functions when insertion needs to 161438fd1498Szrj // reallocate or move existing elements. _Arg is either _Tp& or _Tp. 161538fd1498Szrj template<typename _Arg> 161638fd1498Szrj void 161738fd1498Szrj _M_insert_aux(iterator __position, _Arg&& __arg); 161838fd1498Szrj 161938fd1498Szrj template<typename... _Args> 162038fd1498Szrj void 162138fd1498Szrj _M_realloc_insert(iterator __position, _Args&&... __args); 162238fd1498Szrj 162338fd1498Szrj // Either move-construct at the end, or forward to _M_insert_aux. 162438fd1498Szrj iterator 162538fd1498Szrj _M_insert_rval(const_iterator __position, value_type&& __v); 162638fd1498Szrj 162738fd1498Szrj // Try to emplace at the end, otherwise forward to _M_insert_aux. 162838fd1498Szrj template<typename... _Args> 162938fd1498Szrj iterator 163038fd1498Szrj _M_emplace_aux(const_iterator __position, _Args&&... __args); 163138fd1498Szrj 163238fd1498Szrj // Emplacing an rvalue of the correct type can use _M_insert_rval. 163338fd1498Szrj iterator 163438fd1498Szrj _M_emplace_aux(const_iterator __position, value_type&& __v) 163538fd1498Szrj { return _M_insert_rval(__position, std::move(__v)); } 163638fd1498Szrj #endif 163738fd1498Szrj 163838fd1498Szrj // Called by _M_fill_insert, _M_insert_aux etc. 163938fd1498Szrj size_type 164038fd1498Szrj _M_check_len(size_type __n, const char* __s) const 164138fd1498Szrj { 164238fd1498Szrj if (max_size() - size() < __n) 164338fd1498Szrj __throw_length_error(__N(__s)); 164438fd1498Szrj 164538fd1498Szrj const size_type __len = size() + std::max(size(), __n); 164638fd1498Szrj return (__len < size() || __len > max_size()) ? max_size() : __len; 164738fd1498Szrj } 164838fd1498Szrj 164938fd1498Szrj // Internal erase functions follow. 165038fd1498Szrj 165138fd1498Szrj // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, 165238fd1498Szrj // _M_assign_aux. 165338fd1498Szrj void 165438fd1498Szrj _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPT 165538fd1498Szrj { 165638fd1498Szrj if (size_type __n = this->_M_impl._M_finish - __pos) 165738fd1498Szrj { 165838fd1498Szrj std::_Destroy(__pos, this->_M_impl._M_finish, 165938fd1498Szrj _M_get_Tp_allocator()); 166038fd1498Szrj this->_M_impl._M_finish = __pos; 166138fd1498Szrj _GLIBCXX_ASAN_ANNOTATE_SHRINK(__n); 166238fd1498Szrj } 166338fd1498Szrj } 166438fd1498Szrj 166538fd1498Szrj iterator 166638fd1498Szrj _M_erase(iterator __position); 166738fd1498Szrj 166838fd1498Szrj iterator 166938fd1498Szrj _M_erase(iterator __first, iterator __last); 167038fd1498Szrj 167138fd1498Szrj #if __cplusplus >= 201103L 167238fd1498Szrj private: 167338fd1498Szrj // Constant-time move assignment when source object's memory can be 167438fd1498Szrj // moved, either because the source's allocator will move too 167538fd1498Szrj // or because the allocators are equal. 167638fd1498Szrj void 167738fd1498Szrj _M_move_assign(vector&& __x, std::true_type) noexcept 167838fd1498Szrj { 167938fd1498Szrj vector __tmp(get_allocator()); 168038fd1498Szrj this->_M_impl._M_swap_data(__tmp._M_impl); 168138fd1498Szrj this->_M_impl._M_swap_data(__x._M_impl); 168238fd1498Szrj std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); 168338fd1498Szrj } 168438fd1498Szrj 168538fd1498Szrj // Do move assignment when it might not be possible to move source 168638fd1498Szrj // object's memory, resulting in a linear-time operation. 168738fd1498Szrj void 168838fd1498Szrj _M_move_assign(vector&& __x, std::false_type) 168938fd1498Szrj { 169038fd1498Szrj if (__x._M_get_Tp_allocator() == this->_M_get_Tp_allocator()) 169138fd1498Szrj _M_move_assign(std::move(__x), std::true_type()); 169238fd1498Szrj else 169338fd1498Szrj { 169438fd1498Szrj // The rvalue's allocator cannot be moved and is not equal, 169538fd1498Szrj // so we need to individually move each element. 169638fd1498Szrj this->assign(std::__make_move_if_noexcept_iterator(__x.begin()), 169738fd1498Szrj std::__make_move_if_noexcept_iterator(__x.end())); 169838fd1498Szrj __x.clear(); 169938fd1498Szrj } 170038fd1498Szrj } 170138fd1498Szrj #endif 170238fd1498Szrj 170338fd1498Szrj template<typename _Up> 170438fd1498Szrj _Up* 170538fd1498Szrj _M_data_ptr(_Up* __ptr) const _GLIBCXX_NOEXCEPT 170638fd1498Szrj { return __ptr; } 170738fd1498Szrj 170838fd1498Szrj #if __cplusplus >= 201103L 170938fd1498Szrj template<typename _Ptr> 171038fd1498Szrj typename std::pointer_traits<_Ptr>::element_type* 171138fd1498Szrj _M_data_ptr(_Ptr __ptr) const 171238fd1498Szrj { return empty() ? nullptr : std::__to_address(__ptr); } 171338fd1498Szrj #else 171438fd1498Szrj template<typename _Up> 171538fd1498Szrj _Up* 171638fd1498Szrj _M_data_ptr(_Up* __ptr) _GLIBCXX_NOEXCEPT 171738fd1498Szrj { return __ptr; } 171838fd1498Szrj 171938fd1498Szrj template<typename _Ptr> 172038fd1498Szrj value_type* 172138fd1498Szrj _M_data_ptr(_Ptr __ptr) 172238fd1498Szrj { return empty() ? (value_type*)0 : __ptr.operator->(); } 172338fd1498Szrj 172438fd1498Szrj template<typename _Ptr> 172538fd1498Szrj const value_type* 172638fd1498Szrj _M_data_ptr(_Ptr __ptr) const 172738fd1498Szrj { return empty() ? (const value_type*)0 : __ptr.operator->(); } 172838fd1498Szrj #endif 172938fd1498Szrj }; 173038fd1498Szrj 173138fd1498Szrj #if __cpp_deduction_guides >= 201606 173238fd1498Szrj template<typename _InputIterator, typename _ValT 173338fd1498Szrj = typename iterator_traits<_InputIterator>::value_type, 173438fd1498Szrj typename _Allocator = allocator<_ValT>, 173538fd1498Szrj typename = _RequireInputIter<_InputIterator>, 173638fd1498Szrj typename = _RequireAllocator<_Allocator>> 173738fd1498Szrj vector(_InputIterator, _InputIterator, _Allocator = _Allocator()) 173838fd1498Szrj -> vector<_ValT, _Allocator>; 173938fd1498Szrj #endif 174038fd1498Szrj 174138fd1498Szrj /** 174238fd1498Szrj * @brief Vector equality comparison. 174338fd1498Szrj * @param __x A %vector. 174438fd1498Szrj * @param __y A %vector of the same type as @a __x. 174538fd1498Szrj * @return True iff the size and elements of the vectors are equal. 174638fd1498Szrj * 174738fd1498Szrj * This is an equivalence relation. It is linear in the size of the 174838fd1498Szrj * vectors. Vectors are considered equivalent if their sizes are equal, 174938fd1498Szrj * and if corresponding elements compare equal. 175038fd1498Szrj */ 175138fd1498Szrj template<typename _Tp, typename _Alloc> 175238fd1498Szrj inline bool 175338fd1498Szrj operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 175438fd1498Szrj { return (__x.size() == __y.size() 175538fd1498Szrj && std::equal(__x.begin(), __x.end(), __y.begin())); } 175638fd1498Szrj 175738fd1498Szrj /** 175838fd1498Szrj * @brief Vector ordering relation. 175938fd1498Szrj * @param __x A %vector. 176038fd1498Szrj * @param __y A %vector of the same type as @a __x. 176138fd1498Szrj * @return True iff @a __x is lexicographically less than @a __y. 176238fd1498Szrj * 176338fd1498Szrj * This is a total ordering relation. It is linear in the size of the 176438fd1498Szrj * vectors. The elements must be comparable with @c <. 176538fd1498Szrj * 176638fd1498Szrj * See std::lexicographical_compare() for how the determination is made. 176738fd1498Szrj */ 176838fd1498Szrj template<typename _Tp, typename _Alloc> 176938fd1498Szrj inline bool 177038fd1498Szrj operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 177138fd1498Szrj { return std::lexicographical_compare(__x.begin(), __x.end(), 177238fd1498Szrj __y.begin(), __y.end()); } 177338fd1498Szrj 177438fd1498Szrj /// Based on operator== 177538fd1498Szrj template<typename _Tp, typename _Alloc> 177638fd1498Szrj inline bool 177738fd1498Szrj operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 177838fd1498Szrj { return !(__x == __y); } 177938fd1498Szrj 178038fd1498Szrj /// Based on operator< 178138fd1498Szrj template<typename _Tp, typename _Alloc> 178238fd1498Szrj inline bool 178338fd1498Szrj operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 178438fd1498Szrj { return __y < __x; } 178538fd1498Szrj 178638fd1498Szrj /// Based on operator< 178738fd1498Szrj template<typename _Tp, typename _Alloc> 178838fd1498Szrj inline bool 178938fd1498Szrj operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 179038fd1498Szrj { return !(__y < __x); } 179138fd1498Szrj 179238fd1498Szrj /// Based on operator< 179338fd1498Szrj template<typename _Tp, typename _Alloc> 179438fd1498Szrj inline bool 179538fd1498Szrj operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) 179638fd1498Szrj { return !(__x < __y); } 179738fd1498Szrj 179838fd1498Szrj /// See std::vector::swap(). 179938fd1498Szrj template<typename _Tp, typename _Alloc> 180038fd1498Szrj inline void 180138fd1498Szrj swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) 180238fd1498Szrj _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) 180338fd1498Szrj { __x.swap(__y); } 180438fd1498Szrj 180538fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER 180638fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 180738fd1498Szrj } // namespace std 180838fd1498Szrj 180938fd1498Szrj #endif /* _STL_VECTOR_H */ 1810