xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/debug/vector (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino// Debugging vector implementation -*- C++ -*-
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4*e4b17023SJohn Marino// Free Software Foundation, Inc.
5*e4b17023SJohn Marino//
6*e4b17023SJohn Marino// This file is part of the GNU ISO C++ Library.  This library is free
7*e4b17023SJohn Marino// software; you can redistribute it and/or modify it under the
8*e4b17023SJohn Marino// terms of the GNU General Public License as published by the
9*e4b17023SJohn Marino// Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino// any later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino// This library is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino// but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino// GNU General Public License for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino// Under Section 7 of GPL version 3, you are granted additional
18*e4b17023SJohn Marino// permissions described in the GCC Runtime Library Exception, version
19*e4b17023SJohn Marino// 3.1, as published by the Free Software Foundation.
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino// You should have received a copy of the GNU General Public License and
22*e4b17023SJohn Marino// a copy of the GCC Runtime Library Exception along with this program;
23*e4b17023SJohn Marino// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24*e4b17023SJohn Marino// <http://www.gnu.org/licenses/>.
25*e4b17023SJohn Marino
26*e4b17023SJohn Marino/** @file debug/vector
27*e4b17023SJohn Marino *  This file is a GNU debug extension to the Standard C++ Library.
28*e4b17023SJohn Marino */
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino#ifndef _GLIBCXX_DEBUG_VECTOR
31*e4b17023SJohn Marino#define _GLIBCXX_DEBUG_VECTOR 1
32*e4b17023SJohn Marino
33*e4b17023SJohn Marino#include <vector>
34*e4b17023SJohn Marino#include <utility>
35*e4b17023SJohn Marino#include <debug/safe_sequence.h>
36*e4b17023SJohn Marino#include <debug/safe_iterator.h>
37*e4b17023SJohn Marino
38*e4b17023SJohn Marinonamespace std _GLIBCXX_VISIBILITY(default)
39*e4b17023SJohn Marino{
40*e4b17023SJohn Marinonamespace __debug
41*e4b17023SJohn Marino{
42*e4b17023SJohn Marino  /// Class std::vector with safety/checking/debug instrumentation.
43*e4b17023SJohn Marino  template<typename _Tp,
44*e4b17023SJohn Marino	   typename _Allocator = std::allocator<_Tp> >
45*e4b17023SJohn Marino    class vector
46*e4b17023SJohn Marino    : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
47*e4b17023SJohn Marino      public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
48*e4b17023SJohn Marino    {
49*e4b17023SJohn Marino      typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
50*e4b17023SJohn Marino
51*e4b17023SJohn Marino      typedef typename _Base::iterator _Base_iterator;
52*e4b17023SJohn Marino      typedef typename _Base::const_iterator _Base_const_iterator;
53*e4b17023SJohn Marino      typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
54*e4b17023SJohn Marino
55*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
56*e4b17023SJohn Marino      typedef __gnu_cxx::__alloc_traits<_Allocator>  _Alloc_traits;
57*e4b17023SJohn Marino#endif
58*e4b17023SJohn Marino
59*e4b17023SJohn Marino    public:
60*e4b17023SJohn Marino      typedef typename _Base::reference             reference;
61*e4b17023SJohn Marino      typedef typename _Base::const_reference       const_reference;
62*e4b17023SJohn Marino
63*e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector>
64*e4b17023SJohn Marino      iterator;
65*e4b17023SJohn Marino      typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector>
66*e4b17023SJohn Marino      const_iterator;
67*e4b17023SJohn Marino
68*e4b17023SJohn Marino      typedef typename _Base::size_type             size_type;
69*e4b17023SJohn Marino      typedef typename _Base::difference_type       difference_type;
70*e4b17023SJohn Marino
71*e4b17023SJohn Marino      typedef _Tp				    value_type;
72*e4b17023SJohn Marino      typedef _Allocator			    allocator_type;
73*e4b17023SJohn Marino      typedef typename _Base::pointer               pointer;
74*e4b17023SJohn Marino      typedef typename _Base::const_pointer         const_pointer;
75*e4b17023SJohn Marino      typedef std::reverse_iterator<iterator>       reverse_iterator;
76*e4b17023SJohn Marino      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
77*e4b17023SJohn Marino
78*e4b17023SJohn Marino      // 23.2.4.1 construct/copy/destroy:
79*e4b17023SJohn Marino      explicit
80*e4b17023SJohn Marino      vector(const _Allocator& __a = _Allocator())
81*e4b17023SJohn Marino      : _Base(__a), _M_guaranteed_capacity(0) { }
82*e4b17023SJohn Marino
83*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
84*e4b17023SJohn Marino      explicit
85*e4b17023SJohn Marino      vector(size_type __n)
86*e4b17023SJohn Marino      : _Base(__n), _M_guaranteed_capacity(__n) { }
87*e4b17023SJohn Marino
88*e4b17023SJohn Marino      vector(size_type __n, const _Tp& __value,
89*e4b17023SJohn Marino	     const _Allocator& __a = _Allocator())
90*e4b17023SJohn Marino      : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
91*e4b17023SJohn Marino#else
92*e4b17023SJohn Marino      explicit
93*e4b17023SJohn Marino      vector(size_type __n, const _Tp& __value = _Tp(),
94*e4b17023SJohn Marino	     const _Allocator& __a = _Allocator())
95*e4b17023SJohn Marino      : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
96*e4b17023SJohn Marino#endif
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino      template<class _InputIterator>
99*e4b17023SJohn Marino        vector(_InputIterator __first, _InputIterator __last,
100*e4b17023SJohn Marino	       const _Allocator& __a = _Allocator())
101*e4b17023SJohn Marino        : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
102*e4b17023SJohn Marino								     __last)),
103*e4b17023SJohn Marino		__gnu_debug::__base(__last), __a),
104*e4b17023SJohn Marino	  _M_guaranteed_capacity(0)
105*e4b17023SJohn Marino        { _M_update_guaranteed_capacity(); }
106*e4b17023SJohn Marino
107*e4b17023SJohn Marino      vector(const vector& __x)
108*e4b17023SJohn Marino      : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
109*e4b17023SJohn Marino
110*e4b17023SJohn Marino      /// Construction from a release-mode vector
111*e4b17023SJohn Marino      vector(const _Base& __x)
112*e4b17023SJohn Marino      : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
113*e4b17023SJohn Marino
114*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
115*e4b17023SJohn Marino      vector(vector&& __x) noexcept
116*e4b17023SJohn Marino      : _Base(std::move(__x)),
117*e4b17023SJohn Marino	_M_guaranteed_capacity(this->size())
118*e4b17023SJohn Marino      {
119*e4b17023SJohn Marino	this->_M_swap(__x);
120*e4b17023SJohn Marino	__x._M_guaranteed_capacity = 0;
121*e4b17023SJohn Marino      }
122*e4b17023SJohn Marino
123*e4b17023SJohn Marino      vector(const vector& __x, const allocator_type& __a)
124*e4b17023SJohn Marino      : _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { }
125*e4b17023SJohn Marino
126*e4b17023SJohn Marino      vector(vector&& __x, const allocator_type& __a)
127*e4b17023SJohn Marino      : _Base(std::move(__x), __a),
128*e4b17023SJohn Marino        _M_guaranteed_capacity(this->size())
129*e4b17023SJohn Marino      {
130*e4b17023SJohn Marino	__x._M_invalidate_all();
131*e4b17023SJohn Marino	__x._M_guaranteed_capacity = 0;
132*e4b17023SJohn Marino      }
133*e4b17023SJohn Marino
134*e4b17023SJohn Marino      vector(initializer_list<value_type> __l,
135*e4b17023SJohn Marino	     const allocator_type& __a = allocator_type())
136*e4b17023SJohn Marino      : _Base(__l, __a),
137*e4b17023SJohn Marino	_M_guaranteed_capacity(__l.size()) { }
138*e4b17023SJohn Marino#endif
139*e4b17023SJohn Marino
140*e4b17023SJohn Marino      ~vector() _GLIBCXX_NOEXCEPT { }
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino      vector&
143*e4b17023SJohn Marino      operator=(const vector& __x)
144*e4b17023SJohn Marino      {
145*e4b17023SJohn Marino	static_cast<_Base&>(*this) = __x;
146*e4b17023SJohn Marino	this->_M_invalidate_all();
147*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
148*e4b17023SJohn Marino	return *this;
149*e4b17023SJohn Marino      }
150*e4b17023SJohn Marino
151*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
152*e4b17023SJohn Marino      vector&
153*e4b17023SJohn Marino      operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
154*e4b17023SJohn Marino      {
155*e4b17023SJohn Marino	_Base::operator=(std::move(__x));
156*e4b17023SJohn Marino	this->_M_invalidate_all();
157*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
158*e4b17023SJohn Marino	__x._M_invalidate_all();
159*e4b17023SJohn Marino	__x._M_guaranteed_capacity = 0;
160*e4b17023SJohn Marino	return *this;
161*e4b17023SJohn Marino      }
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino      vector&
164*e4b17023SJohn Marino      operator=(initializer_list<value_type> __l)
165*e4b17023SJohn Marino      {
166*e4b17023SJohn Marino	static_cast<_Base&>(*this) = __l;
167*e4b17023SJohn Marino	this->_M_invalidate_all();
168*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
169*e4b17023SJohn Marino	return *this;
170*e4b17023SJohn Marino      }
171*e4b17023SJohn Marino#endif
172*e4b17023SJohn Marino
173*e4b17023SJohn Marino      template<typename _InputIterator>
174*e4b17023SJohn Marino        void
175*e4b17023SJohn Marino        assign(_InputIterator __first, _InputIterator __last)
176*e4b17023SJohn Marino        {
177*e4b17023SJohn Marino	  __glibcxx_check_valid_range(__first, __last);
178*e4b17023SJohn Marino	  _Base::assign(__gnu_debug::__base(__first),
179*e4b17023SJohn Marino			__gnu_debug::__base(__last));
180*e4b17023SJohn Marino	  this->_M_invalidate_all();
181*e4b17023SJohn Marino	  _M_update_guaranteed_capacity();
182*e4b17023SJohn Marino	}
183*e4b17023SJohn Marino
184*e4b17023SJohn Marino      void
185*e4b17023SJohn Marino      assign(size_type __n, const _Tp& __u)
186*e4b17023SJohn Marino      {
187*e4b17023SJohn Marino	_Base::assign(__n, __u);
188*e4b17023SJohn Marino	this->_M_invalidate_all();
189*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
190*e4b17023SJohn Marino      }
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
193*e4b17023SJohn Marino      void
194*e4b17023SJohn Marino      assign(initializer_list<value_type> __l)
195*e4b17023SJohn Marino      {
196*e4b17023SJohn Marino	_Base::assign(__l);
197*e4b17023SJohn Marino	this->_M_invalidate_all();
198*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
199*e4b17023SJohn Marino      }
200*e4b17023SJohn Marino#endif
201*e4b17023SJohn Marino
202*e4b17023SJohn Marino      using _Base::get_allocator;
203*e4b17023SJohn Marino
204*e4b17023SJohn Marino      // iterators:
205*e4b17023SJohn Marino      iterator
206*e4b17023SJohn Marino      begin() _GLIBCXX_NOEXCEPT
207*e4b17023SJohn Marino      { return iterator(_Base::begin(), this); }
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino      const_iterator
210*e4b17023SJohn Marino      begin() const _GLIBCXX_NOEXCEPT
211*e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
212*e4b17023SJohn Marino
213*e4b17023SJohn Marino      iterator
214*e4b17023SJohn Marino      end() _GLIBCXX_NOEXCEPT
215*e4b17023SJohn Marino      { return iterator(_Base::end(), this); }
216*e4b17023SJohn Marino
217*e4b17023SJohn Marino      const_iterator
218*e4b17023SJohn Marino      end() const _GLIBCXX_NOEXCEPT
219*e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
220*e4b17023SJohn Marino
221*e4b17023SJohn Marino      reverse_iterator
222*e4b17023SJohn Marino      rbegin() _GLIBCXX_NOEXCEPT
223*e4b17023SJohn Marino      { return reverse_iterator(end()); }
224*e4b17023SJohn Marino
225*e4b17023SJohn Marino      const_reverse_iterator
226*e4b17023SJohn Marino      rbegin() const _GLIBCXX_NOEXCEPT
227*e4b17023SJohn Marino      { return const_reverse_iterator(end()); }
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino      reverse_iterator
230*e4b17023SJohn Marino      rend() _GLIBCXX_NOEXCEPT
231*e4b17023SJohn Marino      { return reverse_iterator(begin()); }
232*e4b17023SJohn Marino
233*e4b17023SJohn Marino      const_reverse_iterator
234*e4b17023SJohn Marino      rend() const _GLIBCXX_NOEXCEPT
235*e4b17023SJohn Marino      { return const_reverse_iterator(begin()); }
236*e4b17023SJohn Marino
237*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
238*e4b17023SJohn Marino      const_iterator
239*e4b17023SJohn Marino      cbegin() const noexcept
240*e4b17023SJohn Marino      { return const_iterator(_Base::begin(), this); }
241*e4b17023SJohn Marino
242*e4b17023SJohn Marino      const_iterator
243*e4b17023SJohn Marino      cend() const noexcept
244*e4b17023SJohn Marino      { return const_iterator(_Base::end(), this); }
245*e4b17023SJohn Marino
246*e4b17023SJohn Marino      const_reverse_iterator
247*e4b17023SJohn Marino      crbegin() const noexcept
248*e4b17023SJohn Marino      { return const_reverse_iterator(end()); }
249*e4b17023SJohn Marino
250*e4b17023SJohn Marino      const_reverse_iterator
251*e4b17023SJohn Marino      crend() const noexcept
252*e4b17023SJohn Marino      { return const_reverse_iterator(begin()); }
253*e4b17023SJohn Marino#endif
254*e4b17023SJohn Marino
255*e4b17023SJohn Marino      // 23.2.4.2 capacity:
256*e4b17023SJohn Marino      using _Base::size;
257*e4b17023SJohn Marino      using _Base::max_size;
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
260*e4b17023SJohn Marino      void
261*e4b17023SJohn Marino      resize(size_type __sz)
262*e4b17023SJohn Marino      {
263*e4b17023SJohn Marino	bool __realloc = _M_requires_reallocation(__sz);
264*e4b17023SJohn Marino	if (__sz < this->size())
265*e4b17023SJohn Marino	  this->_M_invalidate_after_nth(__sz);
266*e4b17023SJohn Marino	_Base::resize(__sz);
267*e4b17023SJohn Marino	if (__realloc)
268*e4b17023SJohn Marino	  this->_M_invalidate_all();
269*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
270*e4b17023SJohn Marino      }
271*e4b17023SJohn Marino
272*e4b17023SJohn Marino      void
273*e4b17023SJohn Marino      resize(size_type __sz, const _Tp& __c)
274*e4b17023SJohn Marino      {
275*e4b17023SJohn Marino	bool __realloc = _M_requires_reallocation(__sz);
276*e4b17023SJohn Marino	if (__sz < this->size())
277*e4b17023SJohn Marino	  this->_M_invalidate_after_nth(__sz);
278*e4b17023SJohn Marino	_Base::resize(__sz, __c);
279*e4b17023SJohn Marino	if (__realloc)
280*e4b17023SJohn Marino	  this->_M_invalidate_all();
281*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
282*e4b17023SJohn Marino      }
283*e4b17023SJohn Marino#else
284*e4b17023SJohn Marino      void
285*e4b17023SJohn Marino      resize(size_type __sz, _Tp __c = _Tp())
286*e4b17023SJohn Marino      {
287*e4b17023SJohn Marino	bool __realloc = _M_requires_reallocation(__sz);
288*e4b17023SJohn Marino	if (__sz < this->size())
289*e4b17023SJohn Marino	  this->_M_invalidate_after_nth(__sz);
290*e4b17023SJohn Marino	_Base::resize(__sz, __c);
291*e4b17023SJohn Marino	if (__realloc)
292*e4b17023SJohn Marino	  this->_M_invalidate_all();
293*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
294*e4b17023SJohn Marino      }
295*e4b17023SJohn Marino#endif
296*e4b17023SJohn Marino
297*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
298*e4b17023SJohn Marino      void
299*e4b17023SJohn Marino      shrink_to_fit()
300*e4b17023SJohn Marino      {
301*e4b17023SJohn Marino	if (_Base::_M_shrink_to_fit())
302*e4b17023SJohn Marino	  {
303*e4b17023SJohn Marino	    _M_guaranteed_capacity = _Base::capacity();
304*e4b17023SJohn Marino	    this->_M_invalidate_all();
305*e4b17023SJohn Marino	  }
306*e4b17023SJohn Marino      }
307*e4b17023SJohn Marino#endif
308*e4b17023SJohn Marino
309*e4b17023SJohn Marino      size_type
310*e4b17023SJohn Marino      capacity() const _GLIBCXX_NOEXCEPT
311*e4b17023SJohn Marino      {
312*e4b17023SJohn Marino#ifdef _GLIBCXX_DEBUG_PEDANTIC
313*e4b17023SJohn Marino	return _M_guaranteed_capacity;
314*e4b17023SJohn Marino#else
315*e4b17023SJohn Marino	return _Base::capacity();
316*e4b17023SJohn Marino#endif
317*e4b17023SJohn Marino      }
318*e4b17023SJohn Marino
319*e4b17023SJohn Marino      using _Base::empty;
320*e4b17023SJohn Marino
321*e4b17023SJohn Marino      void
322*e4b17023SJohn Marino      reserve(size_type __n)
323*e4b17023SJohn Marino      {
324*e4b17023SJohn Marino	bool __realloc = _M_requires_reallocation(__n);
325*e4b17023SJohn Marino	_Base::reserve(__n);
326*e4b17023SJohn Marino	if (__n > _M_guaranteed_capacity)
327*e4b17023SJohn Marino	  _M_guaranteed_capacity = __n;
328*e4b17023SJohn Marino	if (__realloc)
329*e4b17023SJohn Marino	  this->_M_invalidate_all();
330*e4b17023SJohn Marino      }
331*e4b17023SJohn Marino
332*e4b17023SJohn Marino      // element access:
333*e4b17023SJohn Marino      reference
334*e4b17023SJohn Marino      operator[](size_type __n)
335*e4b17023SJohn Marino      {
336*e4b17023SJohn Marino	__glibcxx_check_subscript(__n);
337*e4b17023SJohn Marino	return _M_base()[__n];
338*e4b17023SJohn Marino      }
339*e4b17023SJohn Marino
340*e4b17023SJohn Marino      const_reference
341*e4b17023SJohn Marino      operator[](size_type __n) const
342*e4b17023SJohn Marino      {
343*e4b17023SJohn Marino	__glibcxx_check_subscript(__n);
344*e4b17023SJohn Marino	return _M_base()[__n];
345*e4b17023SJohn Marino      }
346*e4b17023SJohn Marino
347*e4b17023SJohn Marino      using _Base::at;
348*e4b17023SJohn Marino
349*e4b17023SJohn Marino      reference
350*e4b17023SJohn Marino      front()
351*e4b17023SJohn Marino      {
352*e4b17023SJohn Marino	__glibcxx_check_nonempty();
353*e4b17023SJohn Marino	return _Base::front();
354*e4b17023SJohn Marino      }
355*e4b17023SJohn Marino
356*e4b17023SJohn Marino      const_reference
357*e4b17023SJohn Marino      front() const
358*e4b17023SJohn Marino      {
359*e4b17023SJohn Marino	__glibcxx_check_nonempty();
360*e4b17023SJohn Marino	return _Base::front();
361*e4b17023SJohn Marino      }
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino      reference
364*e4b17023SJohn Marino      back()
365*e4b17023SJohn Marino      {
366*e4b17023SJohn Marino	__glibcxx_check_nonempty();
367*e4b17023SJohn Marino	return _Base::back();
368*e4b17023SJohn Marino      }
369*e4b17023SJohn Marino
370*e4b17023SJohn Marino      const_reference
371*e4b17023SJohn Marino      back() const
372*e4b17023SJohn Marino      {
373*e4b17023SJohn Marino	__glibcxx_check_nonempty();
374*e4b17023SJohn Marino	return _Base::back();
375*e4b17023SJohn Marino      }
376*e4b17023SJohn Marino
377*e4b17023SJohn Marino      // _GLIBCXX_RESOLVE_LIB_DEFECTS
378*e4b17023SJohn Marino      // DR 464. Suggestion for new member functions in standard containers.
379*e4b17023SJohn Marino      using _Base::data;
380*e4b17023SJohn Marino
381*e4b17023SJohn Marino      // 23.2.4.3 modifiers:
382*e4b17023SJohn Marino      void
383*e4b17023SJohn Marino      push_back(const _Tp& __x)
384*e4b17023SJohn Marino      {
385*e4b17023SJohn Marino	bool __realloc = _M_requires_reallocation(this->size() + 1);
386*e4b17023SJohn Marino	_Base::push_back(__x);
387*e4b17023SJohn Marino	if (__realloc)
388*e4b17023SJohn Marino	  this->_M_invalidate_all();
389*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
390*e4b17023SJohn Marino      }
391*e4b17023SJohn Marino
392*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
393*e4b17023SJohn Marino      template<typename _Up = _Tp>
394*e4b17023SJohn Marino        typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
395*e4b17023SJohn Marino					void>::__type
396*e4b17023SJohn Marino        push_back(_Tp&& __x)
397*e4b17023SJohn Marino	{ emplace_back(std::move(__x)); }
398*e4b17023SJohn Marino
399*e4b17023SJohn Marino      template<typename... _Args>
400*e4b17023SJohn Marino        void
401*e4b17023SJohn Marino        emplace_back(_Args&&... __args)
402*e4b17023SJohn Marino	{
403*e4b17023SJohn Marino	  bool __realloc = _M_requires_reallocation(this->size() + 1);
404*e4b17023SJohn Marino	  _Base::emplace_back(std::forward<_Args>(__args)...);
405*e4b17023SJohn Marino	  if (__realloc)
406*e4b17023SJohn Marino	    this->_M_invalidate_all();
407*e4b17023SJohn Marino	  _M_update_guaranteed_capacity();
408*e4b17023SJohn Marino	}
409*e4b17023SJohn Marino#endif
410*e4b17023SJohn Marino
411*e4b17023SJohn Marino      void
412*e4b17023SJohn Marino      pop_back()
413*e4b17023SJohn Marino      {
414*e4b17023SJohn Marino	__glibcxx_check_nonempty();
415*e4b17023SJohn Marino	this->_M_invalidate_if(_Equal(--_Base::end()));
416*e4b17023SJohn Marino	_Base::pop_back();
417*e4b17023SJohn Marino      }
418*e4b17023SJohn Marino
419*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
420*e4b17023SJohn Marino      template<typename... _Args>
421*e4b17023SJohn Marino        iterator
422*e4b17023SJohn Marino        emplace(iterator __position, _Args&&... __args)
423*e4b17023SJohn Marino	{
424*e4b17023SJohn Marino	  __glibcxx_check_insert(__position);
425*e4b17023SJohn Marino	  bool __realloc = _M_requires_reallocation(this->size() + 1);
426*e4b17023SJohn Marino	  difference_type __offset = __position.base() - _Base::begin();
427*e4b17023SJohn Marino	  _Base_iterator __res = _Base::emplace(__position.base(),
428*e4b17023SJohn Marino						std::forward<_Args>(__args)...);
429*e4b17023SJohn Marino	  if (__realloc)
430*e4b17023SJohn Marino	    this->_M_invalidate_all();
431*e4b17023SJohn Marino	  else
432*e4b17023SJohn Marino	    this->_M_invalidate_after_nth(__offset);
433*e4b17023SJohn Marino	  _M_update_guaranteed_capacity();
434*e4b17023SJohn Marino	  return iterator(__res, this);
435*e4b17023SJohn Marino	}
436*e4b17023SJohn Marino#endif
437*e4b17023SJohn Marino
438*e4b17023SJohn Marino      iterator
439*e4b17023SJohn Marino      insert(iterator __position, const _Tp& __x)
440*e4b17023SJohn Marino      {
441*e4b17023SJohn Marino	__glibcxx_check_insert(__position);
442*e4b17023SJohn Marino	bool __realloc = _M_requires_reallocation(this->size() + 1);
443*e4b17023SJohn Marino	difference_type __offset = __position.base() - _Base::begin();
444*e4b17023SJohn Marino	_Base_iterator __res = _Base::insert(__position.base(), __x);
445*e4b17023SJohn Marino	if (__realloc)
446*e4b17023SJohn Marino	  this->_M_invalidate_all();
447*e4b17023SJohn Marino	else
448*e4b17023SJohn Marino	  this->_M_invalidate_after_nth(__offset);
449*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
450*e4b17023SJohn Marino	return iterator(__res, this);
451*e4b17023SJohn Marino      }
452*e4b17023SJohn Marino
453*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
454*e4b17023SJohn Marino      template<typename _Up = _Tp>
455*e4b17023SJohn Marino        typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
456*e4b17023SJohn Marino					iterator>::__type
457*e4b17023SJohn Marino        insert(iterator __position, _Tp&& __x)
458*e4b17023SJohn Marino        { return emplace(__position, std::move(__x)); }
459*e4b17023SJohn Marino
460*e4b17023SJohn Marino      void
461*e4b17023SJohn Marino      insert(iterator __position, initializer_list<value_type> __l)
462*e4b17023SJohn Marino      { this->insert(__position, __l.begin(), __l.end()); }
463*e4b17023SJohn Marino#endif
464*e4b17023SJohn Marino
465*e4b17023SJohn Marino      void
466*e4b17023SJohn Marino      insert(iterator __position, size_type __n, const _Tp& __x)
467*e4b17023SJohn Marino      {
468*e4b17023SJohn Marino	__glibcxx_check_insert(__position);
469*e4b17023SJohn Marino	bool __realloc = _M_requires_reallocation(this->size() + __n);
470*e4b17023SJohn Marino	difference_type __offset = __position.base() - _Base::begin();
471*e4b17023SJohn Marino	_Base::insert(__position.base(), __n, __x);
472*e4b17023SJohn Marino	if (__realloc)
473*e4b17023SJohn Marino	  this->_M_invalidate_all();
474*e4b17023SJohn Marino	else
475*e4b17023SJohn Marino	  this->_M_invalidate_after_nth(__offset);
476*e4b17023SJohn Marino	_M_update_guaranteed_capacity();
477*e4b17023SJohn Marino      }
478*e4b17023SJohn Marino
479*e4b17023SJohn Marino      template<class _InputIterator>
480*e4b17023SJohn Marino        void
481*e4b17023SJohn Marino        insert(iterator __position,
482*e4b17023SJohn Marino	       _InputIterator __first, _InputIterator __last)
483*e4b17023SJohn Marino        {
484*e4b17023SJohn Marino	  __glibcxx_check_insert_range(__position, __first, __last);
485*e4b17023SJohn Marino
486*e4b17023SJohn Marino	  /* Hard to guess if invalidation will occur, because __last
487*e4b17023SJohn Marino	     - __first can't be calculated in all cases, so we just
488*e4b17023SJohn Marino	     punt here by checking if it did occur. */
489*e4b17023SJohn Marino	  _Base_iterator __old_begin = _M_base().begin();
490*e4b17023SJohn Marino	  difference_type __offset = __position.base() - _Base::begin();
491*e4b17023SJohn Marino	  _Base::insert(__position.base(), __gnu_debug::__base(__first),
492*e4b17023SJohn Marino					   __gnu_debug::__base(__last));
493*e4b17023SJohn Marino
494*e4b17023SJohn Marino	  if (_M_base().begin() != __old_begin)
495*e4b17023SJohn Marino	    this->_M_invalidate_all();
496*e4b17023SJohn Marino	  else
497*e4b17023SJohn Marino	    this->_M_invalidate_after_nth(__offset);
498*e4b17023SJohn Marino	  _M_update_guaranteed_capacity();
499*e4b17023SJohn Marino	}
500*e4b17023SJohn Marino
501*e4b17023SJohn Marino      iterator
502*e4b17023SJohn Marino      erase(iterator __position)
503*e4b17023SJohn Marino      {
504*e4b17023SJohn Marino	__glibcxx_check_erase(__position);
505*e4b17023SJohn Marino	difference_type __offset = __position.base() - _Base::begin();
506*e4b17023SJohn Marino	_Base_iterator __res = _Base::erase(__position.base());
507*e4b17023SJohn Marino	this->_M_invalidate_after_nth(__offset);
508*e4b17023SJohn Marino	return iterator(__res, this);
509*e4b17023SJohn Marino      }
510*e4b17023SJohn Marino
511*e4b17023SJohn Marino      iterator
512*e4b17023SJohn Marino      erase(iterator __first, iterator __last)
513*e4b17023SJohn Marino      {
514*e4b17023SJohn Marino	// _GLIBCXX_RESOLVE_LIB_DEFECTS
515*e4b17023SJohn Marino	// 151. can't currently clear() empty container
516*e4b17023SJohn Marino	__glibcxx_check_erase_range(__first, __last);
517*e4b17023SJohn Marino
518*e4b17023SJohn Marino	if (__first.base() != __last.base())
519*e4b17023SJohn Marino	  {
520*e4b17023SJohn Marino	    difference_type __offset = __first.base() - _Base::begin();
521*e4b17023SJohn Marino	    _Base_iterator __res = _Base::erase(__first.base(),
522*e4b17023SJohn Marino						__last.base());
523*e4b17023SJohn Marino	    this->_M_invalidate_after_nth(__offset);
524*e4b17023SJohn Marino	    return iterator(__res, this);
525*e4b17023SJohn Marino	  }
526*e4b17023SJohn Marino	else
527*e4b17023SJohn Marino	  return __first;
528*e4b17023SJohn Marino      }
529*e4b17023SJohn Marino
530*e4b17023SJohn Marino      void
531*e4b17023SJohn Marino      swap(vector& __x)
532*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
533*e4b17023SJohn Marino			noexcept(_Alloc_traits::_S_nothrow_swap())
534*e4b17023SJohn Marino#endif
535*e4b17023SJohn Marino      {
536*e4b17023SJohn Marino	_Base::swap(__x);
537*e4b17023SJohn Marino	this->_M_swap(__x);
538*e4b17023SJohn Marino        std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
539*e4b17023SJohn Marino      }
540*e4b17023SJohn Marino
541*e4b17023SJohn Marino      void
542*e4b17023SJohn Marino      clear() _GLIBCXX_NOEXCEPT
543*e4b17023SJohn Marino      {
544*e4b17023SJohn Marino	_Base::clear();
545*e4b17023SJohn Marino	this->_M_invalidate_all();
546*e4b17023SJohn Marino        _M_guaranteed_capacity = 0;
547*e4b17023SJohn Marino      }
548*e4b17023SJohn Marino
549*e4b17023SJohn Marino      _Base&
550*e4b17023SJohn Marino      _M_base() _GLIBCXX_NOEXCEPT { return *this; }
551*e4b17023SJohn Marino
552*e4b17023SJohn Marino      const _Base&
553*e4b17023SJohn Marino      _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
554*e4b17023SJohn Marino
555*e4b17023SJohn Marino    private:
556*e4b17023SJohn Marino      size_type _M_guaranteed_capacity;
557*e4b17023SJohn Marino
558*e4b17023SJohn Marino      bool
559*e4b17023SJohn Marino      _M_requires_reallocation(size_type __elements)
560*e4b17023SJohn Marino      { return __elements > this->capacity(); }
561*e4b17023SJohn Marino
562*e4b17023SJohn Marino      void
563*e4b17023SJohn Marino      _M_update_guaranteed_capacity()
564*e4b17023SJohn Marino      {
565*e4b17023SJohn Marino	if (this->size() > _M_guaranteed_capacity)
566*e4b17023SJohn Marino	  _M_guaranteed_capacity = this->size();
567*e4b17023SJohn Marino      }
568*e4b17023SJohn Marino
569*e4b17023SJohn Marino      void
570*e4b17023SJohn Marino      _M_invalidate_after_nth(difference_type __n)
571*e4b17023SJohn Marino      {
572*e4b17023SJohn Marino	typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
573*e4b17023SJohn Marino	this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
574*e4b17023SJohn Marino      }
575*e4b17023SJohn Marino    };
576*e4b17023SJohn Marino
577*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
578*e4b17023SJohn Marino    inline bool
579*e4b17023SJohn Marino    operator==(const vector<_Tp, _Alloc>& __lhs,
580*e4b17023SJohn Marino	       const vector<_Tp, _Alloc>& __rhs)
581*e4b17023SJohn Marino    { return __lhs._M_base() == __rhs._M_base(); }
582*e4b17023SJohn Marino
583*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
584*e4b17023SJohn Marino    inline bool
585*e4b17023SJohn Marino    operator!=(const vector<_Tp, _Alloc>& __lhs,
586*e4b17023SJohn Marino	       const vector<_Tp, _Alloc>& __rhs)
587*e4b17023SJohn Marino    { return __lhs._M_base() != __rhs._M_base(); }
588*e4b17023SJohn Marino
589*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
590*e4b17023SJohn Marino    inline bool
591*e4b17023SJohn Marino    operator<(const vector<_Tp, _Alloc>& __lhs,
592*e4b17023SJohn Marino	      const vector<_Tp, _Alloc>& __rhs)
593*e4b17023SJohn Marino    { return __lhs._M_base() < __rhs._M_base(); }
594*e4b17023SJohn Marino
595*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
596*e4b17023SJohn Marino    inline bool
597*e4b17023SJohn Marino    operator<=(const vector<_Tp, _Alloc>& __lhs,
598*e4b17023SJohn Marino	       const vector<_Tp, _Alloc>& __rhs)
599*e4b17023SJohn Marino    { return __lhs._M_base() <= __rhs._M_base(); }
600*e4b17023SJohn Marino
601*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
602*e4b17023SJohn Marino    inline bool
603*e4b17023SJohn Marino    operator>=(const vector<_Tp, _Alloc>& __lhs,
604*e4b17023SJohn Marino	       const vector<_Tp, _Alloc>& __rhs)
605*e4b17023SJohn Marino    { return __lhs._M_base() >= __rhs._M_base(); }
606*e4b17023SJohn Marino
607*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
608*e4b17023SJohn Marino    inline bool
609*e4b17023SJohn Marino    operator>(const vector<_Tp, _Alloc>& __lhs,
610*e4b17023SJohn Marino	      const vector<_Tp, _Alloc>& __rhs)
611*e4b17023SJohn Marino    { return __lhs._M_base() > __rhs._M_base(); }
612*e4b17023SJohn Marino
613*e4b17023SJohn Marino  template<typename _Tp, typename _Alloc>
614*e4b17023SJohn Marino    inline void
615*e4b17023SJohn Marino    swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
616*e4b17023SJohn Marino    { __lhs.swap(__rhs); }
617*e4b17023SJohn Marino
618*e4b17023SJohn Marino} // namespace __debug
619*e4b17023SJohn Marino
620*e4b17023SJohn Marino#ifdef __GXX_EXPERIMENTAL_CXX0X__
621*e4b17023SJohn Marino  // DR 1182.
622*e4b17023SJohn Marino  /// std::hash specialization for vector<bool>.
623*e4b17023SJohn Marino  template<typename _Alloc>
624*e4b17023SJohn Marino    struct hash<__debug::vector<bool, _Alloc>>
625*e4b17023SJohn Marino    : public __hash_base<size_t, __debug::vector<bool, _Alloc>>
626*e4b17023SJohn Marino    {
627*e4b17023SJohn Marino      size_t
628*e4b17023SJohn Marino      operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
629*e4b17023SJohn Marino      { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
630*e4b17023SJohn Marino	  (__b._M_base()); }
631*e4b17023SJohn Marino    };
632*e4b17023SJohn Marino#endif
633*e4b17023SJohn Marino
634*e4b17023SJohn Marino} // namespace std
635*e4b17023SJohn Marino
636*e4b17023SJohn Marino#endif
637