1#ifndef MSTL_CORE_CONTAINER_DEQUE_HPP__
2#define MSTL_CORE_CONTAINER_DEQUE_HPP__
10MSTL_INLINE17
constexpr size_t MAX_DEQUE_BUFFER_THRESHHOLD = 256;
11MSTL_INLINE17
constexpr size_t MAX_DEQUE_BUFFER_SIZE = 4096;
12MSTL_INLINE17
constexpr size_t DEQUE_INIT_MAP_SIZE = 8;
14constexpr size_t deque_buf_size(
const size_t n,
const size_t sz)
noexcept {
15 return n != 0 ? n : sz < MAX_DEQUE_BUFFER_THRESHHOLD ? MAX_DEQUE_BUFFER_SIZE / sz : 16;
19template <
typename T,
typename Alloc,
size_t BufSize>
22template <
bool IsConst,
typename Deque,
size_t BufSize = 0>
23struct deque_iterator {
25 using container_type = Deque;
26 using iterator = deque_iterator<false, container_type>;
27 using const_iterator = deque_iterator<true, container_type>;
30 using iterator_category = random_access_iterator_tag;
31 using value_type =
typename container_type::value_type;
34 using difference_type =
typename container_type::difference_type;
35 using size_type =
typename container_type::size_type;
38 pointer cur_ =
nullptr;
39 pointer first_ =
nullptr;
40 pointer last_ =
nullptr;
41 pointer* node_ =
nullptr;
42 const container_type* deq_ =
nullptr;
44 static constexpr difference_type buffer_size_ =
_MSTL deque_buf_size(BufSize,
sizeof(value_type));
46 template <
typename,
typename,
size_t>
friend class deque;
47 template <
bool,
typename,
size_t>
friend struct deque_iterator;
50 void change_buff(pointer* new_map)
noexcept {
53 last_ = first_ + buffer_size_;
57 deque_iterator() noexcept = default;
59 deque_iterator(pointer cur, pointer* map, const container_type* deq)
60 : cur_(cur), first_(*map), last_(*map + buffer_size_), node_(map), deq_(deq) {}
62 deque_iterator(pointer cur, pointer first, pointer last, pointer* node,
const container_type* deq) noexcept
63 : cur_(
const_cast<pointer
>(cur)), first_(
const_cast<pointer
>(first)),
64 last_(
const_cast<pointer
>(last)), node_(
const_cast<pointer*
>(node)), deq_(deq) {}
66 deque_iterator(
const iterator& x) noexcept
67 : cur_(
const_cast<pointer
>(x.cur_)), first_(
const_cast<pointer
>(x.first_)),
68 last_(
const_cast<pointer
>(x.last_)), node_(
const_cast<pointer*
>(x.node_)), deq_(x.deq_) {}
70 deque_iterator& operator =(
const iterator& x)
noexcept {
72 cur_ =
const_cast<pointer
>(x.cur_);
73 first_ =
const_cast<pointer
>(x.first_);
74 last_ =
const_cast<pointer
>(x.last_);
75 node_ =
const_cast<pointer*
>(x.node_);
80 deque_iterator(iterator&& x) noexcept
81 : cur_(
const_cast<pointer
>(x.cur_)), first_(
const_cast<pointer
>(x.first_)),
82 last_(
const_cast<pointer
>(x.last_)), node_(
const_cast<pointer*
>(x.node_)), deq_(x.deq_) {
90 deque_iterator& operator =(iterator&& x)
noexcept {
96 deque_iterator(
const const_iterator& x) noexcept
97 : cur_(
const_cast<pointer
>(x.cur_)), first_(
const_cast<pointer
>(x.first_)),
98 last_(
const_cast<pointer
>(x.last_)), node_(
const_cast<pointer*
>(x.node_)), deq_(x.deq_) {}
100 deque_iterator& operator =(
const const_iterator& x)
noexcept {
102 cur_ =
const_cast<pointer
>(x.cur_);
103 first_ =
const_cast<pointer
>(x.first_);
104 last_ =
const_cast<pointer
>(x.last_);
105 node_ =
const_cast<pointer*
>(x.node_);
110 deque_iterator(const_iterator&& x) noexcept
111 : cur_(
const_cast<pointer
>(x.cur_)), first_(
const_cast<pointer
>(x.first_)),
112 last_(
const_cast<pointer
>(x.last_)), node_(
const_cast<pointer*
>(x.node_)), deq_(x.deq_) {
119 deque_iterator& operator =(const_iterator&& x)
noexcept {
121 cur_ =
const_cast<pointer
>(x.cur_);
122 first_ =
const_cast<pointer
>(x.first_);
123 last_ =
const_cast<pointer
>(x.last_);
124 node_ =
const_cast<pointer*
>(x.node_);
134 ~deque_iterator() noexcept = default;
136 MSTL_NODISCARD reference operator *() const noexcept {
137 MSTL_DEBUG_VERIFY(cur_ && deq_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(deque_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
138 MSTL_DEBUG_VERIFY(first_ <= cur_ && cur_ < last_,
139 __MSTL_DEBUG_MESG_OUT_OF_RANGE(deque_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
143 MSTL_NODISCARD pointer operator ->() const noexcept {
144 MSTL_DEBUG_VERIFY(cur_ && deq_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(deque_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
148 deque_iterator& operator ++() noexcept {
149 MSTL_DEBUG_VERIFY(cur_ && deq_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(deque_iterator, __MSTL_DEBUG_TAG_INCREMENT));
152 this->change_buff(node_ + 1);
158 deque_iterator operator ++(
int)
noexcept {
159 deque_iterator tmp = *
this;
164 deque_iterator& operator --() noexcept {
165 MSTL_DEBUG_VERIFY(cur_ && deq_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(deque_iterator, __MSTL_DEBUG_TAG_DECREMENT));
166 if (cur_ == first_) {
167 this->change_buff(node_ - 1);
174 deque_iterator operator --(
int)
noexcept {
175 deque_iterator tmp = *
this;
180 deque_iterator& operator +=(
const difference_type n)
noexcept {
181 MSTL_DEBUG_VERIFY(cur_ && deq_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(deque_iterator, __MSTL_DEBUG_TAG_INCREMENT));
182 const difference_type offset = n + (cur_ - first_);
183 if (offset >= 0 && offset < buffer_size_) {
187 difference_type node_offset = offset > 0 ?
188 offset / buffer_size_ :
189 -
static_cast<difference_type
>((-offset - 1) / buffer_size_) - 1;
190 this->change_buff(node_ + node_offset);
191 cur_ = first_ + (offset - node_offset * buffer_size_);
195 MSTL_NODISCARD deque_iterator operator +(
const difference_type n)
const noexcept {
199 MSTL_NODISCARD
friend deque_iterator operator +(
const difference_type n,
const deque_iterator& it) {
203 deque_iterator& operator -=(
const difference_type n)
noexcept {
206 MSTL_NODISCARD deque_iterator operator -(
const difference_type n)
const noexcept {
207 deque_iterator temp = *
this;
210 difference_type operator -(
const deque_iterator& x)
const noexcept {
211 MSTL_DEBUG_VERIFY(deq_ == x.deq_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(deque_iterator));
212 return (node_ - x.node_) * buffer_size_ + (cur_ - first_) - (x.cur_ - x.first_);
215 MSTL_NODISCARD reference operator [](
const difference_type n)
noexcept {
return *(*
this + n); }
217 MSTL_NODISCARD
bool operator ==(
const deque_iterator& x)
const noexcept {
218 MSTL_DEBUG_VERIFY(deq_ == x.deq_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(deque_iterator));
219 return cur_ == x.cur_;
221 MSTL_NODISCARD
bool operator !=(
const deque_iterator& x)
const noexcept {
return !(*
this == x); }
222 MSTL_NODISCARD
bool operator <(
const deque_iterator& x)
const noexcept {
223 MSTL_DEBUG_VERIFY(deq_ == x.deq_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(deque_iterator));
224 return node_ == x.node_ ? cur_ < x.cur_ : node_ < x.node_;
226 MSTL_NODISCARD
bool operator >(
const deque_iterator& x)
const noexcept {
return x < *
this; }
227 MSTL_NODISCARD
bool operator <=(
const deque_iterator& x)
const noexcept {
return !(*
this > x); }
228 MSTL_NODISCARD
bool operator >=(
const deque_iterator& x)
const noexcept {
return !(*
this < x); }
230 void swap(deque_iterator& x)
noexcept {
243 MSTL_NODISCARD pointer base() const noexcept {
247template <
bool IsConst,
typename Deque,
size_t BufSize>
249 deque_iterator<IsConst, Deque, BufSize>& lhs,
250 deque_iterator<IsConst, Deque, BufSize>& rhs)
noexcept {
256template <
typename T,
typename Alloc = allocator<T>,
size_t BufSize = 0>
257class deque :
public icollector<deque<T, Alloc>> {
258#ifdef MSTL_STANDARD_20__
259 static_assert(is_allocator_v<Alloc>,
"Alloc type is not a standard allocator type.");
261 static_assert(is_same_v<T, typename Alloc::value_type>,
"allocator type mismatch.");
262 static_assert(is_object_v<T>,
"deque only contains object types.");
266 using allocator_type = Alloc;
268 using iterator = deque_iterator<false, deque, BufSize>;
269 using const_iterator = deque_iterator<true, deque, BufSize>;
270 using reverse_iterator =
_MSTL reverse_iterator<iterator>;
271 using const_reverse_iterator =
_MSTL reverse_iterator<const_iterator>;
274 using map_pointer = pointer*;
275 using map_allocator =
typename Alloc::template rebind<pointer>::other;
280 compressed_pair<allocator_type, size_type> map_size_pair_{
281 default_construct_tag{}, 0
284 compressed_pair<map_allocator, map_pointer> map_pair_{
285 default_construct_tag{},
nullptr
288 static constexpr difference_type buffer_size_ = iterator::buffer_size_;
290 template <
bool,
typename,
size_t>
friend struct deque_iterator;
293 map_pointer create_map(
const size_t size) {
294 map_pointer map =
nullptr;
295 map = map_pair_.get_base().allocate(size);
296 for (
size_t i = 0; i < size; ++i) {
297 *(map + i) =
nullptr;
302 void create_nodes(map_pointer nstart, map_pointer nfinish) {
305 for (cur = nstart; cur <= nfinish; ++cur)
306 *cur = map_size_pair_.get_base().allocate(buffer_size_);
308 while (cur != nstart) {
310 map_size_pair_.get_base().deallocate(*cur, buffer_size_);
317 void destroy_nodes(map_pointer nstart, map_pointer nfinish)
noexcept {
318 for (map_pointer cur = nstart; cur <= nfinish; ++cur) {
319 if (*cur ==
nullptr)
continue;
320 map_size_pair_.get_base().deallocate(*cur, buffer_size_);
325 void create_map_and_nodes(
const size_type n) {
326 size_type node_nums = n / buffer_size_ + (n % buffer_size_ ? 1 : 0);
327 map_size_pair_.value =
_MSTL max(DEQUE_INIT_MAP_SIZE, node_nums + 2);
330 map_pair_.value = this->create_map(map_size_pair_.value);
332 map_pair_.value =
nullptr;
333 map_size_pair_.value = 0;
337 map_pointer nstart = map_pair_.value + (map_size_pair_.value - node_nums) / 2;
338 map_pointer nfinish = node_nums == 0 ? nstart : nstart + node_nums - 1;
341 this->create_nodes(nstart, nfinish);
343 this->destroy_nodes(map_pair_.value, map_pair_.value + map_size_pair_.value - 1);
344 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
345 map_pair_.value =
nullptr;
346 map_size_pair_.value = 0;
350 start_.change_buff(nstart);
351 finish_.change_buff(nfinish);
352 start_.cur_ = start_.first_;
353 finish_.cur_ = n == 0 ?
355 finish_.first_ + (n % buffer_size_ ? n % buffer_size_ : buffer_size_);
360 void fill_initialize(
const size_type n,
const T& x) {
361 this->create_map_and_nodes(n);
363 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur)
368 template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
369 void copy_initialize(Iterator first, Iterator last) {
371 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur) {
379 template <
typename Iterator, enable_if_t<!is_ranges_fwd_iter_v<Iterator>,
int> = 0>
380 void copy_initialize(Iterator first, Iterator last) {
382 for (; first != last; ++first) {
383 this->emplace_back(*first);
387 void assign_aux_n(size_type n,
const T& value) {
390 this->insert(end(), n -
size(), value);
393 this->erase(begin() + n, end());
398 template <
typename Iterator>
399 void assign_ranges(Iterator first, Iterator last) {
400 auto first1 = begin();
402 for (; first != last && first1 != last1; ++first, ++first1)
405 this->erase(first1, last1);
407 insert(first1, last1);
410 void reallocate_map(
const size_type n,
const bool add_at_front) {
411 const auto begin_left =
static_cast<size_type
>(start_.cur_ - start_.first_);
412 if (add_at_front && begin_left < n) {
413 const size_t needed = (n - begin_left) / buffer_size_ + 1;
414 if (needed >
static_cast<size_type
>(start_.node_ - map_pair_.value)) {
415 const size_type new_size =
_MSTL max(
416 map_size_pair_.value << 1,
417 map_size_pair_.value + needed + DEQUE_INIT_MAP_SIZE);
418 map_pointer map = this->create_map(new_size);
419 const size_type old_buf = finish_.node_ - start_.node_ + 1;
420 const size_type new_buf = needed + old_buf;
422 auto begin = map + (new_size - new_buf) / 2;
423 auto mid = begin + needed;
424 auto end = mid + old_buf;
425 this->create_nodes(begin, mid - 1);
426 for (
auto begin1 = mid, begin2 = start_.node_;
427 begin1 != end; ++begin1, ++begin2) {
431 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
432 map_pair_.value = map;
433 map_size_pair_.value = new_size;
434 start_ = iterator(*mid + (start_.cur_ - start_.first_), mid,
this);
435 finish_ = iterator(*(end - 1) + (finish_.cur_ - finish_.first_), end - 1,
this);
438 this->create_nodes(start_.node_ - needed, start_.node_ - 1);
441 const auto end_left =
static_cast<size_type
>(finish_.last_ - finish_.cur_ - 1);
442 if (!add_at_front && end_left < n) {
443 const size_type needed = (n - end_left) / buffer_size_ + 1;
444 if (needed >
static_cast<size_type
>((map_pair_.value + map_size_pair_.value) - finish_.node_ - 1)) {
445 const size_type new_size =
_MSTL max(
446 map_size_pair_.value << 1,
447 map_size_pair_.value + needed + DEQUE_INIT_MAP_SIZE);
448 map_pointer map = this->create_map(new_size);
449 const size_type old_buf = finish_.node_ - start_.node_ + 1;
450 const size_type new_buf = needed + old_buf;
452 auto begin = map + (new_size - new_buf) / 2;
453 auto mid = begin + old_buf;
454 auto end = mid + needed;
455 for (
auto begin1 = begin, begin2 = start_.node_;
456 begin1 != mid; ++begin1, ++begin2) {
459 this->create_nodes(mid, end - 1);
461 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
462 map_pair_.value = map;
463 map_size_pair_.value = new_size;
464 start_ = iterator(*begin + (start_.cur_ - start_.first_), begin,
this);
465 finish_ = iterator(*(mid - 1) + (finish_.cur_ - finish_.first_), mid - 1,
this);
468 this->create_nodes(finish_.node_ + 1, finish_.node_ + needed);
472 template <
typename Iterator>
473 void insert_ranges_n(iterator position, Iterator first, Iterator last, size_type n) {
474 difference_type dist_before = position - start_;
475 if (dist_before <
static_cast<difference_type
>(
size() / 2)) {
476 this->reallocate_map(n,
true);
477 auto old_start = start_;
478 auto new_start = start_ - n;
479 position = start_ + dist_before;
482 if (dist_before >= n) {
483 iterator start_n = start_ + n;
486 _MSTL copy(start_n, position, old_start);
490 auto mid =
_MSTL next(first, n - dist_before);
497 if (new_start.node_ != start_.node_) {
498 this->destroy_nodes(new_start.node_, start_.node_ - 1);
504 this->reallocate_map(n,
false);
505 auto old_finish = finish_;
506 auto new_finish = finish_ + n;
507 const size_type dist_after =
size() - dist_before;
508 position = finish_ - dist_after;
511 if (dist_after > n) {
512 auto finish_n = finish_ - n;
514 finish_ = new_finish;
519 auto mid =
_MSTL next(first, dist_after);
522 finish_ = new_finish;
526 if (new_finish.node_ != finish_.node_) {
527 this->destroy_nodes(finish_.node_ + 1, new_finish.node_);
534 template <
typename Iterator, enable_if_t<!is_ranges_fwd_iter_v<Iterator>,
int> = 0>
535 void insert_ranges(iterator position, Iterator first, Iterator last) {
536 if (last <= first)
return;
538 const size_type dist_before = position - start_;
539 if (dist_before <
size() / 2) {
540 this->reallocate_map(n,
true);
543 this->reallocate_map(n,
false);
545 position = start_ + dist_before;
547 for(size_type i = 0; i < n; ++i, --cur) {
548 this->insert(position, *cur);
552 template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
553 void insert_ranges(iterator position, Iterator first, Iterator last) {
554 if (last <= first)
return;
557 if (position.cur_ == start_.cur_) {
558 this->reallocate_map(n,
true);
559 auto new_start = start_ - n;
564 if (new_start.node_ != start_.node_) {
565 this->destroy_nodes(new_start.node_, start_.node_ - 1);
570 else if (position.cur_ == finish_.cur_) {
571 this->reallocate_map(n,
false);
572 auto new_finish = finish_ + n;
575 finish_ = new_finish;
578 if (new_finish.node_ != finish_.node_) {
579 this->destroy_nodes(finish_.node_ + 1, new_finish.node_);
585 this->insert_ranges_n(position, first, last, n);
589 void insert_n_aux(iterator position, size_type n,
const T& x) {
590 difference_type dist_before = position - start_;
591 if (dist_before <
static_cast<difference_type
>(
size() / 2)) {
592 this->reallocate_map(n,
true);
593 auto old_start = start_;
594 auto new_start = start_ - n;
595 position = start_ + dist_before;
598 if (dist_before >= n) {
599 iterator start_n = start_ + n;
602 _MSTL copy(start_n, position, old_start);
612 if (new_start.node_ != start_.node_) {
613 this->destroy_nodes(new_start.node_, start_.node_ - 1);
619 this->reallocate_map(n,
false);
620 auto old_finish = finish_;
621 auto new_finish = finish_ + n;
622 const size_type dist_after =
size() - dist_before;
623 position = finish_ - dist_after;
626 if (dist_after > n) {
627 auto finish_n = finish_ - n;
629 finish_ = new_finish;
636 finish_ = new_finish;
640 if (new_finish.node_ != finish_.node_) {
641 this->destroy_nodes(finish_.node_ + 1, new_finish.node_);
648 template <
typename... Args>
649 iterator insert_aux(iterator position, Args&&... args)
650 noexcept(is_nothrow_move_assignable_v<value_type>) {
651 size_type index = position - start_;
652 if (index <
size() / 2) {
653 this->emplace_front(this->front());
654 iterator front1 = start_;
656 iterator front2 = front1;
658 position = start_ + index;
659 iterator pos1 = position;
664 this->push_back(this->back());
665 iterator back1 = finish_;
667 iterator back2 = back1;
669 position = start_ + index;
679 this->fill_initialize(0,
_MSTL move(T()));
681 explicit deque(
const size_type n) {
682 this->fill_initialize(n, T());
684 deque(
const size_type n,
const T& x) {
685 this->fill_initialize(n, x);
688 template <
typename Iterator, enable_if_t<is_input_iter_v<Iterator>,
int> = 0>
689 deque(Iterator first, Iterator last) {
690 this->copy_initialize(first, last);
693 deque(std::initializer_list<T> l) {
694 this->copy_initialize(l.begin(), l.end());
697 deque& operator =(std::initializer_list<T> l) {
703 deque(
const deque& x) {
704 this->copy_initialize(x.cbegin(), x.cend());
707 deque& operator =(
const deque& x) {
710 const size_t len =
size();
711 if (len >= x.size()) {
712 this->erase(
_MSTL copy(x.start_, x.finish_, start_), finish_);
715 iterator mid = x.cbegin() + len;
717 this->insert(finish_, mid, x.finish_);
722 deque(deque&& x)
noexcept {
726 deque& operator =(deque&& x)
noexcept {
734 if (map_pair_.value ==
nullptr)
return;
737 if (map_pair_.value !=
nullptr) {
738 for (size_type i = 0; i < map_size_pair_.value; ++i) {
739 if (map_pair_.value[i] !=
nullptr) {
740 map_size_pair_.get_base().deallocate(map_pair_.value[i], buffer_size_);
741 map_pair_.value[i] =
nullptr;
745 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
746 map_pair_.value =
nullptr;
750 MSTL_NODISCARD iterator begin() noexcept {
return iterator(start_); }
751 MSTL_NODISCARD iterator end() noexcept {
return iterator(finish_); }
752 MSTL_NODISCARD const_iterator begin() const noexcept {
return cbegin(); }
753 MSTL_NODISCARD const_iterator end() const noexcept {
return cend(); }
754 MSTL_NODISCARD const_iterator cbegin() const noexcept {
return const_iterator(start_); }
755 MSTL_NODISCARD const_iterator cend() const noexcept {
return const_iterator(finish_); }
756 MSTL_NODISCARD reverse_iterator rbegin() noexcept {
return reverse_iterator(end()); }
757 MSTL_NODISCARD reverse_iterator rend() noexcept {
return reverse_iterator(begin()); }
758 MSTL_NODISCARD const_reverse_iterator rbegin() const noexcept {
return crbegin(); }
759 MSTL_NODISCARD const_reverse_iterator rend() const noexcept {
return crend(); }
760 MSTL_NODISCARD const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(cend()); }
761 MSTL_NODISCARD const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(cbegin()); }
763 MSTL_NODISCARD size_type
size() const noexcept {
return finish_ - start_; }
764 MSTL_NODISCARD size_type max_size() const noexcept {
return static_cast<size_type
>(-1); }
765 MSTL_NODISCARD
bool empty() const noexcept {
return finish_ == start_; }
767 MSTL_NODISCARD allocator_type get_allocator() const noexcept {
return allocator_type(); }
769 MSTL_NODISCARD reference front() noexcept {
770 MSTL_DEBUG_VERIFY(!
empty(),
"front called on empty deque");
773 MSTL_NODISCARD const_reference front() const noexcept {
774 MSTL_DEBUG_VERIFY(!
empty(),
"front called on empty deque");
777 MSTL_NODISCARD reference back() noexcept {
778 MSTL_DEBUG_VERIFY(!
empty(),
"back called on empty deque");
779 return *(finish_ - 1);
781 MSTL_NODISCARD const_reference back() const noexcept {
782 MSTL_DEBUG_VERIFY(!
empty(),
"back called on empty deque");
783 return *(finish_ - 1);
786 void resize(size_type new_size,
const T& x) {
787 const auto size = this->
size();
789 this->erase(start_ + new_size, finish_);
791 this->insert(finish_, new_size - size, x);
793 void resize(
const size_type new_size) {
794 this->resize(new_size, T());
797 template <
typename... Args>
798 iterator emplace(iterator position, Args&& ...args) {
799 if (position.cur_ == start_.cur_) {
803 if (position.cur_ == finish_.cur_) {
810 template <
typename... Args>
811 void emplace_back(Args&&... args) {
812 if (finish_.cur_ != finish_.last_ - 1) {
817 this->reallocate_map(1,
false);
823 template <
typename... Args>
824 void emplace_front(Args&&... args) {
825 if (start_.cur_ != start_.first_) {
830 this->reallocate_map(1,
true);
836 void push_back(
const T& x) {
837 if (finish_.cur_ != finish_.last_ - 1) {
842 reallocate_map(1,
false);
848 void push_front(
const T& x) {
849 if (start_.cur_ != start_.first_) {
854 this->reallocate_map(1,
true);
860 void push_back(T&& x) {
864 void push_front(T&& x) {
868 void pop_back() noexcept {
869 MSTL_DEBUG_VERIFY(!
empty(),
"pop_back called on empty deque");
870 if (finish_.cur_ != finish_.first_) {
875 auto cur = finish_.node_;
878 map_size_pair_.get_base().deallocate(*cur, buffer_size_);
883 void pop_front() noexcept {
884 MSTL_DEBUG_VERIFY(!
empty(),
"pop_front called on empty deque");
885 if (start_.cur_ != start_.last_ - 1) {
891 auto cur = start_.node_;
892 map_size_pair_.get_base().deallocate(start_.first_, buffer_size_);
898 void assign(
const size_type
count,
const T& value) {
899 this->assign_aux_n(
count, value);
902 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
903 void assign(Iterator first, Iterator last) {
904 this->assign_ranges(first, last);
907 void assign(std::initializer_list<T> l) {
908 this->assign_ranges(l.begin(), l.end());
911 iterator insert(iterator position,
const T& x) {
912 if (position.cur_ == start_.cur_) {
916 if (position.cur_ == finish_.cur_) {
920 return this->insert_aux(position, x);
923 iterator insert(iterator position, T&& x) {
924 if (position.cur_ == start_.cur_) {
928 if (position.cur_ == finish_.cur_) {
932 return this->insert_aux(position,
_MSTL move(x));
935 template <
typename Iterator, enable_if_t<is_ranges_input_iter_v<Iterator>,
int> = 0>
936 void insert(iterator position, Iterator first, Iterator last) {
937 this->insert_ranges(position, first, last);
940 iterator insert(iterator position, std::initializer_list<T> l) {
941 return this->insert(position, l.begin(), l.end());
944 void insert(iterator position,
const size_t n,
const T& x) {
945 if (position.cur_ == start_.cur_) {
946 this->reallocate_map(n,
true);
947 auto new_start = start_ - n;
951 else if (position.cur_ == finish_.cur_) {
952 this->reallocate_map(n,
false);
953 auto new_finish = finish_ + n;
955 finish_ = new_finish;
958 return this->insert_n_aux(position, n, x);
961 iterator erase(iterator position)
noexcept {
963 const size_type dest_before = position - start_;
964 if (dest_before <
size() / 2) {
972 return start_ + dest_before;
975 iterator erase(iterator first, iterator last)
noexcept {
976 if (first == start_ && last == finish_) {
981 const size_type len = last - first;
982 const size_type dist_before = first - start_;
983 if (dist_before < (
size() - len) / 2) {
985 iterator new_start = start_ + len;
991 iterator new_finish = finish_ - len;
993 finish_ = new_finish;
995 return start_ + dist_before;
998 void shrink_to_fit() {
999 for (map_pointer cur = map_pair_.value; cur < start_.node_; ++cur) {
1000 if (*cur ==
nullptr)
continue;
1001 map_size_pair_.get_base().deallocate(*cur, buffer_size_);
1004 for (map_pointer cur = finish_.node_ + 1; cur < map_pair_.value + map_size_pair_.value; ++cur) {
1005 if (*cur ==
nullptr)
continue;
1006 map_size_pair_.get_base().deallocate(*cur, buffer_size_);
1011 void clear() noexcept {
1012 for (map_pointer cur = start_.node_ + 1; cur < finish_.node_; ++cur) {
1016 if (start_.node_ == finish_.node_)
1027 MSTL_NODISCARD const_reference at(size_type position)
const {
1028 return const_iterator(start_)[position];
1030 MSTL_NODISCARD reference at(
const size_type position) {
1031 return const_cast<reference
>(
static_cast<const deque*
>(
this)->at(position));
1033 MSTL_NODISCARD const_reference operator [](
const size_type position)
const {
1034 return this->at(position);
1036 MSTL_NODISCARD reference operator [](
const size_type position) {
1037 return this->at(position);
1040 void swap(deque& x)
noexcept {
1045 _MSTL swap(map_size_pair_, x.map_size_pair_);
1048 MSTL_NODISCARD
bool operator ==(
const deque& rhs)
const
1049 noexcept(
noexcept(this->
size() == rhs.size() &&
_MSTL equal(this->cbegin(), this->cend(), rhs.cbegin()))) {
1050 return this->
size() == rhs.size() &&
_MSTL equal(this->cbegin(), this->cend(), rhs.cbegin());
1052 MSTL_NODISCARD
bool operator <(
const deque& rhs)
const
1057#if MSTL_SUPPORT_DEDUCTION_GUIDES__
1058template <
typename Iterator,
typename Alloc>
1059deque(Iterator, Iterator, Alloc = Alloc()) -> deque<iter_value_t<Iterator>, Alloc>;
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr const T & max(const T &a, const T &b, Compare comp) noexcept(noexcept(comp(a, b)))
返回两个值中的较大者
MSTL_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
MSTL_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)
统计范围内等于指定值的元素数量
MSTL_CONSTEXPR20 enable_if_t< is_constructible_v< T, Args... >, void * > construct(T *ptr, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
在指定内存位置构造对象
MSTL_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)
计算两个迭代器之间的距离
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
constexpr Iterator2 copy_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向复制范围元素
constexpr void fill(Iterator first, Iterator last, const T &value)
填充范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制范围元素
void swap()=delete
删除无参数的swap重载
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
MSTL_CONSTEXPR20 Iterator uninitialized_fill_n(Iterator first, size_t n, const T &x)
在未初始化内存中用指定值填充指定数量的元素
MSTL_CONSTEXPR20 void uninitialized_fill(Iterator first, Iterator last, const T &x)
在未初始化内存上填充值
MSTL_CONSTEXPR20 Iterator2 uninitialized_copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制元素到未初始化内存
MSTL_NODISCARD constexpr decltype(auto) size() const noexcept(noexcept(derived().size()))
获取集合大小
MSTL_NODISCARD constexpr bool empty() const noexcept(noexcept(derived().empty()))
检查集合是否为空