Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
list.cc
Go to the documentation of this file.
1
44
45template <class _TypeT, class _Allocator>
46list<_TypeT, _Allocator>::
47~list ()
48{
49 if (_C_node) {
50 clear ();
51 _C_put_node (_C_node);
52 _RWSTD_NODE_LIST_FREE ();
53 }
54}
55
56
57template <class _TypeT, class _Allocator>
58typename list<_TypeT, _Allocator>::iterator
59list<_TypeT, _Allocator>::erase (iterator __first, iterator __last)
60{
61 _RWSTD_ASSERT_RANGE (begin (), __first);
62 _RWSTD_ASSERT_RANGE (__first, __last);
63
64 while (!(__first == __last)) {
65 __first = erase (__first);
66 }
67
68 return __first;
69}
70
71
72#if !defined (_RWSTD_NO_LIST_NODE_BUFFER)
73
74template <class _TypeT, class _Allocator>
75void list<_TypeT, _Allocator>::_C_add_buffer (bool __is_list_empty)
76{
77 // empty list gets one node
78 _RWSTD_SIZE_T __next_buffer_size = 1;
79 if(!__is_list_empty) {
80 if ((void*)_C_buflist) {
81 __next_buffer_size =
82 _RWSTD_NEW_CAPACITY (list, this, _C_buflist->_C_bufsize);
83 }
84 else {
85 __next_buffer_size = _RWSTD_NEW_CAPACITY (list, this, 0);
86 }
87 }
88 _C_buf_pointer __tmp =
89 _C_buf_alloc_type (*this).allocate (1, (void*)_C_buflist);
90
91 _TRY {
92 __tmp->_C_buffer =
93 _C_node_alloc_type (*this).allocate (__next_buffer_size,
94 (void*)_C_last);
95 }
96 _CATCH (...) {
97 _C_buf_alloc_type (*this).deallocate (__tmp, 1);
99 }
100
101 __tmp->_C_next_buf = _C_buflist;
102 __tmp->_C_bufsize = __next_buffer_size;
103
104 _C_buflist = __tmp;
105 _C_next_avail = _C_buflist->_C_buffer;
106 _C_last = _C_next_avail + __next_buffer_size;
107}
108
109
110template <class _TypeT, class _Allocator>
111void list<_TypeT, _Allocator>::_C_free_buffers ()
112{
113 while ((void*)_C_buflist) {
114 _C_buf_pointer __tmp = _C_buflist;
115 _C_buflist = _C_buflist->_C_next_buf;
116 _C_node_alloc_type (*this).deallocate (__tmp->_C_buffer,
117 __tmp->_C_bufsize);
118 _C_buf_alloc_type (*this).deallocate (__tmp, 1);
119 }
120 _C_free_list = 0;
121 _C_next_avail = 0;
122 _C_last = 0;
123}
124
125#endif // defined (_RWSTD_NO_LIST_NODE_BUFFER)
126
127
128template <class _TypeT, class _Allocator>
129void list<_TypeT, _Allocator>::_C_transfer (iterator __it, iterator __first,
130 iterator __last, list& __x)
131{
132 _RWSTD_ASSERT_RANGE (begin (), __it);
133 _RWSTD_ASSERT_RANGE (__first, __last);
134
135 if (this == &__x) {
136 (*(_C_link_type ((*_ITER_NODE (__last))._C_prev)))._C_next =
137 _ITER_NODE (__it);
138 (*(_C_link_type ((*_ITER_NODE (__first))._C_prev)))._C_next =
139 _ITER_NODE (__last);
140 (*(_C_link_type ((*_ITER_NODE (__it))._C_prev)))._C_next =
141 _ITER_NODE (__first);
142
143 _C_link_type __tmp = _C_link_type ((*_ITER_NODE (__it))._C_prev);
144
145 (*_ITER_NODE (__it))._C_prev = (*_ITER_NODE (__last))._C_prev;
146 (*_ITER_NODE (__last))._C_prev = (*_ITER_NODE (__first))._C_prev;
147 (*_ITER_NODE (__first))._C_prev = __tmp;
148 }
149 else {
150 insert (__it, __first, __last);
151 __x.erase (__first, __last);
152 }
153}
154
155
156template <class _TypeT, class _Allocator>
157void list<_TypeT, _Allocator>::resize (size_type __size, _TypeT __val)
158{
159 if (__size > size ())
160 insert (end (), __size - size (), __val);
161 else if (__size < size ()) {
162 iterator __tmp = begin ();
163 advance (__tmp, __size);
164 erase (__tmp, end ());
165 }
166}
167
168
169template <class _TypeT, class _Allocator>
170list<_TypeT, _Allocator>&
171list<_TypeT, _Allocator>::operator= (const list<_TypeT, _Allocator>& __rhs)
172{
173 if (this != &__rhs) {
174 iterator __first1 = begin ();
175 iterator __last1 = end ();
176 const_iterator __first2 = __rhs.begin ();
177 const_iterator __last2 = __rhs.end ();
178
179 for ( ; !(__first1 == __last1) && !(__first2 == __last2);
180 ++__first1, ++__first2)
181 *__first1 = *__first2;
182
183 if (__first2 == __last2)
184 erase (__first1, __last1);
185 else
186 insert (__last1, __first2, __last2);
187 }
188 return *this;
189}
190
191
192template <class _TypeT, class _Allocator>
193void list<_TypeT, _Allocator>::splice (iterator __it, list &__x)
194{
195 // assert 23.2.2.4, p3
196 _RWSTD_ASSERT (&__x != this);
197 _RWSTD_ASSERT_RANGE (begin (), __it);
198
199
200#if !defined (_RWSTD_NO_LIST_NODE_BUFFER)
201 // linear complexity
202 insert (__it, __x.begin (), __x.end ());
203 __x.clear ();
204#else
205 if (get_allocator () == __x.get_allocator ()) {
206
207 // constant complexity
208
209 // relink `it' and the head of `x'
210 (*(_C_link_type ((*_ITER_NODE (__it))._C_prev)))._C_next =
211 __x._C_node->_C_next;
212
213 __x._C_node->_C_next->_C_prev = (*_ITER_NODE (__it))._C_prev;
214 (*_ITER_NODE (__it))._C_prev = __x._C_node->_C_prev;
215 __x._C_node->_C_prev->_C_next = _ITER_NODE (__it);
216
217 // empty out `x'
218 __x._C_node->_C_next =
219 __x._C_node->_C_prev = __x._C_node;
220
221 // adjust sizes
222 _C_length += __x._C_length;
223 __x._C_length = 0;
224 }
225 else {
226 // linear complexity
227 insert (__it, __x.begin (), __x.end ());
228 __x.clear ();
229 }
230#endif // _RWSTD_NO_LIST_NODE_BUFFER
231}
232
233
234template <class _TypeT, class _Allocator>
235void list<_TypeT, _Allocator>::splice (iterator __i, list &__x, iterator __j)
236{
237 _RWSTD_ASSERT_RANGE (begin (), __i);
238 _RWSTD_ASSERT_RANGE (__x.begin (), __j);
239
240 if ( !(__x.end () == __j)
241 && !(__i == __j) && !(__i == ++iterator (__j))) {
242
243#if !defined (_RWSTD_NO_LIST_NODE_BUFFER)
244 // linear complexity
245 insert (__i, *__j);
246 __x.erase (__j);
247#else
248 if (get_allocator () == __x.get_allocator ()) {
249
250 // constant complexity
251
252 // relink `i' and `j'
253 (*(_C_link_type ((*_ITER_NODE (__i))._C_prev)))._C_next =
254 _ITER_NODE (__j);
255
256 // save position before `i'
257 _C_link_type __tmp = (*_ITER_NODE (__i))._C_prev;
258
259 (*_ITER_NODE (__i))._C_prev = _ITER_NODE (__j);
260 (*_ITER_NODE (__j))._C_prev->_C_next = (*_ITER_NODE (__j))._C_next;
261 (*_ITER_NODE (__j))._C_next->_C_prev = (*_ITER_NODE (__j))._C_prev;
262
263 (*_ITER_NODE (__j))._C_next = _ITER_NODE (__i);
264 (*_ITER_NODE (__j))._C_prev = __tmp;
265
266 // adjust sizes
267 ++_C_length;
268 --__x._C_length;
269 }
270 else {
271 // linear complexity
272 insert (__i, *__j);
273 __x.erase (__j);
274 }
275#endif // _RWSTD_NO_LIST_NODE_BUFFER
276 }
277}
278
279
280template <class _TypeT, class _Allocator>
281void list<_TypeT, _Allocator>::
282splice (iterator __i, list &__x, iterator __j, iterator __k)
283{
284 _RWSTD_ASSERT_RANGE (begin (), __i);
285 _RWSTD_ASSERT_RANGE (__x.begin (), __j);
286 _RWSTD_ASSERT_RANGE (__j, __k);
287
288 // 23.2.2.4, p12 - check undefined behavior
289 _RWSTD_ASSERT (&__x != this || (__i != __j && __i != __k));
290
291 if (__j == __k)
292 return;
293
294#if !defined (_RWSTD_NO_LIST_NODE_BUFFER)
295 insert (__i, __j, __k);
296 __x.erase (__j, __k);
297#else
298 if (get_allocator () == __x.get_allocator ()) {
299
300# ifdef _RWSTDDEBUG
301
302 for (iterator __it = __j; __it != __k; ++__it) {
303 // 23.2.2.4, p12 - check undefined behavior (linear time)
304 _RWSTD_ASSERT (&__x != this || __i != __j);
305
306 ++_C_length;
307 --__x._C_length;
308 }
309
310# else // if !defined (_RWSTDDEBUG)
311
312 if (&__x != this) {
313 // adjust sizes first
314 for (iterator __it = __j; __it != __k; ++__it) {
315 ++_C_length;
316 --__x._C_length;
317 }
318 }
319
320# endif // _RWSTDDEBUG
321
322 (*(_C_link_type ((*_ITER_NODE (__k))._C_prev)))._C_next =
323 _ITER_NODE (__i);
324 (*(_C_link_type ((*_ITER_NODE (__j))._C_prev)))._C_next =
325 _ITER_NODE (__k);
326 (*(_C_link_type ((*_ITER_NODE (__i))._C_prev)))._C_next =
327 _ITER_NODE (__j);
328
329 _C_link_type __tmp = _C_link_type ((*_ITER_NODE (__i))._C_prev);
330
331 (*_ITER_NODE (__i))._C_prev = (*_ITER_NODE (__k))._C_prev;
332 (*_ITER_NODE (__k))._C_prev = (*_ITER_NODE (__j))._C_prev;
333 (*_ITER_NODE (__j))._C_prev = __tmp;
334 }
335 else {
336 insert (__i, __j, __k);
337 __x.erase (__j, __k);
338 }
339#endif // _RWSTD_NO_LIST_NODE_BUFFER
340}
341
342template <class _TypeT, class _Allocator>
343void list<_TypeT, _Allocator>::remove (const_reference __val)
344{
345 for (iterator __first = begin (), __last = end (); !(__first == __last); ) {
346 iterator __next = __first;
347 ++__next;
348 if (*__first == __val)
349 erase (__first);
350 __first = __next;
351 }
352}
353
354
355template <class _TypeT, class _Allocator>
356void list<_TypeT, _Allocator>::unique ()
357{
358 iterator __first = begin ();
359 iterator __last = end ();
360
361 if (__first == __last)
362 return;
363
364 iterator __next = __first;
365
366 while (!(++__next == __last)) {
367 if (*__first == *__next)
368 erase (__next);
369 else
370 __first = __next;
371 __next = __first;
372 }
373}
374
375
376template <class _TypeT, class _Allocator>
377void list<_TypeT, _Allocator>::merge (list<_TypeT, _Allocator>& __x)
378{
379 if (&__x == this)
380 return;
381 iterator __first1 = begin ();
382 iterator __last1 = end ();
383 iterator __first2 = __x.begin ();
384 iterator __last2 = __x.end ();
385
386 while (!(__first1 == __last1) && !(__first2 == __last2)) {
387 if (*__first2 < *__first1) {
388 iterator __next = __first2;
389 _C_transfer (__first1, __first2, ++__next, __x);
390 __first2 = __next;
391 }
392 else
393 ++__first1;
394 }
395
396 if (!(__first2 == __last2))
397 _C_transfer (__last1, __first2, __last2, __x);
398}
399
400
401template <class _TypeT, class _Allocator>
402void list<_TypeT, _Allocator>::reverse ()
403{
404 if (size () < 2)
405 return;
406
407 for (iterator __first = ++begin (); !(__first == end ()); ) {
408 iterator __tmp = __first;
409 _C_transfer (begin (), __tmp, ++__first, *this);
410 }
411}
412
413// sorts list by moving nodes within list; preserves iterators pointing to
414// elements of the list.
415template <class _TypeT, class _Allocator>
416void list<_TypeT, _Allocator>::sort ()
417{
418 for (size_type __n = 1; __n < size (); __n *= 2) {
419 iterator __i1 = begin (),
420 __i2 = begin (),
421 __i3 = begin ();
422
423 _C_advance (__i2, (difference_type)__n, end ());
424 _C_advance (__i3, (difference_type)(2 * __n), end ());
425
426 for (size_type __m = 0;
427 __m < (size () + (2 * __n)) / (__n * 2); __m++) {
428
429 if (!(__i1 == end ()) && !(__i2 == end ())) {
430 _C_adjacent_merge (__i1, __i2, __i3);
431 __i1 = __i2 = __i3;
432 _C_advance (__i2, (difference_type) __n, end ());
433 _C_advance (__i3, (difference_type) 2 * __n, end ());
434 }
435 }
436 }
437}
438
439
440template <class _TypeT, class _Allocator>
441void list<_TypeT, _Allocator>::
442_C_adjacent_merge (iterator __first1, iterator __last1, iterator __last2)
443{
444 difference_type __n = _DISTANCE (__first1, __last1, difference_type);
445
446 for (iterator __first2 = __last1; __n >= 0 && !(__first2 == __last2); ) {
447 if (*__first2 < *__first1) {
448 iterator __next = __first2;
449 _C_transfer (__first1, __first2, ++__next, *this);
450 __first2 = __next;
451 }
452 else {
453 ++__first1;
454 --__n;
455 }
456 }
457}
458
459
460template <class _TypeT, class _Allocator>
461template<class _Compare>
462void list<_TypeT, _Allocator>::
463_C_adjacent_merge (iterator __first1, iterator __last1, iterator __last2,
464 _Compare __cmp)
465{
466 difference_type __n = _DISTANCE (__first1, __last1, difference_type);
467
468 for (iterator __first2 = __last1; __n >= 0 && !(__first2 == __last2); ) {
469 if (__cmp (*__first2, *__first1)) {
470 iterator __next = __first2;
471 _C_transfer (__first1, __first2, ++__next, *this);
472 __first2 = __next;
473 }
474 else {
475 ++__first1;
476 --__n;
477 }
478 }
479}
480
481
482template<class _TypeT, class _Allocator>
483template<class _Predicate>
484void list<_TypeT, _Allocator>::remove_if (_Predicate __pred)
485{
486 iterator __first = begin ();
487 iterator __last = end ();
488
489 while (!(__first == __last)) {
490 iterator __next = __first;
491 ++__next;
492 if (__pred (*__first))
493 erase (__first);
494 __first = __next;
495 }
496}
497
498
499template<class _TypeT, class _Allocator>
500template<class _BinaryPredicate>
501void list<_TypeT, _Allocator>::unique (_BinaryPredicate __pred)
502{
503 iterator __first = begin ();
504 iterator __last = end ();
505
506 if (__first == __last)
507 return;
508
509 iterator __next = __first;
510 while (!(++__next == __last)) {
511 if (__pred (*__first, *__next))
512 erase (__next);
513 else
514 __first = __next;
515 __next = __first;
516 }
517}
518
519
520template<class _TypeT, class _Allocator>
521template<class _Compare>
522void list<_TypeT, _Allocator>::
523merge (list<_TypeT, _Allocator>& __x, _Compare __cmp)
524{
525 if (&__x == this)
526 return;
527 iterator __first1 = begin ();
528 iterator __last1 = end ();
529 iterator __first2 = __x.begin ();
530 iterator __last2 = __x.end ();
531
532 while (!(__first1 == __last1) && !(__first2 == __last2)) {
533 if (__cmp (*__first2, *__first1)) {
534 iterator __next = __first2;
535 _C_transfer (__first1, __first2, ++__next, __x);
536 __first2 = __next;
537 }
538 else
539 ++__first1;
540 }
541
542 if (!(__first2 == __last2))
543 _C_transfer (__last1, __first2, __last2, __x);
544}
545
546
547template <class _TypeT, class _Allocator>
548template<class _Compare>
549void list<_TypeT, _Allocator>::sort (_Compare __cmp)
550{
551 for (size_type __n = 1; __n < size (); __n *= 2) {
552
553 iterator __it1 = begin (),
554 __it2 = begin (),
555 __it3 = begin ();
556
557 _C_advance (__it2, __n, end ());
558 _C_advance (__it3, 2 * __n, end ());
559
560 for (size_type __m = 0;
561 __m != (size () + (2 * __n)) / (__n * 2); ++__m) {
562
563 if (!(__it1 == end ()) && !(__it2 == end ())) {
564 _C_adjacent_merge (__it1, __it2, __it3, __cmp);
565 __it1 = __it3;
566 __it2 = __it3;
567 _C_advance (__it2, __n, end ());
568 _C_advance (__it3, 2 * __n, end ());
569 }
570 }
571 }
572}
573
574
575} // namespace std
const int end
#define _RETHROW
Definition _defs.h:853
#define _TRY
Definition _defs.h:850
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_NEW_CAPACITY(ignore, what, from)
Definition _defs.h:462
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _DISTANCE(first, last, ignore)
Definition _defs.h:1225
#define _CATCH(ex)
Definition _defs.h:851
#define _RWSTD_ASSERT_RANGE(ign1, ign2)
Definition _defs.h:1247
#define _ITER_NODE(it)
Definition json.h:5363