* flow.c (find_basic_blocks): Handle cfg issues for rethrows and
[official-gcc.git] / libstdc++ / stl / stl_slist.h
blobf31ea9e15e540386ef496f9a9f6b9179e2fbc01b
1 /*
2 * Copyright (c) 1997
3 * Silicon Graphics Computer Systems, Inc.
5 * Permission to use, copy, modify, distribute and sell this software
6 * and its documentation for any purpose is hereby granted without fee,
7 * provided that the above copyright notice appear in all copies and
8 * that both that copyright notice and this permission notice appear
9 * in supporting documentation. Silicon Graphics makes no
10 * representations about the suitability of this software for any
11 * purpose. It is provided "as is" without express or implied warranty.
15 /* NOTE: This is an internal header file, included by other STL headers.
16 * You should not attempt to use it directly.
19 #ifndef __SGI_STL_INTERNAL_SLIST_H
20 #define __SGI_STL_INTERNAL_SLIST_H
23 __STL_BEGIN_NAMESPACE
25 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
26 #pragma set woff 1174
27 #endif
29 struct __slist_node_base
31 __slist_node_base* next;
34 inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,
35 __slist_node_base* new_node)
37 new_node->next = prev_node->next;
38 prev_node->next = new_node;
39 return new_node;
42 inline __slist_node_base* __slist_previous(__slist_node_base* head,
43 const __slist_node_base* node)
45 while (head && head->next != node)
46 head = head->next;
47 return head;
50 inline const __slist_node_base* __slist_previous(const __slist_node_base* head,
51 const __slist_node_base* node)
53 while (head && head->next != node)
54 head = head->next;
55 return head;
58 inline void __slist_splice_after(__slist_node_base* pos,
59 __slist_node_base* before_first,
60 __slist_node_base* before_last)
62 if (pos != before_first && pos != before_last) {
63 __slist_node_base* first = before_first->next;
64 __slist_node_base* after = pos->next;
65 before_first->next = before_last->next;
66 pos->next = first;
67 before_last->next = after;
71 inline __slist_node_base* __slist_reverse(__slist_node_base* node)
73 __slist_node_base* result = node;
74 node = node->next;
75 result->next = 0;
76 while(node) {
77 __slist_node_base* next = node->next;
78 node->next = result;
79 result = node;
80 node = next;
82 return result;
85 template <class T>
86 struct __slist_node : public __slist_node_base
88 T data;
91 struct __slist_iterator_base
93 typedef size_t size_type;
94 typedef ptrdiff_t difference_type;
95 typedef forward_iterator_tag iterator_category;
97 __slist_node_base* node;
99 __slist_iterator_base(__slist_node_base* x) : node(x) {}
100 void incr() { node = node->next; }
102 bool operator==(const __slist_iterator_base& x) const {
103 return node == x.node;
105 bool operator!=(const __slist_iterator_base& x) const {
106 return node != x.node;
110 template <class T, class Ref, class Ptr>
111 struct __slist_iterator : public __slist_iterator_base
113 typedef __slist_iterator<T, T&, T*> iterator;
114 typedef __slist_iterator<T, const T&, const T*> const_iterator;
115 typedef __slist_iterator<T, Ref, Ptr> self;
117 typedef T value_type;
118 typedef Ptr pointer;
119 typedef Ref reference;
120 typedef __slist_node<T> list_node;
122 __slist_iterator(list_node* x) : __slist_iterator_base(x) {}
123 __slist_iterator() : __slist_iterator_base(0) {}
124 __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}
126 reference operator*() const { return ((list_node*) node)->data; }
127 #ifndef __SGI_STL_NO_ARROW_OPERATOR
128 pointer operator->() const { return &(operator*()); }
129 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
131 self& operator++()
133 incr();
134 return *this;
136 self operator++(int)
138 self tmp = *this;
139 incr();
140 return tmp;
144 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
146 inline ptrdiff_t*
147 distance_type(const __slist_iterator_base&)
149 return 0;
152 inline forward_iterator_tag
153 iterator_category(const __slist_iterator_base&)
155 return forward_iterator_tag();
158 template <class T, class Ref, class Ptr>
159 inline T*
160 value_type(const __slist_iterator<T, Ref, Ptr>&) {
161 return 0;
164 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
166 inline size_t __slist_size(__slist_node_base* node)
168 size_t result = 0;
169 for ( ; node != 0; node = node->next)
170 ++result;
171 return result;
174 template <class T, class Alloc = alloc>
175 class slist
177 public:
178 typedef T value_type;
179 typedef value_type* pointer;
180 typedef const value_type* const_pointer;
181 typedef value_type& reference;
182 typedef const value_type& const_reference;
183 typedef size_t size_type;
184 typedef ptrdiff_t difference_type;
186 typedef __slist_iterator<T, T&, T*> iterator;
187 typedef __slist_iterator<T, const T&, const T*> const_iterator;
189 private:
190 typedef __slist_node<T> list_node;
191 typedef __slist_node_base list_node_base;
192 typedef __slist_iterator_base iterator_base;
193 typedef simple_alloc<list_node, Alloc> list_node_allocator;
195 static list_node* create_node(const value_type& x) {
196 list_node* node = list_node_allocator::allocate();
197 __STL_TRY {
198 construct(&node->data, x);
199 node->next = 0;
201 __STL_UNWIND(list_node_allocator::deallocate(node));
202 return node;
205 static void destroy_node(list_node* node) {
206 destroy(&node->data);
207 list_node_allocator::deallocate(node);
210 void fill_initialize(size_type n, const value_type& x) {
211 head.next = 0;
212 __STL_TRY {
213 _insert_after_fill(&head, n, x);
215 __STL_UNWIND(clear());
218 #ifdef __STL_MEMBER_TEMPLATES
219 template <class InputIterator>
220 void range_initialize(InputIterator first, InputIterator last) {
221 head.next = 0;
222 __STL_TRY {
223 _insert_after_range(&head, first, last);
225 __STL_UNWIND(clear());
227 #else /* __STL_MEMBER_TEMPLATES */
228 void range_initialize(const value_type* first, const value_type* last) {
229 head.next = 0;
230 __STL_TRY {
231 _insert_after_range(&head, first, last);
233 __STL_UNWIND(clear());
235 void range_initialize(const_iterator first, const_iterator last) {
236 head.next = 0;
237 __STL_TRY {
238 _insert_after_range(&head, first, last);
240 __STL_UNWIND(clear());
242 #endif /* __STL_MEMBER_TEMPLATES */
244 private:
245 list_node_base head;
247 public:
248 slist() { head.next = 0; }
250 slist(size_type n, const value_type& x) { fill_initialize(n, x); }
251 slist(int n, const value_type& x) { fill_initialize(n, x); }
252 slist(long n, const value_type& x) { fill_initialize(n, x); }
253 explicit slist(size_type n) { fill_initialize(n, value_type()); }
255 #ifdef __STL_MEMBER_TEMPLATES
256 template <class InputIterator>
257 slist(InputIterator first, InputIterator last) {
258 range_initialize(first, last);
261 #else /* __STL_MEMBER_TEMPLATES */
262 slist(const_iterator first, const_iterator last) {
263 range_initialize(first, last);
265 slist(const value_type* first, const value_type* last) {
266 range_initialize(first, last);
268 #endif /* __STL_MEMBER_TEMPLATES */
270 slist(const slist& L) { range_initialize(L.begin(), L.end()); }
272 slist& operator= (const slist& L);
274 ~slist() { clear(); }
276 public:
278 iterator begin() { return iterator((list_node*)head.next); }
279 const_iterator begin() const { return const_iterator((list_node*)head.next);}
281 iterator end() { return iterator(0); }
282 const_iterator end() const { return const_iterator(0); }
284 size_type size() const { return __slist_size(head.next); }
286 size_type max_size() const { return size_type(-1); }
288 bool empty() const { return head.next == 0; }
290 void swap(slist& L)
292 list_node_base* tmp = head.next;
293 head.next = L.head.next;
294 L.head.next = tmp;
297 public:
298 friend bool operator== __STL_NULL_TMPL_ARGS(const slist<T, Alloc>& L1,
299 const slist<T, Alloc>& L2);
301 public:
303 reference front() { return ((list_node*) head.next)->data; }
304 const_reference front() const { return ((list_node*) head.next)->data; }
305 void push_front(const value_type& x) {
306 __slist_make_link(&head, create_node(x));
308 void pop_front() {
309 list_node* node = (list_node*) head.next;
310 head.next = node->next;
311 destroy_node(node);
314 iterator previous(const_iterator pos) {
315 return iterator((list_node*) __slist_previous(&head, pos.node));
317 const_iterator previous(const_iterator pos) const {
318 return const_iterator((list_node*) __slist_previous(&head, pos.node));
321 private:
322 list_node* _insert_after(list_node_base* pos, const value_type& x) {
323 return (list_node*) (__slist_make_link(pos, create_node(x)));
326 void _insert_after_fill(list_node_base* pos,
327 size_type n, const value_type& x) {
328 for (size_type i = 0; i < n; ++i)
329 pos = __slist_make_link(pos, create_node(x));
332 #ifdef __STL_MEMBER_TEMPLATES
333 template <class InIter>
334 void _insert_after_range(list_node_base* pos, InIter first, InIter last) {
335 while (first != last) {
336 pos = __slist_make_link(pos, create_node(*first));
337 ++first;
340 #else /* __STL_MEMBER_TEMPLATES */
341 void _insert_after_range(list_node_base* pos,
342 const_iterator first, const_iterator last) {
343 while (first != last) {
344 pos = __slist_make_link(pos, create_node(*first));
345 ++first;
348 void _insert_after_range(list_node_base* pos,
349 const value_type* first, const value_type* last) {
350 while (first != last) {
351 pos = __slist_make_link(pos, create_node(*first));
352 ++first;
355 #endif /* __STL_MEMBER_TEMPLATES */
357 list_node_base* erase_after(list_node_base* pos) {
358 list_node* next = (list_node*) (pos->next);
359 list_node_base* next_next = next->next;
360 pos->next = next_next;
361 destroy_node(next);
362 return next_next;
365 list_node_base* erase_after(list_node_base* before_first,
366 list_node_base* last_node) {
367 list_node* cur = (list_node*) (before_first->next);
368 while (cur != last_node) {
369 list_node* tmp = cur;
370 cur = (list_node*) cur->next;
371 destroy_node(tmp);
373 before_first->next = last_node;
374 return last_node;
378 public:
380 iterator insert_after(iterator pos, const value_type& x) {
381 return iterator(_insert_after(pos.node, x));
384 iterator insert_after(iterator pos) {
385 return insert_after(pos, value_type());
388 void insert_after(iterator pos, size_type n, const value_type& x) {
389 _insert_after_fill(pos.node, n, x);
391 void insert_after(iterator pos, int n, const value_type& x) {
392 _insert_after_fill(pos.node, (size_type) n, x);
394 void insert_after(iterator pos, long n, const value_type& x) {
395 _insert_after_fill(pos.node, (size_type) n, x);
398 #ifdef __STL_MEMBER_TEMPLATES
399 template <class InIter>
400 void insert_after(iterator pos, InIter first, InIter last) {
401 _insert_after_range(pos.node, first, last);
403 #else /* __STL_MEMBER_TEMPLATES */
404 void insert_after(iterator pos, const_iterator first, const_iterator last) {
405 _insert_after_range(pos.node, first, last);
407 void insert_after(iterator pos,
408 const value_type* first, const value_type* last) {
409 _insert_after_range(pos.node, first, last);
411 #endif /* __STL_MEMBER_TEMPLATES */
413 iterator insert(iterator pos, const value_type& x) {
414 return iterator(_insert_after(__slist_previous(&head, pos.node), x));
417 iterator insert(iterator pos) {
418 return iterator(_insert_after(__slist_previous(&head, pos.node),
419 value_type()));
422 void insert(iterator pos, size_type n, const value_type& x) {
423 _insert_after_fill(__slist_previous(&head, pos.node), n, x);
425 void insert(iterator pos, int n, const value_type& x) {
426 _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
428 void insert(iterator pos, long n, const value_type& x) {
429 _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
432 #ifdef __STL_MEMBER_TEMPLATES
433 template <class InIter>
434 void insert(iterator pos, InIter first, InIter last) {
435 _insert_after_range(__slist_previous(&head, pos.node), first, last);
437 #else /* __STL_MEMBER_TEMPLATES */
438 void insert(iterator pos, const_iterator first, const_iterator last) {
439 _insert_after_range(__slist_previous(&head, pos.node), first, last);
441 void insert(iterator pos, const value_type* first, const value_type* last) {
442 _insert_after_range(__slist_previous(&head, pos.node), first, last);
444 #endif /* __STL_MEMBER_TEMPLATES */
447 public:
448 iterator erase_after(iterator pos) {
449 return iterator((list_node*)erase_after(pos.node));
451 iterator erase_after(iterator before_first, iterator last) {
452 return iterator((list_node*)erase_after(before_first.node, last.node));
455 iterator erase(iterator pos) {
456 return (list_node*) erase_after(__slist_previous(&head, pos.node));
458 iterator erase(iterator first, iterator last) {
459 return (list_node*) erase_after(__slist_previous(&head, first.node),
460 last.node);
463 void resize(size_type new_size, const T& x);
464 void resize(size_type new_size) { resize(new_size, T()); }
465 void clear() { erase_after(&head, 0); }
467 public:
468 // Moves the range [before_first + 1, before_last + 1) to *this,
469 // inserting it immediately after pos. This is constant time.
470 void splice_after(iterator pos,
471 iterator before_first, iterator before_last)
473 if (before_first != before_last)
474 __slist_splice_after(pos.node, before_first.node, before_last.node);
477 // Moves the element that follows prev to *this, inserting it immediately
478 // after pos. This is constant time.
479 void splice_after(iterator pos, iterator prev)
481 __slist_splice_after(pos.node, prev.node, prev.node->next);
485 // Linear in distance(begin(), pos), and linear in L.size().
486 void splice(iterator pos, slist& L) {
487 if (L.head.next)
488 __slist_splice_after(__slist_previous(&head, pos.node),
489 &L.head,
490 __slist_previous(&L.head, 0));
493 // Linear in distance(begin(), pos), and in distance(L.begin(), i).
494 void splice(iterator pos, slist& L, iterator i) {
495 __slist_splice_after(__slist_previous(&head, pos.node),
496 __slist_previous(&L.head, i.node),
497 i.node);
500 // Linear in distance(begin(), pos), in distance(L.begin(), first),
501 // and in distance(first, last).
502 void splice(iterator pos, slist& L, iterator first, iterator last)
504 if (first != last)
505 __slist_splice_after(__slist_previous(&head, pos.node),
506 __slist_previous(&L.head, first.node),
507 __slist_previous(first.node, last.node));
510 public:
511 void reverse() { if (head.next) head.next = __slist_reverse(head.next); }
513 void remove(const T& val);
514 void unique();
515 void merge(slist& L);
516 void sort();
518 #ifdef __STL_MEMBER_TEMPLATES
519 template <class Predicate> void remove_if(Predicate pred);
520 template <class BinaryPredicate> void unique(BinaryPredicate pred);
521 template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering);
522 template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp);
523 #endif /* __STL_MEMBER_TEMPLATES */
526 template <class T, class Alloc>
527 slist<T, Alloc>& slist<T,Alloc>::operator=(const slist<T, Alloc>& L)
529 if (&L != this) {
530 list_node_base* p1 = &head;
531 list_node* n1 = (list_node*) head.next;
532 const list_node* n2 = (const list_node*) L.head.next;
533 while (n1 && n2) {
534 n1->data = n2->data;
535 p1 = n1;
536 n1 = (list_node*) n1->next;
537 n2 = (const list_node*) n2->next;
539 if (n2 == 0)
540 erase_after(p1, 0);
541 else
542 _insert_after_range(p1,
543 const_iterator((list_node*)n2), const_iterator(0));
545 return *this;
548 template <class T, class Alloc>
549 bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
551 typedef typename slist<T,Alloc>::list_node list_node;
552 list_node* n1 = (list_node*) L1.head.next;
553 list_node* n2 = (list_node*) L2.head.next;
554 while (n1 && n2 && n1->data == n2->data) {
555 n1 = (list_node*) n1->next;
556 n2 = (list_node*) n2->next;
558 return n1 == 0 && n2 == 0;
561 template <class T, class Alloc>
562 inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
564 return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end());
567 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
569 template <class T, class Alloc>
570 inline void swap(slist<T, Alloc>& x, slist<T, Alloc>& y) {
571 x.swap(y);
574 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
577 template <class T, class Alloc>
578 void slist<T, Alloc>::resize(size_type len, const T& x)
580 list_node_base* cur = &head;
581 while (cur->next != 0 && len > 0) {
582 --len;
583 cur = cur->next;
585 if (cur->next)
586 erase_after(cur, 0);
587 else
588 _insert_after_fill(cur, len, x);
591 template <class T, class Alloc>
592 void slist<T,Alloc>::remove(const T& val)
594 list_node_base* cur = &head;
595 while (cur && cur->next) {
596 if (((list_node*) cur->next)->data == val)
597 erase_after(cur);
598 else
599 cur = cur->next;
603 template <class T, class Alloc>
604 void slist<T,Alloc>::unique()
606 list_node_base* cur = head.next;
607 if (cur) {
608 while (cur->next) {
609 if (((list_node*)cur)->data == ((list_node*)(cur->next))->data)
610 erase_after(cur);
611 else
612 cur = cur->next;
617 template <class T, class Alloc>
618 void slist<T,Alloc>::merge(slist<T,Alloc>& L)
620 list_node_base* n1 = &head;
621 while (n1->next && L.head.next) {
622 if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data)
623 __slist_splice_after(n1, &L.head, L.head.next);
624 n1 = n1->next;
626 if (L.head.next) {
627 n1->next = L.head.next;
628 L.head.next = 0;
632 template <class T, class Alloc>
633 void slist<T,Alloc>::sort()
635 if (head.next && head.next->next) {
636 slist carry;
637 slist counter[64];
638 int fill = 0;
639 while (!empty()) {
640 __slist_splice_after(&carry.head, &head, head.next);
641 int i = 0;
642 while (i < fill && !counter[i].empty()) {
643 counter[i].merge(carry);
644 carry.swap(counter[i]);
645 ++i;
647 carry.swap(counter[i]);
648 if (i == fill)
649 ++fill;
652 for (int i = 1; i < fill; ++i)
653 counter[i].merge(counter[i-1]);
654 this->swap(counter[fill-1]);
658 #ifdef __STL_MEMBER_TEMPLATES
660 template <class T, class Alloc>
661 template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred)
663 list_node_base* cur = &head;
664 while (cur->next) {
665 if (pred(((list_node*) cur->next)->data))
666 erase_after(cur);
667 else
668 cur = cur->next;
672 template <class T, class Alloc> template <class BinaryPredicate>
673 void slist<T,Alloc>::unique(BinaryPredicate pred)
675 list_node* cur = (list_node*) head.next;
676 if (cur) {
677 while (cur->next) {
678 if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data))
679 erase_after(cur);
680 else
681 cur = (list_node*) cur->next;
686 template <class T, class Alloc> template <class StrictWeakOrdering>
687 void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp)
689 list_node_base* n1 = &head;
690 while (n1->next && L.head.next) {
691 if (comp(((list_node*) L.head.next)->data,
692 ((list_node*) n1->next)->data))
693 __slist_splice_after(n1, &L.head, L.head.next);
694 n1 = n1->next;
696 if (L.head.next) {
697 n1->next = L.head.next;
698 L.head.next = 0;
702 template <class T, class Alloc> template <class StrictWeakOrdering>
703 void slist<T,Alloc>::sort(StrictWeakOrdering comp)
705 if (head.next && head.next->next) {
706 slist carry;
707 slist counter[64];
708 int fill = 0;
709 while (!empty()) {
710 __slist_splice_after(&carry.head, &head, head.next);
711 int i = 0;
712 while (i < fill && !counter[i].empty()) {
713 counter[i].merge(carry, comp);
714 carry.swap(counter[i]);
715 ++i;
717 carry.swap(counter[i]);
718 if (i == fill)
719 ++fill;
722 for (int i = 1; i < fill; ++i)
723 counter[i].merge(counter[i-1], comp);
724 this->swap(counter[fill-1]);
728 #endif /* __STL_MEMBER_TEMPLATES */
730 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
731 #pragma reset woff 1174
732 #endif
734 __STL_END_NAMESPACE
736 #endif /* __SGI_STL_INTERNAL_SLIST_H */
738 // Local Variables:
739 // mode:C++
740 // End: