Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | /* |
2 | * |
||
3 | * Copyright (c) 1994 |
||
4 | * Hewlett-Packard Company |
||
5 | * |
||
6 | * Permission to use, copy, modify, distribute and sell this software |
||
7 | * and its documentation for any purpose is hereby granted without fee, |
||
8 | * provided that the above copyright notice appear in all copies and |
||
9 | * that both that copyright notice and this permission notice appear |
||
10 | * in supporting documentation. Hewlett-Packard Company makes no |
||
11 | * representations about the suitability of this software for any |
||
12 | * purpose. It is provided "as is" without express or implied warranty. |
||
13 | * |
||
14 | * |
||
15 | * Copyright (c) 1996,1997 |
||
16 | * Silicon Graphics Computer Systems, Inc. |
||
17 | * |
||
18 | * Permission to use, copy, modify, distribute and sell this software |
||
19 | * and its documentation for any purpose is hereby granted without fee, |
||
20 | * provided that the above copyright notice appear in all copies and |
||
21 | * that both that copyright notice and this permission notice appear |
||
22 | * in supporting documentation. Silicon Graphics makes no |
||
23 | * representations about the suitability of this software for any |
||
24 | * purpose. It is provided "as is" without express or implied warranty. |
||
25 | */ |
||
26 | |||
27 | /* NOTE: This is an internal header file, included by other STL headers. |
||
28 | * You should not attempt to use it directly. |
||
29 | */ |
||
30 | |||
31 | #ifndef __SGI_STL_INTERNAL_LIST_H |
||
32 | #define __SGI_STL_INTERNAL_LIST_H |
||
33 | |||
34 | #include |
||
35 | |||
36 | namespace std |
||
37 | { |
||
38 | |||
39 | struct _List_node_base { |
||
40 | _List_node_base* _M_next; |
||
41 | _List_node_base* _M_prev; |
||
42 | }; |
||
43 | |||
44 | template |
||
45 | struct _List_node : public _List_node_base { |
||
46 | _Tp _M_data; |
||
47 | }; |
||
48 | |||
49 | struct _List_iterator_base { |
||
50 | typedef size_t size_type; |
||
51 | typedef ptrdiff_t difference_type; |
||
52 | typedef bidirectional_iterator_tag iterator_category; |
||
53 | |||
54 | _List_node_base* _M_node; |
||
55 | |||
56 | _List_iterator_base(_List_node_base* __x) : _M_node(__x) {} |
||
57 | _List_iterator_base() {} |
||
58 | |||
59 | void _M_incr() { _M_node = _M_node->_M_next; } |
||
60 | void _M_decr() { _M_node = _M_node->_M_prev; } |
||
61 | |||
62 | bool operator==(const _List_iterator_base& __x) const { |
||
63 | return _M_node == __x._M_node; |
||
64 | } |
||
65 | bool operator!=(const _List_iterator_base& __x) const { |
||
66 | return _M_node != __x._M_node; |
||
67 | } |
||
68 | }; |
||
69 | |||
70 | template |
||
71 | struct _List_iterator : public _List_iterator_base { |
||
72 | typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; |
||
73 | typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; |
||
74 | typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; |
||
75 | |||
76 | typedef _Tp value_type; |
||
77 | typedef _Ptr pointer; |
||
78 | typedef _Ref reference; |
||
79 | typedef _List_node<_Tp> _Node; |
||
80 | |||
81 | _List_iterator(_Node* __x) : _List_iterator_base(__x) {} |
||
82 | _List_iterator() {} |
||
83 | _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {} |
||
84 | |||
85 | reference operator*() const { return ((_Node*) _M_node)->_M_data; } |
||
86 | pointer operator->() const { return &(operator*()); } |
||
87 | |||
88 | _Self& operator++() { |
||
89 | this->_M_incr(); |
||
90 | return *this; |
||
91 | } |
||
92 | _Self operator++(int) { |
||
93 | _Self __tmp = *this; |
||
94 | this->_M_incr(); |
||
95 | return __tmp; |
||
96 | } |
||
97 | _Self& operator--() { |
||
98 | this->_M_decr(); |
||
99 | return *this; |
||
100 | } |
||
101 | _Self operator--(int) { |
||
102 | _Self __tmp = *this; |
||
103 | this->_M_decr(); |
||
104 | return __tmp; |
||
105 | } |
||
106 | }; |
||
107 | |||
108 | |||
109 | // Base class that encapsulates details of allocators. Three cases: |
||
110 | // an ordinary standard-conforming allocator, a standard-conforming |
||
111 | // allocator with no non-static data, and an SGI-style allocator. |
||
112 | // This complexity is necessary only because we're worrying about backward |
||
113 | // compatibility and because we want to avoid wasting storage on an |
||
114 | // allocator instance if it isn't necessary. |
||
115 | |||
116 | |||
117 | // Base for general standard-conforming allocators. |
||
118 | template |
||
119 | class _List_alloc_base { |
||
120 | public: |
||
121 | typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type |
||
122 | allocator_type; |
||
123 | allocator_type get_allocator() const { return _Node_allocator; } |
||
124 | |||
125 | _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {} |
||
126 | |||
127 | protected: |
||
128 | _List_node<_Tp>* _M_get_node() |
||
129 | { return _Node_allocator.allocate(1); } |
||
130 | void _M_put_node(_List_node<_Tp>* __p) |
||
131 | { _Node_allocator.deallocate(__p, 1); } |
||
132 | |||
133 | protected: |
||
134 | typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type |
||
135 | _Node_allocator; |
||
136 | _List_node<_Tp>* _M_node; |
||
137 | }; |
||
138 | |||
139 | // Specialization for instanceless allocators. |
||
140 | |||
141 | template |
||
142 | class _List_alloc_base<_Tp, _Allocator, true> { |
||
143 | public: |
||
144 | typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type |
||
145 | allocator_type; |
||
146 | allocator_type get_allocator() const { return allocator_type(); } |
||
147 | |||
148 | _List_alloc_base(const allocator_type&) {} |
||
149 | |||
150 | protected: |
||
151 | typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type |
||
152 | _Alloc_type; |
||
153 | _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } |
||
154 | void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } |
||
155 | |||
156 | protected: |
||
157 | _List_node<_Tp>* _M_node; |
||
158 | }; |
||
159 | |||
160 | template |
||
161 | class _List_base |
||
162 | : public _List_alloc_base<_Tp, _Alloc, |
||
163 | _Alloc_traits<_Tp, _Alloc>::_S_instanceless> |
||
164 | { |
||
165 | public: |
||
166 | typedef _List_alloc_base<_Tp, _Alloc, |
||
167 | _Alloc_traits<_Tp, _Alloc>::_S_instanceless> |
||
168 | _Base; |
||
169 | typedef typename _Base::allocator_type allocator_type; |
||
170 | |||
171 | _List_base(const allocator_type& __a) : _Base(__a) { |
||
172 | _M_node = _M_get_node(); |
||
173 | _M_node->_M_next = _M_node; |
||
174 | _M_node->_M_prev = _M_node; |
||
175 | } |
||
176 | ~_List_base() { |
||
177 | clear(); |
||
178 | _M_put_node(_M_node); |
||
179 | } |
||
180 | |||
181 | void clear(); |
||
182 | }; |
||
183 | |||
184 | |||
185 | template |
||
186 | void |
||
187 | _List_base<_Tp,_Alloc>::clear() |
||
188 | { |
||
189 | _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next; |
||
190 | while (__cur != _M_node) { |
||
191 | _List_node<_Tp>* __tmp = __cur; |
||
192 | __cur = (_List_node<_Tp>*) __cur->_M_next; |
||
193 | _Destroy(&__tmp->_M_data); |
||
194 | _M_put_node(__tmp); |
||
195 | } |
||
196 | _M_node->_M_next = _M_node; |
||
197 | _M_node->_M_prev = _M_node; |
||
198 | } |
||
199 | |||
200 | template |
||
201 | class list : protected _List_base<_Tp, _Alloc> |
||
202 | { |
||
203 | // concept requirements |
||
204 | __glibcpp_class_requires(_Tp, _SGIAssignableConcept); |
||
205 | |||
206 | typedef _List_base<_Tp, _Alloc> _Base; |
||
207 | protected: |
||
208 | typedef void* _Void_pointer; |
||
209 | |||
210 | public: |
||
211 | typedef _Tp value_type; |
||
212 | typedef value_type* pointer; |
||
213 | typedef const value_type* const_pointer; |
||
214 | typedef value_type& reference; |
||
215 | typedef const value_type& const_reference; |
||
216 | typedef _List_node<_Tp> _Node; |
||
217 | typedef size_t size_type; |
||
218 | typedef ptrdiff_t difference_type; |
||
219 | |||
220 | typedef typename _Base::allocator_type allocator_type; |
||
221 | allocator_type get_allocator() const { return _Base::get_allocator(); } |
||
222 | |||
223 | public: |
||
224 | typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; |
||
225 | typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; |
||
226 | |||
227 | typedef reverse_iterator |
||
228 | typedef reverse_iterator |
||
229 | |||
230 | protected: |
||
231 | using _Base::_M_node; |
||
232 | using _Base::_M_put_node; |
||
233 | using _Base::_M_get_node; |
||
234 | |||
235 | protected: |
||
236 | _Node* _M_create_node(const _Tp& __x) |
||
237 | { |
||
238 | _Node* __p = _M_get_node(); |
||
239 | __STL_TRY { |
||
240 | _Construct(&__p->_M_data, __x); |
||
241 | } |
||
242 | __STL_UNWIND(_M_put_node(__p)); |
||
243 | return __p; |
||
244 | } |
||
245 | |||
246 | _Node* _M_create_node() |
||
247 | { |
||
248 | _Node* __p = _M_get_node(); |
||
249 | __STL_TRY { |
||
250 | _Construct(&__p->_M_data); |
||
251 | } |
||
252 | __STL_UNWIND(_M_put_node(__p)); |
||
253 | return __p; |
||
254 | } |
||
255 | |||
256 | public: |
||
257 | explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {} |
||
258 | |||
259 | iterator begin() { return (_Node*)(_M_node->_M_next); } |
||
260 | const_iterator begin() const { return (_Node*)(_M_node->_M_next); } |
||
261 | |||
262 | iterator end() { return _M_node; } |
||
263 | const_iterator end() const { return _M_node; } |
||
264 | |||
265 | reverse_iterator rbegin() |
||
266 | { return reverse_iterator(end()); } |
||
267 | const_reverse_iterator rbegin() const |
||
268 | { return const_reverse_iterator(end()); } |
||
269 | |||
270 | reverse_iterator rend() |
||
271 | { return reverse_iterator(begin()); } |
||
272 | const_reverse_iterator rend() const |
||
273 | { return const_reverse_iterator(begin()); } |
||
274 | |||
275 | bool empty() const { return _M_node->_M_next == _M_node; } |
||
276 | size_type size() const { |
||
277 | size_type __result = 0; |
||
278 | distance(begin(), end(), __result); |
||
279 | return __result; |
||
280 | } |
||
281 | size_type max_size() const { return size_type(-1); } |
||
282 | |||
283 | reference front() { return *begin(); } |
||
284 | const_reference front() const { return *begin(); } |
||
285 | reference back() { return *(--end()); } |
||
286 | const_reference back() const { return *(--end()); } |
||
287 | |||
288 | void swap(list<_Tp, _Alloc>& __x) { std::swap(_M_node, __x._M_node); } |
||
289 | |||
290 | iterator insert(iterator __position, const _Tp& __x) { |
||
291 | _Node* __tmp = _M_create_node(__x); |
||
292 | __tmp->_M_next = __position._M_node; |
||
293 | __tmp->_M_prev = __position._M_node->_M_prev; |
||
294 | __position._M_node->_M_prev->_M_next = __tmp; |
||
295 | __position._M_node->_M_prev = __tmp; |
||
296 | return __tmp; |
||
297 | } |
||
298 | iterator insert(iterator __position) { return insert(__position, _Tp()); } |
||
299 | |||
300 | // Check whether it's an integral type. If so, it's not an iterator. |
||
301 | template |
||
302 | void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, |
||
303 | __true_type) { |
||
304 | _M_fill_insert(__pos, (size_type) __n, (_Tp) __x); |
||
305 | } |
||
306 | |||
307 | template |
||
308 | void _M_insert_dispatch(iterator __pos, |
||
309 | _InputIterator __first, _InputIterator __last, |
||
310 | __false_type); |
||
311 | |||
312 | template |
||
313 | void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { |
||
314 | typedef typename _Is_integer<_InputIterator>::_Integral _Integral; |
||
315 | _M_insert_dispatch(__pos, __first, __last, _Integral()); |
||
316 | } |
||
317 | |||
318 | void insert(iterator __pos, size_type __n, const _Tp& __x) |
||
319 | { _M_fill_insert(__pos, __n, __x); } |
||
320 | void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x); |
||
321 | |||
322 | void push_front(const _Tp& __x) { insert(begin(), __x); } |
||
323 | void push_front() {insert(begin());} |
||
324 | void push_back(const _Tp& __x) { insert(end(), __x); } |
||
325 | void push_back() {insert(end());} |
||
326 | |||
327 | iterator erase(iterator __position) { |
||
328 | _List_node_base* __next_node = __position._M_node->_M_next; |
||
329 | _List_node_base* __prev_node = __position._M_node->_M_prev; |
||
330 | _Node* __n = (_Node*) __position._M_node; |
||
331 | __prev_node->_M_next = __next_node; |
||
332 | __next_node->_M_prev = __prev_node; |
||
333 | _Destroy(&__n->_M_data); |
||
334 | _M_put_node(__n); |
||
335 | return iterator((_Node*) __next_node); |
||
336 | } |
||
337 | iterator erase(iterator __first, iterator __last); |
||
338 | void clear() { _Base::clear(); } |
||
339 | |||
340 | void resize(size_type __new_size, const _Tp& __x); |
||
341 | void resize(size_type __new_size) { this->resize(__new_size, _Tp()); } |
||
342 | |||
343 | void pop_front() { erase(begin()); } |
||
344 | void pop_back() { |
||
345 | iterator __tmp = end(); |
||
346 | erase(--__tmp); |
||
347 | } |
||
348 | list(size_type __n, const _Tp& __value, |
||
349 | const allocator_type& __a = allocator_type()) |
||
350 | : _Base(__a) |
||
351 | { insert(begin(), __n, __value); } |
||
352 | explicit list(size_type __n) |
||
353 | : _Base(allocator_type()) |
||
354 | { insert(begin(), __n, _Tp()); } |
||
355 | |||
356 | // We don't need any dispatching tricks here, because insert does all of |
||
357 | // that anyway. |
||
358 | template |
||
359 | list(_InputIterator __first, _InputIterator __last, |
||
360 | const allocator_type& __a = allocator_type()) |
||
361 | : _Base(__a) |
||
362 | { insert(begin(), __first, __last); } |
||
363 | |||
364 | list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator()) |
||
365 | { insert(begin(), __x.begin(), __x.end()); } |
||
366 | |||
367 | ~list() { } |
||
368 | |||
369 | list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x); |
||
370 | |||
371 | public: |
||
372 | // assign(), a generalized assignment member function. Two |
||
373 | // versions: one that takes a count, and one that takes a range. |
||
374 | // The range version is a member template, so we dispatch on whether |
||
375 | // or not the type is an integer. |
||
376 | |||
377 | void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } |
||
378 | |||
379 | void _M_fill_assign(size_type __n, const _Tp& __val); |
||
380 | |||
381 | template |
||
382 | void assign(_InputIterator __first, _InputIterator __last) { |
||
383 | typedef typename _Is_integer<_InputIterator>::_Integral _Integral; |
||
384 | _M_assign_dispatch(__first, __last, _Integral()); |
||
385 | } |
||
386 | |||
387 | template |
||
388 | void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) |
||
389 | { _M_fill_assign((size_type) __n, (_Tp) __val); } |
||
390 | |||
391 | template |
||
392 | void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, |
||
393 | __false_type); |
||
394 | |||
395 | protected: |
||
396 | void transfer(iterator __position, iterator __first, iterator __last) { |
||
397 | if (__position != __last) { |
||
398 | // Remove [first, last) from its old position. |
||
399 | __last._M_node->_M_prev->_M_next = __position._M_node; |
||
400 | __first._M_node->_M_prev->_M_next = __last._M_node; |
||
401 | __position._M_node->_M_prev->_M_next = __first._M_node; |
||
402 | |||
403 | // Splice [first, last) into its new position. |
||
404 | _List_node_base* __tmp = __position._M_node->_M_prev; |
||
405 | __position._M_node->_M_prev = __last._M_node->_M_prev; |
||
406 | __last._M_node->_M_prev = __first._M_node->_M_prev; |
||
407 | __first._M_node->_M_prev = __tmp; |
||
408 | } |
||
409 | } |
||
410 | |||
411 | public: |
||
412 | void splice(iterator __position, list& __x) { |
||
413 | if (!__x.empty()) |
||
414 | this->transfer(__position, __x.begin(), __x.end()); |
||
415 | } |
||
416 | void splice(iterator __position, list&, iterator __i) { |
||
417 | iterator __j = __i; |
||
418 | ++__j; |
||
419 | if (__position == __i || __position == __j) return; |
||
420 | this->transfer(__position, __i, __j); |
||
421 | } |
||
422 | void splice(iterator __position, list&, iterator __first, iterator __last) { |
||
423 | if (__first != __last) |
||
424 | this->transfer(__position, __first, __last); |
||
425 | } |
||
426 | void remove(const _Tp& __value); |
||
427 | void unique(); |
||
428 | void merge(list& __x); |
||
429 | void reverse(); |
||
430 | void sort(); |
||
431 | |||
432 | template |
||
433 | template |
||
434 | template |
||
435 | template |
||
436 | }; |
||
437 | |||
438 | template |
||
439 | inline bool |
||
440 | operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) |
||
441 | { |
||
442 | typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; |
||
443 | const_iterator __end1 = __x.end(); |
||
444 | const_iterator __end2 = __y.end(); |
||
445 | |||
446 | const_iterator __i1 = __x.begin(); |
||
447 | const_iterator __i2 = __y.begin(); |
||
448 | while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { |
||
449 | ++__i1; |
||
450 | ++__i2; |
||
451 | } |
||
452 | return __i1 == __end1 && __i2 == __end2; |
||
453 | } |
||
454 | |||
455 | template |
||
456 | inline bool operator<(const list<_Tp,_Alloc>& __x, |
||
457 | const list<_Tp,_Alloc>& __y) |
||
458 | { |
||
459 | return lexicographical_compare(__x.begin(), __x.end(), |
||
460 | __y.begin(), __y.end()); |
||
461 | } |
||
462 | |||
463 | template |
||
464 | inline bool operator!=(const list<_Tp,_Alloc>& __x, |
||
465 | const list<_Tp,_Alloc>& __y) { |
||
466 | return !(__x == __y); |
||
467 | } |
||
468 | |||
469 | template |
||
470 | inline bool operator>(const list<_Tp,_Alloc>& __x, |
||
471 | const list<_Tp,_Alloc>& __y) { |
||
472 | return __y < __x; |
||
473 | } |
||
474 | |||
475 | template |
||
476 | inline bool operator<=(const list<_Tp,_Alloc>& __x, |
||
477 | const list<_Tp,_Alloc>& __y) { |
||
478 | return !(__y < __x); |
||
479 | } |
||
480 | |||
481 | template |
||
482 | inline bool operator>=(const list<_Tp,_Alloc>& __x, |
||
483 | const list<_Tp,_Alloc>& __y) { |
||
484 | return !(__x < __y); |
||
485 | } |
||
486 | |||
487 | template |
||
488 | inline void |
||
489 | swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) |
||
490 | { |
||
491 | __x.swap(__y); |
||
492 | } |
||
493 | |||
494 | template |
||
495 | void |
||
496 | list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position, |
||
497 | _InputIter __first, _InputIter __last, |
||
498 | __false_type) |
||
499 | { |
||
500 | for ( ; __first != __last; ++__first) |
||
501 | insert(__position, *__first); |
||
502 | } |
||
503 | |||
504 | template |
||
505 | void |
||
506 | list<_Tp, _Alloc>::_M_fill_insert(iterator __position, |
||
507 | size_type __n, const _Tp& __x) |
||
508 | { |
||
509 | for ( ; __n > 0; --__n) |
||
510 | insert(__position, __x); |
||
511 | } |
||
512 | |||
513 | template |
||
514 | typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, |
||
515 | iterator __last) |
||
516 | { |
||
517 | while (__first != __last) |
||
518 | erase(__first++); |
||
519 | return __last; |
||
520 | } |
||
521 | |||
522 | template |
||
523 | void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) |
||
524 | { |
||
525 | iterator __i = begin(); |
||
526 | size_type __len = 0; |
||
527 | for ( ; __i != end() && __len < __new_size; ++__i, ++__len) |
||
528 | ; |
||
529 | if (__len == __new_size) |
||
530 | erase(__i, end()); |
||
531 | else // __i == end() |
||
532 | insert(end(), __new_size - __len, __x); |
||
533 | } |
||
534 | |||
535 | template |
||
536 | list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) |
||
537 | { |
||
538 | if (this != &__x) { |
||
539 | iterator __first1 = begin(); |
||
540 | iterator __last1 = end(); |
||
541 | const_iterator __first2 = __x.begin(); |
||
542 | const_iterator __last2 = __x.end(); |
||
543 | while (__first1 != __last1 && __first2 != __last2) |
||
544 | *__first1++ = *__first2++; |
||
545 | if (__first2 == __last2) |
||
546 | erase(__first1, __last1); |
||
547 | else |
||
548 | insert(__last1, __first2, __last2); |
||
549 | } |
||
550 | return *this; |
||
551 | } |
||
552 | |||
553 | template |
||
554 | void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { |
||
555 | iterator __i = begin(); |
||
556 | for ( ; __i != end() && __n > 0; ++__i, --__n) |
||
557 | *__i = __val; |
||
558 | if (__n > 0) |
||
559 | insert(end(), __n, __val); |
||
560 | else |
||
561 | erase(__i, end()); |
||
562 | } |
||
563 | |||
564 | template |
||
565 | void |
||
566 | list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2, |
||
567 | __false_type) |
||
568 | { |
||
569 | iterator __first1 = begin(); |
||
570 | iterator __last1 = end(); |
||
571 | for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) |
||
572 | *__first1 = *__first2; |
||
573 | if (__first2 == __last2) |
||
574 | erase(__first1, __last1); |
||
575 | else |
||
576 | insert(__last1, __first2, __last2); |
||
577 | } |
||
578 | |||
579 | template |
||
580 | void list<_Tp, _Alloc>::remove(const _Tp& __value) |
||
581 | { |
||
582 | iterator __first = begin(); |
||
583 | iterator __last = end(); |
||
584 | while (__first != __last) { |
||
585 | iterator __next = __first; |
||
586 | ++__next; |
||
587 | if (*__first == __value) erase(__first); |
||
588 | __first = __next; |
||
589 | } |
||
590 | } |
||
591 | |||
592 | template |
||
593 | void list<_Tp, _Alloc>::unique() |
||
594 | { |
||
595 | iterator __first = begin(); |
||
596 | iterator __last = end(); |
||
597 | if (__first == __last) return; |
||
598 | iterator __next = __first; |
||
599 | while (++__next != __last) { |
||
600 | if (*__first == *__next) |
||
601 | erase(__next); |
||
602 | else |
||
603 | __first = __next; |
||
604 | __next = __first; |
||
605 | } |
||
606 | } |
||
607 | |||
608 | template |
||
609 | void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x) |
||
610 | { |
||
611 | iterator __first1 = begin(); |
||
612 | iterator __last1 = end(); |
||
613 | iterator __first2 = __x.begin(); |
||
614 | iterator __last2 = __x.end(); |
||
615 | while (__first1 != __last1 && __first2 != __last2) |
||
616 | if (*__first2 < *__first1) { |
||
617 | iterator __next = __first2; |
||
618 | transfer(__first1, __first2, ++__next); |
||
619 | __first2 = __next; |
||
620 | } |
||
621 | else |
||
622 | ++__first1; |
||
623 | if (__first2 != __last2) transfer(__last1, __first2, __last2); |
||
624 | } |
||
625 | |||
626 | inline void __List_base_reverse(_List_node_base* __p) |
||
627 | { |
||
628 | _List_node_base* __tmp = __p; |
||
629 | do { |
||
630 | std::swap(__tmp->_M_next, __tmp->_M_prev); |
||
631 | __tmp = __tmp->_M_prev; // Old next node is now prev. |
||
632 | } while (__tmp != __p); |
||
633 | } |
||
634 | |||
635 | template |
||
636 | inline void list<_Tp, _Alloc>::reverse() |
||
637 | { |
||
638 | __List_base_reverse(this->_M_node); |
||
639 | } |
||
640 | |||
641 | template |
||
642 | void list<_Tp, _Alloc>::sort() |
||
643 | { |
||
644 | // Do nothing if the list has length 0 or 1. |
||
645 | if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { |
||
646 | list<_Tp, _Alloc> __carry; |
||
647 | list<_Tp, _Alloc> __counter[64]; |
||
648 | int __fill = 0; |
||
649 | while (!empty()) { |
||
650 | __carry.splice(__carry.begin(), *this, begin()); |
||
651 | int __i = 0; |
||
652 | while(__i < __fill && !__counter[__i].empty()) { |
||
653 | __counter[__i].merge(__carry); |
||
654 | __carry.swap(__counter[__i++]); |
||
655 | } |
||
656 | __carry.swap(__counter[__i]); |
||
657 | if (__i == __fill) ++__fill; |
||
658 | } |
||
659 | |||
660 | for (int __i = 1; __i < __fill; ++__i) |
||
661 | __counter[__i].merge(__counter[__i-1]); |
||
662 | swap(__counter[__fill-1]); |
||
663 | } |
||
664 | } |
||
665 | |||
666 | template |
||
667 | void list<_Tp, _Alloc>::remove_if(_Predicate __pred) |
||
668 | { |
||
669 | iterator __first = begin(); |
||
670 | iterator __last = end(); |
||
671 | while (__first != __last) { |
||
672 | iterator __next = __first; |
||
673 | ++__next; |
||
674 | if (__pred(*__first)) erase(__first); |
||
675 | __first = __next; |
||
676 | } |
||
677 | } |
||
678 | |||
679 | template |
||
680 | void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) |
||
681 | { |
||
682 | iterator __first = begin(); |
||
683 | iterator __last = end(); |
||
684 | if (__first == __last) return; |
||
685 | iterator __next = __first; |
||
686 | while (++__next != __last) { |
||
687 | if (__binary_pred(*__first, *__next)) |
||
688 | erase(__next); |
||
689 | else |
||
690 | __first = __next; |
||
691 | __next = __first; |
||
692 | } |
||
693 | } |
||
694 | |||
695 | template |
||
696 | void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x, |
||
697 | _StrictWeakOrdering __comp) |
||
698 | { |
||
699 | iterator __first1 = begin(); |
||
700 | iterator __last1 = end(); |
||
701 | iterator __first2 = __x.begin(); |
||
702 | iterator __last2 = __x.end(); |
||
703 | while (__first1 != __last1 && __first2 != __last2) |
||
704 | if (__comp(*__first2, *__first1)) { |
||
705 | iterator __next = __first2; |
||
706 | transfer(__first1, __first2, ++__next); |
||
707 | __first2 = __next; |
||
708 | } |
||
709 | else |
||
710 | ++__first1; |
||
711 | if (__first2 != __last2) transfer(__last1, __first2, __last2); |
||
712 | } |
||
713 | |||
714 | template |
||
715 | void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) |
||
716 | { |
||
717 | // Do nothing if the list has length 0 or 1. |
||
718 | if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { |
||
719 | list<_Tp, _Alloc> __carry; |
||
720 | list<_Tp, _Alloc> __counter[64]; |
||
721 | int __fill = 0; |
||
722 | while (!empty()) { |
||
723 | __carry.splice(__carry.begin(), *this, begin()); |
||
724 | int __i = 0; |
||
725 | while(__i < __fill && !__counter[__i].empty()) { |
||
726 | __counter[__i].merge(__carry, __comp); |
||
727 | __carry.swap(__counter[__i++]); |
||
728 | } |
||
729 | __carry.swap(__counter[__i]); |
||
730 | if (__i == __fill) ++__fill; |
||
731 | } |
||
732 | |||
733 | for (int __i = 1; __i < __fill; ++__i) |
||
734 | __counter[__i].merge(__counter[__i-1], __comp); |
||
735 | swap(__counter[__fill-1]); |
||
736 | } |
||
737 | } |
||
738 | |||
739 | } // namespace std |
||
740 | |||
741 | #endif /* __SGI_STL_INTERNAL_LIST_H */ |
||
742 | |||
743 | // Local Variables: |
||
744 | // mode:C++ |
||
745 | // End:>>>>>>>>=(const>>(const> |