]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.6/include/debug/list
update
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.6 / include / debug / list
1 // Debugging list 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/list
27  *  This file is a GNU debug extension to the Standard C++ Library.
28  */
29
30 #ifndef _GLIBCXX_DEBUG_LIST
31 #define _GLIBCXX_DEBUG_LIST 1
32
33 #include <list>
34 #include <debug/safe_sequence.h>
35 #include <debug/safe_iterator.h>
36
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 namespace __debug
40 {
41   /// Class std::list with safety/checking/debug instrumentation.
42   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
43     class list
44     : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
45       public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
46     {
47       typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
48       typedef __gnu_debug::_Safe_sequence<list>  _Safe_base;
49
50       typedef typename _Base::iterator       _Base_iterator;
51       typedef typename _Base::const_iterator _Base_const_iterator;
52       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
53       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
54     public:
55       typedef typename _Base::reference             reference;
56       typedef typename _Base::const_reference       const_reference;
57
58       typedef __gnu_debug::_Safe_iterator<_Base_iterator, list>
59                                                     iterator;
60       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list>
61                                                     const_iterator;
62
63       typedef typename _Base::size_type             size_type;
64       typedef typename _Base::difference_type       difference_type;
65
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;
72
73       // 23.2.2.1 construct/copy/destroy:
74       explicit
75       list(const _Allocator& __a = _Allocator())
76       : _Base(__a) { }
77
78 #ifdef __GXX_EXPERIMENTAL_CXX0X__
79       explicit
80       list(size_type __n)
81       : _Base(__n) { }
82
83       list(size_type __n, const _Tp& __value,
84            const _Allocator& __a = _Allocator())
85       : _Base(__n, __value, __a) { }
86 #else
87       explicit
88       list(size_type __n, const _Tp& __value = _Tp(),
89            const _Allocator& __a = _Allocator())
90       : _Base(__n, __value, __a) { }
91 #endif
92
93       template<class _InputIterator>
94       list(_InputIterator __first, _InputIterator __last,
95            const _Allocator& __a = _Allocator())
96       : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
97                                                                    __last)),
98               __gnu_debug::__base(__last), __a)
99       { }
100
101
102       list(const list& __x)
103       : _Base(__x), _Safe_base() { }
104
105       list(const _Base& __x)
106       : _Base(__x), _Safe_base() { }
107
108 #ifdef __GXX_EXPERIMENTAL_CXX0X__
109       list(list&& __x)
110       : _Base(std::move(__x)), _Safe_base()
111       { this->_M_swap(__x); }
112
113       list(initializer_list<value_type> __l,
114            const allocator_type& __a = allocator_type())
115         : _Base(__l, __a), _Safe_base() { }
116 #endif
117
118       ~list() { }
119
120       list&
121       operator=(const list& __x)
122       {
123         static_cast<_Base&>(*this) = __x;
124         this->_M_invalidate_all();
125         return *this;
126       }
127
128 #ifdef __GXX_EXPERIMENTAL_CXX0X__
129       list&
130       operator=(list&& __x)
131       {
132         // NB: DR 1204.
133         // NB: DR 675.
134         clear();
135         swap(__x);
136         return *this;
137       }
138
139       list&
140       operator=(initializer_list<value_type> __l)
141       {
142         static_cast<_Base&>(*this) = __l;
143         this->_M_invalidate_all();
144         return *this;
145       }
146
147       void
148       assign(initializer_list<value_type> __l)
149       {
150         _Base::assign(__l);
151         this->_M_invalidate_all();
152       }
153 #endif
154
155       template<class _InputIterator>
156         void
157         assign(_InputIterator __first, _InputIterator __last)
158         {
159           __glibcxx_check_valid_range(__first, __last);
160           _Base::assign(__gnu_debug::__base(__first),
161                         __gnu_debug::__base(__last));
162           this->_M_invalidate_all();
163         }
164
165       void
166       assign(size_type __n, const _Tp& __t)
167       {
168         _Base::assign(__n, __t);
169         this->_M_invalidate_all();
170       }
171
172       using _Base::get_allocator;
173
174       // iterators:
175       iterator
176       begin()
177       { return iterator(_Base::begin(), this); }
178
179       const_iterator
180       begin() const
181       { return const_iterator(_Base::begin(), this); }
182
183       iterator
184       end()
185       { return iterator(_Base::end(), this); }
186
187       const_iterator
188       end() const
189       { return const_iterator(_Base::end(), this); }
190
191       reverse_iterator
192       rbegin()
193       { return reverse_iterator(end()); }
194
195       const_reverse_iterator
196       rbegin() const
197       { return const_reverse_iterator(end()); }
198
199       reverse_iterator
200       rend()
201       { return reverse_iterator(begin()); }
202
203       const_reverse_iterator
204       rend() const
205       { return const_reverse_iterator(begin()); }
206
207 #ifdef __GXX_EXPERIMENTAL_CXX0X__
208       const_iterator
209       cbegin() const
210       { return const_iterator(_Base::begin(), this); }
211
212       const_iterator
213       cend() const
214       { return const_iterator(_Base::end(), this); }
215
216       const_reverse_iterator
217       crbegin() const
218       { return const_reverse_iterator(end()); }
219
220       const_reverse_iterator
221       crend() const
222       { return const_reverse_iterator(begin()); }
223 #endif
224
225       // 23.2.2.2 capacity:
226       using _Base::empty;
227       using _Base::size;
228       using _Base::max_size;
229
230 #ifdef __GXX_EXPERIMENTAL_CXX0X__
231       void
232       resize(size_type __sz)
233       {
234         this->_M_detach_singular();
235
236         // if __sz < size(), invalidate all iterators in [begin+__sz, end())
237         _Base_iterator __victim = _Base::begin();
238         _Base_iterator __end = _Base::end();
239         for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
240           ++__victim;
241
242         for (; __victim != __end; ++__victim)
243           {
244             this->_M_invalidate_if(_Equal(__victim));
245           }
246
247         __try
248           {
249             _Base::resize(__sz);
250           }
251         __catch(...)
252           {
253             this->_M_revalidate_singular();
254             __throw_exception_again;
255           }
256       }
257
258       void
259       resize(size_type __sz, const _Tp& __c)
260       {
261         this->_M_detach_singular();
262
263         // if __sz < size(), invalidate all iterators in [begin+__sz, end())
264         _Base_iterator __victim = _Base::begin();
265         _Base_iterator __end = _Base::end();
266         for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
267           ++__victim;
268
269         for (; __victim != __end; ++__victim)
270           {
271             this->_M_invalidate_if(_Equal(__victim));
272           }
273
274         __try
275           {
276             _Base::resize(__sz, __c);
277           }
278         __catch(...)
279           {
280             this->_M_revalidate_singular();
281             __throw_exception_again;
282           }
283       }
284 #else
285       void
286       resize(size_type __sz, _Tp __c = _Tp())
287       {
288         this->_M_detach_singular();
289
290         // if __sz < size(), invalidate all iterators in [begin+__sz, end())
291         _Base_iterator __victim = _Base::begin();
292         _Base_iterator __end = _Base::end();
293         for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
294           ++__victim;
295
296         for (; __victim != __end; ++__victim)
297           {
298             this->_M_invalidate_if(_Equal(__victim));
299           }
300
301         __try
302           {
303             _Base::resize(__sz, __c);
304           }
305         __catch(...)
306           {
307             this->_M_revalidate_singular();
308             __throw_exception_again;
309           }
310       }
311 #endif
312
313       // element access:
314       reference
315       front()
316       {
317         __glibcxx_check_nonempty();
318         return _Base::front();
319       }
320
321       const_reference
322       front() const
323       {
324         __glibcxx_check_nonempty();
325         return _Base::front();
326       }
327
328       reference
329       back()
330       {
331         __glibcxx_check_nonempty();
332         return _Base::back();
333       }
334
335       const_reference
336       back() const
337       {
338         __glibcxx_check_nonempty();
339         return _Base::back();
340       }
341
342       // 23.2.2.3 modifiers:
343       using _Base::push_front;
344
345 #ifdef __GXX_EXPERIMENTAL_CXX0X__
346       using _Base::emplace_front;
347 #endif
348
349       void
350       pop_front()
351       {
352         __glibcxx_check_nonempty();
353         this->_M_invalidate_if(_Equal(_Base::begin()));
354         _Base::pop_front();
355       }
356
357       using _Base::push_back;
358
359 #ifdef __GXX_EXPERIMENTAL_CXX0X__
360       using _Base::emplace_back;
361 #endif
362
363       void
364       pop_back()
365       {
366         __glibcxx_check_nonempty();
367         this->_M_invalidate_if(_Equal(--_Base::end()));
368         _Base::pop_back();
369       }
370
371 #ifdef __GXX_EXPERIMENTAL_CXX0X__
372       template<typename... _Args>
373         iterator
374         emplace(iterator __position, _Args&&... __args)
375         {
376           __glibcxx_check_insert(__position);
377           return iterator(_Base::emplace(__position.base(),
378                                         std::forward<_Args>(__args)...), this);
379         }
380 #endif
381
382       iterator
383       insert(iterator __position, const _Tp& __x)
384       {
385         __glibcxx_check_insert(__position);
386         return iterator(_Base::insert(__position.base(), __x), this);
387       }
388
389 #ifdef __GXX_EXPERIMENTAL_CXX0X__
390       iterator
391       insert(iterator __position, _Tp&& __x)
392       { return emplace(__position, std::move(__x)); }
393
394       void
395       insert(iterator __p, initializer_list<value_type> __l)
396       {
397         __glibcxx_check_insert(__p);
398         _Base::insert(__p, __l);
399       }
400 #endif
401
402       void
403       insert(iterator __position, size_type __n, const _Tp& __x)
404       {
405         __glibcxx_check_insert(__position);
406         _Base::insert(__position.base(), __n, __x);
407       }
408
409       template<class _InputIterator>
410         void
411         insert(iterator __position, _InputIterator __first,
412                _InputIterator __last)
413         {
414           __glibcxx_check_insert_range(__position, __first, __last);
415           _Base::insert(__position.base(), __gnu_debug::__base(__first),
416                                            __gnu_debug::__base(__last));
417         }
418
419     private:
420       _Base_iterator
421       _M_erase(_Base_iterator __position)
422       {
423         this->_M_invalidate_if(_Equal(__position));
424         return _Base::erase(__position);
425       }
426     public:
427       iterator
428       erase(iterator __position)
429       {
430         __glibcxx_check_erase(__position);
431         return iterator(_M_erase(__position.base()), this);
432       }
433
434       iterator
435       erase(iterator __position, iterator __last)
436       {
437         // _GLIBCXX_RESOLVE_LIB_DEFECTS
438         // 151. can't currently clear() empty container
439         __glibcxx_check_erase_range(__position, __last);
440         for (_Base_iterator __victim = __position.base();
441              __victim != __last.base(); ++__victim)
442           {
443             _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
444                                   _M_message(__gnu_debug::__msg_valid_range)
445                                   ._M_iterator(__position, "position")
446                                   ._M_iterator(__last, "last"));
447             this->_M_invalidate_if(_Equal(__victim));
448           }
449         return iterator(_Base::erase(__position.base(), __last.base()), this);
450       }
451
452       void
453       swap(list& __x)
454       {
455         _Base::swap(__x);
456         this->_M_swap(__x);
457       }
458
459       void
460       clear()
461       {
462         _Base::clear();
463         this->_M_invalidate_all();
464       }
465
466       // 23.2.2.4 list operations:
467       void
468 #ifdef __GXX_EXPERIMENTAL_CXX0X__
469       splice(iterator __position, list&& __x)
470 #else
471       splice(iterator __position, list& __x)
472 #endif
473       {
474         _GLIBCXX_DEBUG_VERIFY(&__x != this,
475                               _M_message(__gnu_debug::__msg_self_splice)
476                               ._M_sequence(*this, "this"));
477         this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
478         _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()));
479       }
480
481 #ifdef __GXX_EXPERIMENTAL_CXX0X__
482       void
483       splice(iterator __position, list& __x)
484       { splice(__position, std::move(__x)); }
485 #endif
486
487       void
488 #ifdef __GXX_EXPERIMENTAL_CXX0X__
489       splice(iterator __position, list&& __x, iterator __i)
490 #else
491       splice(iterator __position, list& __x, iterator __i)
492 #endif
493       {
494         __glibcxx_check_insert(__position);
495
496         // We used to perform the splice_alloc check:  not anymore, redundant
497         // after implementing the relevant bits of N1599.
498
499         _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
500                               _M_message(__gnu_debug::__msg_splice_bad)
501                               ._M_iterator(__i, "__i"));
502         _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
503                               _M_message(__gnu_debug::__msg_splice_other)
504                              ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
505
506         // _GLIBCXX_RESOLVE_LIB_DEFECTS
507         // 250. splicing invalidates iterators
508         this->_M_transfer_from_if(__x, _Equal(__i.base()));
509         _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
510                       __i.base());
511       }
512
513 #ifdef __GXX_EXPERIMENTAL_CXX0X__
514       void
515       splice(iterator __position, list& __x, iterator __i)
516       { splice(__position, std::move(__x), __i); }
517 #endif
518
519       void
520 #ifdef __GXX_EXPERIMENTAL_CXX0X__
521       splice(iterator __position, list&& __x, iterator __first,
522              iterator __last)
523 #else
524       splice(iterator __position, list& __x, iterator __first,
525              iterator __last)
526 #endif
527       {
528         __glibcxx_check_insert(__position);
529         __glibcxx_check_valid_range(__first, __last);
530         _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
531                               _M_message(__gnu_debug::__msg_splice_other)
532                               ._M_sequence(__x, "x")
533                               ._M_iterator(__first, "first"));
534
535         // We used to perform the splice_alloc check:  not anymore, redundant
536         // after implementing the relevant bits of N1599.
537
538         for (_Base_iterator __tmp = __first.base();
539              __tmp != __last.base(); ++__tmp)
540           {
541             _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
542                                   _M_message(__gnu_debug::__msg_valid_range)
543                                   ._M_iterator(__first, "first")
544                                   ._M_iterator(__last, "last"));
545             _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
546                                 _M_message(__gnu_debug::__msg_splice_overlap)
547                                   ._M_iterator(__tmp, "position")
548                                   ._M_iterator(__first, "first")
549                                   ._M_iterator(__last, "last"));
550             // _GLIBCXX_RESOLVE_LIB_DEFECTS
551             // 250. splicing invalidates iterators
552             this->_M_transfer_from_if(__x, _Equal(__tmp));
553           }
554
555         _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
556                       __first.base(), __last.base());
557       }
558
559 #ifdef __GXX_EXPERIMENTAL_CXX0X__
560       void
561       splice(iterator __position, list& __x, iterator __first, iterator __last)
562       { splice(__position, std::move(__x), __first, __last); }
563 #endif
564
565       void
566       remove(const _Tp& __value)
567       {
568         for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
569           {
570             if (*__x == __value)
571               __x = _M_erase(__x);
572             else
573               ++__x;
574           }
575       }
576
577       template<class _Predicate>
578         void
579         remove_if(_Predicate __pred)
580         {
581           for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
582             {
583               if (__pred(*__x))
584                 __x = _M_erase(__x);
585               else
586                 ++__x;
587             }
588         }
589
590       void
591       unique()
592       {
593         _Base_iterator __first = _Base::begin();
594         _Base_iterator __last = _Base::end();
595         if (__first == __last)
596           return;
597         _Base_iterator __next = __first; ++__next;
598         while (__next != __last)
599           {
600             if (*__first == *__next)
601               __next = _M_erase(__next);
602             else
603               __first = __next++;
604           }
605       }
606
607       template<class _BinaryPredicate>
608         void
609         unique(_BinaryPredicate __binary_pred)
610         {
611           _Base_iterator __first = _Base::begin();
612           _Base_iterator __last = _Base::end();
613           if (__first == __last)
614             return;
615           _Base_iterator __next = __first; ++__next;
616           while (__next != __last)
617             {
618               if (__binary_pred(*__first, *__next))
619                 __next = _M_erase(__next);
620               else
621                 __first = __next++;
622             }
623         }
624
625       void
626 #ifdef __GXX_EXPERIMENTAL_CXX0X__
627       merge(list&& __x)
628 #else
629       merge(list& __x)
630 #endif
631       {
632         // _GLIBCXX_RESOLVE_LIB_DEFECTS
633         // 300. list::merge() specification incomplete
634         if (this != &__x)
635           {
636             __glibcxx_check_sorted(_Base::begin(), _Base::end());
637             __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
638             this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
639             _Base::merge(_GLIBCXX_MOVE(__x._M_base()));
640           }
641       }
642
643 #ifdef __GXX_EXPERIMENTAL_CXX0X__
644       void
645       merge(list& __x)
646       { merge(std::move(__x)); }
647 #endif
648
649       template<class _Compare>
650         void
651 #ifdef __GXX_EXPERIMENTAL_CXX0X__
652         merge(list&& __x, _Compare __comp)
653 #else
654         merge(list& __x, _Compare __comp)
655 #endif
656         {
657           // _GLIBCXX_RESOLVE_LIB_DEFECTS
658           // 300. list::merge() specification incomplete
659           if (this != &__x)
660             {
661               __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(),
662                                           __comp);
663               __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
664                                           __comp);
665               this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
666               _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
667             }
668         }
669
670 #ifdef __GXX_EXPERIMENTAL_CXX0X__
671       template<typename _Compare>
672         void
673         merge(list& __x, _Compare __comp)
674         { merge(std::move(__x), __comp); }
675 #endif
676
677       void
678       sort() { _Base::sort(); }
679
680       template<typename _StrictWeakOrdering>
681         void
682         sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
683
684       using _Base::reverse;
685
686       _Base&
687       _M_base()       { return *this; }
688
689       const _Base&
690       _M_base() const { return *this; }
691
692     private:
693       void
694       _M_invalidate_all()
695       {
696         this->_M_invalidate_if(_Not_equal(_Base::end()));
697       }
698     };
699
700   template<typename _Tp, typename _Alloc>
701     inline bool
702     operator==(const list<_Tp, _Alloc>& __lhs,
703                const list<_Tp, _Alloc>& __rhs)
704     { return __lhs._M_base() == __rhs._M_base(); }
705
706   template<typename _Tp, typename _Alloc>
707     inline bool
708     operator!=(const list<_Tp, _Alloc>& __lhs,
709                const list<_Tp, _Alloc>& __rhs)
710     { return __lhs._M_base() != __rhs._M_base(); }
711
712   template<typename _Tp, typename _Alloc>
713     inline bool
714     operator<(const list<_Tp, _Alloc>& __lhs,
715               const list<_Tp, _Alloc>& __rhs)
716     { return __lhs._M_base() < __rhs._M_base(); }
717
718   template<typename _Tp, typename _Alloc>
719     inline bool
720     operator<=(const list<_Tp, _Alloc>& __lhs,
721                const list<_Tp, _Alloc>& __rhs)
722     { return __lhs._M_base() <= __rhs._M_base(); }
723
724   template<typename _Tp, typename _Alloc>
725     inline bool
726     operator>=(const list<_Tp, _Alloc>& __lhs,
727                const list<_Tp, _Alloc>& __rhs)
728     { return __lhs._M_base() >= __rhs._M_base(); }
729
730   template<typename _Tp, typename _Alloc>
731     inline bool
732     operator>(const list<_Tp, _Alloc>& __lhs,
733               const list<_Tp, _Alloc>& __rhs)
734     { return __lhs._M_base() > __rhs._M_base(); }
735
736   template<typename _Tp, typename _Alloc>
737     inline void
738     swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
739     { __lhs.swap(__rhs); }
740
741 } // namespace __debug
742 } // namespace std
743
744 #endif