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
19NEFORCE_BEGIN_NAMESPACE__
20
26
37template <bool IsConst, typename Deque, size_t BufSize = 0>
38struct deque_iterator : iiterator<deque_iterator<IsConst, Deque, BufSize>> {
39public:
40 using container_type = Deque;
41 using value_type = typename container_type::value_type;
42 using size_type = typename container_type::size_type;
43 using difference_type = typename container_type::difference_type;
45 using reference = conditional_t<IsConst, typename container_type::const_reference,
46 typename container_type::reference>;
47 using pointer = conditional_t<IsConst, typename container_type::const_pointer,
48 typename container_type::pointer>;
49
59 static constexpr size_t deque_buf_size(const size_t n, const size_t sz) noexcept {
60 constexpr size_t buffer_threshhold = 256;
61 constexpr size_t buffer_max_size = MEMORY_BIG_ALLOC_THRESHHOLD;
62 return n != 0 ? n : sz < buffer_threshhold ? buffer_max_size / sz : 16;
63 }
64
66 static constexpr difference_type buffer_size = deque_buf_size(BufSize, sizeof(value_type));
67
68private:
69 pointer current_ = nullptr;
70 pointer first_ = nullptr;
71 pointer last_ = nullptr;
72 pointer* node_ = nullptr;
73 const container_type* container_ = nullptr;
74
75 template <typename, typename, size_t>
76 friend class deque;
77 template <bool, typename, size_t>
78 friend struct deque_iterator;
79
80private:
87 void change_buff(pointer* new_map) noexcept {
88 node_ = new_map;
89 first_ = *new_map;
90 last_ = first_ + buffer_size;
91 }
92
93public:
94 deque_iterator() noexcept = default;
95 ~deque_iterator() = default;
96
97 deque_iterator(const deque_iterator&) noexcept = default;
98 deque_iterator& operator=(const deque_iterator&) noexcept = default;
99 deque_iterator(deque_iterator&&) noexcept = default;
100 deque_iterator& operator=(deque_iterator&&) noexcept = default;
101
108 deque_iterator(pointer cur, pointer* map, const container_type* deq) :
109 current_(cur),
110 first_(*map),
111 last_(*map + buffer_size),
112 node_(map),
113 container_(deq) {}
114
123 deque_iterator(pointer cur, pointer first, pointer last, pointer* node, const container_type* deq) noexcept :
124 current_(cur),
125 first_(first),
126 last_(last),
127 node_(node),
128 container_(deq) {}
129
135 template <bool IsConst2>
136 explicit deque_iterator(const deque_iterator<IsConst2, Deque, BufSize>& other) noexcept :
137 current_(const_cast<pointer>(other.current_)),
138 first_(const_cast<pointer>(other.first_)),
139 last_(const_cast<pointer>(other.last_)),
140 node_(const_cast<pointer*>(other.node_)),
141 container_(other.container_) {}
142
147 NEFORCE_NODISCARD reference dereference() const noexcept {
148 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to dereference on a null pointer");
149 NEFORCE_DEBUG_VERIFY(first_ <= current_ && current_ < last_, "Attempting to dereference out of boundary");
150 return *current_;
151 }
152
158 void increment() noexcept {
159 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to increment a null pointer");
160 ++current_;
161 if (current_ == last_) {
162 deque_iterator::change_buff(node_ + 1);
163 current_ = first_;
164 }
165 }
166
172 void decrement() noexcept {
173 NEFORCE_DEBUG_VERIFY(current_ && container_, "Attempting to decrement a null pointer");
174 if (current_ == first_) {
175 deque_iterator::change_buff(node_ - 1);
176 current_ = last_;
177 }
178 --current_;
179 }
180
187 void advance(difference_type off) noexcept {
188 NEFORCE_DEBUG_VERIFY((current_ && container_) || off == 0, "Attempting to advance a null pointer");
189 const difference_type offset = off + (current_ - first_);
190 if (offset >= 0 && offset < buffer_size) {
191 current_ += off;
192 } else {
193 difference_type node_offset =
194 offset > 0 ? offset / buffer_size : -static_cast<difference_type>((-offset - 1) / buffer_size) - 1;
195 deque_iterator::change_buff(node_ + node_offset);
196 current_ = first_ + (offset - node_offset * buffer_size);
197 }
198 }
199
207 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20 difference_type distance_to(const deque_iterator& other) const noexcept {
208 NEFORCE_DEBUG_VERIFY(container_ == other.container_, "Attempting to distance to a different container");
209 return (node_ - other.node_) * buffer_size + (current_ - first_) - (other.current_ - other.first_);
210 }
211
217 NEFORCE_NODISCARD reference operator[](const difference_type n) const noexcept { return *(*this + n); }
218
224 NEFORCE_NODISCARD bool equal_to(const deque_iterator& rhs) const noexcept {
225 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_, "Attempting to equal to a different container");
226 return current_ == rhs.current_;
227 }
228
234 NEFORCE_NODISCARD bool less_than(const deque_iterator& rhs) const noexcept {
235 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_, "Attempting to less than a different container");
236 return node_ == rhs.node_ ? current_ < rhs.current_ : node_ < rhs.node_;
237 }
238
243 NEFORCE_NODISCARD pointer base() const noexcept { return current_; }
244
249 NEFORCE_NODISCARD const container_type* container() const noexcept { return container_; }
250};
251
252
265template <typename T, typename Alloc = allocator<T>, size_t BufSize = 0>
266class deque : public icollector<deque<T, Alloc>> {
267 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
268 static_assert(is_same_v<T, typename Alloc::value_type>, "allocator type mismatch.");
269 static_assert(is_object_v<T>, "deque only contains object types.");
270
271public:
272 using pointer = T*;
273 using reference = T&;
274 using const_pointer = const T*;
275 using const_reference = const T&;
276 using value_type = T;
283 using allocator_type = Alloc;
284
287
288private:
289 using map_pointer = pointer*;
290 using map_allocator = typename Alloc::template rebind<pointer>::other;
291
292 iterator start_{};
293 iterator finish_{};
294 // 压缩存储:分配器 + 中控器大小
295 compressed_pair<allocator_type, size_type> map_size_pair_{default_construct_tag{}, 0};
296 // 压缩存储:中控器分配器 + 中控器指针
297 compressed_pair<map_allocator, map_pointer> map_pair_{default_construct_tag{}, nullptr};
298
299private:
301 static constexpr size_t init_map_size = 8;
302
308 map_pointer create_map(const size_t n) {
309 map_pointer map = map_pair_.get_base().allocate(n);
310 for (size_t i = 0; i < n; ++i) {
311 *(map + i) = nullptr;
312 }
313 return map;
314 }
315
323 void create_nodes(map_pointer start, map_pointer finish) {
324 map_pointer cur = nullptr;
325 try {
326 for (cur = start; cur <= finish; ++cur) {
327 *cur = map_size_pair_.get_base().allocate(buffer_size);
328 }
329 } catch (...) {
330 while (cur != start) {
331 --cur;
332 map_size_pair_.get_base().deallocate(*cur, buffer_size);
333 *cur = nullptr;
334 }
335 throw;
336 }
337 }
338
346 void destroy_nodes(map_pointer start, map_pointer finish) noexcept(is_nothrow_destructible_v<value_type>) {
347 for (map_pointer cur = start; cur <= finish; ++cur) {
348 if (*cur == nullptr) {
349 continue;
350 }
351 map_size_pair_.get_base().deallocate(*cur, buffer_size);
352 *cur = nullptr;
353 }
354 }
355
362 void create_map_and_nodes(const size_type n) {
363 size_type node_nums = n / buffer_size + ((n % buffer_size) != 0U ? 1 : 0);
364 map_size_pair_.value = _NEFORCE max(init_map_size, node_nums + 2);
365
366 try {
367 map_pair_.value = deque::create_map(map_size_pair_.value);
368 } catch (...) {
369 map_pair_.value = nullptr;
370 map_size_pair_.value = 0;
371 throw;
372 }
373
374 map_pointer nstart = map_pair_.value + (map_size_pair_.value - node_nums) / 2;
375 map_pointer nfinish = node_nums == 0 ? nstart : nstart + node_nums - 1;
376
377 try {
378 deque::create_nodes(nstart, nfinish);
379 } catch (...) {
380 deque::destroy_nodes(map_pair_.value, map_pair_.value + map_size_pair_.value - 1);
381 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
382 map_pair_.value = nullptr;
383 map_size_pair_.value = 0;
384 throw;
385 }
386
387 start_.change_buff(nstart);
388 finish_.change_buff(nfinish);
389 start_.current_ = start_.first_;
390 finish_.current_ =
391 n == 0 ? start_.first_ : finish_.first_ + ((n % buffer_size) != 0U ? n % buffer_size : buffer_size);
392 start_.container_ = this;
393 finish_.container_ = this;
394 }
395
401 void fill_initialize(const size_type n, const T& value) {
402 deque::create_map_and_nodes(n);
403 if (n == 0) {
404 return;
405 }
406
407 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur) {
408 _NEFORCE uninitialized_fill(*cur, *cur + buffer_size, value);
409 }
410 _NEFORCE uninitialized_fill(finish_.first_, finish_.current_, value);
411 }
412
419 template <typename Iterator>
420 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> copy_initialize(Iterator first, Iterator last) {
421 deque::create_map_and_nodes(0);
422 deque::insert(end(), first, last);
423 return;
424 }
425
432 template <typename Iterator>
433 enable_if_t<is_ranges_fwd_iter_v<Iterator>> copy_initialize(Iterator first, Iterator last) {
434 deque::create_map_and_nodes(_NEFORCE distance(first, last));
435
436 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur) {
437 Iterator next = _NEFORCE next(first, buffer_size);
438 _NEFORCE uninitialized_copy(first, next, *cur);
439 first = next;
440 }
441 _NEFORCE uninitialized_copy(first, last, finish_.first_);
442 return;
443 }
444
450 void assign_aux_n(size_type n, const T& value) {
451 if (n > size()) {
452 _NEFORCE fill(begin(), end(), value);
453 deque::insert(end(), n - size(), value);
454 } else {
455 deque::erase(begin() + n, end());
456 _NEFORCE fill(begin(), end(), value);
457 }
458 }
459
466 template <typename Iterator>
467 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> assign_ranges(Iterator first, Iterator last) {
468 clear();
469 deque::insert(end(), first, last);
470 return;
471 }
472
479 template <typename Iterator>
480 enable_if_t<is_ranges_fwd_iter_v<Iterator>> assign_ranges(Iterator first, Iterator last) {
481 auto first1 = begin();
482 auto last1 = end();
483
484 for (; first != last && first1 != last1; ++first, ++first1) {
485 *first1 = *first;
486 }
487
488 if (first1 != last1) {
489 deque::erase(first1, last1);
490 } else {
491 deque::insert(first1, first, last);
492 }
493 return;
494 }
495
504 void reallocate_map(const size_type n, const bool add_at_front) {
505 const size_type begin_left = start_.current_ - start_.first_;
506
507 if (add_at_front && begin_left < n) {
508 const size_t needed = (n - begin_left) / buffer_size + 1;
509
510 if (needed > static_cast<size_type>(start_.node_ - map_pair_.value)) {
511 const size_type new_size =
512 _NEFORCE max(map_size_pair_.value << 1, map_size_pair_.value + needed + init_map_size);
513 map_pointer map = deque::create_map(new_size);
514 const size_type old_buf = finish_.node_ - start_.node_ + 1;
515 const size_type new_buf = needed + old_buf;
516
517 auto begin = map + (new_size - new_buf) / 2;
518 auto mid = begin + needed;
519 auto end = mid + old_buf;
520
521 deque::create_nodes(begin, mid - 1);
522 for (auto begin1 = mid, begin2 = start_.node_; begin1 != end; ++begin1, ++begin2) {
523 *begin1 = *begin2;
524 }
525
526 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
527 map_pair_.value = map;
528 map_size_pair_.value = new_size;
529 start_ = iterator(*mid + (start_.current_ - start_.first_), mid, this);
530 finish_ = iterator(*(end - 1) + (finish_.current_ - finish_.first_), end - 1, this);
531 return;
532 }
533
534 deque::create_nodes(start_.node_ - needed, start_.node_ - 1);
535 return;
536 }
537
538 const size_type end_left = finish_.last_ - finish_.current_ - 1;
539
540 if (!add_at_front && end_left < n) {
541
542 const size_type needed = (n - end_left) / buffer_size + 1;
543
544 if (needed > static_cast<size_type>((map_pair_.value + map_size_pair_.value) - finish_.node_ - 1)) {
545 const size_type new_size =
546 _NEFORCE max(map_size_pair_.value << 1, map_size_pair_.value + needed + init_map_size);
547 map_pointer map = deque::create_map(new_size);
548 const size_type old_buf = finish_.node_ - start_.node_ + 1;
549 const size_type new_buf = needed + old_buf;
550
551 auto begin = map + (new_size - new_buf) / 2;
552 auto mid = begin + old_buf;
553 auto end = mid + needed;
554
555 for (auto begin1 = begin, begin2 = start_.node_; begin1 != mid; ++begin1, ++begin2) {
556 *begin1 = *begin2;
557 }
558 deque::create_nodes(mid, end - 1);
559
560 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
561 map_pair_.value = map;
562 map_size_pair_.value = new_size;
563 start_ = iterator(*begin + (start_.current_ - start_.first_), begin, this);
564 finish_ = iterator(*(mid - 1) + (finish_.current_ - finish_.first_), mid - 1, this);
565 return;
566 }
567
568 deque::create_nodes(finish_.node_ + 1, finish_.node_ + needed);
569 }
570 }
571
580 template <typename Iterator>
581 void insert_ranges_n(iterator position, Iterator first, Iterator last, size_type n) {
582 difference_type dist_before = position - start_;
583
584 if (dist_before < static_cast<difference_type>(size() / 2)) {
585 deque::reallocate_map(n, true);
586 auto old_start = start_;
587 auto new_start = start_ - n;
588 position = start_ + dist_before;
589
590 try {
591 if (dist_before >= n) {
592 iterator start_n = start_ + n;
593 _NEFORCE uninitialized_copy(start_, start_n, new_start);
594 start_ = new_start;
595 _NEFORCE copy(start_n, position, old_start);
596 _NEFORCE copy(first, last, position - n);
597 } else {
598 auto mid = _NEFORCE next(first, n - dist_before);
599 _NEFORCE uninitialized_copy(first, mid, _NEFORCE uninitialized_copy(start_, position, new_start));
600 start_ = new_start;
601 _NEFORCE copy(mid, last, old_start);
602 }
603 } catch (...) {
604 if (new_start.node_ != start_.node_) {
605 deque::destroy_nodes(new_start.node_, start_.node_ - 1);
606 }
607 throw;
608 }
609 } else {
610 deque::reallocate_map(n, false);
611 auto old_finish = finish_;
612 auto new_finish = finish_ + n;
613 const size_type dist_after = size() - dist_before;
614 position = finish_ - dist_after;
615
616 try {
617 if (dist_after > n) {
618 auto finish_n = finish_ - n;
619 _NEFORCE uninitialized_copy(finish_n, finish_, finish_);
620 finish_ = new_finish;
621 _NEFORCE copy_backward(position, finish_n, old_finish);
622 _NEFORCE copy(first, last, position);
623 } else {
624 auto mid = _NEFORCE next(first, dist_after);
625 _NEFORCE uninitialized_copy(position, finish_, _NEFORCE uninitialized_copy(mid, last, finish_));
626 finish_ = new_finish;
627 _NEFORCE copy(first, mid, position);
628 }
629 } catch (...) {
630 if (new_finish.node_ != finish_.node_) {
631 deque::destroy_nodes(finish_.node_ + 1, new_finish.node_);
632 }
633 throw;
634 }
635 }
636 }
637
645 template <typename Iterator>
646 enable_if_t<!is_ranges_fwd_iter_v<Iterator>> insert_ranges(iterator position, Iterator first, Iterator last) {
647 const size_type n = _NEFORCE distance(first, last);
648 const size_type dist_before = position - start_;
649
650 if (dist_before < size() / 2) {
651 deque::reallocate_map(n, true);
652 } else {
653 deque::reallocate_map(n, false);
654 }
655
656 position = start_ + dist_before;
657 auto cur = --last;
658
659 for (size_type i = 0; i < n; ++i, --cur) {
660 deque::insert(position, *cur);
661 }
662 return;
663 }
664
672 template <typename Iterator>
673 enable_if_t<is_ranges_fwd_iter_v<Iterator>> insert_ranges(iterator position, Iterator first, Iterator last) {
674 const size_type n = _NEFORCE distance(first, last);
675
676 if (position.current_ == start_.current_) {
677 deque::reallocate_map(n, true);
678 auto new_start = start_ - n;
679 try {
680 _NEFORCE uninitialized_copy(first, last, new_start);
681 start_ = new_start;
682 } catch (...) {
683 if (new_start.node_ != start_.node_) {
684 deque::destroy_nodes(new_start.node_, start_.node_ - 1);
685 }
686 throw;
687 }
688 } else if (position.current_ == finish_.current_) {
689 deque::reallocate_map(n, false);
690 auto new_finish = finish_ + n;
691 try {
692 _NEFORCE uninitialized_copy(first, last, finish_);
693 finish_ = new_finish;
694 } catch (...) {
695 if (new_finish.node_ != finish_.node_) {
696 deque::destroy_nodes(finish_.node_ + 1, new_finish.node_);
697 }
698 throw;
699 }
700 } else {
701 deque::insert_ranges_n(position, first, last, n);
702 }
703 return;
704 }
705
712 void insert_n_aux(iterator position, size_type n, const T& value) {
713 difference_type dist_before = position - start_;
714 if (dist_before < static_cast<difference_type>(size() / 2)) {
715 deque::reallocate_map(n, true);
716 auto old_start = start_;
717 auto new_start = start_ - n;
718 position = start_ + dist_before;
719
720 try {
721 if (dist_before >= n) {
722 iterator start_n = start_ + n;
723 _NEFORCE uninitialized_copy(start_, start_n, new_start);
724 start_ = new_start;
725 _NEFORCE copy(start_n, position, old_start);
726 _NEFORCE fill(position - n, position, value);
727 } else {
728 _NEFORCE uninitialized_fill(_NEFORCE uninitialized_copy(start_, position, new_start), start_,
729 value);
730 start_ = new_start;
731 _NEFORCE fill(old_start, position, value);
732 }
733 } catch (...) {
734 if (new_start.node_ != start_.node_) {
735 deque::destroy_nodes(new_start.node_, start_.node_ - 1);
736 }
737 throw;
738 }
739 } else {
740 deque::reallocate_map(n, false);
741 auto old_finish = finish_;
742 auto new_finish = finish_ + n;
743 const size_type dist_after = size() - dist_before;
744 position = finish_ - dist_after;
745
746 try {
747 if (dist_after > n) {
748 auto finish_n = finish_ - n;
749 _NEFORCE uninitialized_copy(finish_n, finish_, finish_);
750 finish_ = new_finish;
751 _NEFORCE copy_backward(position, finish_n, old_finish);
752 _NEFORCE fill(position, position + n, value);
753 } else {
754 _NEFORCE uninitialized_fill(finish_, position + n, value);
755 _NEFORCE uninitialized_copy(position, finish_, position + n);
756 finish_ = new_finish;
757 _NEFORCE fill(position, old_finish, value);
758 }
759 } catch (...) {
760 if (new_finish.node_ != finish_.node_) {
761 deque::destroy_nodes(finish_.node_ + 1, new_finish.node_);
762 }
763 throw;
764 }
765 }
766 }
767
775 template <typename... Args>
776 iterator insert_aux(iterator position, Args&&... args) noexcept(is_nothrow_move_assignable_v<value_type>) {
777 size_type index = position - start_;
778
779 if (index < size() / 2) {
781
782 iterator new_pos = start_ + index;
783 if (new_pos != finish_ - 1) {
784 _NEFORCE copy_backward(new_pos, finish_ - 1, finish_);
785 }
786
787 _NEFORCE destroy(new_pos.current_);
788 _NEFORCE construct(new_pos.current_, _NEFORCE forward<Args>(args)...);
789 return new_pos;
790 } else {
792
793 iterator new_pos = start_ + index;
794 if (new_pos != start_) {
795 _NEFORCE copy_backward(start_, new_pos, new_pos + 1);
796 }
797
798 _NEFORCE destroy(new_pos.current_);
799 _NEFORCE construct(new_pos.current_, _NEFORCE forward<Args>(args)...);
800 return new_pos;
801 }
802 }
803
804public:
810 deque() { deque::fill_initialize(0, _NEFORCE initialize<T>()); }
811
816 explicit deque(const size_type n) { deque::fill_initialize(n, _NEFORCE initialize<T>()); }
817
823 deque(const size_type n, const T& value) { deque::fill_initialize(n, value); }
824
831 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
832 deque(Iterator first, Iterator last) {
833 deque::copy_initialize(first, last);
834 }
835
840 deque(std::initializer_list<T> ilist) { deque::copy_initialize(ilist.begin(), ilist.end()); }
841
847 deque& operator=(std::initializer_list<T> ilist) {
848 deque tmp(ilist);
849 deque::swap(tmp);
850 return *this;
851 }
852
857 deque(const deque& other) { deque::copy_initialize(other.cbegin(), other.cend()); }
858
864 deque& operator=(const deque& other) {
865 if (_NEFORCE addressof(other) == this) {
866 return *this;
867 }
868
869 const size_t len = size();
870 if (len >= other.size()) {
871 deque::erase(_NEFORCE copy(other.start_, other.finish_, start_), finish_);
872 } else {
873 auto mid = other.begin() + len;
874 _NEFORCE copy(other.begin(), mid, start_);
875 deque::insert(end(), mid, other.end());
876 }
877 return *this;
878 }
879
884 deque(deque&& other) noexcept { deque::swap(other); }
885
891 deque& operator=(deque&& other) noexcept {
892 if (_NEFORCE addressof(other) == this) {
893 return *this;
894 }
895 clear();
896 deque::swap(other);
897 return *this;
898 }
899
906 if (map_pair_.value == nullptr) {
907 return;
908 }
909 clear();
910
911 if (map_pair_.value != nullptr) {
912 for (size_type i = 0; i < map_size_pair_.value; ++i) {
913 if (map_pair_.value[i] != nullptr) {
914 map_size_pair_.get_base().deallocate(map_pair_.value[i], buffer_size);
915 map_pair_.value[i] = nullptr;
916 }
917 }
918
919 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
920 map_pair_.value = nullptr;
921 }
922 }
923
928 NEFORCE_NODISCARD iterator begin() noexcept { return iterator(start_); }
929
934 NEFORCE_NODISCARD iterator end() noexcept { return iterator(finish_); }
935
940 NEFORCE_NODISCARD const_iterator begin() const noexcept { return cbegin(); }
941
946 NEFORCE_NODISCARD const_iterator end() const noexcept { return cend(); }
947
952 NEFORCE_NODISCARD const_iterator cbegin() const noexcept { return const_iterator(start_); }
953
958 NEFORCE_NODISCARD const_iterator cend() const noexcept { return const_iterator(finish_); }
959
964 NEFORCE_NODISCARD reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
965
970 NEFORCE_NODISCARD reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
971
976 NEFORCE_NODISCARD const_reverse_iterator rbegin() const noexcept { return crbegin(); }
977
982 NEFORCE_NODISCARD const_reverse_iterator rend() const noexcept { return crend(); }
983
988 NEFORCE_NODISCARD const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
989
994 NEFORCE_NODISCARD const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
995
1000 NEFORCE_NODISCARD size_type size() const noexcept { return finish_ - start_; }
1001
1006 NEFORCE_NODISCARD size_type max_size() const noexcept { return static_cast<size_type>(-1); }
1007
1012 NEFORCE_NODISCARD bool empty() const noexcept { return finish_ == start_; }
1013
1018 NEFORCE_NODISCARD reference front() noexcept {
1019 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty deque");
1020 return *start_;
1021 }
1022
1027 NEFORCE_NODISCARD const_reference front() const noexcept {
1028 NEFORCE_DEBUG_VERIFY(!empty(), "front called on empty deque");
1029 return *start_;
1030 }
1031
1036 NEFORCE_NODISCARD reference back() noexcept {
1037 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty deque");
1038 return *(finish_ - 1);
1039 }
1040
1045 NEFORCE_NODISCARD const_reference back() const noexcept {
1046 NEFORCE_DEBUG_VERIFY(!empty(), "back called on empty deque");
1047 return *(finish_ - 1);
1048 }
1049
1058 void resize(size_type n, const T& value) {
1059 const auto old_size = size();
1060 if (n < old_size) {
1061 deque::erase(start_ + n, finish_);
1062 } else {
1063 deque::insert(finish_, n - old_size, value);
1064 }
1065 }
1066
1071 void resize(const size_type n) { deque::resize(n, _NEFORCE initialize<T>()); }
1072
1080 template <typename... Args>
1081 iterator emplace(iterator position, Args&&... args) {
1082 if (position.current_ == start_.current_) {
1083 deque::emplace_front(_NEFORCE forward<Args>(args)...);
1084 return start_;
1085 }
1086 if (position.current_ == finish_.current_) {
1087 deque::emplace_back(_NEFORCE forward<Args>(args)...);
1088 return finish_ - 1;
1089 }
1090 return deque::insert_aux(position, _NEFORCE forward<Args>(args)...);
1091 }
1092
1098 template <typename... Args>
1099 void emplace_back(Args&&... args) {
1100 if (finish_.current_ != finish_.last_ - 1) {
1101 _NEFORCE construct(finish_.current_, _NEFORCE forward<Args>(args)...);
1102 ++finish_.current_;
1103 } else {
1104 deque::reallocate_map(1, false);
1105 _NEFORCE construct(finish_.current_, _NEFORCE forward<Args>(args)...);
1106 ++finish_;
1107 }
1108 }
1109
1115 template <typename... Args>
1116 void emplace_front(Args&&... args) {
1117 if (start_.current_ != start_.first_) {
1118 _NEFORCE construct(start_.current_ - 1, _NEFORCE forward<Args>(args)...);
1119 --start_.current_;
1120 } else {
1121 deque::reallocate_map(1, true);
1122 --start_;
1123 _NEFORCE construct(start_.current_, _NEFORCE forward<Args>(args)...);
1124 }
1125 }
1126
1131 void push_back(const T& value) { deque::emplace_back(value); }
1132
1137 void push_front(const T& value) { deque::emplace_front(value); }
1138
1143 void push_back(T&& value) { deque::emplace_back(_NEFORCE move(value)); }
1144
1149 void push_front(T&& value) { deque::emplace_front(_NEFORCE move(value)); }
1150
1155 NEFORCE_DEBUG_VERIFY(!empty(), "pop_back called on empty deque");
1156
1157 if (finish_.current_ != finish_.first_) {
1158 --finish_.current_;
1159 _NEFORCE destroy(finish_.current_);
1160 } else {
1161 _NEFORCE destroy(finish_.current_);
1162 auto cur = finish_.node_;
1163 map_size_pair_.get_base().deallocate(*cur, buffer_size);
1164 *cur = nullptr;
1165 --finish_;
1166 }
1167 }
1168
1173 NEFORCE_DEBUG_VERIFY(!empty(), "pop_front called on empty deque");
1174
1175 if (start_.current_ != start_.last_ - 1) {
1176 _NEFORCE destroy(start_.current_);
1177 ++start_.current_;
1178 } else {
1179 _NEFORCE destroy(start_.current_);
1180 auto cur = start_.node_;
1181 map_size_pair_.get_base().deallocate(start_.first_, buffer_size);
1182 *cur = nullptr;
1183 ++start_;
1184 }
1185 }
1186
1192 void assign(const size_type count, const T& value) { deque::assign_aux_n(count, value); }
1193
1200 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1201 void assign(Iterator first, Iterator last) {
1202 deque::assign_ranges(first, last);
1203 }
1204
1209 void assign(std::initializer_list<T> ilist) { deque::assign_ranges(ilist.begin(), ilist.end()); }
1210
1217 iterator insert(iterator position, const T& value) {
1218 if (position.current_ == start_.current_) {
1219 deque::push_front(value);
1220 return start_;
1221 }
1222 if (position.current_ == finish_.current_) {
1223 deque::push_back(value);
1224 return _NEFORCE prev(finish_);
1225 }
1226 return deque::insert_aux(position, value);
1227 }
1228
1235 iterator insert(iterator position, T&& value) {
1236 if (position.current_ == start_.current_) {
1237 deque::emplace_front(_NEFORCE move(value));
1238 return start_;
1239 }
1240 if (position.current_ == finish_.current_) {
1241 deque::emplace_back(_NEFORCE move(value));
1242 return _NEFORCE prev(finish_);
1243 }
1244 return deque::insert_aux(position, _NEFORCE move(value));
1245 }
1246
1254 template <typename Iterator, enable_if_t<is_iter_v<Iterator>, int> = 0>
1255 void insert(iterator position, Iterator first, Iterator last) {
1256 deque::insert_ranges(position, first, last);
1257 }
1258
1264 iterator insert(iterator position, std::initializer_list<T> list) {
1265 return deque::insert(position, list.begin(), list.end());
1266 }
1267
1274 void insert(iterator position, const size_t n, const T& value) {
1275 if (position.current_ == start_.current_) {
1276 deque::reallocate_map(n, true);
1277 auto new_start = start_ - n;
1278 _NEFORCE uninitialized_fill_n(new_start, n, value);
1279 start_ = new_start;
1280 } else if (position.current_ == finish_.current_) {
1281 deque::reallocate_map(n, false);
1282 auto new_finish = finish_ + n;
1283 _NEFORCE uninitialized_fill_n(finish_, n, value);
1284 finish_ = new_finish;
1285 } else {
1286 return deque::insert_n_aux(position, n, value);
1287 }
1288 }
1289
1296 iterator next = _NEFORCE next(position);
1297 const size_type dest_before = position - start_;
1298 if (dest_before < size() / 2) {
1299 _NEFORCE copy_backward(start_, position, next);
1301 } else {
1302 _NEFORCE copy(next, finish_, position);
1304 }
1305 return start_ + dest_before;
1306 }
1307
1315 if (first == start_ && last == finish_) {
1316 clear();
1317 return finish_;
1318 }
1319
1320 const size_type len = last - first;
1321 const size_type dist_before = first - start_;
1322 if (dist_before < (size() - len) / 2) {
1323 _NEFORCE copy_backward(start_, first, last);
1324 iterator new_start = start_ + len;
1325 _NEFORCE destroy(start_.current_, new_start.current_);
1326 start_ = new_start;
1327 } else {
1328 _NEFORCE copy(last, finish_, first);
1329 iterator new_finish = finish_ - len;
1330 _NEFORCE destroy(new_finish.current_, finish_.current_);
1331 finish_ = new_finish;
1332 }
1333 return start_ + dist_before;
1334 }
1335
1342 for (map_pointer cur = map_pair_.value; cur < start_.node_; ++cur) {
1343 if (*cur == nullptr) {
1344 continue;
1345 }
1346 map_size_pair_.get_base().deallocate(*cur, buffer_size);
1347 *cur = nullptr;
1348 }
1349 for (map_pointer cur = finish_.node_ + 1; cur < map_pair_.value + map_size_pair_.value; ++cur) {
1350 if (*cur == nullptr) {
1351 continue;
1352 }
1353 map_size_pair_.get_base().deallocate(*cur, buffer_size);
1354 *cur = nullptr;
1355 }
1356 }
1357
1364 for (map_pointer cur = start_.node_ + 1; cur < finish_.node_; ++cur) {
1365 _NEFORCE destroy(*cur, *cur + buffer_size);
1366 }
1367
1368 if (start_.node_ == finish_.node_) {
1369 _NEFORCE destroy(start_.current_, finish_.current_);
1370 } else {
1371 _NEFORCE destroy(start_.current_, start_.last_);
1372 _NEFORCE destroy(finish_.first_, finish_.current_);
1373 }
1374
1375 shrink_to_fit();
1376 finish_ = start_;
1377 }
1378
1384 NEFORCE_NODISCARD const_reference at(size_type position) const noexcept { return start_[position]; }
1385
1391 NEFORCE_NODISCARD reference at(const size_type position) noexcept { return start_[position]; }
1392
1398 NEFORCE_NODISCARD const_reference operator[](const size_type position) const noexcept { return at(position); }
1399
1405 NEFORCE_NODISCARD reference operator[](const size_type position) noexcept { return at(position); }
1406
1412 if (_NEFORCE addressof(other) == this) {
1413 return;
1414 }
1415
1416 _NEFORCE swap(start_, other.start_);
1417 _NEFORCE swap(finish_, other.finish_);
1418 _NEFORCE swap(map_pair_, other.map_pair_);
1419 _NEFORCE swap(map_size_pair_, other.map_size_pair_);
1420 }
1421
1427 NEFORCE_NODISCARD bool equal_to(const deque& rhs) const
1428 noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin()))) {
1429 return size() == rhs.size() && _NEFORCE equal(cbegin(), cend(), rhs.cbegin());
1430 }
1431
1437 NEFORCE_NODISCARD bool less_than(const deque& rhs) const
1438 noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend()))) {
1439 return _NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend());
1440 }
1441};
1442
1443#ifndef NEFORCE_STANDARD_17
1444template <typename T, typename Alloc, size_t BufSize>
1446template <typename T, typename Alloc, size_t BufSize>
1447constexpr size_t deque<T, Alloc, BufSize>::init_map_size;
1448#endif
1449
1450
1451#ifdef NEFORCE_STANDARD_17
1452template <typename T, typename Alloc>
1453deque(T, Alloc = Alloc()) -> deque<T, Alloc>;
1454
1455template <typename Iterator, typename Alloc>
1456deque(Iterator, Iterator, Alloc = Alloc()) -> deque<iter_value_t<Iterator>, Alloc>;
1457#endif
1458 // Container
1460
1461NEFORCE_END_NAMESPACE__
1462#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)
使用默认构造的元素调整大小
const_iterator begin() const noexcept
获取常量起始迭代器
deque()
默认构造函数
~deque()
析构函数
void push_back(const T &value)
在末尾拷贝插入元素
const T * const_pointer
常量指针类型
iterator begin() noexcept
获取起始迭代器
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个默认构造元素的双端队列
const_reference back() const noexcept
访问最后一个常量元素
void assign(Iterator first, Iterator last)
范围赋值
iterator end() noexcept
获取结束迭代器
reference at(const size_type position) noexcept
带边界检查的索引访问
reference front() noexcept
访问第一个元素
void pop_back() noexcept(is_nothrow_destructible_v< value_type >)
移除末尾元素
bool less_than(const deque &rhs) const noexcept(noexcept(_NEFORCE lexicographical_compare(cbegin(), cend(), rhs.cbegin(), rhs.cend())))
小于比较操作符
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
void emplace_back(Args &&... args)
在末尾构造元素
iterator erase(iterator position)
删除指定位置的元素
reference back() noexcept
访问最后一个元素
iterator insert(iterator position, T &&value)
在指定位置移动插入元素
deque & operator=(std::initializer_list< T > ilist)
初始化列表赋值运算符
const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
reverse_iterator rend() noexcept
获取反向结束迭代器
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)
调整大小
const_reference operator[](const size_type position) const noexcept
常量下标访问操作符
deque & operator=(deque &&other) noexcept
移动赋值运算符
const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
void shrink_to_fit() noexcept(is_nothrow_destructible_v< value_type >)
收缩容量以适应当前大小
reverse_iterator rbegin() noexcept
获取反向起始迭代器
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
void push_front(const T &value)
在开头拷贝插入元素
const_iterator cend() const noexcept
获取常量结束迭代器
iterator erase(iterator first, iterator last)
删除指定范围内的元素
const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
reference operator[](const size_type position) noexcept
下标访问操作符
const_iterator cbegin() const noexcept
获取常量起始迭代器
deque(const size_type n, const T &value)
构造包含n个指定值元素的双端队列
void insert(iterator position, const size_t n, const T &value)
插入n个指定值的元素
size_type max_size() const noexcept
获取最大可能大小
size_t size_type
大小类型
static constexpr ptrdiff_t buffer_size
缓冲区大小
iterator emplace(iterator position, Args &&... args)
在指定位置构造元素
iterator insert(iterator position, std::initializer_list< T > list)
初始化列表插入
const_reference at(size_type position) const noexcept
带边界检查的常量索引访问
bool equal_to(const deque &rhs) const noexcept(noexcept(_NEFORCE equal(cbegin(), cend(), rhs.cbegin())))
相等比较操作符
const_iterator end() const noexcept
获取常量结束迭代器
T & reference
引用类型
bool empty() const noexcept
检查是否为空
size_type size() const noexcept
获取当前元素数量
deque_iterator< true, deque, BufSize > const_iterator
常量迭代器类型
ptrdiff_t difference_type
差值类型
void pop_front() noexcept(is_nothrow_destructible_v< value_type >)
移除开头元素
void insert(iterator position, Iterator first, Iterator last)
范围插入
void push_back(T &&value)
在末尾移动插入元素
const T & const_reference
常量引用类型
deque(Iterator first, Iterator last)
范围构造函数
deque(deque &&other) noexcept
移动构造函数
void emplace_front(Args &&... args)
在开头构造元素
deque_iterator< false, deque, BufSize > iterator
迭代器类型
deque(std::initializer_list< T > ilist)
初始化列表构造函数
void assign(const size_type count, const T &value)
赋值n个指定值的元素
const_reference front() const noexcept
访问第一个常量元素
deque & operator=(const deque &other)
拷贝赋值运算符
双向链表容器
iterator begin() noexcept
获取起始迭代器
iterator end() noexcept
获取结束迭代器
映射容器
定义 map.hpp:37
比较算法
压缩对实现
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr bool is_object_v
is_object的便捷变量模板
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
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 bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr T * construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
constexpr Iterator next(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的后一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的前一个位置
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重载
constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
constexpr bool is_allocator_v
is_allocator的便捷变量模板
constexpr decltype(auto) cbegin(const Container &cont) noexcept(noexcept(cont.cbegin()))
获取const容器的const起始迭代器
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr decltype(auto) cend(const Container &cont) noexcept(noexcept(cont.cend()))
获取const容器的const结束迭代器
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
constexpr bool is_nothrow_move_assignable_v
is_nothrow_move_assignable的便捷变量模板
constexpr bool is_nothrow_destructible_v
is_nothrow_destructible的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr bool is_same_v
is_same的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr void uninitialized_fill(Iterator first, Iterator last, const T &x)
在未初始化内存上填充值
constexpr Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
constexpr 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
构造函数
deque_iterator(const deque_iterator< IsConst2, Deque, BufSize > &other) noexcept
从另一个迭代器转换构造(常量/非常量转换)
constexpr difference_type distance_to(const deque_iterator &other) const noexcept
计算距离操作
bool equal_to(const deque_iterator &rhs) const noexcept
相等比较
Deque container_type
容器类型
reference operator[](const difference_type n) const noexcept
下标访问操作符
void increment() noexcept
递增操作
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
void decrement() 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
大小类型
bool less_than(const deque_iterator &rhs) const noexcept
小于比较
pointer base() const noexcept
获取底层指针
const container_type * container() const noexcept
获取关联容器
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
迭代器类别(随机访问)
reference dereference() const noexcept
解引用操作
集合器接口模板
迭代器接口模板
随机访问迭代器标签
未初始化内存操作