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