1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | #ifndef _FORWARD_LIST_H |
31 | #define _FORWARD_LIST_H 1 |
32 | |
33 | #pragma GCC system_header |
34 | |
35 | #include <initializer_list> |
36 | #include <bits/stl_iterator_base_types.h> |
37 | #include <bits/stl_iterator.h> |
38 | #include <bits/stl_algobase.h> |
39 | #include <bits/stl_function.h> |
40 | #include <bits/allocator.h> |
41 | #include <ext/alloc_traits.h> |
42 | #include <ext/aligned_buffer.h> |
43 | |
44 | namespace std _GLIBCXX_VISIBILITY(default) |
45 | { |
46 | _GLIBCXX_BEGIN_NAMESPACE_CONTAINER |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | struct _Fwd_list_node_base |
54 | { |
55 | _Fwd_list_node_base() = default; |
56 | |
57 | _Fwd_list_node_base* _M_next = nullptr; |
58 | |
59 | _Fwd_list_node_base* |
60 | _M_transfer_after(_Fwd_list_node_base* __begin, |
61 | _Fwd_list_node_base* __end) noexcept |
62 | { |
63 | _Fwd_list_node_base* __keep = __begin->_M_next; |
64 | if (__end) |
65 | { |
66 | __begin->_M_next = __end->_M_next; |
67 | __end->_M_next = _M_next; |
68 | } |
69 | else |
70 | __begin->_M_next = 0; |
71 | _M_next = __keep; |
72 | return __end; |
73 | } |
74 | |
75 | void |
76 | _M_reverse_after() noexcept |
77 | { |
78 | _Fwd_list_node_base* __tail = _M_next; |
79 | if (!__tail) |
80 | return; |
81 | while (_Fwd_list_node_base* __temp = __tail->_M_next) |
82 | { |
83 | _Fwd_list_node_base* __keep = _M_next; |
84 | _M_next = __temp; |
85 | __tail->_M_next = __temp->_M_next; |
86 | _M_next->_M_next = __keep; |
87 | } |
88 | } |
89 | }; |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | template<typename _Tp> |
98 | struct _Fwd_list_node |
99 | : public _Fwd_list_node_base |
100 | { |
101 | _Fwd_list_node() = default; |
102 | |
103 | __gnu_cxx::__aligned_buffer<_Tp> _M_storage; |
104 | |
105 | _Tp* |
106 | _M_valptr() noexcept |
107 | { return _M_storage._M_ptr(); } |
108 | |
109 | const _Tp* |
110 | _M_valptr() const noexcept |
111 | { return _M_storage._M_ptr(); } |
112 | }; |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | template<typename _Tp> |
120 | struct _Fwd_list_iterator |
121 | { |
122 | typedef _Fwd_list_iterator<_Tp> _Self; |
123 | typedef _Fwd_list_node<_Tp> _Node; |
124 | |
125 | typedef _Tp value_type; |
126 | typedef _Tp* pointer; |
127 | typedef _Tp& reference; |
128 | typedef ptrdiff_t difference_type; |
129 | typedef std::forward_iterator_tag iterator_category; |
130 | |
131 | _Fwd_list_iterator() noexcept |
132 | : _M_node() { } |
133 | |
134 | explicit |
135 | _Fwd_list_iterator(_Fwd_list_node_base* __n) noexcept |
136 | : _M_node(__n) { } |
137 | |
138 | reference |
139 | operator*() const noexcept |
140 | { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); } |
141 | |
142 | pointer |
143 | operator->() const noexcept |
144 | { return static_cast<_Node*>(this->_M_node)->_M_valptr(); } |
145 | |
146 | _Self& |
147 | operator++() noexcept |
148 | { |
149 | _M_node = _M_node->_M_next; |
150 | return *this; |
151 | } |
152 | |
153 | _Self |
154 | operator++(int) noexcept |
155 | { |
156 | _Self __tmp(*this); |
157 | _M_node = _M_node->_M_next; |
158 | return __tmp; |
159 | } |
160 | |
161 | bool |
162 | operator==(const _Self& __x) const noexcept |
163 | { return _M_node == __x._M_node; } |
164 | |
165 | bool |
166 | operator!=(const _Self& __x) const noexcept |
167 | { return _M_node != __x._M_node; } |
168 | |
169 | _Self |
170 | _M_next() const noexcept |
171 | { |
172 | if (_M_node) |
173 | return _Fwd_list_iterator(_M_node->_M_next); |
174 | else |
175 | return _Fwd_list_iterator(0); |
176 | } |
177 | |
178 | _Fwd_list_node_base* _M_node; |
179 | }; |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | template<typename _Tp> |
187 | struct _Fwd_list_const_iterator |
188 | { |
189 | typedef _Fwd_list_const_iterator<_Tp> _Self; |
190 | typedef const _Fwd_list_node<_Tp> _Node; |
191 | typedef _Fwd_list_iterator<_Tp> iterator; |
192 | |
193 | typedef _Tp value_type; |
194 | typedef const _Tp* pointer; |
195 | typedef const _Tp& reference; |
196 | typedef ptrdiff_t difference_type; |
197 | typedef std::forward_iterator_tag iterator_category; |
198 | |
199 | _Fwd_list_const_iterator() noexcept |
200 | : _M_node() { } |
201 | |
202 | explicit |
203 | _Fwd_list_const_iterator(const _Fwd_list_node_base* __n) noexcept |
204 | : _M_node(__n) { } |
205 | |
206 | _Fwd_list_const_iterator(const iterator& __iter) noexcept |
207 | : _M_node(__iter._M_node) { } |
208 | |
209 | reference |
210 | operator*() const noexcept |
211 | { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); } |
212 | |
213 | pointer |
214 | operator->() const noexcept |
215 | { return static_cast<_Node*>(this->_M_node)->_M_valptr(); } |
216 | |
217 | _Self& |
218 | operator++() noexcept |
219 | { |
220 | _M_node = _M_node->_M_next; |
221 | return *this; |
222 | } |
223 | |
224 | _Self |
225 | operator++(int) noexcept |
226 | { |
227 | _Self __tmp(*this); |
228 | _M_node = _M_node->_M_next; |
229 | return __tmp; |
230 | } |
231 | |
232 | bool |
233 | operator==(const _Self& __x) const noexcept |
234 | { return _M_node == __x._M_node; } |
235 | |
236 | bool |
237 | operator!=(const _Self& __x) const noexcept |
238 | { return _M_node != __x._M_node; } |
239 | |
240 | _Self |
241 | _M_next() const noexcept |
242 | { |
243 | if (this->_M_node) |
244 | return _Fwd_list_const_iterator(_M_node->_M_next); |
245 | else |
246 | return _Fwd_list_const_iterator(0); |
247 | } |
248 | |
249 | const _Fwd_list_node_base* _M_node; |
250 | }; |
251 | |
252 | |
253 | |
254 | |
255 | template<typename _Tp> |
256 | inline bool |
257 | operator==(const _Fwd_list_iterator<_Tp>& __x, |
258 | const _Fwd_list_const_iterator<_Tp>& __y) noexcept |
259 | { return __x._M_node == __y._M_node; } |
260 | |
261 | |
262 | |
263 | |
264 | template<typename _Tp> |
265 | inline bool |
266 | operator!=(const _Fwd_list_iterator<_Tp>& __x, |
267 | const _Fwd_list_const_iterator<_Tp>& __y) noexcept |
268 | { return __x._M_node != __y._M_node; } |
269 | |
270 | |
271 | |
272 | |
273 | template<typename _Tp, typename _Alloc> |
274 | struct _Fwd_list_base |
275 | { |
276 | protected: |
277 | typedef __alloc_rebind<_Alloc, _Fwd_list_node<_Tp>> _Node_alloc_type; |
278 | typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits; |
279 | |
280 | struct _Fwd_list_impl |
281 | : public _Node_alloc_type |
282 | { |
283 | _Fwd_list_node_base _M_head; |
284 | |
285 | _Fwd_list_impl() |
286 | : _Node_alloc_type(), _M_head() |
287 | { } |
288 | |
289 | _Fwd_list_impl(const _Node_alloc_type& __a) |
290 | : _Node_alloc_type(__a), _M_head() |
291 | { } |
292 | |
293 | _Fwd_list_impl(_Node_alloc_type&& __a) |
294 | : _Node_alloc_type(std::move(__a)), _M_head() |
295 | { } |
296 | }; |
297 | |
298 | _Fwd_list_impl _M_impl; |
299 | |
300 | public: |
301 | typedef _Fwd_list_iterator<_Tp> iterator; |
302 | typedef _Fwd_list_const_iterator<_Tp> const_iterator; |
303 | typedef _Fwd_list_node<_Tp> _Node; |
304 | |
305 | _Node_alloc_type& |
306 | _M_get_Node_allocator() noexcept |
307 | { return this->_M_impl; } |
308 | |
309 | const _Node_alloc_type& |
310 | _M_get_Node_allocator() const noexcept |
311 | { return this->_M_impl; } |
312 | |
313 | _Fwd_list_base() |
314 | : _M_impl() { } |
315 | |
316 | _Fwd_list_base(_Node_alloc_type&& __a) |
317 | : _M_impl(std::move(__a)) { } |
318 | |
319 | _Fwd_list_base(_Fwd_list_base&& __lst, _Node_alloc_type&& __a); |
320 | |
321 | _Fwd_list_base(_Fwd_list_base&& __lst) |
322 | : _M_impl(std::move(__lst._M_get_Node_allocator())) |
323 | { |
324 | this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next; |
325 | __lst._M_impl._M_head._M_next = 0; |
326 | } |
327 | |
328 | ~_Fwd_list_base() |
329 | { _M_erase_after(&_M_impl._M_head, 0); } |
330 | |
331 | protected: |
332 | |
333 | _Node* |
334 | _M_get_node() |
335 | { |
336 | auto __ptr = _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); |
337 | return std::__addressof(*__ptr); |
338 | } |
339 | |
340 | template<typename... _Args> |
341 | _Node* |
342 | _M_create_node(_Args&&... __args) |
343 | { |
344 | _Node* __node = this->_M_get_node(); |
345 | __try |
346 | { |
347 | ::new ((void*)__node) _Node; |
348 | _Node_alloc_traits::construct(_M_get_Node_allocator(), |
349 | __node->_M_valptr(), |
350 | std::forward<_Args>(__args)...); |
351 | } |
352 | __catch(...) |
353 | { |
354 | this->_M_put_node(__node); |
355 | __throw_exception_again; |
356 | } |
357 | return __node; |
358 | } |
359 | |
360 | template<typename... _Args> |
361 | _Fwd_list_node_base* |
362 | _M_insert_after(const_iterator __pos, _Args&&... __args); |
363 | |
364 | void |
365 | _M_put_node(_Node* __p) |
366 | { |
367 | typedef typename _Node_alloc_traits::pointer _Ptr; |
368 | auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__p); |
369 | _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __ptr, 1); |
370 | } |
371 | |
372 | _Fwd_list_node_base* |
373 | _M_erase_after(_Fwd_list_node_base* __pos); |
374 | |
375 | _Fwd_list_node_base* |
376 | _M_erase_after(_Fwd_list_node_base* __pos, |
377 | _Fwd_list_node_base* __last); |
378 | }; |
379 | |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | |
386 | |
387 | |
388 | |
389 | |
390 | |
391 | |
392 | |
393 | |
394 | |
395 | |
396 | |
397 | |
398 | |
399 | |
400 | |
401 | |
402 | |
403 | |
404 | |
405 | |
406 | template<typename _Tp, typename _Alloc = allocator<_Tp> > |
407 | class forward_list : private _Fwd_list_base<_Tp, _Alloc> |
408 | { |
409 | private: |
410 | typedef _Fwd_list_base<_Tp, _Alloc> _Base; |
411 | typedef _Fwd_list_node<_Tp> _Node; |
412 | typedef _Fwd_list_node_base _Node_base; |
413 | typedef typename _Base::_Node_alloc_type _Node_alloc_type; |
414 | typedef typename _Base::_Node_alloc_traits _Node_alloc_traits; |
415 | typedef allocator_traits<__alloc_rebind<_Alloc, _Tp>> _Alloc_traits; |
416 | |
417 | public: |
418 | |
419 | typedef _Tp value_type; |
420 | typedef typename _Alloc_traits::pointer pointer; |
421 | typedef typename _Alloc_traits::const_pointer const_pointer; |
422 | typedef value_type& reference; |
423 | typedef const value_type& const_reference; |
424 | |
425 | typedef _Fwd_list_iterator<_Tp> iterator; |
426 | typedef _Fwd_list_const_iterator<_Tp> const_iterator; |
427 | typedef std::size_t size_type; |
428 | typedef std::ptrdiff_t difference_type; |
429 | typedef _Alloc allocator_type; |
430 | |
431 | |
432 | |
433 | |
434 | |
435 | |
436 | forward_list() |
437 | noexcept(is_nothrow_default_constructible<_Node_alloc_type>::value) |
438 | : _Base() |
439 | { } |
440 | |
441 | |
442 | |
443 | |
444 | |
445 | explicit |
446 | forward_list(const _Alloc& __al) noexcept |
447 | : _Base(_Node_alloc_type(__al)) |
448 | { } |
449 | |
450 | |
451 | |
452 | |
453 | |
454 | |
455 | |
456 | forward_list(const forward_list& __list, const _Alloc& __al) |
457 | : _Base(_Node_alloc_type(__al)) |
458 | { _M_range_initialize(__list.begin(), __list.end()); } |
459 | |
460 | |
461 | |
462 | |
463 | |
464 | |
465 | forward_list(forward_list&& __list, const _Alloc& __al) |
466 | noexcept(_Node_alloc_traits::_S_always_equal()) |
467 | : _Base(std::move(__list), _Node_alloc_type(__al)) |
468 | { |
469 | |
470 | |
471 | insert_after(cbefore_begin(), |
472 | std::__make_move_if_noexcept_iterator(__list.begin()), |
473 | std::__make_move_if_noexcept_iterator(__list.end())); |
474 | } |
475 | |
476 | |
477 | |
478 | |
479 | |
480 | |
481 | |
482 | |
483 | |
484 | explicit |
485 | forward_list(size_type __n, const _Alloc& __al = _Alloc()) |
486 | : _Base(_Node_alloc_type(__al)) |
487 | { _M_default_initialize(__n); } |
488 | |
489 | |
490 | |
491 | |
492 | |
493 | |
494 | |
495 | |
496 | |
497 | |
498 | forward_list(size_type __n, const _Tp& __value, |
499 | const _Alloc& __al = _Alloc()) |
500 | : _Base(_Node_alloc_type(__al)) |
501 | { _M_fill_initialize(__n, __value); } |
502 | |
503 | |
504 | |
505 | |
506 | |
507 | |
508 | |
509 | |
510 | |
511 | |
512 | |
513 | template<typename _InputIterator, |
514 | typename = std::_RequireInputIter<_InputIterator>> |
515 | forward_list(_InputIterator __first, _InputIterator __last, |
516 | const _Alloc& __al = _Alloc()) |
517 | : _Base(_Node_alloc_type(__al)) |
518 | { _M_range_initialize(__first, __last); } |
519 | |
520 | |
521 | |
522 | |
523 | |
524 | |
525 | forward_list(const forward_list& __list) |
526 | : _Base(_Node_alloc_traits::_S_select_on_copy( |
527 | __list._M_get_Node_allocator())) |
528 | { _M_range_initialize(__list.begin(), __list.end()); } |
529 | |
530 | |
531 | |
532 | |
533 | |
534 | |
535 | |
536 | |
537 | |
538 | |
539 | forward_list(forward_list&& __list) noexcept |
540 | : _Base(std::move(__list)) { } |
541 | |
542 | |
543 | |
544 | |
545 | |
546 | |
547 | |
548 | |
549 | |
550 | forward_list(std::initializer_list<_Tp> __il, |
551 | const _Alloc& __al = _Alloc()) |
552 | : _Base(_Node_alloc_type(__al)) |
553 | { _M_range_initialize(__il.begin(), __il.end()); } |
554 | |
555 | |
556 | |
557 | |
558 | ~forward_list() noexcept |
559 | { } |
560 | |
561 | |
562 | |
563 | |
564 | |
565 | |
566 | |
567 | |
568 | |
569 | |
570 | forward_list& |
571 | operator=(const forward_list& __list); |
572 | |
573 | |
574 | |
575 | |
576 | |
577 | |
578 | |
579 | |
580 | |
581 | |
582 | |
583 | |
584 | |
585 | forward_list& |
586 | operator=(forward_list&& __list) |
587 | noexcept(_Node_alloc_traits::_S_nothrow_move()) |
588 | { |
589 | constexpr bool __move_storage = |
590 | _Node_alloc_traits::_S_propagate_on_move_assign() |
591 | || _Node_alloc_traits::_S_always_equal(); |
592 | _M_move_assign(std::move(__list), __bool_constant<__move_storage>()); |
593 | return *this; |
594 | } |
595 | |
596 | |
597 | |
598 | |
599 | |
600 | |
601 | |
602 | |
603 | |
604 | forward_list& |
605 | operator=(std::initializer_list<_Tp> __il) |
606 | { |
607 | assign(__il); |
608 | return *this; |
609 | } |
610 | |
611 | |
612 | |
613 | |
614 | |
615 | |
616 | |
617 | |
618 | |
619 | |
620 | |
621 | |
622 | |
623 | template<typename _InputIterator, |
624 | typename = std::_RequireInputIter<_InputIterator>> |
625 | void |
626 | assign(_InputIterator __first, _InputIterator __last) |
627 | { |
628 | typedef is_assignable<_Tp, decltype(*__first)> __assignable; |
629 | _M_assign(__first, __last, __assignable()); |
630 | } |
631 | |
632 | |
633 | |
634 | |
635 | |
636 | |
637 | |
638 | |
639 | |
640 | |
641 | |
642 | void |
643 | assign(size_type __n, const _Tp& __val) |
644 | { _M_assign_n(__n, __val, is_copy_assignable<_Tp>()); } |
645 | |
646 | |
647 | |
648 | |
649 | |
650 | |
651 | |
652 | |
653 | |
654 | void |
655 | assign(std::initializer_list<_Tp> __il) |
656 | { assign(__il.begin(), __il.end()); } |
657 | |
658 | |
659 | allocator_type |
660 | get_allocator() const noexcept |
661 | { return allocator_type(this->_M_get_Node_allocator()); } |
662 | |
663 | |
664 | |
665 | |
666 | |
667 | |
668 | |
669 | iterator |
670 | before_begin() noexcept |
671 | { return iterator(&this->_M_impl._M_head); } |
672 | |
673 | |
674 | |
675 | |
676 | |
677 | |
678 | const_iterator |
679 | before_begin() const noexcept |
680 | { return const_iterator(&this->_M_impl._M_head); } |
681 | |
682 | |
683 | |
684 | |
685 | |
686 | iterator |
687 | begin() noexcept |
688 | { return iterator(this->_M_impl._M_head._M_next); } |
689 | |
690 | |
691 | |
692 | |
693 | |
694 | |
695 | const_iterator |
696 | begin() const noexcept |
697 | { return const_iterator(this->_M_impl._M_head._M_next); } |
698 | |
699 | |
700 | |
701 | |
702 | |
703 | |
704 | iterator |
705 | end() noexcept |
706 | { return iterator(0); } |
707 | |
708 | |
709 | |
710 | |
711 | |
712 | |
713 | const_iterator |
714 | end() const noexcept |
715 | { return const_iterator(0); } |
716 | |
717 | |
718 | |
719 | |
720 | |
721 | |
722 | const_iterator |
723 | cbegin() const noexcept |
724 | { return const_iterator(this->_M_impl._M_head._M_next); } |
725 | |
726 | |
727 | |
728 | |
729 | |
730 | |
731 | const_iterator |
732 | cbefore_begin() const noexcept |
733 | { return const_iterator(&this->_M_impl._M_head); } |
734 | |
735 | |
736 | |
737 | |
738 | |
739 | |
740 | const_iterator |
741 | cend() const noexcept |
742 | { return const_iterator(0); } |
743 | |
744 | |
745 | |
746 | |
747 | |
748 | bool |
749 | empty() const noexcept |
750 | { return this->_M_impl._M_head._M_next == 0; } |
751 | |
752 | |
753 | |
754 | |
755 | size_type |
756 | max_size() const noexcept |
757 | { return _Node_alloc_traits::max_size(this->_M_get_Node_allocator()); } |
758 | |
759 | |
760 | |
761 | |
762 | |
763 | |
764 | |
765 | reference |
766 | front() |
767 | { |
768 | _Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next); |
769 | return *__front->_M_valptr(); |
770 | } |
771 | |
772 | |
773 | |
774 | |
775 | |
776 | const_reference |
777 | front() const |
778 | { |
779 | _Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next); |
780 | return *__front->_M_valptr(); |
781 | } |
782 | |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | |
789 | |
790 | |
791 | |
792 | |
793 | |
794 | |
795 | |
796 | template<typename... _Args> |
797 | #if __cplusplus > 201402L |
798 | reference |
799 | #else |
800 | void |
801 | #endif |
802 | emplace_front(_Args&&... __args) |
803 | { |
804 | this->_M_insert_after(cbefore_begin(), |
805 | std::forward<_Args>(__args)...); |
806 | #if __cplusplus > 201402L |
807 | return front(); |
808 | #endif |
809 | } |
810 | |
811 | |
812 | |
813 | |
814 | |
815 | |
816 | |
817 | |
818 | |
819 | |
820 | |
821 | void |
822 | push_front(const _Tp& __val) |
823 | { this->_M_insert_after(cbefore_begin(), __val); } |
824 | |
825 | |
826 | |
827 | |
828 | void |
829 | push_front(_Tp&& __val) |
830 | { this->_M_insert_after(cbefore_begin(), std::move(__val)); } |
831 | |
832 | |
833 | |
834 | |
835 | |
836 | |
837 | |
838 | |
839 | |
840 | |
841 | |
842 | |
843 | |
844 | void |
845 | pop_front() |
846 | { this->_M_erase_after(&this->_M_impl._M_head); } |
847 | |
848 | |
849 | |
850 | |
851 | |
852 | |
853 | |
854 | |
855 | |
856 | |
857 | |
858 | |
859 | |
860 | |
861 | template<typename... _Args> |
862 | iterator |
863 | emplace_after(const_iterator __pos, _Args&&... __args) |
864 | { return iterator(this->_M_insert_after(__pos, |
865 | std::forward<_Args>(__args)...)); } |
866 | |
867 | |
868 | |
869 | |
870 | |
871 | |
872 | |
873 | |
874 | |
875 | |
876 | |
877 | |
878 | |
879 | iterator |
880 | insert_after(const_iterator __pos, const _Tp& __val) |
881 | { return iterator(this->_M_insert_after(__pos, __val)); } |
882 | |
883 | |
884 | |
885 | |
886 | iterator |
887 | insert_after(const_iterator __pos, _Tp&& __val) |
888 | { return iterator(this->_M_insert_after(__pos, std::move(__val))); } |
889 | |
890 | |
891 | |
892 | |
893 | |
894 | |
895 | |
896 | |
897 | |
898 | |
899 | |
900 | |
901 | |
902 | |
903 | |
904 | |
905 | iterator |
906 | insert_after(const_iterator __pos, size_type __n, const _Tp& __val); |
907 | |
908 | |
909 | |
910 | |
911 | |
912 | |
913 | |
914 | |
915 | |
916 | |
917 | |
918 | |
919 | |
920 | |
921 | |
922 | |
923 | template<typename _InputIterator, |
924 | typename = std::_RequireInputIter<_InputIterator>> |
925 | iterator |
926 | insert_after(const_iterator __pos, |
927 | _InputIterator __first, _InputIterator __last); |
928 | |
929 | |
930 | |
931 | |
932 | |
933 | |
934 | |
935 | |
936 | |
937 | |
938 | |
939 | |
940 | |
941 | |
942 | |
943 | |
944 | iterator |
945 | insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) |
946 | { return insert_after(__pos, __il.begin(), __il.end()); } |
947 | |
948 | |
949 | |
950 | |
951 | |
952 | |
953 | |
954 | |
955 | |
956 | |
957 | |
958 | |
959 | |
960 | |
961 | |
962 | |
963 | |
964 | |
965 | iterator |
966 | erase_after(const_iterator __pos) |
967 | { return iterator(this->_M_erase_after(const_cast<_Node_base*> |
968 | (__pos._M_node))); } |
969 | |
970 | |
971 | |
972 | |
973 | |
974 | |
975 | |
976 | |
977 | |
978 | |
979 | |
980 | |
981 | |
982 | |
983 | |
984 | |
985 | |
986 | |
987 | |
988 | iterator |
989 | erase_after(const_iterator __pos, const_iterator __last) |
990 | { return iterator(this->_M_erase_after(const_cast<_Node_base*> |
991 | (__pos._M_node), |
992 | const_cast<_Node_base*> |
993 | (__last._M_node))); } |
994 | |
995 | |
996 | |
997 | |
998 | |
999 | |
1000 | |
1001 | |
1002 | |
1003 | |
1004 | |
1005 | |
1006 | |
1007 | void |
1008 | swap(forward_list& __list) noexcept |
1009 | { |
1010 | std::swap(this->_M_impl._M_head._M_next, |
1011 | __list._M_impl._M_head._M_next); |
1012 | _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(), |
1013 | __list._M_get_Node_allocator()); |
1014 | } |
1015 | |
1016 | |
1017 | |
1018 | |
1019 | |
1020 | |
1021 | |
1022 | |
1023 | |
1024 | |
1025 | |
1026 | |
1027 | void |
1028 | resize(size_type __sz); |
1029 | |
1030 | |
1031 | |
1032 | |
1033 | |
1034 | |
1035 | |
1036 | |
1037 | |
1038 | |
1039 | |
1040 | |
1041 | |
1042 | void |
1043 | resize(size_type __sz, const value_type& __val); |
1044 | |
1045 | |
1046 | |
1047 | |
1048 | |
1049 | |
1050 | |
1051 | |
1052 | |
1053 | void |
1054 | clear() noexcept |
1055 | { this->_M_erase_after(&this->_M_impl._M_head, 0); } |
1056 | |
1057 | |
1058 | |
1059 | |
1060 | |
1061 | |
1062 | |
1063 | |
1064 | |
1065 | |
1066 | |
1067 | |
1068 | |
1069 | |
1070 | void |
1071 | splice_after(const_iterator __pos, forward_list&& __list) noexcept |
1072 | { |
1073 | if (!__list.empty()) |
1074 | _M_splice_after(__pos, __list.before_begin(), __list.end()); |
1075 | } |
1076 | |
1077 | void |
1078 | splice_after(const_iterator __pos, forward_list& __list) noexcept |
1079 | { splice_after(__pos, std::move(__list)); } |
1080 | |
1081 | |
1082 | |
1083 | |
1084 | |
1085 | |
1086 | |
1087 | |
1088 | |
1089 | |
1090 | |
1091 | void |
1092 | splice_after(const_iterator __pos, forward_list&& __list, |
1093 | const_iterator __i) noexcept; |
1094 | |
1095 | void |
1096 | splice_after(const_iterator __pos, forward_list& __list, |
1097 | const_iterator __i) noexcept |
1098 | { splice_after(__pos, std::move(__list), __i); } |
1099 | |
1100 | |
1101 | |
1102 | |
1103 | |
1104 | |
1105 | |
1106 | |
1107 | |
1108 | |
1109 | |
1110 | |
1111 | |
1112 | |
1113 | |
1114 | void |
1115 | splice_after(const_iterator __pos, forward_list&&, |
1116 | const_iterator __before, const_iterator __last) noexcept |
1117 | { _M_splice_after(__pos, __before, __last); } |
1118 | |
1119 | void |
1120 | splice_after(const_iterator __pos, forward_list&, |
1121 | const_iterator __before, const_iterator __last) noexcept |
1122 | { _M_splice_after(__pos, __before, __last); } |
1123 | |
1124 | |
1125 | |
1126 | |
1127 | |
1128 | |
1129 | |
1130 | |
1131 | |
1132 | |
1133 | |
1134 | |
1135 | |
1136 | void |
1137 | remove(const _Tp& __val); |
1138 | |
1139 | |
1140 | |
1141 | |
1142 | |
1143 | |
1144 | |
1145 | |
1146 | |
1147 | |
1148 | |
1149 | |
1150 | template<typename _Pred> |
1151 | void |
1152 | remove_if(_Pred __pred); |
1153 | |
1154 | |
1155 | |
1156 | |
1157 | |
1158 | |
1159 | |
1160 | |
1161 | |
1162 | |
1163 | |
1164 | void |
1165 | unique() |
1166 | { unique(std::equal_to<_Tp>()); } |
1167 | |
1168 | |
1169 | |
1170 | |
1171 | |
1172 | |
1173 | |
1174 | |
1175 | |
1176 | |
1177 | |
1178 | |
1179 | |
1180 | template<typename _BinPred> |
1181 | void |
1182 | unique(_BinPred __binary_pred); |
1183 | |
1184 | |
1185 | |
1186 | |
1187 | |
1188 | |
1189 | |
1190 | |
1191 | |
1192 | |
1193 | void |
1194 | merge(forward_list&& __list) |
1195 | { merge(std::move(__list), std::less<_Tp>()); } |
1196 | |
1197 | void |
1198 | merge(forward_list& __list) |
1199 | { merge(std::move(__list)); } |
1200 | |
1201 | |
1202 | |
1203 | |
1204 | |
1205 | |
1206 | |
1207 | |
1208 | |
1209 | |
1210 | |
1211 | |
1212 | template<typename _Comp> |
1213 | void |
1214 | merge(forward_list&& __list, _Comp __comp); |
1215 | |
1216 | template<typename _Comp> |
1217 | void |
1218 | merge(forward_list& __list, _Comp __comp) |
1219 | { merge(std::move(__list), __comp); } |
1220 | |
1221 | |
1222 | |
1223 | |
1224 | |
1225 | |
1226 | |
1227 | void |
1228 | sort() |
1229 | { sort(std::less<_Tp>()); } |
1230 | |
1231 | |
1232 | |
1233 | |
1234 | |
1235 | |
1236 | |
1237 | template<typename _Comp> |
1238 | void |
1239 | sort(_Comp __comp); |
1240 | |
1241 | |
1242 | |
1243 | |
1244 | |
1245 | |
1246 | void |
1247 | reverse() noexcept |
1248 | { this->_M_impl._M_head._M_reverse_after(); } |
1249 | |
1250 | private: |
1251 | |
1252 | template<typename _InputIterator> |
1253 | void |
1254 | _M_range_initialize(_InputIterator __first, _InputIterator __last); |
1255 | |
1256 | |
1257 | |
1258 | void |
1259 | _M_fill_initialize(size_type __n, const value_type& __value); |
1260 | |
1261 | |
1262 | iterator |
1263 | _M_splice_after(const_iterator __pos, const_iterator __before, |
1264 | const_iterator __last); |
1265 | |
1266 | |
1267 | void |
1268 | _M_default_initialize(size_type __n); |
1269 | |
1270 | |
1271 | void |
1272 | _M_default_insert_after(const_iterator __pos, size_type __n); |
1273 | |
1274 | |
1275 | void |
1276 | _M_move_assign(forward_list&& __list, std::true_type) noexcept |
1277 | { |
1278 | clear(); |
1279 | this->_M_impl._M_head._M_next = __list._M_impl._M_head._M_next; |
1280 | __list._M_impl._M_head._M_next = nullptr; |
1281 | std::__alloc_on_move(this->_M_get_Node_allocator(), |
1282 | __list._M_get_Node_allocator()); |
1283 | } |
1284 | |
1285 | |
1286 | void |
1287 | _M_move_assign(forward_list&& __list, std::false_type) |
1288 | { |
1289 | if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator()) |
1290 | _M_move_assign(std::move(__list), std::true_type()); |
1291 | else |
1292 | |
1293 | |
1294 | this->assign(std::__make_move_if_noexcept_iterator(__list.begin()), |
1295 | std::__make_move_if_noexcept_iterator(__list.end())); |
1296 | } |
1297 | |
1298 | |
1299 | |
1300 | template<typename _InputIterator> |
1301 | void |
1302 | _M_assign(_InputIterator __first, _InputIterator __last, true_type) |
1303 | { |
1304 | auto __prev = before_begin(); |
1305 | auto __curr = begin(); |
1306 | auto __end = end(); |
1307 | while (__curr != __end && __first != __last) |
1308 | { |
1309 | *__curr = *__first; |
1310 | ++__prev; |
1311 | ++__curr; |
1312 | ++__first; |
1313 | } |
1314 | if (__first != __last) |
1315 | insert_after(__prev, __first, __last); |
1316 | else if (__curr != __end) |
1317 | erase_after(__prev, __end); |
1318 | } |
1319 | |
1320 | |
1321 | |
1322 | template<typename _InputIterator> |
1323 | void |
1324 | _M_assign(_InputIterator __first, _InputIterator __last, false_type) |
1325 | { |
1326 | clear(); |
1327 | insert_after(cbefore_begin(), __first, __last); |
1328 | } |
1329 | |
1330 | |
1331 | void |
1332 | _M_assign_n(size_type __n, const _Tp& __val, true_type) |
1333 | { |
1334 | auto __prev = before_begin(); |
1335 | auto __curr = begin(); |
1336 | auto __end = end(); |
1337 | while (__curr != __end && __n > 0) |
1338 | { |
1339 | *__curr = __val; |
1340 | ++__prev; |
1341 | ++__curr; |
1342 | --__n; |
1343 | } |
1344 | if (__n > 0) |
1345 | insert_after(__prev, __n, __val); |
1346 | else if (__curr != __end) |
1347 | erase_after(__prev, __end); |
1348 | } |
1349 | |
1350 | |
1351 | void |
1352 | _M_assign_n(size_type __n, const _Tp& __val, false_type) |
1353 | { |
1354 | clear(); |
1355 | insert_after(cbefore_begin(), __n, __val); |
1356 | } |
1357 | }; |
1358 | |
1359 | |
1360 | |
1361 | |
1362 | |
1363 | |
1364 | |
1365 | |
1366 | |
1367 | |
1368 | |
1369 | template<typename _Tp, typename _Alloc> |
1370 | bool |
1371 | operator==(const forward_list<_Tp, _Alloc>& __lx, |
1372 | const forward_list<_Tp, _Alloc>& __ly); |
1373 | |
1374 | |
1375 | |
1376 | |
1377 | |
1378 | |
1379 | |
1380 | |
1381 | |
1382 | |
1383 | |
1384 | |
1385 | |
1386 | template<typename _Tp, typename _Alloc> |
1387 | inline bool |
1388 | operator<(const forward_list<_Tp, _Alloc>& __lx, |
1389 | const forward_list<_Tp, _Alloc>& __ly) |
1390 | { return std::lexicographical_compare(__lx.cbegin(), __lx.cend(), |
1391 | __ly.cbegin(), __ly.cend()); } |
1392 | |
1393 | |
1394 | template<typename _Tp, typename _Alloc> |
1395 | inline bool |
1396 | operator!=(const forward_list<_Tp, _Alloc>& __lx, |
1397 | const forward_list<_Tp, _Alloc>& __ly) |
1398 | { return !(__lx == __ly); } |
1399 | |
1400 | |
1401 | template<typename _Tp, typename _Alloc> |
1402 | inline bool |
1403 | operator>(const forward_list<_Tp, _Alloc>& __lx, |
1404 | const forward_list<_Tp, _Alloc>& __ly) |
1405 | { return (__ly < __lx); } |
1406 | |
1407 | |
1408 | template<typename _Tp, typename _Alloc> |
1409 | inline bool |
1410 | operator>=(const forward_list<_Tp, _Alloc>& __lx, |
1411 | const forward_list<_Tp, _Alloc>& __ly) |
1412 | { return !(__lx < __ly); } |
1413 | |
1414 | |
1415 | template<typename _Tp, typename _Alloc> |
1416 | inline bool |
1417 | operator<=(const forward_list<_Tp, _Alloc>& __lx, |
1418 | const forward_list<_Tp, _Alloc>& __ly) |
1419 | { return !(__ly < __lx); } |
1420 | |
1421 | |
1422 | template<typename _Tp, typename _Alloc> |
1423 | inline void |
1424 | swap(forward_list<_Tp, _Alloc>& __lx, |
1425 | forward_list<_Tp, _Alloc>& __ly) |
1426 | noexcept(noexcept(__lx.swap(__ly))) |
1427 | { __lx.swap(__ly); } |
1428 | |
1429 | _GLIBCXX_END_NAMESPACE_CONTAINER |
1430 | } |
1431 | |
1432 | #endif |
1433 | |