BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstp_slist.h
Go to the documentation of this file.
1/// @file bslstp_slist.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstp_slist.h -*-C++-*-
8#ifndef INCLUDED_BSLSTP_SLIST
9#define INCLUDED_BSLSTP_SLIST
10
11/// @defgroup bslstp_slist bslstp_slist
12/// @brief Provide a singly linked list container.
13/// @addtogroup bsl
14/// @{
15/// @addtogroup bslstp
16/// @{
17/// @addtogroup bslstp_slist
18/// @{
19///
20/// <h1> Outline </h1>
21/// * <a href="#bslstp_slist-purpose"> Purpose</a>
22/// * <a href="#bslstp_slist-classes"> Classes </a>
23/// * <a href="#bslstp_slist-description"> Description </a>
24/// * <a href="#bslstp_slist-usage"> Usage </a>
25///
26/// # Purpose {#bslstp_slist-purpose}
27/// Provide a singly linked list container.
28///
29/// @deprecated Do not use directly.
30///
31/// # Classes {#bslstp_slist-classes}
32///
33/// - slist: singly linked list
34///
35/// @see bsl_slist
36///
37/// # Description {#bslstp_slist-description}
38/// This component is for internal use only.
39///
40/// Note that the functions in this component are based on STLPort's
41/// implementation, with copyright notice as follows:
42/// @code
43/// /*
44/// * Copyright (c) 1997
45/// * Silicon Graphics Computer Systems, Inc.
46/// *
47/// * Permission to use, copy, modify, distribute and sell this software
48/// * and its documentation for any purpose is hereby granted without fee,
49/// * provided that the above copyright notice appear in all copies and
50/// * that both that copyright notice and this permission notice appear
51/// * in supporting documentation. Silicon Graphics makes no
52/// * representations about the suitability of this software for any
53/// * purpose. It is provided "as is" without express or implied warranty.
54/// *
55/// */
56///
57/// // Contents originally from stl/_slist.h
58///
59/// /*
60/// *
61/// * Copyright (c) 1996,1997
62/// * Silicon Graphics Computer Systems, Inc.
63/// *
64/// * Copyright (c) 1997
65/// * Moscow Center for SPARC Technology
66/// *
67/// * Copyright (c) 1999
68/// * Boris Fomitchev
69/// *
70/// * This material is provided "as is", with absolutely no warranty expressed
71/// * or implied. Any use is at your own risk.
72/// *
73/// * Permission to use or copy this software for any purpose is hereby granted
74/// * without fee, provided the above notices are retained on all copies.
75/// * Permission to modify the code and to distribute modified code is granted,
76/// * provided the above notices are retained, and a notice that the code was
77/// * modified is included with the above copyright notice.
78/// *
79/// */
80/// @endcode
81///
82/// ## Usage {#bslstp_slist-usage}
83///
84///
85/// This component is for internal use only.
86/// @}
87/** @} */
88/** @} */
89
90/** @addtogroup bsl
91 * @{
92 */
93/** @addtogroup bslstp
94 * @{
95 */
96/** @addtogroup bslstp_slist
97 * @{
98 */
99
100#ifdef BDE_OPENSOURCE_PUBLICATION // STP
101#error "bslstp_slist is not for publication"
102#endif
103#include <bslscm_version.h>
104
105#include <bslstp_alloc.h>
106#include <bslstp_iterator.h>
107#include <bslstp_slistbase.h>
108#include <bslstp_util.h>
109
112
113#include <bslma_autodestructor.h>
116#include <bslma_bslallocator.h>
117
118#include <bslmf_isfundamental.h>
120
121#include <bsls_exceptionutil.h>
122#include <bsls_objectbuffer.h>
123
124
125#include <bsls_util.h>
126
127#include <algorithm>
128
129#include <iterator>
130
131#include <cstddef>
132
133//# undef slist
134//# define slist __WORKAROUND_DBG_RENAME(slist)
135
136//_STLP_BEGIN_NAMESPACE
137namespace bsl {
138
139template <class _Tp>
141{
143};
144
146
147 typedef std::size_t size_type;
148 typedef std::ptrdiff_t difference_type;
149 typedef std::forward_iterator_tag iterator_category;
150
152
154
155 void _M_incr() {
156// _STLP_VERBOSE_ASSERT(_M_node != 0, _StlMsg_INVALID_ADVANCE)
158 }
159 bool operator==(const _Slist_iterator_base& __y ) const {
160 return _M_node == __y._M_node;
161 }
162 bool operator!=(const _Slist_iterator_base& __y ) const {
163 return _M_node != __y._M_node;
164 }
165};
166
167
168template <class _Tp, class _Traits>
170{
171 typedef _Tp value_type;
172 typedef typename _Traits::pointer pointer;
173 typedef typename _Traits::reference reference;
174 typedef std::forward_iterator_tag iterator_category;
175 typedef std::size_t size_type;
176 typedef ptrdiff_t difference_type;
177
181
183
187
188 reference operator*() const { return ((_Node*) _M_node)->_M_data; }
189
190 pointer operator -> ( ) const { return & ( operator * ( ) ) ; }
191
193 {
194 _M_incr();
195 return *this;
196 }
198 {
199 _Self __tmp = *this;
200 _M_incr();
201 return __tmp;
202 }
203};
204
205// Base class that encapsulates details of allocators and simplifies EH
206
207template <class _Tp, class _Alloc>
209
212
214 _M_head(__a, _Slist_node_base() ) {
215 _M_head._M_data._M_next = 0;
216 }
218
219protected:
221
223 {
224 _Node* __next = (_Node*) (__pos->_M_next);
225 _Slist_node_base* __next_next = __next->_M_next;
226 __pos->_M_next = __next_next;
227 BloombergLP::bslma::DestructionUtil::destroy(
229 _M_head.allocatorRef().deallocate(__next,1);
230 return __next_next;
231 }
233
234public:
236 //return _STLP_CONVERT_ALLOCATOR((const _M_node_allocator_type&)_M_head, _Tp);
237 return _M_head.get_allocator();
238 }
240};
241
242template <class _Tp, class _Alloc = bsl::allocator<_Tp> >
243class slist : protected _Slist_base<_Tp,_Alloc>
244{
245private:
247 typedef slist<_Tp,_Alloc> _Self;
248
249 struct QuickSwap;
250 friend struct QuickSwap;
251
252 /// Function object to quickly swap two slists with identical
253 /// allocators and allocation modes.
254 struct QuickSwap {
255
256 /// Swap contents of `v1` and `v2`. Undefined unless
257 /// `v1.get_allocator() == v2.get_allocator()`.
258 void operator()(_Self& v1, _Self& v2) const
259 {
260 // MODIFIED BY ARTHUR
261 //_STLP_STD::swap(v1._M_head._M_data, v2._M_head._M_data);
262 typedef BloombergLP::bslalg::ScalarPrimitives primitive;
263 primitive::swap(v1._M_head._M_data, v2._M_head._M_data);
264 }
265 };
266
267public:
268 typedef _Tp value_type;
270 typedef const value_type* const_pointer;
273 typedef std::size_t size_type;
274 typedef std::ptrdiff_t difference_type;
275 typedef std::forward_iterator_tag _Iterator_category;
276
279
281
282
283private:
284 typedef _Slist_node<_Tp> _Node;
287
288 _Node* _M_create_node(const value_type& __x = _Tp()) {
289 _Node* __node = this->_M_head.allocatorRef().allocate(1);
290 BSLS_TRY {
291 typedef BloombergLP::bslma::ConstructionUtil Util;
292 Util::construct(BSLS_UTIL_ADDRESSOF(__node->_M_data),
293 this->get_allocator(),
294 __x);
295 __node->_M_next = 0;
296 }
297 BSLS_CATCH(...) {
298 this->_M_head.allocatorRef().deallocate(__node, 1);
300 }
301 return __node;
302 }
303
304public:
306
307 explicit slist(const allocator_type& __a = allocator_type()) : _Slist_base<_Tp,_Alloc>(__a) {}
308
309 explicit slist(size_type __n, const value_type& __x = _Tp(),
310 const allocator_type& __a = allocator_type())
311 : _Slist_base<_Tp,_Alloc>(__a)
312 { _M_insert_after_fill(&this->_M_head._M_data, __n, __x); }
313
314
315 // We don't need any dispatching tricks here, because _M_insert_after_range
316 // already does them.
317 template <class _InputIterator>
318 slist(_InputIterator __first, _InputIterator __last,
319 const allocator_type& __a = allocator_type()) :
320 _Slist_base<_Tp,_Alloc>(__a)
321 { _M_insert_after_range(&this->_M_head._M_data, __first, __last); }
322
323 slist(const _Self& __x)
324 : _Slist_base<_Tp, _Alloc>(BloombergLP::bslstp::Util::copyContainerAllocator(__x.get_allocator()))
325 { insert(begin(), __x.begin(), __x.end()); }
326
327 // Copy-construct with alternative allocator.
328 slist(const _Self& __x, const allocator_type& __a)
329 : _Slist_base<_Tp, _Alloc>(__a)
330 { insert(begin(), __x.begin(), __x.end()); }
331
332 /*explicit slist(__full_move_source<_Self> src)
333 : _Slist_base<_Tp, _Alloc>(_FullMoveSource<_Slist_base<_Tp, _Alloc> >(src.get())) {
334 }*/
335
336// explicit slist(__partial_move_source<_Self> src)
337// : _Slist_base<_Tp, _Alloc>(src.get()) {
338// src.get()._M_head._M_data._M_next = 0;
339// }
340
341 _Self& operator= (const _Self& __x);
342
344
345public:
346 // assign(), a generalized assignment member function. Two
347 // versions: one that takes a count, and one that takes a range.
348 // The range version is a member template, so we dispatch on whether
349 // or not the type is an integer.
350
351 void assign(size_type __n, const _Tp& __val)
352 { _M_fill_assign(__n, __val); }
353
354 void _M_fill_assign(size_type __n, const _Tp& __val);
355
356 template <class _InputIterator>
357 void assign(_InputIterator __first, _InputIterator __last) {
358
359 // SIMPLIFIED BY ALISDAIR
361 }
362
363 template <class _Integer>
364 void _M_assign_dispatch(_Integer __n, _Integer __val, bsl::true_type *)
365 { _M_fill_assign((size_type) __n, (_Tp) __val); }
366
367 template <class _InputIter>
368 void
369 _M_assign_dispatch(_InputIter __first, _InputIter __last, bsl::false_type *) {
370 _Node_base* __prev = &this->_M_head._M_data;
371 _Node* __node = (_Node*) this->_M_head._M_data._M_next;
372 while (__node != 0 && __first != __last) {
373 __node->_M_data = *__first;
374 __prev = __node;
375 __node = (_Node*) __node->_M_next;
376 ++__first;
377 }
378 if (__first != __last)
379 _M_insert_after_range(__prev, __first, __last);
380 else
381 this->_M_erase_after(__prev, 0);
382 }
383
384public:
385
386 // Experimental new feature: before_begin() returns a
387 // non-dereferenceable iterator that, when incremented, yields
388 // begin(). This iterator may be used as the argument to
389 // insert_after, erase_after, etc. Note that even for an empty
390 // slist, before_begin() is not the same iterator as end(). It
391 // is always necessary to increment before_begin() at least once to
392 // obtain end().
393 iterator before_begin() { return iterator((_Node*) &this->_M_head._M_data); }
394 const_iterator before_begin() const
395 { return const_iterator((_Node*) &this->_M_head._M_data); }
396
397 iterator begin() { return iterator((_Node*)this->_M_head._M_data._M_next); }
398 const_iterator begin() const
399 { return const_iterator((_Node*)this->_M_head._M_data._M_next);}
400
401 iterator end() { return iterator(0); }
402 const_iterator end() const { return const_iterator(0); }
403
404 size_type size() const { return _Sl_global_inst::size(this->_M_head._M_data._M_next); }
405
406 size_type max_size() const { return size_type(-1); }
407
408 bool empty() const { return this->_M_head._M_data._M_next == 0; }
409
410 void swap(_Self& __x) {
411 BloombergLP::bslstp::Util::swapContainers(*this, __x, QuickSwap());
412 }
413
414public:
415 reference front() { return ((_Node*) this->_M_head._M_data._M_next)->_M_data; }
416 const_reference front() const
417 { return ((_Node*) this->_M_head._M_data._M_next)->_M_data; }
418 void push_front(const value_type& __x = _Tp()) {
419 __slist_make_link(&this->_M_head._M_data, _M_create_node(__x));
420 }
421
422 void pop_front() {
423 _Node* __node = (_Node*) this->_M_head._M_data._M_next;
424 this->_M_head._M_data._M_next = __node->_M_next;
425 BloombergLP::bslma::DestructionUtil::destroy(
427 this->_M_head.allocatorRef().deallocate(__node, 1);
428 }
429
431 return iterator((_Node*) _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node));
432 }
434 return const_iterator((_Node*) _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node));
435 }
436
437private:
438 _Node* _M_insert_after(_Node_base* __pos, const value_type& __x = _Tp()) {
439 return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
440 }
441
442
443 void _M_insert_after_fill(_Node_base *__pos,
444 size_type __n, const value_type& __x) {
445 for (size_type __i = 0; __i < __n; ++__i)
446 __pos = __slist_make_link(__pos, _M_create_node(__x));
447 }
448
449 // Check whether it's an integral type. If so, it's not an iterator.
450 template <class _InIter>
451 void _M_insert_after_range(_Node_base *__pos,
452 _InIter __first, _InIter __last) {
453 // SIMPLIFIED BY ALISDAIR
454 _M_insert_after_range(__pos, __first, __last, (bsl::is_fundamental<_InIter> *) 0);
455 }
456
457 template <class _Integer>
458 void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x,
459 bsl::true_type *) {
460 _M_insert_after_fill(__pos, __n, __x);
461 }
462
463 template <class _InIter>
464 void _M_insert_after_range(_Node_base *__pos,
465 _InIter __first, _InIter __last,
466 bsl::false_type *) {
467 while (__first != __last) {
468 __pos = __slist_make_link(__pos, _M_create_node(*__first));
469 ++__first;
470 }
471 }
472
473
474public:
475
476 iterator insert_after(iterator __pos, const value_type& __x = _Tp()) {
477 return iterator(_M_insert_after(__pos._M_node, __x));
478 }
479
480
481 void insert_after(iterator __pos, size_type __n, const value_type& __x) {
482 _M_insert_after_fill(__pos._M_node, __n, __x);
483 }
484
485 // We don't need any dispatching tricks here, because _M_insert_after_range
486 // already does them.
487 template <class _InIter>
488 void insert_after(iterator __pos, _InIter __first, _InIter __last) {
489 _M_insert_after_range(__pos._M_node, __first, __last);
490 }
491
492
493 iterator insert(iterator __pos, const value_type& __x = _Tp()) {
494 return iterator(_M_insert_after(
495 _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
496 __x));
497 }
498
499
500 void insert(iterator __pos, size_type __n, const value_type& __x) {
501 _M_insert_after_fill(_Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node), __n, __x);
502 }
503
504 // We don't need any dispatching tricks here, because _M_insert_after_range
505 // already does them.
506 template <class _InIter>
507 void insert(iterator __pos, _InIter __first, _InIter __last) {
508 _M_insert_after_range(
509 _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
510 __first, __last);
511 }
512
513
514
515public:
517 return iterator((_Node*) this->_M_erase_after(__pos._M_node));
518 }
519 iterator erase_after(iterator __before_first, iterator __last) {
520 return iterator((_Node*) this->_M_erase_after(__before_first._M_node,
521 __last._M_node));
522 }
523
526 &this->_M_head._M_data,
527 __pos._M_node)));
528 }
529 iterator erase(iterator __first, iterator __last) {
530 return iterator((_Node*) this->_M_erase_after(
531 _Sl_global_inst::__previous(&this->_M_head._M_data, __first._M_node), __last._M_node));
532 }
533
534 void resize(size_type new_size, const value_type& __x = _Tp());
535
536 void clear() {
537 this->_M_erase_after(&this->_M_head._M_data, 0);
538 }
539
540public:
541 // Moves the range [__before_first + 1, __before_last + 1) to *this,
542 // inserting it immediately after __pos. This is constant time.
543 void splice_after(iterator __pos,
544 iterator __before_first, iterator __before_last)
545 {
546 if (__before_first != __before_last) {
547 _Sl_global_inst::__splice_after(__pos._M_node, __before_first._M_node,
548 __before_last._M_node);
549 }
550 }
551
552 // Moves the element that follows __prev to *this, inserting it immediately
553 // after __pos. This is constant time.
554 void splice_after(iterator __pos, iterator __prev)
555 {
557 __prev._M_node, __prev._M_node->_M_next);
558 }
559
560 // Removes all of the elements from the list __x to *this, inserting
561 // them immediately after __pos. __x must not be *this. Complexity:
562 // linear in __x.size().
563 void splice_after(iterator __pos, _Self& __x)
564 {
566 }
567
568 // Linear in distance(begin(), __pos), and linear in __x.size().
569 void splice(iterator __pos, _Self& __x) {
570 if (__x._M_head._M_data._M_next)
572 &__x._M_head._M_data, _Sl_global_inst::__previous(&__x._M_head._M_data, 0));
573 }
574
575 // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i).
576 void splice(iterator __pos, _Self& __x, iterator __i) {
578 _Sl_global_inst::__previous(&this->_M_head._M_data, __pos._M_node),
580 __i._M_node);
581 }
582
583 // Linear in distance(begin(), __pos), in distance(__x.begin(), __first),
584 // and in distance(__first, __last).
585 void splice(iterator __pos, _Self& __x, iterator __first, iterator __last)
586 {
587 if (__first != __last)
589 _Sl_global_inst::__previous(&__x._M_head._M_data, __first._M_node),
591 }
592
593public:
594 void reverse() {
595 if (this->_M_head._M_data._M_next)
596 this->_M_head._M_data._M_next = _Sl_global_inst::__reverse(this->_M_head._M_data._M_next);
597 }
598
599 void remove(const _Tp& __val);
600 void unique();
601 void merge(_Self& __x);
602 void sort();
603
604 template <class _Predicate>
605 void remove_if(_Predicate __pred) {
606 _Node_base* __cur = &this->_M_head._M_data;
607 while (__cur->_M_next) {
608 if (__pred(((_Node*) __cur->_M_next)->_M_data))
609 this->_M_erase_after(__cur);
610 else
611 __cur = __cur->_M_next;
612 }
613 }
614
615 template <class _BinaryPredicate>
616 void unique(_BinaryPredicate __pred) {
617 _Node* __cur = (_Node*) this->_M_head._M_data._M_next;
618 if (__cur) {
619 while (__cur->_M_next) {
620 if (__pred(((_Node*)__cur)->_M_data,
621 ((_Node*)(__cur->_M_next))->_M_data))
622 this->_M_erase_after(__cur);
623 else
624 __cur = (_Node*) __cur->_M_next;
625 }
626 }
627 }
628
629 template <class _StrictWeakOrdering>
631 _StrictWeakOrdering __comp) {
632 _Node_base* __n1 = &this->_M_head._M_data;
633 while (__n1->_M_next && __x._M_head._M_data._M_next) {
634 if (__comp(((_Node*) __x._M_head._M_data._M_next)->_M_data,
635 ((_Node*) __n1->_M_next)->_M_data))
636 _Sl_global_inst::__splice_after(__n1, &__x._M_head._M_data, __x._M_head._M_data._M_next);
637 __n1 = __n1->_M_next;
638 }
639 if (__x._M_head._M_data._M_next) {
640 __n1->_M_next = __x._M_head._M_data._M_next;
641 __x._M_head._M_data._M_next = 0;
642 }
643 }
644
645 template <class _StrictWeakOrdering>
646 void sort(_StrictWeakOrdering __comp) {
647 if (this->_M_head._M_data._M_next && this->_M_head._M_data._M_next->_M_next) {
648 _Self __carry(this->get_allocator());
649
650 // Create an array of 64 '_Self' objects. Since we cannot pass
651 // constructor arguments to array element constructors, we instead use
652 // an array of raw memory objects ('bsls::ObjectBuffer') and initialize
653 // them with the desired allocator as a separate step. After
654 // initialization, we ensure that destructors are called by creating an
655 // auto-destructor object.
656 BloombergLP::bsls::ObjectBuffer<_Self> __counterBuffers[64];
657 _Self* __counter = &__counterBuffers[0].object();
658 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
659 __counter, 64, __carry,
660 this->_M_head.get_allocator());
661 BloombergLP::bslma::AutoDestructor<_Self> __counterGuard(__counter, 64);
662
663 int __fill = 0;
664 while (!empty()) {
665 _Sl_global_inst::__splice_after(&__carry._M_head._M_data, &this->_M_head._M_data, this->_M_head._M_data._M_next);
666 int __i = 0;
667 while (__i < __fill && !__counter[__i].empty()) {
668 __counter[__i].merge(__carry, __comp);
669 __carry.swap(__counter[__i]);
670 ++__i;
671 }
672 __carry.swap(__counter[__i]);
673 if (__i == __fill)
674 ++__fill;
675 }
676
677 for (int __i = 1; __i < __fill; ++__i)
678 __counter[__i].merge(__counter[__i-1], __comp);
679 this->swap(__counter[__fill-1]);
680 }
681 }
682
683};
684
685template <class _Tp, class _Alloc>
686inline
687bool operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2)
688{
689 typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator;
690 const_iterator __end1 = _SL1.end();
691 const_iterator __end2 = _SL2.end();
692
693 const_iterator __i1 = _SL1.begin();
694 const_iterator __i2 = _SL2.begin();
695 while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
696 ++__i1;
697 ++__i2;
698 }
699 return __i1 == __end1 && __i2 == __end2;
700}
701
702template <class _Tp, class _Alloc>
703inline
704bool operator<(const slist<_Tp, _Alloc>& __x,
705 const slist<_Tp, _Alloc>& __y) {
706 return std::lexicographical_compare(__x.begin(), __x.end(),
707 __y.begin(), __y.end());
708}
709
710template <class _Tp, class _Alloc>
711inline
712bool operator!=(const slist<_Tp, _Alloc>& __x,
713 const slist<_Tp, _Alloc>& __y) {return !(__x == __y);}
714
715template <class _Tp, class _Alloc>
716inline
717bool operator>(const slist<_Tp, _Alloc>& __x,
718 const slist<_Tp, _Alloc>& __y) {return __y < __x;}
719
720template <class _Tp, class _Alloc>
721inline
722bool operator<=(const slist<_Tp, _Alloc>& __x,
723 const slist<_Tp, _Alloc>& __y) { return !(__y < __x);}
724
725template <class _Tp, class _Alloc>
726inline
727bool operator>=(const slist<_Tp, _Alloc>& __x,
728 const slist<_Tp, _Alloc>& __y) { return !(__x < __y);}
729
730//template <class _Tp, class _Alloc>
731//struct __partial_move_traits<slist<_Tp, _Alloc> > {
732// typedef __true_type supported;
733//};
734//
735//template <class _Tp, class _Alloc>
736//struct __action_on_move<slist<_Tp, _Alloc> > {
737// typedef __true_type swap;
738//};
739
740//# define _STLP_EQUAL_OPERATOR_SPECIALIZED
741//# define _STLP_TEMPLATE_HEADER template <class _Tp, class _Alloc>
742//# define _STLP_TEMPLATE_CONTAINER slist<_Tp, _Alloc>
743//# include <bslstp_stl_relops_cont.h>
744//# undef _STLP_TEMPLATE_CONTAINER
745//# undef _STLP_TEMPLATE_HEADER
746//# undef _STLP_EQUAL_OPERATOR_SPECIALIZED
747
748} // close namespace bsl
749
750// BEGIN FORMER CONTENTS OF bslstp_stl_slist.c
751/*
752 *
753 * Copyright (c) 1996,1997
754 * Silicon Graphics Computer Systems, Inc.
755 *
756 * Copyright (c) 1999
757 * Boris Fomitchev
758 *
759 * This material is provided "as is", with absolutely no warranty expressed
760 * or implied. Any use is at your own risk.
761 *
762 * Permission to use or copy this software for any purpose is hereby granted
763 * without fee, provided the above notices are retained on all copies.
764 * Permission to modify the code and to distribute modified code is granted,
765 * provided the above notices are retained, and a notice that the code was
766 * modified is included with the above copyright notice.
767 *
768 */
769
770// #ifndef INCLUDED_BSLSTP_STL_SLIST
771// # include <bslstp_stl_slist.h>
772// #endif
773
774namespace bsl {
775
776template <class _Tp, class _Alloc>
777_Slist_node_base*
779 _Slist_node_base* __last_node) {
780 _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next);
781 while (__cur != __last_node) {
782 _Slist_node<_Tp>* __tmp = __cur;
783 __cur = (_Slist_node<_Tp>*) __cur->_M_next;
784 BloombergLP::bslma::DestructionUtil::destroy(
786 _M_head.allocatorRef().deallocate(__tmp,1);
787 }
788 __before_first->_M_next = __last_node;
789 return __last_node;
790}
791
792template <class _Tp, class _Alloc>
794{
795 if (&__x != this) {
796 _Node_base* __p1 = &this->_M_head._M_data;
797 _Node* __n1 = (_Node*) this->_M_head._M_data._M_next;
798 const _Node* __n2 = (const _Node*) __x._M_head._M_data._M_next;
799 while (__n1 && __n2) {
800 __n1->_M_data = __n2->_M_data;
801 __p1 = __n1;
802 __n1 = (_Node*) __n1->_M_next;
803 __n2 = (const _Node*) __n2->_M_next;
804 }
805 if (__n2 == 0)
806 this->_M_erase_after(__p1, 0);
807 else
808 _M_insert_after_range(__p1, const_iterator(const_cast<_Node*>(__n2)),
809 const_iterator(0));
810 }
811 return *this;
812}
813
814template <class _Tp, class _Alloc>
816 _Node_base* __prev = &this->_M_head._M_data;
817 _Node* __node = (_Node*) this->_M_head._M_data._M_next;
818 for ( ; __node != 0 && __n > 0 ; --__n) {
819 __node->_M_data = __val;
820 __prev = __node;
821 __node = (_Node*) __node->_M_next;
822 }
823 if (__n > 0)
824 _M_insert_after_fill(__prev, __n, __val);
825 else
826 this->_M_erase_after(__prev, 0);
827}
828
829
830template <class _Tp, class _Alloc>
831void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x)
832{
833 _Node_base* __cur = &this->_M_head._M_data;
834 while (__cur->_M_next != 0 && __len > 0) {
835 --__len;
836 __cur = __cur->_M_next;
837 }
838 if (__cur->_M_next)
839 this->_M_erase_after(__cur, 0);
840 else
841 _M_insert_after_fill(__cur, __len, __x);
842}
843
844template <class _Tp, class _Alloc>
845void slist<_Tp,_Alloc>::remove(const _Tp& __val)
846{
847 _Node_base* __cur = &this->_M_head._M_data;
848 while (__cur && __cur->_M_next) {
849 if (((_Node*) __cur->_M_next)->_M_data == __val)
850 this->_M_erase_after(__cur);
851 else
852 __cur = __cur->_M_next;
853 }
854}
855
856template <class _Tp, class _Alloc>
858{
859 _Node_base* __cur = this->_M_head._M_data._M_next;
860 if (__cur) {
861 while (__cur->_M_next) {
862 if (((_Node*)__cur)->_M_data ==
863 ((_Node*)(__cur->_M_next))->_M_data)
864 this->_M_erase_after(__cur);
865 else
866 __cur = __cur->_M_next;
867 }
868 }
869}
870
871template <class _Tp, class _Alloc>
873{
874 _Node_base* __n1 = &this->_M_head._M_data;
875 while (__n1->_M_next && __x._M_head._M_data._M_next) {
876 if (((_Node*) __x._M_head._M_data._M_next)->_M_data <
877 ((_Node*) __n1->_M_next)->_M_data)
878 _Sl_global_inst::__splice_after(__n1, &__x._M_head._M_data, __x._M_head._M_data._M_next);
879 __n1 = __n1->_M_next;
880 }
881 if (__x._M_head._M_data._M_next) {
882 __n1->_M_next = __x._M_head._M_data._M_next;
883 __x._M_head._M_data._M_next = 0;
884 }
885}
886
887template <class _Tp, class _Alloc>
889{
890 if (this->_M_head._M_data._M_next && this->_M_head._M_data._M_next->_M_next) {
891 _Self __carry(this->get_allocator());
892
893 // Create an array of 64 '_Self' objects. Since we cannot pass
894 // constructor arguments to array element constructors, we instead use
895 // an array of raw memory objects ('bsls::ObjectBuffer') and initialize
896 // them with the desired allocator as a separate step. After
897 // initialization, we ensure that destructors are called by creating an
898 // auto-destructor object.
899 BloombergLP::bsls::ObjectBuffer<_Self> __counterBuffers[64];
900 _Self* __counter = &__counterBuffers[0].object();
902 this->get_allocator());
903 BloombergLP::bslalg::ArrayPrimitives::uninitializedFillN(
904 __counter, 64, __carry,
905 __alloc);
906 BloombergLP::bslma::AutoDestructor<_Self> __counterGuard(__counter, 64);
907
908 int __fill = 0;
909 while (!empty()) {
910 _Sl_global_inst::__splice_after(&__carry._M_head._M_data, &this->_M_head._M_data, this->_M_head._M_data._M_next);
911 int __i = 0;
912 while (__i < __fill && !__counter[__i].empty()) {
913 __counter[__i].merge(__carry);
914 __carry.swap(__counter[__i]);
915 ++__i;
916 }
917 __carry.swap(__counter[__i]);
918 if (__i == __fill)
919 ++__fill;
920 }
921
922 for (int __i = 1; __i < __fill; ++__i)
923 __counter[__i].merge(__counter[__i-1]);
924 this->swap(__counter[__fill-1]);
925 }
926}
927
928//# undef slist
929//# undef size_type
930
931} // close namespace bsl
932
933// Local Variables:
934// mode:C++
935// End:
936// END FORMER CONTENTS OF bslstp_stl_slist.c
937
938//# undef slist
939//# define __slist__ __FULL_NAME(slist)
940//
941//#if defined (_STLP_DEBUG)
942//# include <stl/debug/bslstp_stl_slist.h>
943//#endif
944
945namespace std {
946
947// Specialization of insert_iterator so that insertions will be constant
948// time rather than linear time.
949
950
951template <class _Tp, class _Alloc>
952class insert_iterator<bsl::slist<_Tp, _Alloc> > {
953protected:
957public:
959 typedef output_iterator_tag iterator_category;
960 typedef void value_type;
961 typedef void difference_type;
962 typedef void pointer;
963 typedef void reference;
964
966 : container(&__x) {
967 if (__i == __x.begin())
968 iter = __x.before_begin();
969 else
970 iter = __x.previous(__i);
971 }
972
973 insert_iterator<_Container>&
974 operator=(const typename _Container::value_type& __val) {
975 iter = container->insert_after(iter, __val);
976 return *this;
977 }
978 insert_iterator<_Container>& operator*() { return *this; }
979 insert_iterator<_Container>& operator++() { return *this; }
980 insert_iterator<_Container>& operator++(int) { return *this; }
981};
982
983
984} // close namespace std
985
986//# if defined ( _STLP_USE_WRAPPER_FOR_ALLOC_PARAM )
987//# include <stl/wrappers/bslstp_stl_slist.h>
988//# endif
989
990//# if (_STLP_OUTERMOST_HEADER_ID == 0x58)
991//# include <bslstp_stl_epilog.h>
992//# undef _STLP_OUTERMOST_HEADER_ID
993//# endif
994
995#endif /* INCLUDED_BSLSTP_SLIST */
996
997// Local Variables:
998// mode:C++
999// End:
1000
1001/** @} */
1002/** @} */
1003/** @} */
Definition bslstp_alloc.h:105
static void __splice_after(_Slist_node_base *__pos, _Slist_node_base *__before_first, _Slist_node_base *__before_last)
Definition bslstp_slistbase.h:188
static std::size_t size(_Slist_node_base *__node)
Definition bslstp_slistbase.h:219
static _Slist_node_base * __previous(_Slist_node_base *__head, const _Slist_node_base *__node)
Definition bslstp_slistbase.h:165
static _Slist_node_base * __reverse(_Slist_node_base *__node)
Definition bslstp_slistbase.h:203
Definition bslstp_slist.h:244
void splice(iterator __pos, _Self &__x, iterator __first, iterator __last)
Definition bslstp_slist.h:585
const_reference front() const
Definition bslstp_slist.h:416
void swap(_Self &__x)
Definition bslstp_slist.h:410
value_type & reference
Definition bslstp_slist.h:271
void merge(_Self &__x)
Definition bslstp_slist.h:872
_Tp value_type
Definition bslstp_slist.h:268
void unique()
Definition bslstp_slist.h:857
std::ptrdiff_t difference_type
Definition bslstp_slist.h:274
iterator end()
Definition bslstp_slist.h:401
iterator erase_after(iterator __before_first, iterator __last)
Definition bslstp_slist.h:519
iterator before_begin()
Definition bslstp_slist.h:393
void insert(iterator __pos, size_type __n, const value_type &__x)
Definition bslstp_slist.h:500
void reverse()
Definition bslstp_slist.h:594
void splice_after(iterator __pos, iterator __before_first, iterator __before_last)
Definition bslstp_slist.h:543
void remove_if(_Predicate __pred)
Definition bslstp_slist.h:605
_Self & operator=(const _Self &__x)
Definition bslstp_slist.h:793
const value_type * const_pointer
Definition bslstp_slist.h:270
reference front()
Definition bslstp_slist.h:415
bool empty() const
Definition bslstp_slist.h:408
size_type size() const
Definition bslstp_slist.h:404
iterator begin()
Definition bslstp_slist.h:397
iterator insert(iterator __pos, const value_type &__x=_Tp())
Definition bslstp_slist.h:493
void sort(_StrictWeakOrdering __comp)
Definition bslstp_slist.h:646
void insert_after(iterator __pos, _InIter __first, _InIter __last)
Definition bslstp_slist.h:488
iterator insert_after(iterator __pos, const value_type &__x=_Tp())
Definition bslstp_slist.h:476
slist(const _Self &__x)
Definition bslstp_slist.h:323
const_iterator end() const
Definition bslstp_slist.h:402
void splice_after(iterator __pos, _Self &__x)
Definition bslstp_slist.h:563
iterator erase(iterator __pos)
Definition bslstp_slist.h:524
void _M_fill_assign(size_type __n, const _Tp &__val)
Definition bslstp_slist.h:815
void insert_after(iterator __pos, size_type __n, const value_type &__x)
Definition bslstp_slist.h:481
slist(const allocator_type &__a=allocator_type())
Definition bslstp_slist.h:307
void unique(_BinaryPredicate __pred)
Definition bslstp_slist.h:616
iterator erase(iterator __first, iterator __last)
Definition bslstp_slist.h:529
_Base::allocator_type allocator_type
Definition bslstp_slist.h:280
allocator_type get_allocator() const
Definition bslstp_slist.h:305
slist(size_type __n, const value_type &__x=_Tp(), const allocator_type &__a=allocator_type())
Definition bslstp_slist.h:309
void merge(slist< _Tp, _Alloc > &__x, _StrictWeakOrdering __comp)
Definition bslstp_slist.h:630
const_iterator before_begin() const
Definition bslstp_slist.h:394
iterator previous(const_iterator __pos)
Definition bslstp_slist.h:430
void push_front(const value_type &__x=_Tp())
Definition bslstp_slist.h:418
void splice_after(iterator __pos, iterator __prev)
Definition bslstp_slist.h:554
_Slist_iterator< _Tp, _Nonconst_traits< _Tp > > iterator
Definition bslstp_slist.h:277
void splice(iterator __pos, _Self &__x, iterator __i)
Definition bslstp_slist.h:576
void splice(iterator __pos, _Self &__x)
Definition bslstp_slist.h:569
slist(const _Self &__x, const allocator_type &__a)
Definition bslstp_slist.h:328
void sort()
Definition bslstp_slist.h:888
void insert(iterator __pos, _InIter __first, _InIter __last)
Definition bslstp_slist.h:507
std::forward_iterator_tag _Iterator_category
Definition bslstp_slist.h:275
void _M_assign_dispatch(_InputIter __first, _InputIter __last, bsl::false_type *)
Definition bslstp_slist.h:369
const_iterator begin() const
Definition bslstp_slist.h:398
_Slist_iterator< _Tp, _Const_traits< _Tp > > const_iterator
Definition bslstp_slist.h:278
size_type max_size() const
Definition bslstp_slist.h:406
value_type * pointer
Definition bslstp_slist.h:269
const_iterator previous(const_iterator __pos) const
Definition bslstp_slist.h:433
void resize(size_type new_size, const value_type &__x=_Tp())
Definition bslstp_slist.h:831
void assign(_InputIterator __first, _InputIterator __last)
Definition bslstp_slist.h:357
slist(_InputIterator __first, _InputIterator __last, const allocator_type &__a=allocator_type())
Definition bslstp_slist.h:318
friend struct QuickSwap
Definition bslstp_slist.h:250
~slist()
Definition bslstp_slist.h:343
void assign(size_type __n, const _Tp &__val)
Definition bslstp_slist.h:351
const value_type & const_reference
Definition bslstp_slist.h:272
void remove(const _Tp &__val)
Definition bslstp_slist.h:845
void pop_front()
Definition bslstp_slist.h:422
std::size_t size_type
Definition bslstp_slist.h:273
void _M_assign_dispatch(_Integer __n, _Integer __val, bsl::true_type *)
Definition bslstp_slist.h:364
iterator erase_after(iterator __pos)
Definition bslstp_slist.h:516
void clear()
Definition bslstp_slist.h:536
_Container::iterator iter
Definition bslstp_slist.h:956
output_iterator_tag iterator_category
Definition bslstp_slist.h:959
insert_iterator< _Container > & operator++()
Definition bslstp_slist.h:979
void difference_type
Definition bslstp_slist.h:961
_Container * container
Definition bslstp_slist.h:955
bsl::slist< _Tp, _Alloc > _Container
Definition bslstp_slist.h:954
void reference
Definition bslstp_slist.h:963
insert_iterator< _Container > & operator++(int)
Definition bslstp_slist.h:980
_Container container_type
Definition bslstp_slist.h:958
insert_iterator< _Container > & operator=(const typename _Container::value_type &__val)
Definition bslstp_slist.h:974
insert_iterator< _Container > & operator*()
Definition bslstp_slist.h:978
void pointer
Definition bslstp_slist.h:962
insert_iterator(_Container &__x, typename _Container::iterator __i)
Definition bslstp_slist.h:965
void value_type
Definition bslstp_slist.h:960
#define BSLS_CATCH(X)
Definition bsls_exceptionutil.h:372
#define BSLS_TRY
Definition bsls_exceptionutil.h:370
#define BSLS_RETHROW
Definition bsls_exceptionutil.h:378
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
Definition bdlb_printmethods.h:283
_Slist_node_base * __slist_make_link(_Slist_node_base *__prev_node, _Slist_node_base *__new_node)
Definition bslstp_slistbase.h:95
BSLS_KEYWORD_CONSTEXPR bool empty(const CONTAINER &container)
Definition bslstl_iterator.h:1279
Definition bslstp_exfunctional.h:323
Definition bdldfp_decimal.h:5188
_Rebind_type::other allocator_type
Definition bslstp_alloc.h:98
Definition bslstp_slist.h:208
_Slist_node_base * _M_erase_after(_Slist_node_base *, _Slist_node_base *)
Definition bslstp_slist.h:778
_STLP_alloc_proxy< _Slist_node_base, _Node, _M_node_allocator_type > _M_head
Definition bslstp_slist.h:239
_Slist_node_base * _M_erase_after(_Slist_node_base *__pos)
Definition bslstp_slist.h:222
_Alloc_traits< _Tp, _Alloc >::allocator_type allocator_type
Definition bslstp_slist.h:210
~_Slist_base()
Definition bslstp_slist.h:217
_Slist_node< _Tp > _Node
Definition bslstp_slist.h:211
_Alloc_traits< _Node, _Alloc >::allocator_type _M_node_allocator_type
Definition bslstp_slist.h:220
allocator_type get_allocator() const
Definition bslstp_slist.h:235
_Slist_base(const allocator_type &__a)
Definition bslstp_slist.h:213
Definition bslstp_slist.h:145
std::ptrdiff_t difference_type
Definition bslstp_slist.h:148
bool operator!=(const _Slist_iterator_base &__y) const
Definition bslstp_slist.h:162
_Slist_node_base * _M_node
Definition bslstp_slist.h:151
std::forward_iterator_tag iterator_category
Definition bslstp_slist.h:149
std::size_t size_type
Definition bslstp_slist.h:147
void _M_incr()
Definition bslstp_slist.h:155
_Slist_iterator_base(_Slist_node_base *__x)
Definition bslstp_slist.h:153
bool operator==(const _Slist_iterator_base &__y) const
Definition bslstp_slist.h:159
Definition bslstp_slist.h:170
_Traits::pointer pointer
Definition bslstp_slist.h:172
_Slist_node< value_type > _Node
Definition bslstp_slist.h:182
_Slist_iterator< _Tp, _Const_traits< _Tp > > const_iterator
Definition bslstp_slist.h:179
_Slist_iterator(const iterator &__x)
Definition bslstp_slist.h:186
_Slist_iterator< _Tp, _Nonconst_traits< _Tp > > iterator
Definition bslstp_slist.h:178
ptrdiff_t difference_type
Definition bslstp_slist.h:176
_Tp value_type
Definition bslstp_slist.h:171
std::forward_iterator_tag iterator_category
Definition bslstp_slist.h:174
pointer operator->() const
Definition bslstp_slist.h:190
reference operator*() const
Definition bslstp_slist.h:188
_Self operator++(int)
Definition bslstp_slist.h:197
std::size_t size_type
Definition bslstp_slist.h:175
_Slist_iterator(_Node *__x)
Definition bslstp_slist.h:184
_Slist_iterator< _Tp, _Traits > _Self
Definition bslstp_slist.h:180
_Traits::reference reference
Definition bslstp_slist.h:173
_Slist_iterator()
Definition bslstp_slist.h:185
_Self & operator++()
Definition bslstp_slist.h:192
Definition bslstp_slistbase.h:90
_Slist_node_base * _M_next
Definition bslstp_slistbase.h:91
Definition bslstp_slist.h:141
_Tp _M_data
Definition bslstp_slist.h:142
Definition bslmf_isfundamental.h:329