vector revision 132720
1132720Skan// Debugging vector implementation -*- C++ -*-
2132720Skan
3132720Skan// Copyright (C) 2003, 2004
4132720Skan// Free Software Foundation, Inc.
5132720Skan//
6132720Skan// This file is part of the GNU ISO C++ Library.  This library is free
7132720Skan// software; you can redistribute it and/or modify it under the
8132720Skan// terms of the GNU General Public License as published by the
9132720Skan// Free Software Foundation; either version 2, or (at your option)
10132720Skan// any later version.
11132720Skan
12132720Skan// This library is distributed in the hope that it will be useful,
13132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
14132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15132720Skan// GNU General Public License for more details.
16132720Skan
17132720Skan// You should have received a copy of the GNU General Public License along
18132720Skan// with this library; see the file COPYING.  If not, write to the Free
19132720Skan// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20132720Skan// USA.
21132720Skan
22132720Skan// As a special exception, you may use this file as part of a free software
23132720Skan// library without restriction.  Specifically, if other files instantiate
24132720Skan// templates or use macros or inline functions from this file, or you compile
25132720Skan// this file and link it with other files to produce an executable, this
26132720Skan// file does not by itself cause the resulting executable to be covered by
27132720Skan// the GNU General Public License.  This exception does not however
28132720Skan// invalidate any other reasons why the executable file might be covered by
29132720Skan// the GNU General Public License.
30132720Skan
31132720Skan#ifndef _GLIBCXX_DEBUG_VECTOR
32132720Skan#define _GLIBCXX_DEBUG_VECTOR 1
33132720Skan
34132720Skan#include <vector>
35132720Skan#include <debug/safe_sequence.h>
36132720Skan#include <debug/safe_iterator.h>
37132720Skan#include <utility>
38132720Skan
39132720Skannamespace __gnu_debug_def
40132720Skan{
41132720Skan  template<typename _Tp,
42132720Skan	   typename _Allocator = std::allocator<_Tp> >
43132720Skan    class vector
44132720Skan    : public _GLIBCXX_STD::vector<_Tp, _Allocator>,
45132720Skan      public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
46132720Skan    {
47132720Skan      typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base;
48132720Skan      typedef __gnu_debug::_Safe_sequence<vector>              _Safe_base;
49132720Skan
50132720Skan      typedef typename _Base::const_iterator _Base_const_iterator;
51132720Skan      typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
52132720Skan
53132720Skan    public:
54132720Skan      typedef typename _Base::reference             reference;
55132720Skan      typedef typename _Base::const_reference       const_reference;
56132720Skan
57132720Skan      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector>
58132720Skan      iterator;
59132720Skan      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector>
60132720Skan      const_iterator;
61132720Skan
62132720Skan      typedef typename _Base::size_type             size_type;
63132720Skan      typedef typename _Base::difference_type       difference_type;
64132720Skan
65132720Skan      typedef _Tp				    value_type;
66132720Skan      typedef _Allocator			    allocator_type;
67132720Skan      typedef typename _Allocator::pointer          pointer;
68132720Skan      typedef typename _Allocator::const_pointer    const_pointer;
69132720Skan      typedef std::reverse_iterator<iterator>       reverse_iterator;
70132720Skan      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
71132720Skan
72132720Skan      // 23.2.4.1 construct/copy/destroy:
73132720Skan      explicit vector(const _Allocator& __a = _Allocator())
74132720Skan      : _Base(__a), _M_guaranteed_capacity(0) { }
75132720Skan
76132720Skan      explicit vector(size_type __n, const _Tp& __value = _Tp(),
77132720Skan		      const _Allocator& __a = _Allocator())
78132720Skan      : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
79132720Skan
80132720Skan      template<class _InputIterator>
81132720Skan        vector(_InputIterator __first, _InputIterator __last,
82132720Skan	       const _Allocator& __a = _Allocator())
83132720Skan	: _Base(__gnu_debug::__check_valid_range(__first, __last),
84132720Skan		__last, __a),
85132720Skan	  _M_guaranteed_capacity(0)
86132720Skan        { _M_update_guaranteed_capacity(); }
87132720Skan
88132720Skan      vector(const vector<_Tp,_Allocator>& __x)
89132720Skan      : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
90132720Skan
91132720Skan      /// Construction from a release-mode vector
92132720Skan      vector(const _Base& __x)
93132720Skan      : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
94132720Skan
95132720Skan      ~vector() { }
96132720Skan
97132720Skan      vector<_Tp,_Allocator>&
98132720Skan      operator=(const vector<_Tp,_Allocator>& __x)
99132720Skan      {
100132720Skan	static_cast<_Base&>(*this) = __x;
101132720Skan	this->_M_invalidate_all();
102132720Skan	_M_update_guaranteed_capacity();
103132720Skan	return *this;
104132720Skan      }
105132720Skan
106132720Skan      template<typename _InputIterator>
107132720Skan        void
108132720Skan        assign(_InputIterator __first, _InputIterator __last)
109132720Skan        {
110132720Skan	  __glibcxx_check_valid_range(__first, __last);
111132720Skan	  _Base::assign(__first, __last);
112132720Skan	  this->_M_invalidate_all();
113132720Skan	  _M_update_guaranteed_capacity();
114132720Skan	}
115132720Skan
116132720Skan      void
117132720Skan      assign(size_type __n, const _Tp& __u)
118132720Skan      {
119132720Skan	_Base::assign(__n, __u);
120132720Skan	this->_M_invalidate_all();
121132720Skan	_M_update_guaranteed_capacity();
122132720Skan      }
123132720Skan
124132720Skan      using _Base::get_allocator;
125132720Skan
126132720Skan      // iterators:
127132720Skan      iterator
128132720Skan      begin()
129132720Skan      { return iterator(_Base::begin(), this); }
130132720Skan
131132720Skan      const_iterator
132132720Skan      begin() const
133132720Skan      { return const_iterator(_Base::begin(), this); }
134132720Skan
135132720Skan      iterator
136132720Skan      end()
137132720Skan      { return iterator(_Base::end(), this); }
138132720Skan
139132720Skan      const_iterator
140132720Skan      end() const
141132720Skan      { return const_iterator(_Base::end(), this); }
142132720Skan
143132720Skan      reverse_iterator
144132720Skan      rbegin()
145132720Skan      { return reverse_iterator(end()); }
146132720Skan
147132720Skan      const_reverse_iterator
148132720Skan      rbegin() const
149132720Skan      { return const_reverse_iterator(end()); }
150132720Skan
151132720Skan      reverse_iterator
152132720Skan      rend()
153132720Skan      { return reverse_iterator(begin()); }
154132720Skan
155132720Skan      const_reverse_iterator
156132720Skan      rend() const
157132720Skan      { return const_reverse_iterator(begin()); }
158132720Skan
159132720Skan      // 23.2.4.2 capacity:
160132720Skan      using _Base::size;
161132720Skan      using _Base::max_size;
162132720Skan
163132720Skan      void
164132720Skan      resize(size_type __sz, _Tp __c = _Tp())
165132720Skan      {
166132720Skan	bool __realloc = _M_requires_reallocation(__sz);
167132720Skan	if (__sz < this->size())
168132720Skan	  this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
169132720Skan	_Base::resize(__sz, __c);
170132720Skan	if (__realloc)
171132720Skan	  this->_M_invalidate_all();
172132720Skan      }
173132720Skan
174132720Skan      using _Base::capacity;
175132720Skan      using _Base::empty;
176132720Skan
177132720Skan      void
178132720Skan      reserve(size_type __n)
179132720Skan      {
180132720Skan	bool __realloc = _M_requires_reallocation(__n);
181132720Skan	_Base::reserve(__n);
182132720Skan	if (__n > _M_guaranteed_capacity)
183132720Skan	  _M_guaranteed_capacity = __n;
184132720Skan	if (__realloc)
185132720Skan	  this->_M_invalidate_all();
186132720Skan      }
187132720Skan
188132720Skan      // element access:
189132720Skan      reference
190132720Skan      operator[](size_type __n)
191132720Skan      {
192132720Skan	__glibcxx_check_subscript(__n);
193132720Skan	return _M_base()[__n];
194132720Skan      }
195132720Skan
196132720Skan      const_reference
197132720Skan      operator[](size_type __n) const
198132720Skan      {
199132720Skan	__glibcxx_check_subscript(__n);
200132720Skan	return _M_base()[__n];
201132720Skan      }
202132720Skan
203132720Skan      using _Base::at;
204132720Skan
205132720Skan      reference
206132720Skan      front()
207132720Skan      {
208132720Skan	__glibcxx_check_nonempty();
209132720Skan	return _Base::front();
210132720Skan      }
211132720Skan
212132720Skan      const_reference
213132720Skan      front() const
214132720Skan      {
215132720Skan	__glibcxx_check_nonempty();
216132720Skan	return _Base::front();
217132720Skan      }
218132720Skan
219132720Skan      reference
220132720Skan      back()
221132720Skan      {
222132720Skan	__glibcxx_check_nonempty();
223132720Skan	return _Base::back();
224132720Skan      }
225132720Skan
226132720Skan      const_reference
227132720Skan      back() const
228132720Skan      {
229132720Skan	__glibcxx_check_nonempty();
230132720Skan	return _Base::back();
231132720Skan      }
232132720Skan
233132720Skan      // 23.2.4.3 modifiers:
234132720Skan      void
235132720Skan      push_back(const _Tp& __x)
236132720Skan      {
237132720Skan	bool __realloc = _M_requires_reallocation(this->size() + 1);
238132720Skan	_Base::push_back(__x);
239132720Skan	if (__realloc)
240132720Skan	  this->_M_invalidate_all();
241132720Skan	_M_update_guaranteed_capacity();
242132720Skan      }
243132720Skan
244132720Skan      void
245132720Skan      pop_back()
246132720Skan      {
247132720Skan	__glibcxx_check_nonempty();
248132720Skan	iterator __victim = end() - 1;
249132720Skan	__victim._M_invalidate();
250132720Skan	_Base::pop_back();
251132720Skan      }
252132720Skan
253132720Skan      iterator
254132720Skan      insert(iterator __position, const _Tp& __x)
255132720Skan      {
256132720Skan	__glibcxx_check_insert(__position);
257132720Skan	bool __realloc = _M_requires_reallocation(this->size() + 1);
258132720Skan	difference_type __offset = __position - begin();
259132720Skan	typename _Base::iterator __res = _Base::insert(__position.base(),__x);
260132720Skan	if (__realloc)
261132720Skan	  this->_M_invalidate_all();
262132720Skan	else
263132720Skan	  this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
264132720Skan	_M_update_guaranteed_capacity();
265132720Skan	return iterator(__res, this);
266132720Skan      }
267132720Skan
268132720Skan      void
269132720Skan      insert(iterator __position, size_type __n, const _Tp& __x)
270132720Skan      {
271132720Skan	__glibcxx_check_insert(__position);
272132720Skan	bool __realloc = _M_requires_reallocation(this->size() + __n);
273132720Skan	difference_type __offset = __position - begin();
274132720Skan	_Base::insert(__position.base(), __n, __x);
275132720Skan	if (__realloc)
276132720Skan	  this->_M_invalidate_all();
277132720Skan	else
278132720Skan	  this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
279132720Skan	_M_update_guaranteed_capacity();
280132720Skan      }
281132720Skan
282132720Skan      template<class _InputIterator>
283132720Skan        void
284132720Skan        insert(iterator __position,
285132720Skan	       _InputIterator __first, _InputIterator __last)
286132720Skan        {
287132720Skan	  __glibcxx_check_insert_range(__position, __first, __last);
288132720Skan
289132720Skan	  /* Hard to guess if invalidation will occur, because __last
290132720Skan	     - __first can't be calculated in all cases, so we just
291132720Skan	     punt here by checking if it did occur. */
292132720Skan	  typename _Base::iterator __old_begin = _M_base().begin();
293132720Skan	  difference_type __offset = __position - begin();
294132720Skan	  _Base::insert(__position.base(), __first, __last);
295132720Skan
296132720Skan	  if (_M_base().begin() != __old_begin)
297132720Skan	    this->_M_invalidate_all();
298132720Skan	  else
299132720Skan	    this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
300132720Skan	  _M_update_guaranteed_capacity();
301132720Skan	}
302132720Skan
303132720Skan      iterator
304132720Skan      erase(iterator __position)
305132720Skan      {
306132720Skan	__glibcxx_check_erase(__position);
307132720Skan	difference_type __offset = __position - begin();
308132720Skan	typename _Base::iterator __res = _Base::erase(__position.base());
309132720Skan	this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
310132720Skan	return iterator(__res, this);
311132720Skan      }
312132720Skan
313132720Skan      iterator
314132720Skan      erase(iterator __first, iterator __last)
315132720Skan      {
316132720Skan	// _GLIBCXX_RESOLVE_LIB_DEFECTS
317132720Skan	// 151. can't currently clear() empty container
318132720Skan	__glibcxx_check_erase_range(__first, __last);
319132720Skan
320132720Skan	difference_type __offset = __first - begin();
321132720Skan	typename _Base::iterator __res = _Base::erase(__first.base(),
322132720Skan							 __last.base());
323132720Skan	this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
324132720Skan	return iterator(__res, this);
325132720Skan      }
326132720Skan
327132720Skan      void
328132720Skan      swap(vector<_Tp,_Allocator>& __x)
329132720Skan      {
330132720Skan	_Base::swap(__x);
331132720Skan	this->_M_swap(__x);
332132720Skan        std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
333132720Skan      }
334132720Skan
335132720Skan      void
336132720Skan      clear()
337132720Skan      {
338132720Skan	_Base::clear();
339132720Skan	this->_M_invalidate_all();
340132720Skan        _M_guaranteed_capacity = 0;
341132720Skan      }
342132720Skan
343132720Skan      _Base&
344132720Skan      _M_base() { return *this; }
345132720Skan
346132720Skan      const _Base&
347132720Skan      _M_base() const { return *this; }
348132720Skan
349132720Skan    private:
350132720Skan      size_type _M_guaranteed_capacity;
351132720Skan
352132720Skan      bool
353132720Skan      _M_requires_reallocation(size_type __elements)
354132720Skan      {
355132720Skan#ifdef _GLIBCXX_DEBUG_PEDANTIC
356132720Skan	return __elements > this->capacity();
357132720Skan#else
358132720Skan	return __elements > _M_guaranteed_capacity;
359132720Skan#endif
360132720Skan      }
361132720Skan
362132720Skan      void
363132720Skan      _M_update_guaranteed_capacity()
364132720Skan      {
365132720Skan	if (this->size() > _M_guaranteed_capacity)
366132720Skan	  _M_guaranteed_capacity = this->size();
367132720Skan      }
368132720Skan    };
369132720Skan
370132720Skan  template<typename _Tp, typename _Alloc>
371132720Skan    inline bool
372132720Skan    operator==(const vector<_Tp, _Alloc>& __lhs,
373132720Skan	       const vector<_Tp, _Alloc>& __rhs)
374132720Skan    { return __lhs._M_base() == __rhs._M_base(); }
375132720Skan
376132720Skan  template<typename _Tp, typename _Alloc>
377132720Skan    inline bool
378132720Skan    operator!=(const vector<_Tp, _Alloc>& __lhs,
379132720Skan	       const vector<_Tp, _Alloc>& __rhs)
380132720Skan    { return __lhs._M_base() != __rhs._M_base(); }
381132720Skan
382132720Skan  template<typename _Tp, typename _Alloc>
383132720Skan    inline bool
384132720Skan    operator<(const vector<_Tp, _Alloc>& __lhs,
385132720Skan	      const vector<_Tp, _Alloc>& __rhs)
386132720Skan    { return __lhs._M_base() < __rhs._M_base(); }
387132720Skan
388132720Skan  template<typename _Tp, typename _Alloc>
389132720Skan    inline bool
390132720Skan    operator<=(const vector<_Tp, _Alloc>& __lhs,
391132720Skan	       const vector<_Tp, _Alloc>& __rhs)
392132720Skan    { return __lhs._M_base() <= __rhs._M_base(); }
393132720Skan
394132720Skan  template<typename _Tp, typename _Alloc>
395132720Skan    inline bool
396132720Skan    operator>=(const vector<_Tp, _Alloc>& __lhs,
397132720Skan	       const vector<_Tp, _Alloc>& __rhs)
398132720Skan    { return __lhs._M_base() >= __rhs._M_base(); }
399132720Skan
400132720Skan  template<typename _Tp, typename _Alloc>
401132720Skan    inline bool
402132720Skan    operator>(const vector<_Tp, _Alloc>& __lhs,
403132720Skan	      const vector<_Tp, _Alloc>& __rhs)
404132720Skan    { return __lhs._M_base() > __rhs._M_base(); }
405132720Skan
406132720Skan  template<typename _Tp, typename _Alloc>
407132720Skan    inline void
408132720Skan    swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
409132720Skan    { __lhs.swap(__rhs); }
410132720Skan} // namespace __gnu_debug_def
411132720Skan
412132720Skan#endif
413