Merged revisions 143552,143554,143557,143560,143562,143564-143567,143570-143573,14357...
[official-gcc.git] / libstdc++-v3 / include / debug / deque
blob2003734eca97931a277cd639d22d28ea46900448
1 // Debugging deque implementation -*- C++ -*-
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
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 2, or (at your option)
10 // any later version.
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.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
31 /** @file debug/deque
32  *  This file is a GNU debug extension to the Standard C++ Library.
33  */
35 #ifndef _GLIBCXX_DEBUG_DEQUE
36 #define _GLIBCXX_DEBUG_DEQUE 1
38 #include <deque>
39 #include <debug/safe_sequence.h>
40 #include <debug/safe_iterator.h>
42 namespace std
44 namespace __debug
46   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
47     class deque
48     : public _GLIBCXX_STD_D::deque<_Tp, _Allocator>,
49       public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
50     {
51       typedef  _GLIBCXX_STD_D::deque<_Tp, _Allocator> _Base;
52       typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
54     public:
55       typedef typename _Base::reference             reference;
56       typedef typename _Base::const_reference       const_reference;
58       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque>
59                                                     iterator;
60       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque>
61                                                      const_iterator;
63       typedef typename _Base::size_type             size_type;
64       typedef typename _Base::difference_type       difference_type;
66       typedef _Tp                                   value_type;
67       typedef _Allocator                            allocator_type;
68       typedef typename _Base::pointer               pointer;
69       typedef typename _Base::const_pointer         const_pointer;
70       typedef std::reverse_iterator<iterator>       reverse_iterator;
71       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
73       // 23.2.1.1 construct/copy/destroy:
74       explicit deque(const _Allocator& __a = _Allocator())
75       : _Base(__a) { }
77       explicit deque(size_type __n, const _Tp& __value = _Tp(),
78                      const _Allocator& __a = _Allocator())
79       : _Base(__n, __value, __a) { }
81       template<class _InputIterator>
82         deque(_InputIterator __first, _InputIterator __last,
83               const _Allocator& __a = _Allocator())
84         : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
85         { }
87       deque(const deque& __x)
88       : _Base(__x), _Safe_base() { }
90       deque(const _Base& __x)
91       : _Base(__x), _Safe_base() { }
93 #ifdef __GXX_EXPERIMENTAL_CXX0X__
94       deque(deque&& __x)
95       : _Base(std::forward<deque>(__x)), _Safe_base()
96       { this->_M_swap(__x); }
98       deque(initializer_list<value_type> __l,
99             const allocator_type& __a = allocator_type())
100       : _Base(__l, __a), _Safe_base() { }
101 #endif
103       ~deque() { }
105       deque&
106       operator=(const deque& __x)
107       {
108         *static_cast<_Base*>(this) = __x;
109         this->_M_invalidate_all();
110         return *this;
111       }
113 #ifdef __GXX_EXPERIMENTAL_CXX0X__
114       deque&
115       operator=(deque&& __x)
116       {
117         // NB: DR 675.
118         clear();
119         swap(__x);        
120         return *this;
121       }
123       deque&
124       operator=(initializer_list<value_type> __l)
125       {
126         *static_cast<_Base*>(this) = __l;
127         this->_M_invalidate_all();
128         return *this;
129       }
130 #endif
132       template<class _InputIterator>
133         void
134         assign(_InputIterator __first, _InputIterator __last)
135         {
136           __glibcxx_check_valid_range(__first, __last);
137           _Base::assign(__first, __last);
138           this->_M_invalidate_all();
139         }
141       void
142       assign(size_type __n, const _Tp& __t)
143       {
144         _Base::assign(__n, __t);
145         this->_M_invalidate_all();
146       }
148 #ifdef __GXX_EXPERIMENTAL_CXX0X__
149       void
150       assign(initializer_list<value_type> __l)
151       {
152         _Base::assign(__l);
153         this->_M_invalidate_all();
154       }
155 #endif
157       using _Base::get_allocator;
159       // iterators:
160       iterator
161       begin()
162       { return iterator(_Base::begin(), this); }
164       const_iterator
165       begin() const
166       { return const_iterator(_Base::begin(), this); }
168       iterator
169       end()
170       { return iterator(_Base::end(), this); }
172       const_iterator
173       end() const
174       { return const_iterator(_Base::end(), this); }
176       reverse_iterator
177       rbegin()
178       { return reverse_iterator(end()); }
180       const_reverse_iterator
181       rbegin() const
182       { return const_reverse_iterator(end()); }
184       reverse_iterator
185       rend()
186       { return reverse_iterator(begin()); }
188       const_reverse_iterator
189       rend() const
190       { return const_reverse_iterator(begin()); }
192 #ifdef __GXX_EXPERIMENTAL_CXX0X__
193       const_iterator
194       cbegin() const
195       { return const_iterator(_Base::begin(), this); }
197       const_iterator
198       cend() const
199       { return const_iterator(_Base::end(), this); }
201       const_reverse_iterator
202       crbegin() const
203       { return const_reverse_iterator(end()); }
205       const_reverse_iterator
206       crend() const
207       { return const_reverse_iterator(begin()); }
208 #endif
210       // 23.2.1.2 capacity:
211       using _Base::size;
212       using _Base::max_size;
214       void
215       resize(size_type __sz, _Tp __c = _Tp())
216       {
217         typedef typename _Base::const_iterator _Base_const_iterator;
218         typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
220         bool __invalidate_all = __sz > this->size();
221         if (__sz < this->size())
222           this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
224         _Base::resize(__sz, __c);
226         if (__invalidate_all)
227           this->_M_invalidate_all();
228       }
230       using _Base::empty;
232       // element access:
233       reference
234       operator[](size_type __n)
235       {
236         __glibcxx_check_subscript(__n);
237         return _M_base()[__n];
238       }
240       const_reference
241       operator[](size_type __n) const
242       {
243         __glibcxx_check_subscript(__n);
244         return _M_base()[__n];
245       }
247       using _Base::at;
249       reference
250       front()
251       {
252         __glibcxx_check_nonempty();
253         return _Base::front();
254       }
256       const_reference
257       front() const
258       {
259         __glibcxx_check_nonempty();
260         return _Base::front();
261       }
263       reference
264       back()
265       {
266         __glibcxx_check_nonempty();
267         return _Base::back();
268       }
270       const_reference
271       back() const
272       {
273         __glibcxx_check_nonempty();
274         return _Base::back();
275       }
277       // 23.2.1.3 modifiers:
278       void
279       push_front(const _Tp& __x)
280       {
281         _Base::push_front(__x);
282         this->_M_invalidate_all();
283       }
285       void
286       push_back(const _Tp& __x)
287       {
288         _Base::push_back(__x);
289         this->_M_invalidate_all();
290       }
292 #ifdef __GXX_EXPERIMENTAL_CXX0X__
293       void
294       push_front(_Tp&& __x)
295       { emplace_front(std::move(__x)); }
297       void
298       push_back(_Tp&& __x)
299       { emplace_back(std::move(__x)); }
301       template<typename... _Args>
302         void
303         emplace_front(_Args&&... __args)
304         {
305           _Base::emplace_front(std::forward<_Args>(__args)...);
306           this->_M_invalidate_all();
307         }
309       template<typename... _Args>
310         void
311         emplace_back(_Args&&... __args)
312         {
313           _Base::emplace_back(std::forward<_Args>(__args)...);
314           this->_M_invalidate_all();
315         }
317       template<typename... _Args>
318         iterator
319         emplace(iterator __position, _Args&&... __args)
320         {
321           __glibcxx_check_insert(__position);
322           typename _Base::iterator __res = _Base::emplace(__position.base(),
323                                             std::forward<_Args>(__args)...);
324           this->_M_invalidate_all();
325           return iterator(__res, this);
326         }
327 #endif
329       iterator
330       insert(iterator __position, const _Tp& __x)
331       {
332         __glibcxx_check_insert(__position);
333         typename _Base::iterator __res = _Base::insert(__position.base(), __x);
334         this->_M_invalidate_all();
335         return iterator(__res, this);
336       }
338 #ifdef __GXX_EXPERIMENTAL_CXX0X__
339       iterator
340       insert(iterator __position, _Tp&& __x)
341       { return emplace(__position, std::move(__x)); }
343       void
344       insert(iterator __p, initializer_list<value_type> __l)
345       {
346         _Base::insert(__p, __l);
347         this->_M_invalidate_all();
348       }
349 #endif
351       void
352       insert(iterator __position, size_type __n, const _Tp& __x)
353       {
354         __glibcxx_check_insert(__position);
355         _Base::insert(__position.base(), __n, __x);
356         this->_M_invalidate_all();
357       }
359       template<class _InputIterator>
360         void
361         insert(iterator __position,
362                _InputIterator __first, _InputIterator __last)
363         {
364           __glibcxx_check_insert_range(__position, __first, __last);
365           _Base::insert(__position.base(), __first, __last);
366           this->_M_invalidate_all();
367         }
369       void
370       pop_front()
371       {
372         __glibcxx_check_nonempty();
373         iterator __victim = begin();
374         __victim._M_invalidate();
375         _Base::pop_front();
376       }
378       void
379       pop_back()
380       {
381         __glibcxx_check_nonempty();
382         iterator __victim = end();
383         --__victim;
384         __victim._M_invalidate();
385         _Base::pop_back();
386       }
388       iterator
389       erase(iterator __position)
390       {
391         __glibcxx_check_erase(__position);
392         if (__position == begin() || __position == end()-1)
393           {
394             __position._M_invalidate();
395             return iterator(_Base::erase(__position.base()), this);
396           }
397         else
398           {
399             typename _Base::iterator __res = _Base::erase(__position.base());
400             this->_M_invalidate_all();
401             return iterator(__res, this);
402           }
403       }
405       iterator
406       erase(iterator __first, iterator __last)
407       {
408         // _GLIBCXX_RESOLVE_LIB_DEFECTS
409         // 151. can't currently clear() empty container
410         __glibcxx_check_erase_range(__first, __last);
411         if (__first == begin() || __last == end())
412           {
413             this->_M_detach_singular();
414             for (iterator __position = __first; __position != __last; )
415               {
416                 iterator __victim = __position++;
417                 __victim._M_invalidate();
418               }
419             __try
420               {
421                 return iterator(_Base::erase(__first.base(), __last.base()),
422                                 this);
423               }
424             __catch(...)
425               {
426                 this->_M_revalidate_singular();
427                 __throw_exception_again;
428               }
429           }
430         else
431           {
432             typename _Base::iterator __res = _Base::erase(__first.base(),
433                                                           __last.base());
434             this->_M_invalidate_all();
435             return iterator(__res, this);
436           }
437       }
439       void
440 #ifdef __GXX_EXPERIMENTAL_CXX0X__
441       swap(deque&& __x)
442 #else
443       swap(deque& __x)
444 #endif
445       {
446         _Base::swap(__x);
447         this->_M_swap(__x);
448       }
450       void
451       clear()
452       {
453         _Base::clear();
454         this->_M_invalidate_all();
455       }
457       _Base&
458       _M_base()       { return *this; }
460       const _Base&
461       _M_base() const { return *this; }
462     };
464   template<typename _Tp, typename _Alloc>
465     inline bool
466     operator==(const deque<_Tp, _Alloc>& __lhs,
467                const deque<_Tp, _Alloc>& __rhs)
468     { return __lhs._M_base() == __rhs._M_base(); }
470   template<typename _Tp, typename _Alloc>
471     inline bool
472     operator!=(const deque<_Tp, _Alloc>& __lhs,
473                const deque<_Tp, _Alloc>& __rhs)
474     { return __lhs._M_base() != __rhs._M_base(); }
476   template<typename _Tp, typename _Alloc>
477     inline bool
478     operator<(const deque<_Tp, _Alloc>& __lhs,
479               const deque<_Tp, _Alloc>& __rhs)
480     { return __lhs._M_base() < __rhs._M_base(); }
482   template<typename _Tp, typename _Alloc>
483     inline bool
484     operator<=(const deque<_Tp, _Alloc>& __lhs,
485                const deque<_Tp, _Alloc>& __rhs)
486     { return __lhs._M_base() <= __rhs._M_base(); }
488   template<typename _Tp, typename _Alloc>
489     inline bool
490     operator>=(const deque<_Tp, _Alloc>& __lhs,
491                const deque<_Tp, _Alloc>& __rhs)
492     { return __lhs._M_base() >= __rhs._M_base(); }
494   template<typename _Tp, typename _Alloc>
495     inline bool
496     operator>(const deque<_Tp, _Alloc>& __lhs,
497               const deque<_Tp, _Alloc>& __rhs)
498     { return __lhs._M_base() > __rhs._M_base(); }
500   template<typename _Tp, typename _Alloc>
501     inline void
502     swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
503     { __lhs.swap(__rhs); }
505 #ifdef __GXX_EXPERIMENTAL_CXX0X__
506   template<typename _Tp, typename _Alloc>
507     inline void
508     swap(deque<_Tp, _Alloc>&& __lhs, deque<_Tp, _Alloc>& __rhs)
509     { __lhs.swap(__rhs); }
511   template<typename _Tp, typename _Alloc>
512     inline void
513     swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>&& __rhs)
514     { __lhs.swap(__rhs); }
515 #endif
517 } // namespace __debug
518 } // namespace std
520 #endif