xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_vector.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // Vector implementation -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /*
26*38fd1498Szrj  *
27*38fd1498Szrj  * Copyright (c) 1994
28*38fd1498Szrj  * Hewlett-Packard Company
29*38fd1498Szrj  *
30*38fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
31*38fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
32*38fd1498Szrj  * provided that the above copyright notice appear in all copies and
33*38fd1498Szrj  * that both that copyright notice and this permission notice appear
34*38fd1498Szrj  * in supporting documentation.  Hewlett-Packard Company makes no
35*38fd1498Szrj  * representations about the suitability of this software for any
36*38fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
37*38fd1498Szrj  *
38*38fd1498Szrj  *
39*38fd1498Szrj  * Copyright (c) 1996
40*38fd1498Szrj  * Silicon Graphics Computer Systems, Inc.
41*38fd1498Szrj  *
42*38fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
43*38fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
44*38fd1498Szrj  * provided that the above copyright notice appear in all copies and
45*38fd1498Szrj  * that both that copyright notice and this permission notice appear
46*38fd1498Szrj  * in supporting documentation.  Silicon Graphics makes no
47*38fd1498Szrj  * representations about the suitability of this  software for any
48*38fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
49*38fd1498Szrj  */
50*38fd1498Szrj 
51*38fd1498Szrj /** @file bits/stl_vector.h
52*38fd1498Szrj  *  This is an internal header file, included by other library headers.
53*38fd1498Szrj  *  Do not attempt to use it directly. @headername{vector}
54*38fd1498Szrj  */
55*38fd1498Szrj 
56*38fd1498Szrj #ifndef _STL_VECTOR_H
57*38fd1498Szrj #define _STL_VECTOR_H 1
58*38fd1498Szrj 
59*38fd1498Szrj #include <bits/stl_iterator_base_funcs.h>
60*38fd1498Szrj #include <bits/functexcept.h>
61*38fd1498Szrj #include <bits/concept_check.h>
62*38fd1498Szrj #if __cplusplus >= 201103L
63*38fd1498Szrj #include <initializer_list>
64*38fd1498Szrj #endif
65*38fd1498Szrj 
66*38fd1498Szrj #include <debug/assertions.h>
67*38fd1498Szrj 
68*38fd1498Szrj #if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR
69*38fd1498Szrj extern "C" void
70*38fd1498Szrj __sanitizer_annotate_contiguous_container(const void*, const void*,
71*38fd1498Szrj 					  const void*, const void*);
72*38fd1498Szrj #endif
73*38fd1498Szrj 
74*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
75*38fd1498Szrj {
76*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
77*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
78*38fd1498Szrj 
79*38fd1498Szrj   /// See bits/stl_deque.h's _Deque_base for an explanation.
80*38fd1498Szrj   template<typename _Tp, typename _Alloc>
81*38fd1498Szrj     struct _Vector_base
82*38fd1498Szrj     {
83*38fd1498Szrj       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
84*38fd1498Szrj 	rebind<_Tp>::other _Tp_alloc_type;
85*38fd1498Szrj       typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
86*38fd1498Szrj        	pointer;
87*38fd1498Szrj 
88*38fd1498Szrj       struct _Vector_impl
89*38fd1498Szrj       : public _Tp_alloc_type
90*38fd1498Szrj       {
91*38fd1498Szrj 	pointer _M_start;
92*38fd1498Szrj 	pointer _M_finish;
93*38fd1498Szrj 	pointer _M_end_of_storage;
94*38fd1498Szrj 
95*38fd1498Szrj 	_Vector_impl()
96*38fd1498Szrj 	: _Tp_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage()
97*38fd1498Szrj 	{ }
98*38fd1498Szrj 
99*38fd1498Szrj 	_Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT
100*38fd1498Szrj 	: _Tp_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage()
101*38fd1498Szrj 	{ }
102*38fd1498Szrj 
103*38fd1498Szrj #if __cplusplus >= 201103L
104*38fd1498Szrj 	_Vector_impl(_Tp_alloc_type&& __a) noexcept
105*38fd1498Szrj 	: _Tp_alloc_type(std::move(__a)),
106*38fd1498Szrj 	  _M_start(), _M_finish(), _M_end_of_storage()
107*38fd1498Szrj 	{ }
108*38fd1498Szrj #endif
109*38fd1498Szrj 
110*38fd1498Szrj 	void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT
111*38fd1498Szrj 	{
112*38fd1498Szrj 	  std::swap(_M_start, __x._M_start);
113*38fd1498Szrj 	  std::swap(_M_finish, __x._M_finish);
114*38fd1498Szrj 	  std::swap(_M_end_of_storage, __x._M_end_of_storage);
115*38fd1498Szrj 	}
116*38fd1498Szrj 
117*38fd1498Szrj #if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR
118*38fd1498Szrj 	template<typename = _Tp_alloc_type>
119*38fd1498Szrj 	  struct _Asan
120*38fd1498Szrj 	  {
121*38fd1498Szrj 	    typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>
122*38fd1498Szrj 	      ::size_type size_type;
123*38fd1498Szrj 
124*38fd1498Szrj 	    static void _S_shrink(_Vector_impl&, size_type) { }
125*38fd1498Szrj 	    static void _S_on_dealloc(_Vector_impl&) { }
126*38fd1498Szrj 
127*38fd1498Szrj 	    typedef _Vector_impl& _Reinit;
128*38fd1498Szrj 
129*38fd1498Szrj 	    struct _Grow
130*38fd1498Szrj 	    {
131*38fd1498Szrj 	      _Grow(_Vector_impl&, size_type) { }
132*38fd1498Szrj 	      void _M_grew(size_type) { }
133*38fd1498Szrj 	    };
134*38fd1498Szrj 	  };
135*38fd1498Szrj 
136*38fd1498Szrj 	// Enable ASan annotations for memory obtained from std::allocator.
137*38fd1498Szrj 	template<typename _Up>
138*38fd1498Szrj 	  struct _Asan<allocator<_Up> >
139*38fd1498Szrj 	  {
140*38fd1498Szrj 	    typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>
141*38fd1498Szrj 	      ::size_type size_type;
142*38fd1498Szrj 
143*38fd1498Szrj 	    // Adjust ASan annotation for [_M_start, _M_end_of_storage) to
144*38fd1498Szrj 	    // mark end of valid region as __curr instead of __prev.
145*38fd1498Szrj 	    static void
146*38fd1498Szrj 	    _S_adjust(_Vector_impl& __impl, pointer __prev, pointer __curr)
147*38fd1498Szrj 	    {
148*38fd1498Szrj 	      __sanitizer_annotate_contiguous_container(__impl._M_start,
149*38fd1498Szrj 		  __impl._M_end_of_storage, __prev, __curr);
150*38fd1498Szrj 	    }
151*38fd1498Szrj 
152*38fd1498Szrj 	    static void
153*38fd1498Szrj 	    _S_grow(_Vector_impl& __impl, size_type __n)
154*38fd1498Szrj 	    { _S_adjust(__impl, __impl._M_finish, __impl._M_finish + __n); }
155*38fd1498Szrj 
156*38fd1498Szrj 	    static void
157*38fd1498Szrj 	    _S_shrink(_Vector_impl& __impl, size_type __n)
158*38fd1498Szrj 	    { _S_adjust(__impl, __impl._M_finish + __n, __impl._M_finish); }
159*38fd1498Szrj 
160*38fd1498Szrj 	    static void
161*38fd1498Szrj 	    _S_on_dealloc(_Vector_impl& __impl)
162*38fd1498Szrj 	    {
163*38fd1498Szrj 	      if (__impl._M_start)
164*38fd1498Szrj 		_S_adjust(__impl, __impl._M_finish, __impl._M_end_of_storage);
165*38fd1498Szrj 	    }
166*38fd1498Szrj 
167*38fd1498Szrj 	    // Used on reallocation to tell ASan unused capacity is invalid.
168*38fd1498Szrj 	    struct _Reinit
169*38fd1498Szrj 	    {
170*38fd1498Szrj 	      explicit _Reinit(_Vector_impl& __impl) : _M_impl(__impl)
171*38fd1498Szrj 	      {
172*38fd1498Szrj 		// Mark unused capacity as valid again before deallocating it.
173*38fd1498Szrj 		_S_on_dealloc(_M_impl);
174*38fd1498Szrj 	      }
175*38fd1498Szrj 
176*38fd1498Szrj 	      ~_Reinit()
177*38fd1498Szrj 	      {
178*38fd1498Szrj 		// Mark unused capacity as invalid after reallocation.
179*38fd1498Szrj 		if (_M_impl._M_start)
180*38fd1498Szrj 		  _S_adjust(_M_impl, _M_impl._M_end_of_storage,
181*38fd1498Szrj 			    _M_impl._M_finish);
182*38fd1498Szrj 	      }
183*38fd1498Szrj 
184*38fd1498Szrj 	      _Vector_impl& _M_impl;
185*38fd1498Szrj 
186*38fd1498Szrj #if __cplusplus >= 201103L
187*38fd1498Szrj 	      _Reinit(const _Reinit&) = delete;
188*38fd1498Szrj 	      _Reinit& operator=(const _Reinit&) = delete;
189*38fd1498Szrj #endif
190*38fd1498Szrj 	    };
191*38fd1498Szrj 
192*38fd1498Szrj 	    // Tell ASan when unused capacity is initialized to be valid.
193*38fd1498Szrj 	    struct _Grow
194*38fd1498Szrj 	    {
195*38fd1498Szrj 	      _Grow(_Vector_impl& __impl, size_type __n)
196*38fd1498Szrj 	      : _M_impl(__impl), _M_n(__n)
197*38fd1498Szrj 	      { _S_grow(_M_impl, __n); }
198*38fd1498Szrj 
199*38fd1498Szrj 	      ~_Grow() { if (_M_n) _S_shrink(_M_impl, _M_n); }
200*38fd1498Szrj 
201*38fd1498Szrj 	      void _M_grew(size_type __n) { _M_n -= __n; }
202*38fd1498Szrj 
203*38fd1498Szrj #if __cplusplus >= 201103L
204*38fd1498Szrj 	      _Grow(const _Grow&) = delete;
205*38fd1498Szrj 	      _Grow& operator=(const _Grow&) = delete;
206*38fd1498Szrj #endif
207*38fd1498Szrj 	    private:
208*38fd1498Szrj 	      _Vector_impl& _M_impl;
209*38fd1498Szrj 	      size_type _M_n;
210*38fd1498Szrj 	    };
211*38fd1498Szrj 	  };
212*38fd1498Szrj 
213*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_REINIT \
214*38fd1498Szrj   typename _Base::_Vector_impl::template _Asan<>::_Reinit const \
215*38fd1498Szrj 	__attribute__((__unused__)) __reinit_guard(this->_M_impl)
216*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GROW(n) \
217*38fd1498Szrj   typename _Base::_Vector_impl::template _Asan<>::_Grow \
218*38fd1498Szrj 	__attribute__((__unused__)) __grow_guard(this->_M_impl, (n))
219*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GREW(n) __grow_guard._M_grew(n)
220*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) \
221*38fd1498Szrj   _Base::_Vector_impl::template _Asan<>::_S_shrink(this->_M_impl, n)
222*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC \
223*38fd1498Szrj   _Base::_Vector_impl::template _Asan<>::_S_on_dealloc(this->_M_impl)
224*38fd1498Szrj #else // ! (_GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR)
225*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_REINIT
226*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GROW(n)
227*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_GREW(n)
228*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n)
229*38fd1498Szrj #define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC
230*38fd1498Szrj #endif // _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR
231*38fd1498Szrj       };
232*38fd1498Szrj 
233*38fd1498Szrj     public:
234*38fd1498Szrj       typedef _Alloc allocator_type;
235*38fd1498Szrj 
236*38fd1498Szrj       _Tp_alloc_type&
237*38fd1498Szrj       _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
238*38fd1498Szrj       { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
239*38fd1498Szrj 
240*38fd1498Szrj       const _Tp_alloc_type&
241*38fd1498Szrj       _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
242*38fd1498Szrj       { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); }
243*38fd1498Szrj 
244*38fd1498Szrj       allocator_type
245*38fd1498Szrj       get_allocator() const _GLIBCXX_NOEXCEPT
246*38fd1498Szrj       { return allocator_type(_M_get_Tp_allocator()); }
247*38fd1498Szrj 
248*38fd1498Szrj       _Vector_base()
249*38fd1498Szrj       : _M_impl() { }
250*38fd1498Szrj 
251*38fd1498Szrj       _Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPT
252*38fd1498Szrj       : _M_impl(__a) { }
253*38fd1498Szrj 
254*38fd1498Szrj       _Vector_base(size_t __n)
255*38fd1498Szrj       : _M_impl()
256*38fd1498Szrj       { _M_create_storage(__n); }
257*38fd1498Szrj 
258*38fd1498Szrj       _Vector_base(size_t __n, const allocator_type& __a)
259*38fd1498Szrj       : _M_impl(__a)
260*38fd1498Szrj       { _M_create_storage(__n); }
261*38fd1498Szrj 
262*38fd1498Szrj #if __cplusplus >= 201103L
263*38fd1498Szrj       _Vector_base(_Tp_alloc_type&& __a) noexcept
264*38fd1498Szrj       : _M_impl(std::move(__a)) { }
265*38fd1498Szrj 
266*38fd1498Szrj       _Vector_base(_Vector_base&& __x) noexcept
267*38fd1498Szrj       : _M_impl(std::move(__x._M_get_Tp_allocator()))
268*38fd1498Szrj       { this->_M_impl._M_swap_data(__x._M_impl); }
269*38fd1498Szrj 
270*38fd1498Szrj       _Vector_base(_Vector_base&& __x, const allocator_type& __a)
271*38fd1498Szrj       : _M_impl(__a)
272*38fd1498Szrj       {
273*38fd1498Szrj 	if (__x.get_allocator() == __a)
274*38fd1498Szrj 	  this->_M_impl._M_swap_data(__x._M_impl);
275*38fd1498Szrj 	else
276*38fd1498Szrj 	  {
277*38fd1498Szrj 	    size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
278*38fd1498Szrj 	    _M_create_storage(__n);
279*38fd1498Szrj 	  }
280*38fd1498Szrj       }
281*38fd1498Szrj #endif
282*38fd1498Szrj 
283*38fd1498Szrj       ~_Vector_base() _GLIBCXX_NOEXCEPT
284*38fd1498Szrj       {
285*38fd1498Szrj 	_M_deallocate(_M_impl._M_start,
286*38fd1498Szrj 		      _M_impl._M_end_of_storage - _M_impl._M_start);
287*38fd1498Szrj       }
288*38fd1498Szrj 
289*38fd1498Szrj     public:
290*38fd1498Szrj       _Vector_impl _M_impl;
291*38fd1498Szrj 
292*38fd1498Szrj       pointer
293*38fd1498Szrj       _M_allocate(size_t __n)
294*38fd1498Szrj       {
295*38fd1498Szrj 	typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
296*38fd1498Szrj 	return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer();
297*38fd1498Szrj       }
298*38fd1498Szrj 
299*38fd1498Szrj       void
300*38fd1498Szrj       _M_deallocate(pointer __p, size_t __n)
301*38fd1498Szrj       {
302*38fd1498Szrj 	typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
303*38fd1498Szrj 	if (__p)
304*38fd1498Szrj 	  _Tr::deallocate(_M_impl, __p, __n);
305*38fd1498Szrj       }
306*38fd1498Szrj 
307*38fd1498Szrj     private:
308*38fd1498Szrj       void
309*38fd1498Szrj       _M_create_storage(size_t __n)
310*38fd1498Szrj       {
311*38fd1498Szrj 	this->_M_impl._M_start = this->_M_allocate(__n);
312*38fd1498Szrj 	this->_M_impl._M_finish = this->_M_impl._M_start;
313*38fd1498Szrj 	this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
314*38fd1498Szrj       }
315*38fd1498Szrj     };
316*38fd1498Szrj 
317*38fd1498Szrj   /**
318*38fd1498Szrj    *  @brief A standard container which offers fixed time access to
319*38fd1498Szrj    *  individual elements in any order.
320*38fd1498Szrj    *
321*38fd1498Szrj    *  @ingroup sequences
322*38fd1498Szrj    *
323*38fd1498Szrj    *  @tparam _Tp  Type of element.
324*38fd1498Szrj    *  @tparam _Alloc  Allocator type, defaults to allocator<_Tp>.
325*38fd1498Szrj    *
326*38fd1498Szrj    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
327*38fd1498Szrj    *  <a href="tables.html#66">reversible container</a>, and a
328*38fd1498Szrj    *  <a href="tables.html#67">sequence</a>, including the
329*38fd1498Szrj    *  <a href="tables.html#68">optional sequence requirements</a> with the
330*38fd1498Szrj    *  %exception of @c push_front and @c pop_front.
331*38fd1498Szrj    *
332*38fd1498Szrj    *  In some terminology a %vector can be described as a dynamic
333*38fd1498Szrj    *  C-style array, it offers fast and efficient access to individual
334*38fd1498Szrj    *  elements in any order and saves the user from worrying about
335*38fd1498Szrj    *  memory and size allocation.  Subscripting ( @c [] ) access is
336*38fd1498Szrj    *  also provided as with C-style arrays.
337*38fd1498Szrj   */
338*38fd1498Szrj   template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
339*38fd1498Szrj     class vector : protected _Vector_base<_Tp, _Alloc>
340*38fd1498Szrj     {
341*38fd1498Szrj #ifdef _GLIBCXX_CONCEPT_CHECKS
342*38fd1498Szrj       // Concept requirements.
343*38fd1498Szrj       typedef typename _Alloc::value_type		_Alloc_value_type;
344*38fd1498Szrj # if __cplusplus < 201103L
345*38fd1498Szrj       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
346*38fd1498Szrj # endif
347*38fd1498Szrj       __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
348*38fd1498Szrj #endif
349*38fd1498Szrj 
350*38fd1498Szrj #if __cplusplus >= 201103L
351*38fd1498Szrj       static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
352*38fd1498Szrj 	  "std::vector must have a non-const, non-volatile value_type");
353*38fd1498Szrj # ifdef __STRICT_ANSI__
354*38fd1498Szrj       static_assert(is_same<typename _Alloc::value_type, _Tp>::value,
355*38fd1498Szrj 	  "std::vector must have the same value_type as its allocator");
356*38fd1498Szrj # endif
357*38fd1498Szrj #endif
358*38fd1498Szrj 
359*38fd1498Szrj       typedef _Vector_base<_Tp, _Alloc>			_Base;
360*38fd1498Szrj       typedef typename _Base::_Tp_alloc_type		_Tp_alloc_type;
361*38fd1498Szrj       typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type>	_Alloc_traits;
362*38fd1498Szrj 
363*38fd1498Szrj     public:
364*38fd1498Szrj       typedef _Tp					value_type;
365*38fd1498Szrj       typedef typename _Base::pointer			pointer;
366*38fd1498Szrj       typedef typename _Alloc_traits::const_pointer	const_pointer;
367*38fd1498Szrj       typedef typename _Alloc_traits::reference		reference;
368*38fd1498Szrj       typedef typename _Alloc_traits::const_reference	const_reference;
369*38fd1498Szrj       typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
370*38fd1498Szrj       typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
371*38fd1498Szrj       const_iterator;
372*38fd1498Szrj       typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
373*38fd1498Szrj       typedef std::reverse_iterator<iterator>		reverse_iterator;
374*38fd1498Szrj       typedef size_t					size_type;
375*38fd1498Szrj       typedef ptrdiff_t					difference_type;
376*38fd1498Szrj       typedef _Alloc					allocator_type;
377*38fd1498Szrj 
378*38fd1498Szrj     protected:
379*38fd1498Szrj       using _Base::_M_allocate;
380*38fd1498Szrj       using _Base::_M_deallocate;
381*38fd1498Szrj       using _Base::_M_impl;
382*38fd1498Szrj       using _Base::_M_get_Tp_allocator;
383*38fd1498Szrj 
384*38fd1498Szrj     public:
385*38fd1498Szrj       // [23.2.4.1] construct/copy/destroy
386*38fd1498Szrj       // (assign() and get_allocator() are also listed in this section)
387*38fd1498Szrj 
388*38fd1498Szrj       /**
389*38fd1498Szrj        *  @brief  Creates a %vector with no elements.
390*38fd1498Szrj        */
391*38fd1498Szrj       vector()
392*38fd1498Szrj #if __cplusplus >= 201103L
393*38fd1498Szrj       noexcept(is_nothrow_default_constructible<_Alloc>::value)
394*38fd1498Szrj #endif
395*38fd1498Szrj       : _Base() { }
396*38fd1498Szrj 
397*38fd1498Szrj       /**
398*38fd1498Szrj        *  @brief  Creates a %vector with no elements.
399*38fd1498Szrj        *  @param  __a  An allocator object.
400*38fd1498Szrj        */
401*38fd1498Szrj       explicit
402*38fd1498Szrj       vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
403*38fd1498Szrj       : _Base(__a) { }
404*38fd1498Szrj 
405*38fd1498Szrj #if __cplusplus >= 201103L
406*38fd1498Szrj       /**
407*38fd1498Szrj        *  @brief  Creates a %vector with default constructed elements.
408*38fd1498Szrj        *  @param  __n  The number of elements to initially create.
409*38fd1498Szrj        *  @param  __a  An allocator.
410*38fd1498Szrj        *
411*38fd1498Szrj        *  This constructor fills the %vector with @a __n default
412*38fd1498Szrj        *  constructed elements.
413*38fd1498Szrj        */
414*38fd1498Szrj       explicit
415*38fd1498Szrj       vector(size_type __n, const allocator_type& __a = allocator_type())
416*38fd1498Szrj       : _Base(__n, __a)
417*38fd1498Szrj       { _M_default_initialize(__n); }
418*38fd1498Szrj 
419*38fd1498Szrj       /**
420*38fd1498Szrj        *  @brief  Creates a %vector with copies of an exemplar element.
421*38fd1498Szrj        *  @param  __n  The number of elements to initially create.
422*38fd1498Szrj        *  @param  __value  An element to copy.
423*38fd1498Szrj        *  @param  __a  An allocator.
424*38fd1498Szrj        *
425*38fd1498Szrj        *  This constructor fills the %vector with @a __n copies of @a __value.
426*38fd1498Szrj        */
427*38fd1498Szrj       vector(size_type __n, const value_type& __value,
428*38fd1498Szrj 	     const allocator_type& __a = allocator_type())
429*38fd1498Szrj       : _Base(__n, __a)
430*38fd1498Szrj       { _M_fill_initialize(__n, __value); }
431*38fd1498Szrj #else
432*38fd1498Szrj       /**
433*38fd1498Szrj        *  @brief  Creates a %vector with copies of an exemplar element.
434*38fd1498Szrj        *  @param  __n  The number of elements to initially create.
435*38fd1498Szrj        *  @param  __value  An element to copy.
436*38fd1498Szrj        *  @param  __a  An allocator.
437*38fd1498Szrj        *
438*38fd1498Szrj        *  This constructor fills the %vector with @a __n copies of @a __value.
439*38fd1498Szrj        */
440*38fd1498Szrj       explicit
441*38fd1498Szrj       vector(size_type __n, const value_type& __value = value_type(),
442*38fd1498Szrj 	     const allocator_type& __a = allocator_type())
443*38fd1498Szrj       : _Base(__n, __a)
444*38fd1498Szrj       { _M_fill_initialize(__n, __value); }
445*38fd1498Szrj #endif
446*38fd1498Szrj 
447*38fd1498Szrj       /**
448*38fd1498Szrj        *  @brief  %Vector copy constructor.
449*38fd1498Szrj        *  @param  __x  A %vector of identical element and allocator types.
450*38fd1498Szrj        *
451*38fd1498Szrj        *  All the elements of @a __x are copied, but any unused capacity in
452*38fd1498Szrj        *  @a __x  will not be copied
453*38fd1498Szrj        *  (i.e. capacity() == size() in the new %vector).
454*38fd1498Szrj        *
455*38fd1498Szrj        *  The newly-created %vector uses a copy of the allocator object used
456*38fd1498Szrj        *  by @a __x (unless the allocator traits dictate a different object).
457*38fd1498Szrj        */
458*38fd1498Szrj       vector(const vector& __x)
459*38fd1498Szrj       : _Base(__x.size(),
460*38fd1498Szrj 	_Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
461*38fd1498Szrj       {
462*38fd1498Szrj 	this->_M_impl._M_finish =
463*38fd1498Szrj 	  std::__uninitialized_copy_a(__x.begin(), __x.end(),
464*38fd1498Szrj 				      this->_M_impl._M_start,
465*38fd1498Szrj 				      _M_get_Tp_allocator());
466*38fd1498Szrj       }
467*38fd1498Szrj 
468*38fd1498Szrj #if __cplusplus >= 201103L
469*38fd1498Szrj       /**
470*38fd1498Szrj        *  @brief  %Vector move constructor.
471*38fd1498Szrj        *  @param  __x  A %vector of identical element and allocator types.
472*38fd1498Szrj        *
473*38fd1498Szrj        *  The newly-created %vector contains the exact contents of @a __x.
474*38fd1498Szrj        *  The contents of @a __x are a valid, but unspecified %vector.
475*38fd1498Szrj        */
476*38fd1498Szrj       vector(vector&& __x) noexcept
477*38fd1498Szrj       : _Base(std::move(__x)) { }
478*38fd1498Szrj 
479*38fd1498Szrj       /// Copy constructor with alternative allocator
480*38fd1498Szrj       vector(const vector& __x, const allocator_type& __a)
481*38fd1498Szrj       : _Base(__x.size(), __a)
482*38fd1498Szrj       {
483*38fd1498Szrj 	this->_M_impl._M_finish =
484*38fd1498Szrj 	  std::__uninitialized_copy_a(__x.begin(), __x.end(),
485*38fd1498Szrj 				      this->_M_impl._M_start,
486*38fd1498Szrj 				      _M_get_Tp_allocator());
487*38fd1498Szrj       }
488*38fd1498Szrj 
489*38fd1498Szrj       /// Move constructor with alternative allocator
490*38fd1498Szrj       vector(vector&& __rv, const allocator_type& __m)
491*38fd1498Szrj       noexcept(_Alloc_traits::_S_always_equal())
492*38fd1498Szrj       : _Base(std::move(__rv), __m)
493*38fd1498Szrj       {
494*38fd1498Szrj 	if (__rv.get_allocator() != __m)
495*38fd1498Szrj 	  {
496*38fd1498Szrj 	    this->_M_impl._M_finish =
497*38fd1498Szrj 	      std::__uninitialized_move_a(__rv.begin(), __rv.end(),
498*38fd1498Szrj 					  this->_M_impl._M_start,
499*38fd1498Szrj 					  _M_get_Tp_allocator());
500*38fd1498Szrj 	    __rv.clear();
501*38fd1498Szrj 	  }
502*38fd1498Szrj       }
503*38fd1498Szrj 
504*38fd1498Szrj       /**
505*38fd1498Szrj        *  @brief  Builds a %vector from an initializer list.
506*38fd1498Szrj        *  @param  __l  An initializer_list.
507*38fd1498Szrj        *  @param  __a  An allocator.
508*38fd1498Szrj        *
509*38fd1498Szrj        *  Create a %vector consisting of copies of the elements in the
510*38fd1498Szrj        *  initializer_list @a __l.
511*38fd1498Szrj        *
512*38fd1498Szrj        *  This will call the element type's copy constructor N times
513*38fd1498Szrj        *  (where N is @a __l.size()) and do no memory reallocation.
514*38fd1498Szrj        */
515*38fd1498Szrj       vector(initializer_list<value_type> __l,
516*38fd1498Szrj 	     const allocator_type& __a = allocator_type())
517*38fd1498Szrj       : _Base(__a)
518*38fd1498Szrj       {
519*38fd1498Szrj 	_M_range_initialize(__l.begin(), __l.end(),
520*38fd1498Szrj 			    random_access_iterator_tag());
521*38fd1498Szrj       }
522*38fd1498Szrj #endif
523*38fd1498Szrj 
524*38fd1498Szrj       /**
525*38fd1498Szrj        *  @brief  Builds a %vector from a range.
526*38fd1498Szrj        *  @param  __first  An input iterator.
527*38fd1498Szrj        *  @param  __last  An input iterator.
528*38fd1498Szrj        *  @param  __a  An allocator.
529*38fd1498Szrj        *
530*38fd1498Szrj        *  Create a %vector consisting of copies of the elements from
531*38fd1498Szrj        *  [first,last).
532*38fd1498Szrj        *
533*38fd1498Szrj        *  If the iterators are forward, bidirectional, or
534*38fd1498Szrj        *  random-access, then this will call the elements' copy
535*38fd1498Szrj        *  constructor N times (where N is distance(first,last)) and do
536*38fd1498Szrj        *  no memory reallocation.  But if only input iterators are
537*38fd1498Szrj        *  used, then this will do at most 2N calls to the copy
538*38fd1498Szrj        *  constructor, and logN memory reallocations.
539*38fd1498Szrj        */
540*38fd1498Szrj #if __cplusplus >= 201103L
541*38fd1498Szrj       template<typename _InputIterator,
542*38fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
543*38fd1498Szrj 	vector(_InputIterator __first, _InputIterator __last,
544*38fd1498Szrj 	       const allocator_type& __a = allocator_type())
545*38fd1498Szrj 	: _Base(__a)
546*38fd1498Szrj 	{ _M_initialize_dispatch(__first, __last, __false_type()); }
547*38fd1498Szrj #else
548*38fd1498Szrj       template<typename _InputIterator>
549*38fd1498Szrj 	vector(_InputIterator __first, _InputIterator __last,
550*38fd1498Szrj 	       const allocator_type& __a = allocator_type())
551*38fd1498Szrj 	: _Base(__a)
552*38fd1498Szrj 	{
553*38fd1498Szrj 	  // Check whether it's an integral type.  If so, it's not an iterator.
554*38fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
555*38fd1498Szrj 	  _M_initialize_dispatch(__first, __last, _Integral());
556*38fd1498Szrj 	}
557*38fd1498Szrj #endif
558*38fd1498Szrj 
559*38fd1498Szrj       /**
560*38fd1498Szrj        *  The dtor only erases the elements, and note that if the
561*38fd1498Szrj        *  elements themselves are pointers, the pointed-to memory is
562*38fd1498Szrj        *  not touched in any way.  Managing the pointer is the user's
563*38fd1498Szrj        *  responsibility.
564*38fd1498Szrj        */
565*38fd1498Szrj       ~vector() _GLIBCXX_NOEXCEPT
566*38fd1498Szrj       {
567*38fd1498Szrj 	std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
568*38fd1498Szrj 		      _M_get_Tp_allocator());
569*38fd1498Szrj 	_GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC;
570*38fd1498Szrj       }
571*38fd1498Szrj 
572*38fd1498Szrj       /**
573*38fd1498Szrj        *  @brief  %Vector assignment operator.
574*38fd1498Szrj        *  @param  __x  A %vector of identical element and allocator types.
575*38fd1498Szrj        *
576*38fd1498Szrj        *  All the elements of @a __x are copied, but any unused capacity in
577*38fd1498Szrj        *  @a __x will not be copied.
578*38fd1498Szrj        *
579*38fd1498Szrj        *  Whether the allocator is copied depends on the allocator traits.
580*38fd1498Szrj        */
581*38fd1498Szrj       vector&
582*38fd1498Szrj       operator=(const vector& __x);
583*38fd1498Szrj 
584*38fd1498Szrj #if __cplusplus >= 201103L
585*38fd1498Szrj       /**
586*38fd1498Szrj        *  @brief  %Vector move assignment operator.
587*38fd1498Szrj        *  @param  __x  A %vector of identical element and allocator types.
588*38fd1498Szrj        *
589*38fd1498Szrj        *  The contents of @a __x are moved into this %vector (without copying,
590*38fd1498Szrj        *  if the allocators permit it).
591*38fd1498Szrj        *  Afterwards @a __x is a valid, but unspecified %vector.
592*38fd1498Szrj        *
593*38fd1498Szrj        *  Whether the allocator is moved depends on the allocator traits.
594*38fd1498Szrj        */
595*38fd1498Szrj       vector&
596*38fd1498Szrj       operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
597*38fd1498Szrj       {
598*38fd1498Szrj 	constexpr bool __move_storage =
599*38fd1498Szrj 	  _Alloc_traits::_S_propagate_on_move_assign()
600*38fd1498Szrj 	  || _Alloc_traits::_S_always_equal();
601*38fd1498Szrj 	_M_move_assign(std::move(__x), __bool_constant<__move_storage>());
602*38fd1498Szrj 	return *this;
603*38fd1498Szrj       }
604*38fd1498Szrj 
605*38fd1498Szrj       /**
606*38fd1498Szrj        *  @brief  %Vector list assignment operator.
607*38fd1498Szrj        *  @param  __l  An initializer_list.
608*38fd1498Szrj        *
609*38fd1498Szrj        *  This function fills a %vector with copies of the elements in the
610*38fd1498Szrj        *  initializer list @a __l.
611*38fd1498Szrj        *
612*38fd1498Szrj        *  Note that the assignment completely changes the %vector and
613*38fd1498Szrj        *  that the resulting %vector's size is the same as the number
614*38fd1498Szrj        *  of elements assigned.
615*38fd1498Szrj        */
616*38fd1498Szrj       vector&
617*38fd1498Szrj       operator=(initializer_list<value_type> __l)
618*38fd1498Szrj       {
619*38fd1498Szrj 	this->_M_assign_aux(__l.begin(), __l.end(),
620*38fd1498Szrj 			    random_access_iterator_tag());
621*38fd1498Szrj 	return *this;
622*38fd1498Szrj       }
623*38fd1498Szrj #endif
624*38fd1498Szrj 
625*38fd1498Szrj       /**
626*38fd1498Szrj        *  @brief  Assigns a given value to a %vector.
627*38fd1498Szrj        *  @param  __n  Number of elements to be assigned.
628*38fd1498Szrj        *  @param  __val  Value to be assigned.
629*38fd1498Szrj        *
630*38fd1498Szrj        *  This function fills a %vector with @a __n copies of the given
631*38fd1498Szrj        *  value.  Note that the assignment completely changes the
632*38fd1498Szrj        *  %vector and that the resulting %vector's size is the same as
633*38fd1498Szrj        *  the number of elements assigned.
634*38fd1498Szrj        */
635*38fd1498Szrj       void
636*38fd1498Szrj       assign(size_type __n, const value_type& __val)
637*38fd1498Szrj       { _M_fill_assign(__n, __val); }
638*38fd1498Szrj 
639*38fd1498Szrj       /**
640*38fd1498Szrj        *  @brief  Assigns a range to a %vector.
641*38fd1498Szrj        *  @param  __first  An input iterator.
642*38fd1498Szrj        *  @param  __last   An input iterator.
643*38fd1498Szrj        *
644*38fd1498Szrj        *  This function fills a %vector with copies of the elements in the
645*38fd1498Szrj        *  range [__first,__last).
646*38fd1498Szrj        *
647*38fd1498Szrj        *  Note that the assignment completely changes the %vector and
648*38fd1498Szrj        *  that the resulting %vector's size is the same as the number
649*38fd1498Szrj        *  of elements assigned.
650*38fd1498Szrj        */
651*38fd1498Szrj #if __cplusplus >= 201103L
652*38fd1498Szrj       template<typename _InputIterator,
653*38fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
654*38fd1498Szrj 	void
655*38fd1498Szrj 	assign(_InputIterator __first, _InputIterator __last)
656*38fd1498Szrj 	{ _M_assign_dispatch(__first, __last, __false_type()); }
657*38fd1498Szrj #else
658*38fd1498Szrj       template<typename _InputIterator>
659*38fd1498Szrj 	void
660*38fd1498Szrj 	assign(_InputIterator __first, _InputIterator __last)
661*38fd1498Szrj 	{
662*38fd1498Szrj 	  // Check whether it's an integral type.  If so, it's not an iterator.
663*38fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
664*38fd1498Szrj 	  _M_assign_dispatch(__first, __last, _Integral());
665*38fd1498Szrj 	}
666*38fd1498Szrj #endif
667*38fd1498Szrj 
668*38fd1498Szrj #if __cplusplus >= 201103L
669*38fd1498Szrj       /**
670*38fd1498Szrj        *  @brief  Assigns an initializer list to a %vector.
671*38fd1498Szrj        *  @param  __l  An initializer_list.
672*38fd1498Szrj        *
673*38fd1498Szrj        *  This function fills a %vector with copies of the elements in the
674*38fd1498Szrj        *  initializer list @a __l.
675*38fd1498Szrj        *
676*38fd1498Szrj        *  Note that the assignment completely changes the %vector and
677*38fd1498Szrj        *  that the resulting %vector's size is the same as the number
678*38fd1498Szrj        *  of elements assigned.
679*38fd1498Szrj        */
680*38fd1498Szrj       void
681*38fd1498Szrj       assign(initializer_list<value_type> __l)
682*38fd1498Szrj       {
683*38fd1498Szrj 	this->_M_assign_aux(__l.begin(), __l.end(),
684*38fd1498Szrj 			    random_access_iterator_tag());
685*38fd1498Szrj       }
686*38fd1498Szrj #endif
687*38fd1498Szrj 
688*38fd1498Szrj       /// Get a copy of the memory allocation object.
689*38fd1498Szrj       using _Base::get_allocator;
690*38fd1498Szrj 
691*38fd1498Szrj       // iterators
692*38fd1498Szrj       /**
693*38fd1498Szrj        *  Returns a read/write iterator that points to the first
694*38fd1498Szrj        *  element in the %vector.  Iteration is done in ordinary
695*38fd1498Szrj        *  element order.
696*38fd1498Szrj        */
697*38fd1498Szrj       iterator
698*38fd1498Szrj       begin() _GLIBCXX_NOEXCEPT
699*38fd1498Szrj       { return iterator(this->_M_impl._M_start); }
700*38fd1498Szrj 
701*38fd1498Szrj       /**
702*38fd1498Szrj        *  Returns a read-only (constant) iterator that points to the
703*38fd1498Szrj        *  first element in the %vector.  Iteration is done in ordinary
704*38fd1498Szrj        *  element order.
705*38fd1498Szrj        */
706*38fd1498Szrj       const_iterator
707*38fd1498Szrj       begin() const _GLIBCXX_NOEXCEPT
708*38fd1498Szrj       { return const_iterator(this->_M_impl._M_start); }
709*38fd1498Szrj 
710*38fd1498Szrj       /**
711*38fd1498Szrj        *  Returns a read/write iterator that points one past the last
712*38fd1498Szrj        *  element in the %vector.  Iteration is done in ordinary
713*38fd1498Szrj        *  element order.
714*38fd1498Szrj        */
715*38fd1498Szrj       iterator
716*38fd1498Szrj       end() _GLIBCXX_NOEXCEPT
717*38fd1498Szrj       { return iterator(this->_M_impl._M_finish); }
718*38fd1498Szrj 
719*38fd1498Szrj       /**
720*38fd1498Szrj        *  Returns a read-only (constant) iterator that points one past
721*38fd1498Szrj        *  the last element in the %vector.  Iteration is done in
722*38fd1498Szrj        *  ordinary element order.
723*38fd1498Szrj        */
724*38fd1498Szrj       const_iterator
725*38fd1498Szrj       end() const _GLIBCXX_NOEXCEPT
726*38fd1498Szrj       { return const_iterator(this->_M_impl._M_finish); }
727*38fd1498Szrj 
728*38fd1498Szrj       /**
729*38fd1498Szrj        *  Returns a read/write reverse iterator that points to the
730*38fd1498Szrj        *  last element in the %vector.  Iteration is done in reverse
731*38fd1498Szrj        *  element order.
732*38fd1498Szrj        */
733*38fd1498Szrj       reverse_iterator
734*38fd1498Szrj       rbegin() _GLIBCXX_NOEXCEPT
735*38fd1498Szrj       { return reverse_iterator(end()); }
736*38fd1498Szrj 
737*38fd1498Szrj       /**
738*38fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
739*38fd1498Szrj        *  to the last element in the %vector.  Iteration is done in
740*38fd1498Szrj        *  reverse element order.
741*38fd1498Szrj        */
742*38fd1498Szrj       const_reverse_iterator
743*38fd1498Szrj       rbegin() const _GLIBCXX_NOEXCEPT
744*38fd1498Szrj       { return const_reverse_iterator(end()); }
745*38fd1498Szrj 
746*38fd1498Szrj       /**
747*38fd1498Szrj        *  Returns a read/write reverse iterator that points to one
748*38fd1498Szrj        *  before the first element in the %vector.  Iteration is done
749*38fd1498Szrj        *  in reverse element order.
750*38fd1498Szrj        */
751*38fd1498Szrj       reverse_iterator
752*38fd1498Szrj       rend() _GLIBCXX_NOEXCEPT
753*38fd1498Szrj       { return reverse_iterator(begin()); }
754*38fd1498Szrj 
755*38fd1498Szrj       /**
756*38fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
757*38fd1498Szrj        *  to one before the first element in the %vector.  Iteration
758*38fd1498Szrj        *  is done in reverse element order.
759*38fd1498Szrj        */
760*38fd1498Szrj       const_reverse_iterator
761*38fd1498Szrj       rend() const _GLIBCXX_NOEXCEPT
762*38fd1498Szrj       { return const_reverse_iterator(begin()); }
763*38fd1498Szrj 
764*38fd1498Szrj #if __cplusplus >= 201103L
765*38fd1498Szrj       /**
766*38fd1498Szrj        *  Returns a read-only (constant) iterator that points to the
767*38fd1498Szrj        *  first element in the %vector.  Iteration is done in ordinary
768*38fd1498Szrj        *  element order.
769*38fd1498Szrj        */
770*38fd1498Szrj       const_iterator
771*38fd1498Szrj       cbegin() const noexcept
772*38fd1498Szrj       { return const_iterator(this->_M_impl._M_start); }
773*38fd1498Szrj 
774*38fd1498Szrj       /**
775*38fd1498Szrj        *  Returns a read-only (constant) iterator that points one past
776*38fd1498Szrj        *  the last element in the %vector.  Iteration is done in
777*38fd1498Szrj        *  ordinary element order.
778*38fd1498Szrj        */
779*38fd1498Szrj       const_iterator
780*38fd1498Szrj       cend() const noexcept
781*38fd1498Szrj       { return const_iterator(this->_M_impl._M_finish); }
782*38fd1498Szrj 
783*38fd1498Szrj       /**
784*38fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
785*38fd1498Szrj        *  to the last element in the %vector.  Iteration is done in
786*38fd1498Szrj        *  reverse element order.
787*38fd1498Szrj        */
788*38fd1498Szrj       const_reverse_iterator
789*38fd1498Szrj       crbegin() const noexcept
790*38fd1498Szrj       { return const_reverse_iterator(end()); }
791*38fd1498Szrj 
792*38fd1498Szrj       /**
793*38fd1498Szrj        *  Returns a read-only (constant) reverse iterator that points
794*38fd1498Szrj        *  to one before the first element in the %vector.  Iteration
795*38fd1498Szrj        *  is done in reverse element order.
796*38fd1498Szrj        */
797*38fd1498Szrj       const_reverse_iterator
798*38fd1498Szrj       crend() const noexcept
799*38fd1498Szrj       { return const_reverse_iterator(begin()); }
800*38fd1498Szrj #endif
801*38fd1498Szrj 
802*38fd1498Szrj       // [23.2.4.2] capacity
803*38fd1498Szrj       /**  Returns the number of elements in the %vector.  */
804*38fd1498Szrj       size_type
805*38fd1498Szrj       size() const _GLIBCXX_NOEXCEPT
806*38fd1498Szrj       { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
807*38fd1498Szrj 
808*38fd1498Szrj       /**  Returns the size() of the largest possible %vector.  */
809*38fd1498Szrj       size_type
810*38fd1498Szrj       max_size() const _GLIBCXX_NOEXCEPT
811*38fd1498Szrj       { return _Alloc_traits::max_size(_M_get_Tp_allocator()); }
812*38fd1498Szrj 
813*38fd1498Szrj #if __cplusplus >= 201103L
814*38fd1498Szrj       /**
815*38fd1498Szrj        *  @brief  Resizes the %vector to the specified number of elements.
816*38fd1498Szrj        *  @param  __new_size  Number of elements the %vector should contain.
817*38fd1498Szrj        *
818*38fd1498Szrj        *  This function will %resize the %vector to the specified
819*38fd1498Szrj        *  number of elements.  If the number is smaller than the
820*38fd1498Szrj        *  %vector's current size the %vector is truncated, otherwise
821*38fd1498Szrj        *  default constructed elements are appended.
822*38fd1498Szrj        */
823*38fd1498Szrj       void
824*38fd1498Szrj       resize(size_type __new_size)
825*38fd1498Szrj       {
826*38fd1498Szrj 	if (__new_size > size())
827*38fd1498Szrj 	  _M_default_append(__new_size - size());
828*38fd1498Szrj 	else if (__new_size < size())
829*38fd1498Szrj 	  _M_erase_at_end(this->_M_impl._M_start + __new_size);
830*38fd1498Szrj       }
831*38fd1498Szrj 
832*38fd1498Szrj       /**
833*38fd1498Szrj        *  @brief  Resizes the %vector to the specified number of elements.
834*38fd1498Szrj        *  @param  __new_size  Number of elements the %vector should contain.
835*38fd1498Szrj        *  @param  __x  Data with which new elements should be populated.
836*38fd1498Szrj        *
837*38fd1498Szrj        *  This function will %resize the %vector to the specified
838*38fd1498Szrj        *  number of elements.  If the number is smaller than the
839*38fd1498Szrj        *  %vector's current size the %vector is truncated, otherwise
840*38fd1498Szrj        *  the %vector is extended and new elements are populated with
841*38fd1498Szrj        *  given data.
842*38fd1498Szrj        */
843*38fd1498Szrj       void
844*38fd1498Szrj       resize(size_type __new_size, const value_type& __x)
845*38fd1498Szrj       {
846*38fd1498Szrj 	if (__new_size > size())
847*38fd1498Szrj 	  _M_fill_insert(end(), __new_size - size(), __x);
848*38fd1498Szrj 	else if (__new_size < size())
849*38fd1498Szrj 	  _M_erase_at_end(this->_M_impl._M_start + __new_size);
850*38fd1498Szrj       }
851*38fd1498Szrj #else
852*38fd1498Szrj       /**
853*38fd1498Szrj        *  @brief  Resizes the %vector to the specified number of elements.
854*38fd1498Szrj        *  @param  __new_size  Number of elements the %vector should contain.
855*38fd1498Szrj        *  @param  __x  Data with which new elements should be populated.
856*38fd1498Szrj        *
857*38fd1498Szrj        *  This function will %resize the %vector to the specified
858*38fd1498Szrj        *  number of elements.  If the number is smaller than the
859*38fd1498Szrj        *  %vector's current size the %vector is truncated, otherwise
860*38fd1498Szrj        *  the %vector is extended and new elements are populated with
861*38fd1498Szrj        *  given data.
862*38fd1498Szrj        */
863*38fd1498Szrj       void
864*38fd1498Szrj       resize(size_type __new_size, value_type __x = value_type())
865*38fd1498Szrj       {
866*38fd1498Szrj 	if (__new_size > size())
867*38fd1498Szrj 	  _M_fill_insert(end(), __new_size - size(), __x);
868*38fd1498Szrj 	else if (__new_size < size())
869*38fd1498Szrj 	  _M_erase_at_end(this->_M_impl._M_start + __new_size);
870*38fd1498Szrj       }
871*38fd1498Szrj #endif
872*38fd1498Szrj 
873*38fd1498Szrj #if __cplusplus >= 201103L
874*38fd1498Szrj       /**  A non-binding request to reduce capacity() to size().  */
875*38fd1498Szrj       void
876*38fd1498Szrj       shrink_to_fit()
877*38fd1498Szrj       { _M_shrink_to_fit(); }
878*38fd1498Szrj #endif
879*38fd1498Szrj 
880*38fd1498Szrj       /**
881*38fd1498Szrj        *  Returns the total number of elements that the %vector can
882*38fd1498Szrj        *  hold before needing to allocate more memory.
883*38fd1498Szrj        */
884*38fd1498Szrj       size_type
885*38fd1498Szrj       capacity() const _GLIBCXX_NOEXCEPT
886*38fd1498Szrj       { return size_type(this->_M_impl._M_end_of_storage
887*38fd1498Szrj 			 - this->_M_impl._M_start); }
888*38fd1498Szrj 
889*38fd1498Szrj       /**
890*38fd1498Szrj        *  Returns true if the %vector is empty.  (Thus begin() would
891*38fd1498Szrj        *  equal end().)
892*38fd1498Szrj        */
893*38fd1498Szrj       bool
894*38fd1498Szrj       empty() const _GLIBCXX_NOEXCEPT
895*38fd1498Szrj       { return begin() == end(); }
896*38fd1498Szrj 
897*38fd1498Szrj       /**
898*38fd1498Szrj        *  @brief  Attempt to preallocate enough memory for specified number of
899*38fd1498Szrj        *          elements.
900*38fd1498Szrj        *  @param  __n  Number of elements required.
901*38fd1498Szrj        *  @throw  std::length_error  If @a n exceeds @c max_size().
902*38fd1498Szrj        *
903*38fd1498Szrj        *  This function attempts to reserve enough memory for the
904*38fd1498Szrj        *  %vector to hold the specified number of elements.  If the
905*38fd1498Szrj        *  number requested is more than max_size(), length_error is
906*38fd1498Szrj        *  thrown.
907*38fd1498Szrj        *
908*38fd1498Szrj        *  The advantage of this function is that if optimal code is a
909*38fd1498Szrj        *  necessity and the user can determine the number of elements
910*38fd1498Szrj        *  that will be required, the user can reserve the memory in
911*38fd1498Szrj        *  %advance, and thus prevent a possible reallocation of memory
912*38fd1498Szrj        *  and copying of %vector data.
913*38fd1498Szrj        */
914*38fd1498Szrj       void
915*38fd1498Szrj       reserve(size_type __n);
916*38fd1498Szrj 
917*38fd1498Szrj       // element access
918*38fd1498Szrj       /**
919*38fd1498Szrj        *  @brief  Subscript access to the data contained in the %vector.
920*38fd1498Szrj        *  @param __n The index of the element for which data should be
921*38fd1498Szrj        *  accessed.
922*38fd1498Szrj        *  @return  Read/write reference to data.
923*38fd1498Szrj        *
924*38fd1498Szrj        *  This operator allows for easy, array-style, data access.
925*38fd1498Szrj        *  Note that data access with this operator is unchecked and
926*38fd1498Szrj        *  out_of_range lookups are not defined. (For checked lookups
927*38fd1498Szrj        *  see at().)
928*38fd1498Szrj        */
929*38fd1498Szrj       reference
930*38fd1498Szrj       operator[](size_type __n) _GLIBCXX_NOEXCEPT
931*38fd1498Szrj       {
932*38fd1498Szrj 	__glibcxx_requires_subscript(__n);
933*38fd1498Szrj 	return *(this->_M_impl._M_start + __n);
934*38fd1498Szrj       }
935*38fd1498Szrj 
936*38fd1498Szrj       /**
937*38fd1498Szrj        *  @brief  Subscript access to the data contained in the %vector.
938*38fd1498Szrj        *  @param __n The index of the element for which data should be
939*38fd1498Szrj        *  accessed.
940*38fd1498Szrj        *  @return  Read-only (constant) reference to data.
941*38fd1498Szrj        *
942*38fd1498Szrj        *  This operator allows for easy, array-style, data access.
943*38fd1498Szrj        *  Note that data access with this operator is unchecked and
944*38fd1498Szrj        *  out_of_range lookups are not defined. (For checked lookups
945*38fd1498Szrj        *  see at().)
946*38fd1498Szrj        */
947*38fd1498Szrj       const_reference
948*38fd1498Szrj       operator[](size_type __n) const _GLIBCXX_NOEXCEPT
949*38fd1498Szrj       {
950*38fd1498Szrj 	__glibcxx_requires_subscript(__n);
951*38fd1498Szrj 	return *(this->_M_impl._M_start + __n);
952*38fd1498Szrj       }
953*38fd1498Szrj 
954*38fd1498Szrj     protected:
955*38fd1498Szrj       /// Safety check used only from at().
956*38fd1498Szrj       void
957*38fd1498Szrj       _M_range_check(size_type __n) const
958*38fd1498Szrj       {
959*38fd1498Szrj 	if (__n >= this->size())
960*38fd1498Szrj 	  __throw_out_of_range_fmt(__N("vector::_M_range_check: __n "
961*38fd1498Szrj 				       "(which is %zu) >= this->size() "
962*38fd1498Szrj 				       "(which is %zu)"),
963*38fd1498Szrj 				   __n, this->size());
964*38fd1498Szrj       }
965*38fd1498Szrj 
966*38fd1498Szrj     public:
967*38fd1498Szrj       /**
968*38fd1498Szrj        *  @brief  Provides access to the data contained in the %vector.
969*38fd1498Szrj        *  @param __n The index of the element for which data should be
970*38fd1498Szrj        *  accessed.
971*38fd1498Szrj        *  @return  Read/write reference to data.
972*38fd1498Szrj        *  @throw  std::out_of_range  If @a __n is an invalid index.
973*38fd1498Szrj        *
974*38fd1498Szrj        *  This function provides for safer data access.  The parameter
975*38fd1498Szrj        *  is first checked that it is in the range of the vector.  The
976*38fd1498Szrj        *  function throws out_of_range if the check fails.
977*38fd1498Szrj        */
978*38fd1498Szrj       reference
979*38fd1498Szrj       at(size_type __n)
980*38fd1498Szrj       {
981*38fd1498Szrj 	_M_range_check(__n);
982*38fd1498Szrj 	return (*this)[__n];
983*38fd1498Szrj       }
984*38fd1498Szrj 
985*38fd1498Szrj       /**
986*38fd1498Szrj        *  @brief  Provides access to the data contained in the %vector.
987*38fd1498Szrj        *  @param __n The index of the element for which data should be
988*38fd1498Szrj        *  accessed.
989*38fd1498Szrj        *  @return  Read-only (constant) reference to data.
990*38fd1498Szrj        *  @throw  std::out_of_range  If @a __n is an invalid index.
991*38fd1498Szrj        *
992*38fd1498Szrj        *  This function provides for safer data access.  The parameter
993*38fd1498Szrj        *  is first checked that it is in the range of the vector.  The
994*38fd1498Szrj        *  function throws out_of_range if the check fails.
995*38fd1498Szrj        */
996*38fd1498Szrj       const_reference
997*38fd1498Szrj       at(size_type __n) const
998*38fd1498Szrj       {
999*38fd1498Szrj 	_M_range_check(__n);
1000*38fd1498Szrj 	return (*this)[__n];
1001*38fd1498Szrj       }
1002*38fd1498Szrj 
1003*38fd1498Szrj       /**
1004*38fd1498Szrj        *  Returns a read/write reference to the data at the first
1005*38fd1498Szrj        *  element of the %vector.
1006*38fd1498Szrj        */
1007*38fd1498Szrj       reference
1008*38fd1498Szrj       front() _GLIBCXX_NOEXCEPT
1009*38fd1498Szrj       {
1010*38fd1498Szrj 	__glibcxx_requires_nonempty();
1011*38fd1498Szrj 	return *begin();
1012*38fd1498Szrj       }
1013*38fd1498Szrj 
1014*38fd1498Szrj       /**
1015*38fd1498Szrj        *  Returns a read-only (constant) reference to the data at the first
1016*38fd1498Szrj        *  element of the %vector.
1017*38fd1498Szrj        */
1018*38fd1498Szrj       const_reference
1019*38fd1498Szrj       front() const _GLIBCXX_NOEXCEPT
1020*38fd1498Szrj       {
1021*38fd1498Szrj 	__glibcxx_requires_nonempty();
1022*38fd1498Szrj 	return *begin();
1023*38fd1498Szrj       }
1024*38fd1498Szrj 
1025*38fd1498Szrj       /**
1026*38fd1498Szrj        *  Returns a read/write reference to the data at the last
1027*38fd1498Szrj        *  element of the %vector.
1028*38fd1498Szrj        */
1029*38fd1498Szrj       reference
1030*38fd1498Szrj       back() _GLIBCXX_NOEXCEPT
1031*38fd1498Szrj       {
1032*38fd1498Szrj 	__glibcxx_requires_nonempty();
1033*38fd1498Szrj 	return *(end() - 1);
1034*38fd1498Szrj       }
1035*38fd1498Szrj 
1036*38fd1498Szrj       /**
1037*38fd1498Szrj        *  Returns a read-only (constant) reference to the data at the
1038*38fd1498Szrj        *  last element of the %vector.
1039*38fd1498Szrj        */
1040*38fd1498Szrj       const_reference
1041*38fd1498Szrj       back() const _GLIBCXX_NOEXCEPT
1042*38fd1498Szrj       {
1043*38fd1498Szrj 	__glibcxx_requires_nonempty();
1044*38fd1498Szrj 	return *(end() - 1);
1045*38fd1498Szrj       }
1046*38fd1498Szrj 
1047*38fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1048*38fd1498Szrj       // DR 464. Suggestion for new member functions in standard containers.
1049*38fd1498Szrj       // data access
1050*38fd1498Szrj       /**
1051*38fd1498Szrj        *   Returns a pointer such that [data(), data() + size()) is a valid
1052*38fd1498Szrj        *   range.  For a non-empty %vector, data() == &front().
1053*38fd1498Szrj        */
1054*38fd1498Szrj       _Tp*
1055*38fd1498Szrj       data() _GLIBCXX_NOEXCEPT
1056*38fd1498Szrj       { return _M_data_ptr(this->_M_impl._M_start); }
1057*38fd1498Szrj 
1058*38fd1498Szrj       const _Tp*
1059*38fd1498Szrj       data() const _GLIBCXX_NOEXCEPT
1060*38fd1498Szrj       { return _M_data_ptr(this->_M_impl._M_start); }
1061*38fd1498Szrj 
1062*38fd1498Szrj       // [23.2.4.3] modifiers
1063*38fd1498Szrj       /**
1064*38fd1498Szrj        *  @brief  Add data to the end of the %vector.
1065*38fd1498Szrj        *  @param  __x  Data to be added.
1066*38fd1498Szrj        *
1067*38fd1498Szrj        *  This is a typical stack operation.  The function creates an
1068*38fd1498Szrj        *  element at the end of the %vector and assigns the given data
1069*38fd1498Szrj        *  to it.  Due to the nature of a %vector this operation can be
1070*38fd1498Szrj        *  done in constant time if the %vector has preallocated space
1071*38fd1498Szrj        *  available.
1072*38fd1498Szrj        */
1073*38fd1498Szrj       void
1074*38fd1498Szrj       push_back(const value_type& __x)
1075*38fd1498Szrj       {
1076*38fd1498Szrj 	if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
1077*38fd1498Szrj 	  {
1078*38fd1498Szrj 	    _GLIBCXX_ASAN_ANNOTATE_GROW(1);
1079*38fd1498Szrj 	    _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
1080*38fd1498Szrj 				     __x);
1081*38fd1498Szrj 	    ++this->_M_impl._M_finish;
1082*38fd1498Szrj 	    _GLIBCXX_ASAN_ANNOTATE_GREW(1);
1083*38fd1498Szrj 	  }
1084*38fd1498Szrj 	else
1085*38fd1498Szrj 	  _M_realloc_insert(end(), __x);
1086*38fd1498Szrj       }
1087*38fd1498Szrj 
1088*38fd1498Szrj #if __cplusplus >= 201103L
1089*38fd1498Szrj       void
1090*38fd1498Szrj       push_back(value_type&& __x)
1091*38fd1498Szrj       { emplace_back(std::move(__x)); }
1092*38fd1498Szrj 
1093*38fd1498Szrj       template<typename... _Args>
1094*38fd1498Szrj #if __cplusplus > 201402L
1095*38fd1498Szrj 	reference
1096*38fd1498Szrj #else
1097*38fd1498Szrj 	void
1098*38fd1498Szrj #endif
1099*38fd1498Szrj 	emplace_back(_Args&&... __args);
1100*38fd1498Szrj #endif
1101*38fd1498Szrj 
1102*38fd1498Szrj       /**
1103*38fd1498Szrj        *  @brief  Removes last element.
1104*38fd1498Szrj        *
1105*38fd1498Szrj        *  This is a typical stack operation. It shrinks the %vector by one.
1106*38fd1498Szrj        *
1107*38fd1498Szrj        *  Note that no data is returned, and if the last element's
1108*38fd1498Szrj        *  data is needed, it should be retrieved before pop_back() is
1109*38fd1498Szrj        *  called.
1110*38fd1498Szrj        */
1111*38fd1498Szrj       void
1112*38fd1498Szrj       pop_back() _GLIBCXX_NOEXCEPT
1113*38fd1498Szrj       {
1114*38fd1498Szrj 	__glibcxx_requires_nonempty();
1115*38fd1498Szrj 	--this->_M_impl._M_finish;
1116*38fd1498Szrj 	_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
1117*38fd1498Szrj 	_GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
1118*38fd1498Szrj       }
1119*38fd1498Szrj 
1120*38fd1498Szrj #if __cplusplus >= 201103L
1121*38fd1498Szrj       /**
1122*38fd1498Szrj        *  @brief  Inserts an object in %vector before specified iterator.
1123*38fd1498Szrj        *  @param  __position  A const_iterator into the %vector.
1124*38fd1498Szrj        *  @param  __args  Arguments.
1125*38fd1498Szrj        *  @return  An iterator that points to the inserted data.
1126*38fd1498Szrj        *
1127*38fd1498Szrj        *  This function will insert an object of type T constructed
1128*38fd1498Szrj        *  with T(std::forward<Args>(args)...) before the specified location.
1129*38fd1498Szrj        *  Note that this kind of operation could be expensive for a %vector
1130*38fd1498Szrj        *  and if it is frequently used the user should consider using
1131*38fd1498Szrj        *  std::list.
1132*38fd1498Szrj        */
1133*38fd1498Szrj       template<typename... _Args>
1134*38fd1498Szrj 	iterator
1135*38fd1498Szrj 	emplace(const_iterator __position, _Args&&... __args)
1136*38fd1498Szrj 	{ return _M_emplace_aux(__position, std::forward<_Args>(__args)...); }
1137*38fd1498Szrj 
1138*38fd1498Szrj       /**
1139*38fd1498Szrj        *  @brief  Inserts given value into %vector before specified iterator.
1140*38fd1498Szrj        *  @param  __position  A const_iterator into the %vector.
1141*38fd1498Szrj        *  @param  __x  Data to be inserted.
1142*38fd1498Szrj        *  @return  An iterator that points to the inserted data.
1143*38fd1498Szrj        *
1144*38fd1498Szrj        *  This function will insert a copy of the given value before
1145*38fd1498Szrj        *  the specified location.  Note that this kind of operation
1146*38fd1498Szrj        *  could be expensive for a %vector and if it is frequently
1147*38fd1498Szrj        *  used the user should consider using std::list.
1148*38fd1498Szrj        */
1149*38fd1498Szrj       iterator
1150*38fd1498Szrj       insert(const_iterator __position, const value_type& __x);
1151*38fd1498Szrj #else
1152*38fd1498Szrj       /**
1153*38fd1498Szrj        *  @brief  Inserts given value into %vector before specified iterator.
1154*38fd1498Szrj        *  @param  __position  An iterator into the %vector.
1155*38fd1498Szrj        *  @param  __x  Data to be inserted.
1156*38fd1498Szrj        *  @return  An iterator that points to the inserted data.
1157*38fd1498Szrj        *
1158*38fd1498Szrj        *  This function will insert a copy of the given value before
1159*38fd1498Szrj        *  the specified location.  Note that this kind of operation
1160*38fd1498Szrj        *  could be expensive for a %vector and if it is frequently
1161*38fd1498Szrj        *  used the user should consider using std::list.
1162*38fd1498Szrj        */
1163*38fd1498Szrj       iterator
1164*38fd1498Szrj       insert(iterator __position, const value_type& __x);
1165*38fd1498Szrj #endif
1166*38fd1498Szrj 
1167*38fd1498Szrj #if __cplusplus >= 201103L
1168*38fd1498Szrj       /**
1169*38fd1498Szrj        *  @brief  Inserts given rvalue into %vector before specified iterator.
1170*38fd1498Szrj        *  @param  __position  A const_iterator into the %vector.
1171*38fd1498Szrj        *  @param  __x  Data to be inserted.
1172*38fd1498Szrj        *  @return  An iterator that points to the inserted data.
1173*38fd1498Szrj        *
1174*38fd1498Szrj        *  This function will insert a copy of the given rvalue before
1175*38fd1498Szrj        *  the specified location.  Note that this kind of operation
1176*38fd1498Szrj        *  could be expensive for a %vector and if it is frequently
1177*38fd1498Szrj        *  used the user should consider using std::list.
1178*38fd1498Szrj        */
1179*38fd1498Szrj       iterator
1180*38fd1498Szrj       insert(const_iterator __position, value_type&& __x)
1181*38fd1498Szrj       { return _M_insert_rval(__position, std::move(__x)); }
1182*38fd1498Szrj 
1183*38fd1498Szrj       /**
1184*38fd1498Szrj        *  @brief  Inserts an initializer_list into the %vector.
1185*38fd1498Szrj        *  @param  __position  An iterator into the %vector.
1186*38fd1498Szrj        *  @param  __l  An initializer_list.
1187*38fd1498Szrj        *
1188*38fd1498Szrj        *  This function will insert copies of the data in the
1189*38fd1498Szrj        *  initializer_list @a l into the %vector before the location
1190*38fd1498Szrj        *  specified by @a position.
1191*38fd1498Szrj        *
1192*38fd1498Szrj        *  Note that this kind of operation could be expensive for a
1193*38fd1498Szrj        *  %vector and if it is frequently used the user should
1194*38fd1498Szrj        *  consider using std::list.
1195*38fd1498Szrj        */
1196*38fd1498Szrj       iterator
1197*38fd1498Szrj       insert(const_iterator __position, initializer_list<value_type> __l)
1198*38fd1498Szrj       {
1199*38fd1498Szrj 	auto __offset = __position - cbegin();
1200*38fd1498Szrj 	_M_range_insert(begin() + __offset, __l.begin(), __l.end(),
1201*38fd1498Szrj 			std::random_access_iterator_tag());
1202*38fd1498Szrj 	return begin() + __offset;
1203*38fd1498Szrj       }
1204*38fd1498Szrj #endif
1205*38fd1498Szrj 
1206*38fd1498Szrj #if __cplusplus >= 201103L
1207*38fd1498Szrj       /**
1208*38fd1498Szrj        *  @brief  Inserts a number of copies of given data into the %vector.
1209*38fd1498Szrj        *  @param  __position  A const_iterator into the %vector.
1210*38fd1498Szrj        *  @param  __n  Number of elements to be inserted.
1211*38fd1498Szrj        *  @param  __x  Data to be inserted.
1212*38fd1498Szrj        *  @return  An iterator that points to the inserted data.
1213*38fd1498Szrj        *
1214*38fd1498Szrj        *  This function will insert a specified number of copies of
1215*38fd1498Szrj        *  the given data before the location specified by @a position.
1216*38fd1498Szrj        *
1217*38fd1498Szrj        *  Note that this kind of operation could be expensive for a
1218*38fd1498Szrj        *  %vector and if it is frequently used the user should
1219*38fd1498Szrj        *  consider using std::list.
1220*38fd1498Szrj        */
1221*38fd1498Szrj       iterator
1222*38fd1498Szrj       insert(const_iterator __position, size_type __n, const value_type& __x)
1223*38fd1498Szrj       {
1224*38fd1498Szrj 	difference_type __offset = __position - cbegin();
1225*38fd1498Szrj 	_M_fill_insert(begin() + __offset, __n, __x);
1226*38fd1498Szrj 	return begin() + __offset;
1227*38fd1498Szrj       }
1228*38fd1498Szrj #else
1229*38fd1498Szrj       /**
1230*38fd1498Szrj        *  @brief  Inserts a number of copies of given data into the %vector.
1231*38fd1498Szrj        *  @param  __position  An iterator into the %vector.
1232*38fd1498Szrj        *  @param  __n  Number of elements to be inserted.
1233*38fd1498Szrj        *  @param  __x  Data to be inserted.
1234*38fd1498Szrj        *
1235*38fd1498Szrj        *  This function will insert a specified number of copies of
1236*38fd1498Szrj        *  the given data before the location specified by @a position.
1237*38fd1498Szrj        *
1238*38fd1498Szrj        *  Note that this kind of operation could be expensive for a
1239*38fd1498Szrj        *  %vector and if it is frequently used the user should
1240*38fd1498Szrj        *  consider using std::list.
1241*38fd1498Szrj        */
1242*38fd1498Szrj       void
1243*38fd1498Szrj       insert(iterator __position, size_type __n, const value_type& __x)
1244*38fd1498Szrj       { _M_fill_insert(__position, __n, __x); }
1245*38fd1498Szrj #endif
1246*38fd1498Szrj 
1247*38fd1498Szrj #if __cplusplus >= 201103L
1248*38fd1498Szrj       /**
1249*38fd1498Szrj        *  @brief  Inserts a range into the %vector.
1250*38fd1498Szrj        *  @param  __position  A const_iterator into the %vector.
1251*38fd1498Szrj        *  @param  __first  An input iterator.
1252*38fd1498Szrj        *  @param  __last   An input iterator.
1253*38fd1498Szrj        *  @return  An iterator that points to the inserted data.
1254*38fd1498Szrj        *
1255*38fd1498Szrj        *  This function will insert copies of the data in the range
1256*38fd1498Szrj        *  [__first,__last) into the %vector before the location specified
1257*38fd1498Szrj        *  by @a pos.
1258*38fd1498Szrj        *
1259*38fd1498Szrj        *  Note that this kind of operation could be expensive for a
1260*38fd1498Szrj        *  %vector and if it is frequently used the user should
1261*38fd1498Szrj        *  consider using std::list.
1262*38fd1498Szrj        */
1263*38fd1498Szrj       template<typename _InputIterator,
1264*38fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
1265*38fd1498Szrj 	iterator
1266*38fd1498Szrj 	insert(const_iterator __position, _InputIterator __first,
1267*38fd1498Szrj 	       _InputIterator __last)
1268*38fd1498Szrj 	{
1269*38fd1498Szrj 	  difference_type __offset = __position - cbegin();
1270*38fd1498Szrj 	  _M_insert_dispatch(begin() + __offset,
1271*38fd1498Szrj 			     __first, __last, __false_type());
1272*38fd1498Szrj 	  return begin() + __offset;
1273*38fd1498Szrj 	}
1274*38fd1498Szrj #else
1275*38fd1498Szrj       /**
1276*38fd1498Szrj        *  @brief  Inserts a range into the %vector.
1277*38fd1498Szrj        *  @param  __position  An iterator into the %vector.
1278*38fd1498Szrj        *  @param  __first  An input iterator.
1279*38fd1498Szrj        *  @param  __last   An input iterator.
1280*38fd1498Szrj        *
1281*38fd1498Szrj        *  This function will insert copies of the data in the range
1282*38fd1498Szrj        *  [__first,__last) into the %vector before the location specified
1283*38fd1498Szrj        *  by @a pos.
1284*38fd1498Szrj        *
1285*38fd1498Szrj        *  Note that this kind of operation could be expensive for a
1286*38fd1498Szrj        *  %vector and if it is frequently used the user should
1287*38fd1498Szrj        *  consider using std::list.
1288*38fd1498Szrj        */
1289*38fd1498Szrj       template<typename _InputIterator>
1290*38fd1498Szrj 	void
1291*38fd1498Szrj 	insert(iterator __position, _InputIterator __first,
1292*38fd1498Szrj 	       _InputIterator __last)
1293*38fd1498Szrj 	{
1294*38fd1498Szrj 	  // Check whether it's an integral type.  If so, it's not an iterator.
1295*38fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
1296*38fd1498Szrj 	  _M_insert_dispatch(__position, __first, __last, _Integral());
1297*38fd1498Szrj 	}
1298*38fd1498Szrj #endif
1299*38fd1498Szrj 
1300*38fd1498Szrj       /**
1301*38fd1498Szrj        *  @brief  Remove element at given position.
1302*38fd1498Szrj        *  @param  __position  Iterator pointing to element to be erased.
1303*38fd1498Szrj        *  @return  An iterator pointing to the next element (or end()).
1304*38fd1498Szrj        *
1305*38fd1498Szrj        *  This function will erase the element at the given position and thus
1306*38fd1498Szrj        *  shorten the %vector by one.
1307*38fd1498Szrj        *
1308*38fd1498Szrj        *  Note This operation could be expensive and if it is
1309*38fd1498Szrj        *  frequently used the user should consider using std::list.
1310*38fd1498Szrj        *  The user is also cautioned that this function only erases
1311*38fd1498Szrj        *  the element, and that if the element is itself a pointer,
1312*38fd1498Szrj        *  the pointed-to memory is not touched in any way.  Managing
1313*38fd1498Szrj        *  the pointer is the user's responsibility.
1314*38fd1498Szrj        */
1315*38fd1498Szrj       iterator
1316*38fd1498Szrj #if __cplusplus >= 201103L
1317*38fd1498Szrj       erase(const_iterator __position)
1318*38fd1498Szrj       { return _M_erase(begin() + (__position - cbegin())); }
1319*38fd1498Szrj #else
1320*38fd1498Szrj       erase(iterator __position)
1321*38fd1498Szrj       { return _M_erase(__position); }
1322*38fd1498Szrj #endif
1323*38fd1498Szrj 
1324*38fd1498Szrj       /**
1325*38fd1498Szrj        *  @brief  Remove a range of elements.
1326*38fd1498Szrj        *  @param  __first  Iterator pointing to the first element to be erased.
1327*38fd1498Szrj        *  @param  __last  Iterator pointing to one past the last element to be
1328*38fd1498Szrj        *                  erased.
1329*38fd1498Szrj        *  @return  An iterator pointing to the element pointed to by @a __last
1330*38fd1498Szrj        *           prior to erasing (or end()).
1331*38fd1498Szrj        *
1332*38fd1498Szrj        *  This function will erase the elements in the range
1333*38fd1498Szrj        *  [__first,__last) and shorten the %vector accordingly.
1334*38fd1498Szrj        *
1335*38fd1498Szrj        *  Note This operation could be expensive and if it is
1336*38fd1498Szrj        *  frequently used the user should consider using std::list.
1337*38fd1498Szrj        *  The user is also cautioned that this function only erases
1338*38fd1498Szrj        *  the elements, and that if the elements themselves are
1339*38fd1498Szrj        *  pointers, the pointed-to memory is not touched in any way.
1340*38fd1498Szrj        *  Managing the pointer is the user's responsibility.
1341*38fd1498Szrj        */
1342*38fd1498Szrj       iterator
1343*38fd1498Szrj #if __cplusplus >= 201103L
1344*38fd1498Szrj       erase(const_iterator __first, const_iterator __last)
1345*38fd1498Szrj       {
1346*38fd1498Szrj 	const auto __beg = begin();
1347*38fd1498Szrj 	const auto __cbeg = cbegin();
1348*38fd1498Szrj 	return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg));
1349*38fd1498Szrj       }
1350*38fd1498Szrj #else
1351*38fd1498Szrj       erase(iterator __first, iterator __last)
1352*38fd1498Szrj       { return _M_erase(__first, __last); }
1353*38fd1498Szrj #endif
1354*38fd1498Szrj 
1355*38fd1498Szrj       /**
1356*38fd1498Szrj        *  @brief  Swaps data with another %vector.
1357*38fd1498Szrj        *  @param  __x  A %vector of the same element and allocator types.
1358*38fd1498Szrj        *
1359*38fd1498Szrj        *  This exchanges the elements between two vectors in constant time.
1360*38fd1498Szrj        *  (Three pointers, so it should be quite fast.)
1361*38fd1498Szrj        *  Note that the global std::swap() function is specialized such that
1362*38fd1498Szrj        *  std::swap(v1,v2) will feed to this function.
1363*38fd1498Szrj        *
1364*38fd1498Szrj        *  Whether the allocators are swapped depends on the allocator traits.
1365*38fd1498Szrj        */
1366*38fd1498Szrj       void
1367*38fd1498Szrj       swap(vector& __x) _GLIBCXX_NOEXCEPT
1368*38fd1498Szrj       {
1369*38fd1498Szrj #if __cplusplus >= 201103L
1370*38fd1498Szrj 	__glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value
1371*38fd1498Szrj 			 || _M_get_Tp_allocator() == __x._M_get_Tp_allocator());
1372*38fd1498Szrj #endif
1373*38fd1498Szrj 	this->_M_impl._M_swap_data(__x._M_impl);
1374*38fd1498Szrj 	_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
1375*38fd1498Szrj 				  __x._M_get_Tp_allocator());
1376*38fd1498Szrj       }
1377*38fd1498Szrj 
1378*38fd1498Szrj       /**
1379*38fd1498Szrj        *  Erases all the elements.  Note that this function only erases the
1380*38fd1498Szrj        *  elements, and that if the elements themselves are pointers, the
1381*38fd1498Szrj        *  pointed-to memory is not touched in any way.  Managing the pointer is
1382*38fd1498Szrj        *  the user's responsibility.
1383*38fd1498Szrj        */
1384*38fd1498Szrj       void
1385*38fd1498Szrj       clear() _GLIBCXX_NOEXCEPT
1386*38fd1498Szrj       { _M_erase_at_end(this->_M_impl._M_start); }
1387*38fd1498Szrj 
1388*38fd1498Szrj     protected:
1389*38fd1498Szrj       /**
1390*38fd1498Szrj        *  Memory expansion handler.  Uses the member allocation function to
1391*38fd1498Szrj        *  obtain @a n bytes of memory, and then copies [first,last) into it.
1392*38fd1498Szrj        */
1393*38fd1498Szrj       template<typename _ForwardIterator>
1394*38fd1498Szrj 	pointer
1395*38fd1498Szrj 	_M_allocate_and_copy(size_type __n,
1396*38fd1498Szrj 			     _ForwardIterator __first, _ForwardIterator __last)
1397*38fd1498Szrj 	{
1398*38fd1498Szrj 	  pointer __result = this->_M_allocate(__n);
1399*38fd1498Szrj 	  __try
1400*38fd1498Szrj 	    {
1401*38fd1498Szrj 	      std::__uninitialized_copy_a(__first, __last, __result,
1402*38fd1498Szrj 					  _M_get_Tp_allocator());
1403*38fd1498Szrj 	      return __result;
1404*38fd1498Szrj 	    }
1405*38fd1498Szrj 	  __catch(...)
1406*38fd1498Szrj 	    {
1407*38fd1498Szrj 	      _M_deallocate(__result, __n);
1408*38fd1498Szrj 	      __throw_exception_again;
1409*38fd1498Szrj 	    }
1410*38fd1498Szrj 	}
1411*38fd1498Szrj 
1412*38fd1498Szrj 
1413*38fd1498Szrj       // Internal constructor functions follow.
1414*38fd1498Szrj 
1415*38fd1498Szrj       // Called by the range constructor to implement [23.1.1]/9
1416*38fd1498Szrj 
1417*38fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1418*38fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
1419*38fd1498Szrj       template<typename _Integer>
1420*38fd1498Szrj 	void
1421*38fd1498Szrj 	_M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
1422*38fd1498Szrj 	{
1423*38fd1498Szrj 	  this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n));
1424*38fd1498Szrj 	  this->_M_impl._M_end_of_storage =
1425*38fd1498Szrj 	    this->_M_impl._M_start + static_cast<size_type>(__n);
1426*38fd1498Szrj 	  _M_fill_initialize(static_cast<size_type>(__n), __value);
1427*38fd1498Szrj 	}
1428*38fd1498Szrj 
1429*38fd1498Szrj       // Called by the range constructor to implement [23.1.1]/9
1430*38fd1498Szrj       template<typename _InputIterator>
1431*38fd1498Szrj 	void
1432*38fd1498Szrj 	_M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
1433*38fd1498Szrj 			       __false_type)
1434*38fd1498Szrj 	{
1435*38fd1498Szrj 	  typedef typename std::iterator_traits<_InputIterator>::
1436*38fd1498Szrj 	    iterator_category _IterCategory;
1437*38fd1498Szrj 	  _M_range_initialize(__first, __last, _IterCategory());
1438*38fd1498Szrj 	}
1439*38fd1498Szrj 
1440*38fd1498Szrj       // Called by the second initialize_dispatch above
1441*38fd1498Szrj       template<typename _InputIterator>
1442*38fd1498Szrj 	void
1443*38fd1498Szrj 	_M_range_initialize(_InputIterator __first,
1444*38fd1498Szrj 			    _InputIterator __last, std::input_iterator_tag)
1445*38fd1498Szrj 	{
1446*38fd1498Szrj 	  for (; __first != __last; ++__first)
1447*38fd1498Szrj #if __cplusplus >= 201103L
1448*38fd1498Szrj 	    emplace_back(*__first);
1449*38fd1498Szrj #else
1450*38fd1498Szrj 	    push_back(*__first);
1451*38fd1498Szrj #endif
1452*38fd1498Szrj 	}
1453*38fd1498Szrj 
1454*38fd1498Szrj       // Called by the second initialize_dispatch above
1455*38fd1498Szrj       template<typename _ForwardIterator>
1456*38fd1498Szrj 	void
1457*38fd1498Szrj 	_M_range_initialize(_ForwardIterator __first,
1458*38fd1498Szrj 			    _ForwardIterator __last, std::forward_iterator_tag)
1459*38fd1498Szrj 	{
1460*38fd1498Szrj 	  const size_type __n = std::distance(__first, __last);
1461*38fd1498Szrj 	  this->_M_impl._M_start = this->_M_allocate(__n);
1462*38fd1498Szrj 	  this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
1463*38fd1498Szrj 	  this->_M_impl._M_finish =
1464*38fd1498Szrj 	    std::__uninitialized_copy_a(__first, __last,
1465*38fd1498Szrj 					this->_M_impl._M_start,
1466*38fd1498Szrj 					_M_get_Tp_allocator());
1467*38fd1498Szrj 	}
1468*38fd1498Szrj 
1469*38fd1498Szrj       // Called by the first initialize_dispatch above and by the
1470*38fd1498Szrj       // vector(n,value,a) constructor.
1471*38fd1498Szrj       void
1472*38fd1498Szrj       _M_fill_initialize(size_type __n, const value_type& __value)
1473*38fd1498Szrj       {
1474*38fd1498Szrj 	this->_M_impl._M_finish =
1475*38fd1498Szrj 	  std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
1476*38fd1498Szrj 					_M_get_Tp_allocator());
1477*38fd1498Szrj       }
1478*38fd1498Szrj 
1479*38fd1498Szrj #if __cplusplus >= 201103L
1480*38fd1498Szrj       // Called by the vector(n) constructor.
1481*38fd1498Szrj       void
1482*38fd1498Szrj       _M_default_initialize(size_type __n)
1483*38fd1498Szrj       {
1484*38fd1498Szrj 	this->_M_impl._M_finish =
1485*38fd1498Szrj 	  std::__uninitialized_default_n_a(this->_M_impl._M_start, __n,
1486*38fd1498Szrj 					   _M_get_Tp_allocator());
1487*38fd1498Szrj       }
1488*38fd1498Szrj #endif
1489*38fd1498Szrj 
1490*38fd1498Szrj       // Internal assign functions follow.  The *_aux functions do the actual
1491*38fd1498Szrj       // assignment work for the range versions.
1492*38fd1498Szrj 
1493*38fd1498Szrj       // Called by the range assign to implement [23.1.1]/9
1494*38fd1498Szrj 
1495*38fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1496*38fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
1497*38fd1498Szrj       template<typename _Integer>
1498*38fd1498Szrj 	void
1499*38fd1498Szrj 	_M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
1500*38fd1498Szrj 	{ _M_fill_assign(__n, __val); }
1501*38fd1498Szrj 
1502*38fd1498Szrj       // Called by the range assign to implement [23.1.1]/9
1503*38fd1498Szrj       template<typename _InputIterator>
1504*38fd1498Szrj 	void
1505*38fd1498Szrj 	_M_assign_dispatch(_InputIterator __first, _InputIterator __last,
1506*38fd1498Szrj 			   __false_type)
1507*38fd1498Szrj 	{ _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
1508*38fd1498Szrj 
1509*38fd1498Szrj       // Called by the second assign_dispatch above
1510*38fd1498Szrj       template<typename _InputIterator>
1511*38fd1498Szrj 	void
1512*38fd1498Szrj 	_M_assign_aux(_InputIterator __first, _InputIterator __last,
1513*38fd1498Szrj 		      std::input_iterator_tag);
1514*38fd1498Szrj 
1515*38fd1498Szrj       // Called by the second assign_dispatch above
1516*38fd1498Szrj       template<typename _ForwardIterator>
1517*38fd1498Szrj 	void
1518*38fd1498Szrj 	_M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
1519*38fd1498Szrj 		      std::forward_iterator_tag);
1520*38fd1498Szrj 
1521*38fd1498Szrj       // Called by assign(n,t), and the range assign when it turns out
1522*38fd1498Szrj       // to be the same thing.
1523*38fd1498Szrj       void
1524*38fd1498Szrj       _M_fill_assign(size_type __n, const value_type& __val);
1525*38fd1498Szrj 
1526*38fd1498Szrj       // Internal insert functions follow.
1527*38fd1498Szrj 
1528*38fd1498Szrj       // Called by the range insert to implement [23.1.1]/9
1529*38fd1498Szrj 
1530*38fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1531*38fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
1532*38fd1498Szrj       template<typename _Integer>
1533*38fd1498Szrj 	void
1534*38fd1498Szrj 	_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
1535*38fd1498Szrj 			   __true_type)
1536*38fd1498Szrj 	{ _M_fill_insert(__pos, __n, __val); }
1537*38fd1498Szrj 
1538*38fd1498Szrj       // Called by the range insert to implement [23.1.1]/9
1539*38fd1498Szrj       template<typename _InputIterator>
1540*38fd1498Szrj 	void
1541*38fd1498Szrj 	_M_insert_dispatch(iterator __pos, _InputIterator __first,
1542*38fd1498Szrj 			   _InputIterator __last, __false_type)
1543*38fd1498Szrj 	{
1544*38fd1498Szrj 	  _M_range_insert(__pos, __first, __last,
1545*38fd1498Szrj 			  std::__iterator_category(__first));
1546*38fd1498Szrj 	}
1547*38fd1498Szrj 
1548*38fd1498Szrj       // Called by the second insert_dispatch above
1549*38fd1498Szrj       template<typename _InputIterator>
1550*38fd1498Szrj 	void
1551*38fd1498Szrj 	_M_range_insert(iterator __pos, _InputIterator __first,
1552*38fd1498Szrj 			_InputIterator __last, std::input_iterator_tag);
1553*38fd1498Szrj 
1554*38fd1498Szrj       // Called by the second insert_dispatch above
1555*38fd1498Szrj       template<typename _ForwardIterator>
1556*38fd1498Szrj 	void
1557*38fd1498Szrj 	_M_range_insert(iterator __pos, _ForwardIterator __first,
1558*38fd1498Szrj 			_ForwardIterator __last, std::forward_iterator_tag);
1559*38fd1498Szrj 
1560*38fd1498Szrj       // Called by insert(p,n,x), and the range insert when it turns out to be
1561*38fd1498Szrj       // the same thing.
1562*38fd1498Szrj       void
1563*38fd1498Szrj       _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
1564*38fd1498Szrj 
1565*38fd1498Szrj #if __cplusplus >= 201103L
1566*38fd1498Szrj       // Called by resize(n).
1567*38fd1498Szrj       void
1568*38fd1498Szrj       _M_default_append(size_type __n);
1569*38fd1498Szrj 
1570*38fd1498Szrj       bool
1571*38fd1498Szrj       _M_shrink_to_fit();
1572*38fd1498Szrj #endif
1573*38fd1498Szrj 
1574*38fd1498Szrj #if __cplusplus < 201103L
1575*38fd1498Szrj       // Called by insert(p,x)
1576*38fd1498Szrj       void
1577*38fd1498Szrj       _M_insert_aux(iterator __position, const value_type& __x);
1578*38fd1498Szrj 
1579*38fd1498Szrj       void
1580*38fd1498Szrj       _M_realloc_insert(iterator __position, const value_type& __x);
1581*38fd1498Szrj #else
1582*38fd1498Szrj       // A value_type object constructed with _Alloc_traits::construct()
1583*38fd1498Szrj       // and destroyed with _Alloc_traits::destroy().
1584*38fd1498Szrj       struct _Temporary_value
1585*38fd1498Szrj       {
1586*38fd1498Szrj 	template<typename... _Args>
1587*38fd1498Szrj 	  explicit
1588*38fd1498Szrj 	  _Temporary_value(vector* __vec, _Args&&... __args) : _M_this(__vec)
1589*38fd1498Szrj 	  {
1590*38fd1498Szrj 	    _Alloc_traits::construct(_M_this->_M_impl, _M_ptr(),
1591*38fd1498Szrj 				     std::forward<_Args>(__args)...);
1592*38fd1498Szrj 	  }
1593*38fd1498Szrj 
1594*38fd1498Szrj 	~_Temporary_value()
1595*38fd1498Szrj 	{ _Alloc_traits::destroy(_M_this->_M_impl, _M_ptr()); }
1596*38fd1498Szrj 
1597*38fd1498Szrj 	value_type&
1598*38fd1498Szrj 	_M_val() { return *reinterpret_cast<_Tp*>(&__buf); }
1599*38fd1498Szrj 
1600*38fd1498Szrj       private:
1601*38fd1498Szrj 	pointer
1602*38fd1498Szrj 	_M_ptr() { return pointer_traits<pointer>::pointer_to(_M_val()); }
1603*38fd1498Szrj 
1604*38fd1498Szrj 	vector* _M_this;
1605*38fd1498Szrj 	typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __buf;
1606*38fd1498Szrj       };
1607*38fd1498Szrj 
1608*38fd1498Szrj       // Called by insert(p,x) and other functions when insertion needs to
1609*38fd1498Szrj       // reallocate or move existing elements. _Arg is either _Tp& or _Tp.
1610*38fd1498Szrj       template<typename _Arg>
1611*38fd1498Szrj 	void
1612*38fd1498Szrj 	_M_insert_aux(iterator __position, _Arg&& __arg);
1613*38fd1498Szrj 
1614*38fd1498Szrj       template<typename... _Args>
1615*38fd1498Szrj 	void
1616*38fd1498Szrj 	_M_realloc_insert(iterator __position, _Args&&... __args);
1617*38fd1498Szrj 
1618*38fd1498Szrj       // Either move-construct at the end, or forward to _M_insert_aux.
1619*38fd1498Szrj       iterator
1620*38fd1498Szrj       _M_insert_rval(const_iterator __position, value_type&& __v);
1621*38fd1498Szrj 
1622*38fd1498Szrj       // Try to emplace at the end, otherwise forward to _M_insert_aux.
1623*38fd1498Szrj       template<typename... _Args>
1624*38fd1498Szrj 	iterator
1625*38fd1498Szrj 	_M_emplace_aux(const_iterator __position, _Args&&... __args);
1626*38fd1498Szrj 
1627*38fd1498Szrj       // Emplacing an rvalue of the correct type can use _M_insert_rval.
1628*38fd1498Szrj       iterator
1629*38fd1498Szrj       _M_emplace_aux(const_iterator __position, value_type&& __v)
1630*38fd1498Szrj       { return _M_insert_rval(__position, std::move(__v)); }
1631*38fd1498Szrj #endif
1632*38fd1498Szrj 
1633*38fd1498Szrj       // Called by _M_fill_insert, _M_insert_aux etc.
1634*38fd1498Szrj       size_type
1635*38fd1498Szrj       _M_check_len(size_type __n, const char* __s) const
1636*38fd1498Szrj       {
1637*38fd1498Szrj 	if (max_size() - size() < __n)
1638*38fd1498Szrj 	  __throw_length_error(__N(__s));
1639*38fd1498Szrj 
1640*38fd1498Szrj 	const size_type __len = size() + std::max(size(), __n);
1641*38fd1498Szrj 	return (__len < size() || __len > max_size()) ? max_size() : __len;
1642*38fd1498Szrj       }
1643*38fd1498Szrj 
1644*38fd1498Szrj       // Internal erase functions follow.
1645*38fd1498Szrj 
1646*38fd1498Szrj       // Called by erase(q1,q2), clear(), resize(), _M_fill_assign,
1647*38fd1498Szrj       // _M_assign_aux.
1648*38fd1498Szrj       void
1649*38fd1498Szrj       _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPT
1650*38fd1498Szrj       {
1651*38fd1498Szrj 	if (size_type __n = this->_M_impl._M_finish - __pos)
1652*38fd1498Szrj 	  {
1653*38fd1498Szrj 	    std::_Destroy(__pos, this->_M_impl._M_finish,
1654*38fd1498Szrj 			  _M_get_Tp_allocator());
1655*38fd1498Szrj 	    this->_M_impl._M_finish = __pos;
1656*38fd1498Szrj 	    _GLIBCXX_ASAN_ANNOTATE_SHRINK(__n);
1657*38fd1498Szrj 	  }
1658*38fd1498Szrj       }
1659*38fd1498Szrj 
1660*38fd1498Szrj       iterator
1661*38fd1498Szrj       _M_erase(iterator __position);
1662*38fd1498Szrj 
1663*38fd1498Szrj       iterator
1664*38fd1498Szrj       _M_erase(iterator __first, iterator __last);
1665*38fd1498Szrj 
1666*38fd1498Szrj #if __cplusplus >= 201103L
1667*38fd1498Szrj     private:
1668*38fd1498Szrj       // Constant-time move assignment when source object's memory can be
1669*38fd1498Szrj       // moved, either because the source's allocator will move too
1670*38fd1498Szrj       // or because the allocators are equal.
1671*38fd1498Szrj       void
1672*38fd1498Szrj       _M_move_assign(vector&& __x, std::true_type) noexcept
1673*38fd1498Szrj       {
1674*38fd1498Szrj 	vector __tmp(get_allocator());
1675*38fd1498Szrj 	this->_M_impl._M_swap_data(__tmp._M_impl);
1676*38fd1498Szrj 	this->_M_impl._M_swap_data(__x._M_impl);
1677*38fd1498Szrj 	std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator());
1678*38fd1498Szrj       }
1679*38fd1498Szrj 
1680*38fd1498Szrj       // Do move assignment when it might not be possible to move source
1681*38fd1498Szrj       // object's memory, resulting in a linear-time operation.
1682*38fd1498Szrj       void
1683*38fd1498Szrj       _M_move_assign(vector&& __x, std::false_type)
1684*38fd1498Szrj       {
1685*38fd1498Szrj 	if (__x._M_get_Tp_allocator() == this->_M_get_Tp_allocator())
1686*38fd1498Szrj 	  _M_move_assign(std::move(__x), std::true_type());
1687*38fd1498Szrj 	else
1688*38fd1498Szrj 	  {
1689*38fd1498Szrj 	    // The rvalue's allocator cannot be moved and is not equal,
1690*38fd1498Szrj 	    // so we need to individually move each element.
1691*38fd1498Szrj 	    this->assign(std::__make_move_if_noexcept_iterator(__x.begin()),
1692*38fd1498Szrj 			 std::__make_move_if_noexcept_iterator(__x.end()));
1693*38fd1498Szrj 	    __x.clear();
1694*38fd1498Szrj 	  }
1695*38fd1498Szrj       }
1696*38fd1498Szrj #endif
1697*38fd1498Szrj 
1698*38fd1498Szrj       template<typename _Up>
1699*38fd1498Szrj 	_Up*
1700*38fd1498Szrj 	_M_data_ptr(_Up* __ptr) const _GLIBCXX_NOEXCEPT
1701*38fd1498Szrj 	{ return __ptr; }
1702*38fd1498Szrj 
1703*38fd1498Szrj #if __cplusplus >= 201103L
1704*38fd1498Szrj       template<typename _Ptr>
1705*38fd1498Szrj 	typename std::pointer_traits<_Ptr>::element_type*
1706*38fd1498Szrj 	_M_data_ptr(_Ptr __ptr) const
1707*38fd1498Szrj 	{ return empty() ? nullptr : std::__to_address(__ptr); }
1708*38fd1498Szrj #else
1709*38fd1498Szrj       template<typename _Up>
1710*38fd1498Szrj 	_Up*
1711*38fd1498Szrj 	_M_data_ptr(_Up* __ptr) _GLIBCXX_NOEXCEPT
1712*38fd1498Szrj 	{ return __ptr; }
1713*38fd1498Szrj 
1714*38fd1498Szrj       template<typename _Ptr>
1715*38fd1498Szrj 	value_type*
1716*38fd1498Szrj 	_M_data_ptr(_Ptr __ptr)
1717*38fd1498Szrj 	{ return empty() ? (value_type*)0 : __ptr.operator->(); }
1718*38fd1498Szrj 
1719*38fd1498Szrj       template<typename _Ptr>
1720*38fd1498Szrj 	const value_type*
1721*38fd1498Szrj 	_M_data_ptr(_Ptr __ptr) const
1722*38fd1498Szrj 	{ return empty() ? (const value_type*)0 : __ptr.operator->(); }
1723*38fd1498Szrj #endif
1724*38fd1498Szrj     };
1725*38fd1498Szrj 
1726*38fd1498Szrj #if __cpp_deduction_guides >= 201606
1727*38fd1498Szrj   template<typename _InputIterator, typename _ValT
1728*38fd1498Szrj 	     = typename iterator_traits<_InputIterator>::value_type,
1729*38fd1498Szrj 	   typename _Allocator = allocator<_ValT>,
1730*38fd1498Szrj 	   typename = _RequireInputIter<_InputIterator>,
1731*38fd1498Szrj 	   typename = _RequireAllocator<_Allocator>>
1732*38fd1498Szrj     vector(_InputIterator, _InputIterator, _Allocator = _Allocator())
1733*38fd1498Szrj       -> vector<_ValT, _Allocator>;
1734*38fd1498Szrj #endif
1735*38fd1498Szrj 
1736*38fd1498Szrj   /**
1737*38fd1498Szrj    *  @brief  Vector equality comparison.
1738*38fd1498Szrj    *  @param  __x  A %vector.
1739*38fd1498Szrj    *  @param  __y  A %vector of the same type as @a __x.
1740*38fd1498Szrj    *  @return  True iff the size and elements of the vectors are equal.
1741*38fd1498Szrj    *
1742*38fd1498Szrj    *  This is an equivalence relation.  It is linear in the size of the
1743*38fd1498Szrj    *  vectors.  Vectors are considered equivalent if their sizes are equal,
1744*38fd1498Szrj    *  and if corresponding elements compare equal.
1745*38fd1498Szrj   */
1746*38fd1498Szrj   template<typename _Tp, typename _Alloc>
1747*38fd1498Szrj     inline bool
1748*38fd1498Szrj     operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
1749*38fd1498Szrj     { return (__x.size() == __y.size()
1750*38fd1498Szrj 	      && std::equal(__x.begin(), __x.end(), __y.begin())); }
1751*38fd1498Szrj 
1752*38fd1498Szrj   /**
1753*38fd1498Szrj    *  @brief  Vector ordering relation.
1754*38fd1498Szrj    *  @param  __x  A %vector.
1755*38fd1498Szrj    *  @param  __y  A %vector of the same type as @a __x.
1756*38fd1498Szrj    *  @return  True iff @a __x is lexicographically less than @a __y.
1757*38fd1498Szrj    *
1758*38fd1498Szrj    *  This is a total ordering relation.  It is linear in the size of the
1759*38fd1498Szrj    *  vectors.  The elements must be comparable with @c <.
1760*38fd1498Szrj    *
1761*38fd1498Szrj    *  See std::lexicographical_compare() for how the determination is made.
1762*38fd1498Szrj   */
1763*38fd1498Szrj   template<typename _Tp, typename _Alloc>
1764*38fd1498Szrj     inline bool
1765*38fd1498Szrj     operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
1766*38fd1498Szrj     { return std::lexicographical_compare(__x.begin(), __x.end(),
1767*38fd1498Szrj 					  __y.begin(), __y.end()); }
1768*38fd1498Szrj 
1769*38fd1498Szrj   /// Based on operator==
1770*38fd1498Szrj   template<typename _Tp, typename _Alloc>
1771*38fd1498Szrj     inline bool
1772*38fd1498Szrj     operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
1773*38fd1498Szrj     { return !(__x == __y); }
1774*38fd1498Szrj 
1775*38fd1498Szrj   /// Based on operator<
1776*38fd1498Szrj   template<typename _Tp, typename _Alloc>
1777*38fd1498Szrj     inline bool
1778*38fd1498Szrj     operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
1779*38fd1498Szrj     { return __y < __x; }
1780*38fd1498Szrj 
1781*38fd1498Szrj   /// Based on operator<
1782*38fd1498Szrj   template<typename _Tp, typename _Alloc>
1783*38fd1498Szrj     inline bool
1784*38fd1498Szrj     operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
1785*38fd1498Szrj     { return !(__y < __x); }
1786*38fd1498Szrj 
1787*38fd1498Szrj   /// Based on operator<
1788*38fd1498Szrj   template<typename _Tp, typename _Alloc>
1789*38fd1498Szrj     inline bool
1790*38fd1498Szrj     operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
1791*38fd1498Szrj     { return !(__x < __y); }
1792*38fd1498Szrj 
1793*38fd1498Szrj   /// See std::vector::swap().
1794*38fd1498Szrj   template<typename _Tp, typename _Alloc>
1795*38fd1498Szrj     inline void
1796*38fd1498Szrj     swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
1797*38fd1498Szrj     _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
1798*38fd1498Szrj     { __x.swap(__y); }
1799*38fd1498Szrj 
1800*38fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER
1801*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
1802*38fd1498Szrj } // namespace std
1803*38fd1498Szrj 
1804*38fd1498Szrj #endif /* _STL_VECTOR_H */
1805