NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
deque.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_CONTAINER_DEQUE_HPP__
2#define NEFORCE_CORE_CONTAINER_DEQUE_HPP__
3
11
18NEFORCE_BEGIN_NAMESPACE__
19
25
36template <bool IsConst, typename Deque, size_t BufSize = 0>
37struct deque_iterator : iiterator<deque_iterator<IsConst, Deque, BufSize>> {
38public:
39 using container_type = Deque;
40 using value_type = typename container_type::value_type;
41 using size_type = typename container_type::size_type;
42 using difference_type = typename container_type::difference_type;
44 using reference = conditional_t<IsConst, typename container_type::const_reference,
45 typename container_type::reference>;
46 using pointer = conditional_t<IsConst, typename container_type::const_pointer,
47 typename container_type::pointer>;
48
58 static constexpr size_t deque_buf_size(const size_t n, const size_t sz) noexcept {
59 constexpr size_t buffer_threshhold = 256;
60 constexpr size_t buffer_max_size = MEMORY_BIG_ALLOC_THRESHHOLD;
61 return n != 0 ? n : sz < buffer_threshhold ? buffer_max_size / sz : 16;
62 }
63
65 static constexpr difference_type buffer_size = deque_buf_size(BufSize, sizeof(value_type));
66
67private:
68 pointer current_ = nullptr;
69 pointer first_ = nullptr;
70 pointer last_ = nullptr;
71 pointer* node_ = nullptr;
72 const container_type* container_ = nullptr;
73
74 template <typename, typename, size_t>
75 friend class deque;
76 template <bool, typename, size_t>
77 friend struct deque_iterator;
78
79private:
86 void change_buff(pointer* new_map) noexcept {
87 node_ = new_map;
88 first_ = *new_map;
89 last_ = first_ + buffer_size;
90 }
91
92public:
93 deque_iterator() noexcept = default;
94 ~deque_iterator() = default;
95
96 deque_iterator(const deque_iterator&) noexcept = default;
97 deque_iterator& operator=(const deque_iterator&) noexcept = default;
98 deque_iterator(deque_iterator&&) noexcept = default;
99 deque_iterator& operator=(deque_iterator&&) noexcept = default;
100
107 deque_iterator(pointer cur, pointer* map, const container_type* deq) :
108 current_(cur),
109 first_(*map),
110 last_(*map + buffer_size),
111 node_(map),
112 container_(deq) {}
113
122 deque_iterator(pointer cur, pointer first, pointer last, pointer* node, const container_type* deq) noexcept :
123 current_(cur),
124 first_(first),
125 last_(last),
126 node_(node),
127 container_(deq) {}
128
134 template <bool IsConst2>
135 explicit deque_iterator(const deque_iterator<IsConst2, Deque, BufSize>& other) noexcept :
136 current_(const_cast<pointer>(other.current_)),
137 first_(const_cast<pointer>(other.first_)),
138 last_(const_cast<pointer>(other.last_)),
139 node_(const_cast<pointer*>(other.node_)),
140 container_(other.container_) {}
141
146 NEFORCE_NODISCARD reference dereference() const noexcept {
147 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to dereference on a null pointer");
148 NEFORCE_DEBUG_VERIFY(first_ <= current_ && current_ < last_, "Attempting to dereference out of boundary");
149 return *current_;
150 }
151
157 void increment() noexcept {
158 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to increment a null pointer");
159 ++current_;
160 if (current_ == last_) {
161 deque_iterator::change_buff(node_ + 1);
162 current_ = first_;
163 }
164 }
165
171 void decrement() noexcept {
172 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to decrement a null pointer");
173 if (current_ == first_) {
174 deque_iterator::change_buff(node_ - 1);
175 current_ = last_;
176 }
177 --current_;
178 }
179
186 void advance(difference_type off) noexcept {
187 NEFORCE_DEBUG_VERIFY((current_ && container_) || off == 0, "Attempting to advance a null pointer");
188 const difference_type offset = off + (current_ - first_);
189 if (offset >= 0 && offset < buffer_size) {
190 current_ += off;
191 } else {
192 difference_type node_offset =
193 offset > 0 ? offset / buffer_size : -static_cast<difference_type>((-offset - 1) / buffer_size) - 1;
194 deque_iterator::change_buff(node_ + node_offset);
195 current_ = first_ + (offset - node_offset * buffer_size);
196 }
197 }
198
206 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 difference_type distance_to(const deque_iterator& other) const noexcept {
207 NEFORCE_DEBUG_VERIFY(container_ == other.container_, "Attempting to distance to a different container");
208 return (node_ - other.node_) * buffer_size + (current_ - first_) - (other.current_ - other.first_);
209 }
210
216 NEFORCE_NODISCARD reference operator[](const difference_type n) noexcept { return *(*this + n); }
217
223 NEFORCE_NODISCARD bool equal(const deque_iterator& rhs) const noexcept {
224 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_, "Attempting to equal to a different container");
225 return current_ == rhs.current_;
226 }
227
233 NEFORCE_NODISCARD bool less_than(const deque_iterator& rhs) const noexcept {
234 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_, "Attempting to less than a different container");
235 return node_ == rhs.node_ ? current_ < rhs.current_ : node_ < rhs.node_;
236 }
237
242 NEFORCE_NODISCARD pointer base() const noexcept { return current_; }
243
248 NEFORCE_NODISCARD const container_type* container() const noexcept { return container_; }
249};
250
251
264template <typename T, typename Alloc = allocator<T>, size_t BufSize = 0>
265class deque : public icollector<deque<T, Alloc>> {
266 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
267 static_assert(is_same_v<T, typename Alloc::value_type>, "allocator type mismatch.");
268 static_assert(is_object_v<T>, "deque only contains object types.");
269
270public:
271 using pointer = T*;
272 using reference = T&;
273 using const_pointer = const T*;
274 using const_reference = const T&;
275 using value_type = T;
282 using allocator_type = Alloc;
283
286
287private:
288 using map_pointer = pointer*;
289 using map_allocator = typename Alloc::template rebind<pointer>::other;
290
291 iterator start_{};
292 iterator finish_{};
293 // 压缩存储:分配器 + 中控器大小
294 compressed_pair<allocator_type, size_type> map_size_pair_{default_construct_tag{}, 0};
295 // 压缩存储:中控器分配器 + 中控器指针
296 compressed_pair<map_allocator, map_pointer> map_pair_{default_construct_tag{}, nullptr};
297
298private:
300 static constexpr size_t init_map_size = 8;
301
307 map_pointer create_map(const size_t n) {
308 map_pointer map = map_pair_.get_base().allocate(n);
309 for (size_t i = 0; i < n; ++i) {
310 *(map + i) = nullptr;
311 }
312 return map;
313 }
314
322 void create_nodes(map_pointer start, map_pointer finish) {
323 map_pointer cur;
324 try {
325 for (cur = start; cur <= finish; ++cur) {
326 *cur = map_size_pair_.get_base().allocate(buffer_size);
327 }
328 } catch (...) {
329 while (cur != start) {
330 --cur;
331 map_size_pair_.get_base().deallocate(*cur, buffer_size);
332 *cur = nullptr;
333 }
334 throw;
335 }
336 }
337
345 void destroy_nodes(map_pointer start, map_pointer finish) noexcept(is_nothrow_destructible_v<value_type>) {
346 for (map_pointer cur = start; cur <= finish; ++cur) {
347 if (*cur == nullptr) {
348 continue;
349 }
350 map_size_pair_.get_base().deallocate(*cur, buffer_size);
351 *cur = nullptr;
352 }
353 }
354
361 void create_map_and_nodes(const size_type n) {
362 size_type node_nums = n / buffer_size + (n % buffer_size ? 1 : 0);
363 map_size_pair_.value = _NEFORCE max(init_map_size, node_nums + 2);
364
365 try {
366 map_pair_.value = deque::create_map(map_size_pair_.value);
367 } catch (...) {
368 map_pair_.value = nullptr;
369 map_size_pair_.value = 0;
370 throw;
371 }
372
373 map_pointer nstart = map_pair_.value + (map_size_pair_.value - node_nums) / 2;
374 map_pointer nfinish = node_nums == 0 ? nstart : nstart + node_nums - 1;
375
376 try {
377 deque::create_nodes(nstart, nfinish);
378 } catch (...) {
379 deque::destroy_nodes(map_pair_.value, map_pair_.value + map_size_pair_.value - 1);
380 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
381 map_pair_.value = nullptr;
382 map_size_pair_.value = 0;
383 throw;
384 }
385
386 start_.change_buff(nstart);
387 finish_.change_buff(nfinish);
388 start_.current_ = start_.first_;
389 finish_.current_ = n == 0 ? start_.first_ : finish_.first_ + (n % buffer_size ? n % buffer_size : buffer_size);
390 start_.container_ = this;
391 finish_.container_ = this;
392 }
393
399 void fill_initialize(const size_type n, const T& value) {
400 deque::create_map_and_nodes(n);
401 if (n == 0) {
402 return;
403 }
404
405 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur) {
406 _NEFORCE uninitialized_fill(*cur, *cur + buffer_size, value);
407 }
408 _NEFORCE uninitialized_fill(finish_.first_, finish_.current_, value);
409 }
410
417 template <typename Iterator>
418 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> copy_initialize(Iterator first, Iterator last) {
419 deque::create_map_and_nodes(0);
420 deque::insert(end(), first, last);
421 return;
422 }
423
430 template <typename Iterator>
431 enable_if_t<is_ranges_fwd_iter_v<Iterator>> copy_initialize(Iterator first, Iterator last) {
432 deque::create_map_and_nodes(_NEFORCE distance(first, last));
433
434 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur) {
435 Iterator next = _NEFORCE next(first, buffer_size);
436 _NEFORCE uninitialized_copy(first, next, *cur);
437 first = next;
438 }
439 _NEFORCE uninitialized_copy(first, last, finish_.first_);
440 return;
441 }
442
448 void assign_aux_n(size_type n, const T& value) {
449 if (n > size()) {
450 _NEFORCE fill(begin(), end(), value);
451 deque::insert(end(), n - size(), value);
452 } else {
453 deque::erase(begin() + n, end());
454 _NEFORCE fill(begin(), end(), value);
455 }
456 }
457
464 template <typename Iterator>
465 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> assign_ranges(Iterator first, Iterator last) {
466 clear();
467 deque::insert(end(), first, last);
468 return;
469 }
470
477 template <typename Iterator>
478 enable_if_t<is_ranges_fwd_iter_v<Iterator>> assign_ranges(Iterator first, Iterator last) {
479 auto first1 = begin();
480 auto last1 = end();
481
482 for (; first != last && first1 != last1; ++first, ++first1) {
483 *first1 = *first;
484 }
485
486 if (first1 != last1) {
487 deque::erase(first1, last1);
488 } else {
489 deque::insert(first1, last1);
490 }
491 return;
492 }
493
502 void reallocate_map(const size_type n, const bool add_at_front) {
503 const size_type begin_left = start_.current_ - start_.first_;
504
505 if (add_at_front && begin_left < n) {
506 const size_t needed = (n - begin_left) / buffer_size + 1;
507
508 if (needed > static_cast<size_type>(start_.node_ - map_pair_.value)) {
509 const size_type new_size =
510 _NEFORCE max(map_size_pair_.value << 1, map_size_pair_.value + needed + init_map_size);
511 map_pointer map = deque::create_map(new_size);
512 const size_type old_buf = finish_.node_ - start_.node_ + 1;
513 const size_type new_buf = needed + old_buf;
514
515 auto begin = map + (new_size - new_buf) / 2;
516 auto mid = begin + needed;
517 auto end = mid + old_buf;
518
519 deque::create_nodes(begin, mid - 1);
520 for (auto begin1 = mid, begin2 = start_.node_; begin1 != end; ++begin1, ++begin2) {
521 *begin1 = *begin2;
522 }
523
524 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
525 map_pair_.value = map;
526 map_size_pair_.value = new_size;
527 start_ = iterator(*mid + (start_.current_ - start_.first_), mid, this);
528 finish_ = iterator(*(end - 1) + (finish_.current_ - finish_.first_), end - 1, this);
529 return;
530 }
531
532 deque::create_nodes(start_.node_ - needed, start_.node_ - 1);
533 return;
534 }
535
536 const size_type end_left = finish_.last_ - finish_.current_ - 1;
537
538 if (!add_at_front && end_left < n) {
539
540 const size_type needed = (n - end_left) / buffer_size + 1;
541
542 if (needed > static_cast<size_type>((map_pair_.value + map_size_pair_.value) - finish_.node_ - 1)) {
543 const size_type new_size =
544 _NEFORCE max(map_size_pair_.value << 1, map_size_pair_.value + needed + init_map_size);
545 map_pointer map = deque::create_map(new_size);
546 const size_type old_buf = finish_.node_ - start_.node_ + 1;
547 const size_type new_buf = needed + old_buf;
548
549 auto begin = map + (new_size - new_buf) / 2;
550 auto mid = begin + old_buf;
551 auto end = mid + needed;
552
553 for (auto begin1 = begin, begin2 = start_.node_; begin1 != mid; ++begin1, ++begin2) {
554 *begin1 = *begin2;
555 }
556 deque::create_nodes(mid, end - 1);
557
558 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
559 map_pair_.value = map;
560 map_size_pair_.value = new_size;
561 start_ = iterator(*begin + (start_.current_ - start_.first_), begin, this);
562 finish_ = iterator(*(mid - 1) + (finish_.current_ - finish_.first_), mid - 1, this);
563 return;
564 }
565
566 deque::create_nodes(finish_.node_ + 1, finish_.node_ + needed);
567 }
568 }
569
578 template <typename Iterator>
579 void insert_ranges_n(iterator position, Iterator first, Iterator last, size_type n) {
580 difference_type dist_before = position - start_;
581
582 if (dist_before < static_cast<difference_type>(size() / 2)) {
583 deque::reallocate_map(n, true);
584 auto old_start = start_;
585 auto new_start = start_ - n;
586 position = start_ + dist_before;
587
588 try {
589 if (dist_before >= n) {
590 iterator start_n = start_ + n;
591 _NEFORCE uninitialized_copy(start_, start_n, new_start);
592 start_ = new_start;
593 _NEFORCE copy(start_n, position, old_start);
594 _NEFORCE copy(first, last, position - n);
595 } else {
596 auto mid = _NEFORCE next(first, n - dist_before);
597 _NEFORCE uninitialized_copy(first, mid, _NEFORCE uninitialized_copy(start_, position, new_start));
598 start_ = new_start;
599 _NEFORCE copy(mid, last, old_start);
600 }
601 } catch (...) {
602 if (new_start.node_ != start_.node_) {
603 deque::destroy_nodes(new_start.node_, start_.node_ - 1);
604 }
605 throw;
606 }
607 } else {
608 deque::reallocate_map(n, false);
609 auto old_finish = finish_;
610 auto new_finish = finish_ + n;
611 const size_type dist_after = size() - dist_before;
612 position = finish_ - dist_after;
613
614 try {
615 if (dist_after > n) {
616 auto finish_n = finish_ - n;
617 _NEFORCE uninitialized_copy(finish_n, finish_, finish_);
618 finish_ = new_finish;
619 _NEFORCE copy_backward(position, finish_n, old_finish);
620 _NEFORCE copy(first, last, position);
621 } else {
622 auto mid = _NEFORCE next(first, dist_after);
623 _NEFORCE uninitialized_copy(position, finish_, _NEFORCE uninitialized_copy(mid, last, finish_));
624 finish_ = new_finish;
625 _NEFORCE copy(first, mid, position);
626 }
627 } catch (...) {
628 if (new_finish.node_ != finish_.node_) {
629 deque::destroy_nodes(finish_.node_ + 1, new_finish.node_);
630 }
631 throw;
632 }
633 }
634 }
635
643 template <typename Iterator>
644 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> insert_ranges(iterator position, Iterator first, Iterator last) {
645 if (last <= first) {
646 return;
647 }
648
649 const size_type n = _NEFORCE distance(first, last);
650 const size_type dist_before = position - start_;
651
652 if (dist_before < size() / 2) {
653 deque::reallocate_map(n, true);
654 } else {
655 deque::reallocate_map(n, false);
656 }
657
658 position = start_ + dist_before;
659 auto cur = --last;
660
661 for (size_type i = 0; i < n; ++i, --cur) {
662 deque::insert(position, *cur);
663 }
664 return;
665 }
666
674 template <typename Iterator>
675 enable_if_t<is_ranges_fwd_iter_v<Iterator>> insert_ranges(iterator position, Iterator first, Iterator last) {
676 if (last <= first) {
677 return;
678 }
679 const size_type n = _NEFORCE distance(first, last);
680
681 if (position.current_ == start_.current_) {
682 deque::reallocate_map(n, true);
683 auto new_start = start_ - n;
684 try {
685 _NEFORCE uninitialized_copy(first, last, new_start);
686 start_ = new_start;
687 } catch (...) {
688 if (new_start.node_ != start_.node_) {
689 deque::destroy_nodes(new_start.node_, start_.node_ - 1);
690 }
691 throw;
692 }
693 } else if (position.current_ == finish_.current_) {
694 deque::reallocate_map(n, false);
695 auto new_finish = finish_ + n;
696 try {
697 _NEFORCE uninitialized_copy(first, last, finish_);
698 finish_ = new_finish;
699 } catch (...) {
700 if (new_finish.node_ != finish_.node_) {
701 deque::destroy_nodes(finish_.node_ + 1, new_finish.node_);
702 }
703 throw;
704 }
705 } else {
706 deque::insert_ranges_n(position, first, last, n);
707 }
708 return;
709 }
710
717 void insert_n_aux(iterator position, size_type n, const T& value) {
718 difference_type dist_before = position - start_;
719 if (dist_before < static_cast<difference_type>(size() / 2)) {
720 deque::reallocate_map(n, true);
721 auto old_start = start_;
722 auto new_start = start_ - n;
723 position = start_ + dist_before;
724
725 try {
726 if (dist_before >= n) {
727 iterator start_n = start_ + n;
728 _NEFORCE uninitialized_copy(start_, start_n, new_start);
729 start_ = new_start;
730 _NEFORCE copy(start_n, position, old_start);
731 _NEFORCE fill(position - n, position, value);
732 } else {
733 _NEFORCE uninitialized_fill(_NEFORCE uninitialized_copy(start_, position, new_start), start_,
734 value);
735 start_ = new_start;
736 _NEFORCE fill(old_start, position, value);
737 }
738 } catch (...) {
739 if (new_start.node_ != start_.node_) {
740 deque::destroy_nodes(new_start.node_, start_.node_ - 1);
741 }
742 throw;
743 }
744 } else {
745 deque::reallocate_map(n, false);
746 auto old_finish = finish_;
747 auto new_finish = finish_ + n;
748 const size_type dist_after = size() - dist_before;
749 position = finish_ - dist_after;
750
751 try {
752 if (dist_after > n) {
753 auto finish_n = finish_ - n;
754 _NEFORCE uninitialized_copy(finish_n, finish_, finish_);
755 finish_ = new_finish;
756 _NEFORCE copy_backward(position, finish_n, old_finish);
757 _NEFORCE fill(position, position + n, value);
758 } else {
759 _NEFORCE uninitialized_fill(finish_, position + n, value);
760 _NEFORCE uninitialized_copy(position, finish_, position + n);
761 finish_ = new_finish;
762 _NEFORCE fill(position, old_finish, value);
763 }
764 } catch (...) {
765 if (new_finish.node_ != finish_.node_) {
766 deque::destroy_nodes(finish_.node_ + 1, new_finish.node_);
767 }
768 throw;
769 }
770 }
771 }
772
780 template <typename... Args>
781 iterator insert_aux(iterator position, Args&&... args) noexcept(is_nothrow_move_assignable_v<value_type>) {
782 size_type index = position - start_;
783
784 if (index < size() / 2) {
786
787 iterator new_pos = start_ + index;
788 if (new_pos != finish_ - 1) {
789 _NEFORCE copy_backward(new_pos, finish_ - 1, finish_);
790 }
791
792 _NEFORCE destroy(new_pos.current_);
793 _NEFORCE construct(new_pos.current_, _NEFORCE forward<Args>(args)...);
794 return new_pos;
795 } else {
797
798 iterator new_pos = start_ + index;
799 if (new_pos != start_) {
800 _NEFORCE copy_backward(start_, new_pos, new_pos + 1);
801 }
802
803 _NEFORCE destroy(new_pos.current_);
804 _NEFORCE construct(new_pos.current_, _NEFORCE forward<Args>(args)...);
805 return new_pos;
806 }
807 }
808
809public:
815 deque() { deque::fill_initialize(0, _NEFORCE initialize<T>()); }
816
821 explicit deque(const size_type n) { deque::fill_initialize(n, _NEFORCE initialize<T>()); }
822
828 deque(const size_type n, const T& value) { deque::fill_initialize(n, value); }
829
836 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
837 deque(Iterator first, Iterator last) {
838 deque::copy_initialize(first, last);
839 }
840
845 deque(std::initializer_list<T> ilist) { deque::copy_initialize(ilist.begin(), ilist.end()); }
846
852 deque& operator=(std::initializer_list<T> ilist) {
853 deque tmp(ilist);
854 deque::swap(tmp);
855 return *this;
856 }
857
862 deque(const deque& other) { deque::copy_initialize(other.cbegin(), other.cend()); }
863
869 deque& operator=(const deque& other) {
870 if (_NEFORCE addressof(other) == this) {
871 return *this;
872 }
873
874 const size_t len = size();
875 if (len >= other.size()) {
876 deque::erase(_NEFORCE copy(other.start_, other.finish_, start_), finish_);
877 } else {
878 auto mid = other.begin() + len;
879 _NEFORCE copy(other.begin(), mid, start_);
880 deque::insert(end(), mid, other.end());
881 }
882 return *this;
883 }
884
889 deque(deque&& other) noexcept { deque::swap(other); }
890
896 deque& operator=(deque&& other) noexcept {
897 if (_NEFORCE addressof(other) == this) {
898 return *this;
899 }
900 clear();
901 deque::swap(other);
902 return *this;
903 }
904
911 if (map_pair_.value == nullptr) {
912 return;
913 }
914 clear();
915
916 if (map_pair_.value != nullptr) {
917 for (size_type i = 0; i < map_size_pair_.value; ++i) {
918 if (map_pair_.value[i] != nullptr) {
919 map_size_pair_.get_base().deallocate(map_pair_.value[i], buffer_size);
920 map_pair_.value[i] = nullptr;
921 }
922 }
923
924 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
925 map_pair_.value = nullptr;
926 }
927 }
928
933 NEFORCE_NODISCARD iterator begin() noexcept { return iterator(start_); }
934
939 NEFORCE_NODISCARD iterator end() noexcept { return iterator(finish_); }
940
945 NEFORCE_NODISCARD const_iterator begin() const noexcept { return cbegin(); }
946
951 NEFORCE_NODISCARD const_iterator end() const noexcept { return cend(); }
952
957 NEFORCE_NODISCARD const_iterator cbegin() const noexcept { return const_iterator(start_); }
958
963 NEFORCE_NODISCARD const_iterator cend() const noexcept { return const_iterator(finish_); }
964
969 NEFORCE_NODISCARD reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
970
975 NEFORCE_NODISCARD reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
976
981 NEFORCE_NODISCARD const_reverse_iterator rbegin() const noexcept { return crbegin(); }
982
987 NEFORCE_NODISCARD const_reverse_iterator rend() const noexcept { return crend(); }
988
993 NEFORCE_NODISCARD const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
994
999 NEFORCE_NODISCARD const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
1000
1005 NEFORCE_NODISCARD size_type size() const noexcept { return finish_ - start_; }
1006
1011 NEFORCE_NODISCARD size_type max_size() const noexcept { return static_cast<size_type>(-1); }
1012
1017 NEFORCE_NODISCARD bool empty() const noexcept { return finish_ == start_; }
1018
1023 NEFORCE_NODISCARD reference front() noexcept {
1024 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty deque");
1025 return *start_;
1026 }
1027
1032 NEFORCE_NODISCARD const_reference front() const noexcept {
1033 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty deque");
1034 return *start_;
1035 }
1036
1041 NEFORCE_NODISCARD reference back() noexcept {
1042 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty deque");
1043 return *(finish_ - 1);
1044 }
1045
1050 NEFORCE_NODISCARD const_reference back() const noexcept {
1051 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty deque");
1052 return *(finish_ - 1);
1053 }
1054
1063 void resize(size_type n, const T& value) {
1064 const auto old_size = size();
1065 if (n < old_size) {
1066 deque::erase(start_ + n, finish_);
1067 } else {
1068 deque::insert(finish_, n - old_size, value);
1069 }
1070 }
1071
1076 void resize(const size_type n) { deque::resize(n, _NEFORCE initialize<T>()); }
1077
1085 template <typename... Args>
1086 iterator emplace(iterator position, Args&&... args) {
1087 if (position.current_ == start_.current_) {
1088 deque::emplace_front(_NEFORCE forward<Args>(args)...);
1089 return start_;
1090 }
1091 if (position.current_ == finish_.current_) {
1092 deque::emplace_back(_NEFORCE forward<Args>(args)...);
1093 return finish_ - 1;
1094 }
1095 return deque::insert_aux(position, _NEFORCE forward<Args>(args)...);
1096 }
1097
1103 template <typename... Args>
1104 void emplace_back(Args&&... args) {
1105 if (finish_.current_ != finish_.last_ - 1) {
1106 _NEFORCE construct(finish_.current_, _NEFORCE forward<Args>(args)...);
1107 ++finish_.current_;
1108 } else {
1109 deque::reallocate_map(1, false);
1110 _NEFORCE construct(finish_.current_, _NEFORCE forward<Args>(args)...);
1111 ++finish_;
1112 }
1113 }
1114
1120 template <typename... Args>
1121 void emplace_front(Args&&... args) {
1122 if (start_.current_ != start_.first_) {
1123 _NEFORCE construct(start_.current_ - 1, _NEFORCE forward<Args>(args)...);
1124 --start_.current_;
1125 } else {
1126 deque::reallocate_map(1, true);
1127 --start_;
1128 _NEFORCE construct(start_.current_, _NEFORCE forward<Args>(args)...);
1129 }
1130 }
1131
1136 void push_back(const T& value) { deque::emplace_back(value); }
1137
1142 void push_front(const T& value) { deque::emplace_front(value); }
1143
1148 void push_back(T&& value) { deque::emplace_back(_NEFORCE move(value)); }
1149
1154 void push_front(T&& value) { deque::emplace_front(_NEFORCE move(value)); }
1155
1160 NEFORCE_DEBUG_VERIFY(!empty(), "pop_back called on empty deque");
1161
1162 if (finish_.current_ != finish_.first_) {
1163 --finish_.current_;
1164 _NEFORCE destroy(finish_.current_);
1165 } else {
1166 _NEFORCE destroy(finish_.current_);
1167 auto cur = finish_.node_;
1168 map_size_pair_.get_base().deallocate(*cur, buffer_size);
1169 *cur = nullptr;
1170 --finish_;
1171 }
1172 }
1173
1178 NEFORCE_DEBUG_VERIFY(!empty(), "pop_front called on empty deque");
1179
1180 if (start_.current_ != start_.last_ - 1) {
1181 _NEFORCE destroy(start_.current_);
1182 ++start_.current_;
1183 } else {
1184 _NEFORCE destroy(start_.current_);
1185 auto cur = start_.node_;
1186 map_size_pair_.get_base().deallocate(start_.first_, buffer_size);
1187 *cur = nullptr;
1188 ++start_;
1189 }
1190 }
1191
1197 void assign(const size_type count, const T& value) { deque::assign_aux_n(count, value); }
1198
1205 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1206 void assign(Iterator first, Iterator last) {
1207 deque::assign_ranges(first, last);
1208 }
1209
1214 void assign(std::initializer_list<T> ilist) { deque::assign_ranges(ilist.begin(), ilist.end()); }
1215
1222 iterator insert(iterator position, const T& value) {
1223 if (position.current_ == start_.current_) {
1224 deque::push_front(value);
1225 return start_;
1226 }
1227 if (position.current_ == finish_.current_) {
1228 deque::push_back(value);
1229 return _NEFORCE prev(finish_);
1230 }
1231 return deque::insert_aux(position, value);
1232 }
1233
1240 iterator insert(iterator position, T&& value) {
1241 if (position.current_ == start_.current_) {
1242 deque::emplace_front(_NEFORCE move(value));
1243 return start_;
1244 }
1245 if (position.current_ == finish_.current_) {
1246 deque::emplace_back(_NEFORCE move(value));
1247 return _NEFORCE prev(finish_);
1248 }
1249 return deque::insert_aux(position, _NEFORCE move(value));
1250 }
1251
1259 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1260 void insert(iterator position, Iterator first, Iterator last) {
1261 deque::insert_ranges(position, first, last);
1262 }
1263
1269 iterator insert(iterator position, std::initializer_list<T> list) {
1270 return deque::insert(position, list.begin(), list.end());
1271 }
1272
1279 void insert(iterator position, const size_t n, const T& value) {
1280 if (position.current_ == start_.current_) {
1281 deque::reallocate_map(n, true);
1282 auto new_start = start_ - n;
1283 _NEFORCE uninitialized_fill_n(new_start, n, value);
1284 start_ = new_start;
1285 } else if (position.current_ == finish_.current_) {
1286 deque::reallocate_map(n, false);
1287 auto new_finish = finish_ + n;
1288 _NEFORCE uninitialized_fill_n(finish_, n, value);
1289 finish_ = new_finish;
1290 } else {
1291 return deque::insert_n_aux(position, n, value);
1292 }
1293 }
1294
1301 iterator next = _NEFORCE next(position);
1302 const size_type dest_before = position - start_;
1303 if (dest_before < size() / 2) {
1304 _NEFORCE copy_backward(start_, position, next);
1306 } else {
1307 _NEFORCE copy(next, finish_, position);
1309 }
1310 return start_ + dest_before;
1311 }
1312
1320 if (first == start_ && last == finish_) {
1321 clear();
1322 return finish_;
1323 }
1324
1325 const size_type len = last - first;
1326 const size_type dist_before = first - start_;
1327 if (dist_before < (size() - len) / 2) {
1328 _NEFORCE copy_backward(start_, first, last);
1329 iterator new_start = start_ + len;
1330 _NEFORCE destroy(start_.current_, new_start.current_);
1331 start_ = new_start;
1332 } else {
1333 _NEFORCE copy(last, finish_, first);
1334 iterator new_finish = finish_ - len;
1335 _NEFORCE destroy(new_finish.current_, finish_.current_);
1336 finish_ = new_finish;
1337 }
1338 return start_ + dist_before;
1339 }
1340
1347 for (map_pointer cur = map_pair_.value; cur < start_.node_; ++cur) {
1348 if (*cur == nullptr) {
1349 continue;
1350 }
1351 map_size_pair_.get_base().deallocate(*cur, buffer_size);
1352 *cur = nullptr;
1353 }
1354 for (map_pointer cur = finish_.node_ + 1; cur < map_pair_.value + map_size_pair_.value; ++cur) {
1355 if (*cur == nullptr) {
1356 continue;
1357 }
1358 map_size_pair_.get_base().deallocate(*cur, buffer_size);
1359 *cur = nullptr;
1360 }
1361 }
1362
1369 for (map_pointer cur = start_.node_ + 1; cur < finish_.node_; ++cur) {
1370 _NEFORCE destroy(*cur, *cur + buffer_size);
1371 }
1372
1373 if (start_.node_ == finish_.node_) {
1374 _NEFORCE destroy(start_.current_, finish_.current_);
1375 } else {
1376 _NEFORCE destroy(start_.current_, start_.last_);
1377 _NEFORCE destroy(finish_.first_, finish_.current_);
1378 }
1379
1380 shrink_to_fit();
1381 finish_ = start_;
1382 }
1383
1389 NEFORCE_NODISCARD const_reference at(size_type position) const noexcept { return start_[position]; }
1390
1396 NEFORCE_NODISCARD reference at(const size_type position) noexcept { return start_[position]; }
1397
1403 NEFORCE_NODISCARD const_reference operator[](const size_type position) const noexcept { return at(position); }
1404
1410 NEFORCE_NODISCARD reference operator[](const size_type position) noexcept { return at(position); }
1411
1417 if (_NEFORCE addressof(other) == this) {
1418 return;
1419 }
1420
1421 _NEFORCE swap(start_, other.start_);
1422 _NEFORCE swap(finish_, other.finish_);
1423 _NEFORCE swap(map_pair_, other.map_pair_);
1424 _NEFORCE swap(map_size_pair_, other.map_size_pair_);
1425 }
1426
1432 NEFORCE_NODISCARD bool operator==(const deque& rhs) const
1433 noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin()))) {
1434 return size() == rhs.size() && _NEFORCE equal(cbegin(), cend(), rhs.cbegin());
1435 }
1436
1442 NEFORCE_NODISCARD bool operator<(const deque& rhs) const
1443 noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend()))) {
1444 return _NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend());
1445 }
1446};
1447
1448#ifdef NEFORCE_STANDARD_17
1449template <typename T, typename Alloc>
1450deque(T, Alloc = Alloc()) -> deque<T, Alloc>;
1451
1452template <typename Iterator, typename Alloc>
1453deque(Iterator, Iterator, Alloc = Alloc()) -> deque<iter_value_t<Iterator>, Alloc>;
1454#endif
1455 // Container
1457
1458NEFORCE_END_NAMESPACE__
1459#endif // NEFORCE_CORE_CONTAINER_DEQUE_HPP__
双端队列容器
T value_type
值类型
deque(const deque &other)
拷贝构造函数
void clear() noexcept(is_nothrow_destructible_v< value_type >)
清空双端队列
Alloc allocator_type
分配器类型
void resize(const size_type n)
使用默认构造的元素调整大小
NEFORCE_NODISCARD bool operator<(const deque &rhs) const noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend())))
小于比较操作符
NEFORCE_NODISCARD reference operator[](const size_type position) noexcept
下标访问操作符
NEFORCE_NODISCARD const_reference back() const noexcept
访问最后一个常量元素
deque()
默认构造函数
~deque()
析构函数
void push_back(const T &value)
在末尾拷贝插入元素
const T * const_pointer
常量指针类型
void swap(deque &other) noexcept(is_nothrow_swappable_v< map_allocator > &&is_nothrow_swappable_v< allocator_type >)
交换两个双端队列的内容
T * pointer
指针类型
deque(const size_type n)
构造包含n个默认构造元素的双端队列
void assign(Iterator first, Iterator last)
范围赋值
NEFORCE_NODISCARD reverse_iterator rbegin() noexcept
获取反向起始迭代器
NEFORCE_NODISCARD bool operator==(const deque &rhs) const noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin())))
相等比较操作符
NEFORCE_NODISCARD const_reference at(size_type position) const noexcept
带边界检查的常量索引访问
void pop_back() noexcept(is_nothrow_destructible_v< value_type >)
移除末尾元素
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
void emplace_back(Args &&... args)
在末尾构造元素
iterator erase(iterator position)
删除指定位置的元素
iterator insert(iterator position, T &&value)
在指定位置移动插入元素
deque & operator=(std::initializer_list< T > ilist)
初始化列表赋值运算符
NEFORCE_NODISCARD size_type max_size() const noexcept
获取最大可能大小
static constexpr difference_type buffer_size
缓冲区大小
void assign(std::initializer_list< T > ilist)
初始化列表赋值
void push_front(T &&value)
在开头移动插入元素
iterator insert(iterator position, const T &value)
在指定位置拷贝插入元素
void resize(size_type n, const T &value)
调整大小
NEFORCE_NODISCARD iterator end() noexcept
获取结束迭代器
deque & operator=(deque &&other) noexcept
移动赋值运算符
void shrink_to_fit() noexcept(is_nothrow_destructible_v< value_type >)
收缩容量以适应当前大小
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
NEFORCE_NODISCARD const_iterator end() const noexcept
获取常量结束迭代器
void push_front(const T &value)
在开头拷贝插入元素
NEFORCE_NODISCARD const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
NEFORCE_NODISCARD const_iterator begin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
iterator erase(iterator first, iterator last)
删除指定范围内的元素
NEFORCE_NODISCARD iterator begin() noexcept
获取起始迭代器
NEFORCE_NODISCARD const_reference front() const noexcept
访问第一个常量元素
NEFORCE_NODISCARD reference front() noexcept
访问第一个元素
NEFORCE_NODISCARD const_iterator cend() const noexcept
获取常量结束迭代器
deque(const size_type n, const T &value)
构造包含n个指定值元素的双端队列
NEFORCE_NODISCARD const_reference operator[](const size_type position) const noexcept
常量下标访问操作符
void insert(iterator position, const size_t n, const T &value)
插入n个指定值的元素
NEFORCE_NODISCARD reverse_iterator rend() noexcept
获取反向结束迭代器
size_t size_type
大小类型
iterator emplace(iterator position, Args &&... args)
在指定位置构造元素
iterator insert(iterator position, std::initializer_list< T > list)
初始化列表插入
T & reference
引用类型
NEFORCE_NODISCARD size_type size() const noexcept
获取当前元素数量
deque_iterator< true, deque, BufSize > const_iterator
常量迭代器类型
NEFORCE_NODISCARD const_iterator cbegin() const noexcept
获取常量起始迭代器
ptrdiff_t difference_type
差值类型
NEFORCE_NODISCARD bool empty() const noexcept
检查是否为空
void pop_front() noexcept(is_nothrow_destructible_v< value_type >)
移除开头元素
void insert(iterator position, Iterator first, Iterator last)
范围插入
void push_back(T &&value)
在末尾移动插入元素
NEFORCE_NODISCARD reference back() noexcept
访问最后一个元素
const T & const_reference
常量引用类型
deque(Iterator first, Iterator last)
范围构造函数
deque(deque &&other) noexcept
移动构造函数
NEFORCE_NODISCARD const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
void emplace_front(Args &&... args)
在开头构造元素
deque_iterator< false, deque, BufSize > iterator
迭代器类型
NEFORCE_NODISCARD reference at(const size_type position) noexcept
带边界检查的索引访问
NEFORCE_NODISCARD const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
deque(std::initializer_list< T > ilist)
初始化列表构造函数
void assign(const size_type count, const T &value)
赋值n个指定值的元素
deque & operator=(const deque &other)
拷贝赋值运算符
双向链表容器
NEFORCE_NODISCARD iterator begin() noexcept
获取起始迭代器
NEFORCE_NODISCARD iterator end() noexcept
获取结束迭代器
映射容器
定义 map.hpp:37
比较算法
压缩对实现
NEFORCE_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_INLINE17 constexpr bool is_object_v
is_object的便捷变量模板
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
NEFORCE_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
NEFORCE_NODISCARD constexpr bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(comp(*first1, *first2)) &&noexcept(first1==last1 &&first2 !=last2))
字典序比较两个范围
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
#define NEFORCE_DEBUG_VERIFY(CON, MESG)
调试模式断言
NEFORCE_CONSTEXPR20 T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
NEFORCE_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=-1)
获取迭代器的前一个位置
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
uint64_t size_t
无符号大小类型
int64_t ptrdiff_t
指针差类型
constexpr void fill(Iterator first, Iterator last, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充范围元素
constexpr Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_backward_aux(first, last, result)))
反向复制范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_aux(first, last, result)))
复制范围元素
void swap()=delete
删除无参数的swap重载
NEFORCE_INLINE17 constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_allocator_v
is_allocator的便捷变量模板
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) cbegin(const Container &cont) noexcept(noexcept(cont.cbegin()))
获取const容器的const起始迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) cend(const Container &cont) noexcept(noexcept(cont.cend()))
获取const容器的const结束迭代器
NEFORCE_ALWAYS_INLINE constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
NEFORCE_INLINE17 constexpr bool is_nothrow_move_assignable_v
is_nothrow_move_assignable的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
NEFORCE_CONSTEXPR20 Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
NEFORCE_CONSTEXPR20 void uninitialized_fill(Iterator first, Iterator last, const T &x)
在未初始化内存上填充值
NEFORCE_CONSTEXPR20 Iterator uninitialized_fill_n(Iterator first, size_t n, const T &x)
在未初始化内存中用指定值填充指定数量的元素
集合器接口
迭代器接口
标准分配器
constexpr compressed_pair & get_base() noexcept
获取基类引用
双端队列迭代器
static constexpr difference_type buffer_size
deque_iterator(pointer cur, pointer first, pointer last, pointer *node, const container_type *deq) noexcept
构造函数
NEFORCE_NODISCARD bool equal(const deque_iterator &rhs) const noexcept
相等比较
deque_iterator(const deque_iterator< IsConst2, Deque, BufSize > &other) noexcept
从另一个迭代器转换构造(常量/非常量转换)
NEFORCE_NODISCARD bool less_than(const deque_iterator &rhs) const noexcept
小于比较
NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 difference_type distance_to(const deque_iterator &other) const noexcept
计算距离操作
NEFORCE_NODISCARD const container_type * container() const noexcept
获取关联容器
NEFORCE_NODISCARD reference operator[](const difference_type n) noexcept
下标访问操作符
Deque container_type
容器类型
void increment() noexcept
递增操作
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
void decrement() noexcept
递减操作
NEFORCE_NODISCARD reference dereference() const noexcept
解引用操作
NEFORCE_NODISCARD pointer base() const noexcept
获取底层指针
void advance(difference_type off) noexcept
前进操作
typename container_type::value_type value_type
值类型
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
typename container_type::size_type size_type
大小类型
static constexpr size_t deque_buf_size(const size_t n, const size_t sz) noexcept
计算双端队列缓冲区大小
typename container_type::difference_type difference_type
差值类型
random_access_iterator_tag iterator_category
迭代器类别(随机访问)
集合器接口模板
迭代器接口模板
随机访问迭代器标签
未初始化内存操作