MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
deque.hpp
1#ifndef MSTL_CORE_CONTAINER_DEQUE_HPP__
2#define MSTL_CORE_CONTAINER_DEQUE_HPP__
9
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;
13
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;
16}
17
18
19template <typename T, typename Alloc, size_t BufSize>
20class deque;
21
22template <bool IsConst, typename Deque, size_t BufSize = 0>
23struct deque_iterator {
24private:
25 using container_type = Deque;
26 using iterator = deque_iterator<false, container_type>;
27 using const_iterator = deque_iterator<true, container_type>;
28
29public:
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;
36
37private:
38 pointer cur_ = nullptr;
39 pointer first_ = nullptr;
40 pointer last_ = nullptr;
41 pointer* node_ = nullptr;
42 const container_type* deq_ = nullptr;
43
44 static constexpr difference_type buffer_size_ = _MSTL deque_buf_size(BufSize, sizeof(value_type));
45
46 template <typename, typename, size_t> friend class deque;
47 template <bool, typename, size_t> friend struct deque_iterator;
48
49private:
50 void change_buff(pointer* new_map) noexcept {
51 node_ = new_map;
52 first_ = *new_map;
53 last_ = first_ + buffer_size_;
54 }
55
56public:
57 deque_iterator() noexcept = default;
58
59 deque_iterator(pointer cur, pointer* map, const container_type* deq)
60 : cur_(cur), first_(*map), last_(*map + buffer_size_), node_(map), deq_(deq) {}
61
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) {}
65
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_) {}
69
70 deque_iterator& operator =(const iterator& x) noexcept {
71 if (_MSTL addressof(x) == this) return *this;
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_);
76 deq_ = x.deq_;
77 return *this;
78 }
79
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_) {
83 x.cur_ = nullptr;
84 x.first_ = nullptr;
85 x.last_ = nullptr;
86 x.node_ = nullptr;
87 x.deq_ = nullptr;
88 }
89
90 deque_iterator& operator =(iterator&& x) noexcept {
91 if (_MSTL addressof(x) == this) return *this;
92 swap(x);
93 return *this;
94 }
95
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_) {}
99
100 deque_iterator& operator =(const const_iterator& x) noexcept {
101 if (_MSTL addressof(x) == this) return *this;
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_);
106 deq_ = x.deq_;
107 return *this;
108 }
109
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_) {
113 x.cur_ = nullptr;
114 x.first_ = nullptr;
115 x.last_ = nullptr;
116 x.node_ = nullptr;
117 x.deq_ = nullptr;
118 }
119 deque_iterator& operator =(const_iterator&& x) noexcept {
120 if (_MSTL addressof(x) == this) return *this;
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_);
125 deq_ = x.deq_;
126 x.cur_ = nullptr;
127 x.first_ = nullptr;
128 x.last_ = nullptr;
129 x.node_ = nullptr;
130 x.deq_ = nullptr;
131 return *this;
132 }
133
134 ~deque_iterator() noexcept = default;
135
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));
140 return *cur_;
141 }
142
143 MSTL_NODISCARD pointer operator ->() const noexcept {
144 MSTL_DEBUG_VERIFY(cur_ && deq_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(deque_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
145 return cur_;
146 }
147
148 deque_iterator& operator ++() noexcept {
149 MSTL_DEBUG_VERIFY(cur_ && deq_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(deque_iterator, __MSTL_DEBUG_TAG_INCREMENT));
150 ++cur_;
151 if (cur_ == last_) {
152 this->change_buff(node_ + 1);
153 cur_ = first_;
154 }
155 return *this;
156 }
157
158 deque_iterator operator ++(int) noexcept {
159 deque_iterator tmp = *this;
160 ++*this;
161 return tmp;
162 }
163
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);
168 cur_ = last_;
169 }
170 --cur_;
171 return *this;
172 }
173
174 deque_iterator operator --(int) noexcept {
175 deque_iterator tmp = *this;
176 --*this;
177 return tmp;
178 }
179
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_) {
184 cur_ += n;
185 }
186 else {
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_);
192 }
193 return *this;
194 }
195 MSTL_NODISCARD deque_iterator operator +(const difference_type n) const noexcept {
196 auto tmp = *this;
197 return tmp += n;
198 }
199 MSTL_NODISCARD friend deque_iterator operator +(const difference_type n, const deque_iterator& it) {
200 return it + n;
201 }
202
203 deque_iterator& operator -=(const difference_type n) noexcept {
204 return *this += -n;
205 }
206 MSTL_NODISCARD deque_iterator operator -(const difference_type n) const noexcept {
207 deque_iterator temp = *this;
208 return temp -= n;
209 }
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_);
213 }
214
215 MSTL_NODISCARD reference operator [](const difference_type n) noexcept { return *(*this + n); }
216
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_;
220 }
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_;
225 }
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); }
229
230 void swap(deque_iterator& x) noexcept {
231 cur_ = x.cur_;
232 first_ = x.first_;
233 last_ = x.last_;
234 node_ = x.node_;
235 deq_ = x.deq_;
236 x.cur_ = nullptr;
237 x.first_ = nullptr;
238 x.last_ = nullptr;
239 x.node_ = nullptr;
240 x.deq_ = nullptr;
241 }
242
243 MSTL_NODISCARD pointer base() const noexcept {
244 return cur_;
245 }
246};
247template <bool IsConst, typename Deque, size_t BufSize>
248void swap (
249 deque_iterator<IsConst, Deque, BufSize>& lhs,
250 deque_iterator<IsConst, Deque, BufSize>& rhs) noexcept {
251 lhs.swap(rhs);
252}
253
254
255// let BufSize = 0 to use default deque size, or manually set it as you wish.
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.");
260#endif
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.");
263
264public:
266 using allocator_type = Alloc;
267
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>;
272
273private:
274 using map_pointer = pointer*;
275 using map_allocator = typename Alloc::template rebind<pointer>::other;
276
277 iterator start_{};
278 iterator finish_{};
279 // allocator, map_size_
280 compressed_pair<allocator_type, size_type> map_size_pair_{
281 default_construct_tag{}, 0
282 };
283 // map_allocator, map_
284 compressed_pair<map_allocator, map_pointer> map_pair_{
285 default_construct_tag{}, nullptr
286 };
287
288 static constexpr difference_type buffer_size_ = iterator::buffer_size_;
289
290 template <bool, typename, size_t> friend struct deque_iterator;
291
292private:
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;
298 }
299 return map;
300 }
301
302 void create_nodes(map_pointer nstart, map_pointer nfinish) {
303 map_pointer cur;
304 try {
305 for (cur = nstart; cur <= nfinish; ++cur)
306 *cur = map_size_pair_.get_base().allocate(buffer_size_);
307 } catch (...) {
308 while (cur != nstart) {
309 --cur;
310 map_size_pair_.get_base().deallocate(*cur, buffer_size_);
311 *cur = nullptr;
312 }
313 throw;
314 }
315 }
316
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_);
321 *cur = nullptr;
322 }
323 }
324
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);
328
329 try {
330 map_pair_.value = this->create_map(map_size_pair_.value);
331 } catch (...) {
332 map_pair_.value = nullptr;
333 map_size_pair_.value = 0;
334 throw;
335 }
336
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;
339
340 try {
341 this->create_nodes(nstart, nfinish);
342 } catch (...) {
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;
347 throw;
348 }
349
350 start_.change_buff(nstart);
351 finish_.change_buff(nfinish);
352 start_.cur_ = start_.first_;
353 finish_.cur_ = n == 0 ?
354 start_.first_ :
355 finish_.first_ + (n % buffer_size_ ? n % buffer_size_ : buffer_size_);
356 start_.deq_ = this;
357 finish_.deq_ = this;
358 }
359
360 void fill_initialize(const size_type n, const T& x) {
361 this->create_map_and_nodes(n);
362 if (n == 0) return;
363 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur)
364 _MSTL uninitialized_fill(*cur, *cur + buffer_size_, x);
365 _MSTL uninitialized_fill(finish_.first_, finish_.cur_, x);
366 }
367
368 template <typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>, int> = 0>
369 void copy_initialize(Iterator first, Iterator last) {
370 this->create_map_and_nodes(_MSTL distance(first, last));
371 for (map_pointer cur = start_.node_; cur < finish_.node_; ++cur) {
372 Iterator next = _MSTL next(first, buffer_size_);
373 _MSTL uninitialized_copy(first, next, *cur);
374 first = next;
375 }
376 _MSTL uninitialized_copy(first, last, finish_.first_);
377 }
378
379 template <typename Iterator, enable_if_t<!is_ranges_fwd_iter_v<Iterator>, int> = 0>
380 void copy_initialize(Iterator first, Iterator last) {
381 this->create_map_and_nodes(_MSTL distance(first, last));
382 for (; first != last; ++first) {
383 this->emplace_back(*first);
384 }
385 }
386
387 void assign_aux_n(size_type n, const T& value) {
388 if (n > size()) {
389 _MSTL fill(begin(), end(), value);
390 this->insert(end(), n - size(), value);
391 }
392 else {
393 this->erase(begin() + n, end());
394 _MSTL fill(begin(), end(), value);
395 }
396 }
397
398 template <typename Iterator>
399 void assign_ranges(Iterator first, Iterator last) {
400 auto first1 = begin();
401 auto last1 = end();
402 for (; first != last && first1 != last1; ++first, ++first1)
403 *first1 = *first;
404 if (first1 != last1)
405 this->erase(first1, last1);
406 else
407 insert(first1, last1);
408 }
409
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;
421
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) {
428 *begin1 = *begin2;
429 }
430
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);
436 return;
437 }
438 this->create_nodes(start_.node_ - needed, start_.node_ - 1);
439 return;
440 }
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;
451
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) {
457 *begin1 = *begin2;
458 }
459 this->create_nodes(mid, end - 1);
460
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);
466 return;
467 }
468 this->create_nodes(finish_.node_ + 1, finish_.node_ + needed);
469 }
470 }
471
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;
480
481 try {
482 if (dist_before >= n) {
483 iterator start_n = start_ + n;
484 _MSTL uninitialized_copy(start_, start_n, new_start);
485 start_ = new_start;
486 _MSTL copy(start_n, position, old_start);
487 _MSTL copy(first, last, position - n);
488 }
489 else {
490 auto mid = _MSTL next(first, n - dist_before);
491 _MSTL uninitialized_copy(first, mid,
492 _MSTL uninitialized_copy(start_, position, new_start));
493 start_ = new_start;
494 _MSTL copy(mid, last, old_start);
495 }
496 } catch (...) {
497 if (new_start.node_ != start_.node_) {
498 this->destroy_nodes(new_start.node_, start_.node_ - 1);
499 }
500 throw;
501 }
502 }
503 else {
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;
509
510 try {
511 if (dist_after > n) {
512 auto finish_n = finish_ - n;
513 _MSTL uninitialized_copy(finish_n, finish_, finish_);
514 finish_ = new_finish;
515 _MSTL copy_backward(position, finish_n, old_finish);
516 _MSTL copy(first, last, position);
517 }
518 else {
519 auto mid = _MSTL next(first, dist_after);
520 _MSTL uninitialized_copy(position, finish_,
521 _MSTL uninitialized_copy(mid, last, finish_));
522 finish_ = new_finish;
523 _MSTL copy(first, mid, position);
524 }
525 } catch (...) {
526 if (new_finish.node_ != finish_.node_) {
527 this->destroy_nodes(finish_.node_ + 1, new_finish.node_);
528 }
529 throw;
530 }
531 }
532 }
533
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;
537 const size_type n = _MSTL distance(first, last);
538 const size_type dist_before = position - start_;
539 if (dist_before < size() / 2) {
540 this->reallocate_map(n, true);
541 }
542 else {
543 this->reallocate_map(n, false);
544 }
545 position = start_ + dist_before;
546 auto cur = --last;
547 for(size_type i = 0; i < n; ++i, --cur) {
548 this->insert(position, *cur);
549 }
550 }
551
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;
555 const size_type n = _MSTL distance(first, last);
556
557 if (position.cur_ == start_.cur_) {
558 this->reallocate_map(n, true);
559 auto new_start = start_ - n;
560 try {
561 _MSTL uninitialized_copy(first, last, new_start);
562 start_ = new_start;
563 } catch (...) {
564 if (new_start.node_ != start_.node_) {
565 this->destroy_nodes(new_start.node_, start_.node_ - 1);
566 }
567 throw;
568 }
569 }
570 else if (position.cur_ == finish_.cur_) {
571 this->reallocate_map(n, false);
572 auto new_finish = finish_ + n;
573 try {
574 _MSTL uninitialized_copy(first, last, finish_);
575 finish_ = new_finish;
576 }
577 catch (...) {
578 if (new_finish.node_ != finish_.node_) {
579 this->destroy_nodes(finish_.node_ + 1, new_finish.node_);
580 }
581 throw;
582 }
583 }
584 else {
585 this->insert_ranges_n(position, first, last, n);
586 }
587 }
588
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;
596
597 try {
598 if (dist_before >= n) {
599 iterator start_n = start_ + n;
600 _MSTL uninitialized_copy(start_, start_n, new_start);
601 start_ = new_start;
602 _MSTL copy(start_n, position, old_start);
603 _MSTL fill(position - n, position, x);
604 }
605 else {
607 _MSTL uninitialized_copy(start_, position, new_start), start_, x);
608 start_ = new_start;
609 _MSTL fill(old_start, position, x);
610 }
611 } catch (...) {
612 if (new_start.node_ != start_.node_) {
613 this->destroy_nodes(new_start.node_, start_.node_ - 1);
614 }
615 throw;
616 }
617 }
618 else {
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;
624
625 try {
626 if (dist_after > n) {
627 auto finish_n = finish_ - n;
628 _MSTL uninitialized_copy(finish_n, finish_, finish_);
629 finish_ = new_finish;
630 _MSTL copy_backward(position, finish_n, old_finish);
631 _MSTL fill(position, position + n, x);
632 }
633 else {
634 _MSTL uninitialized_fill(finish_, position + n, x);
635 _MSTL uninitialized_copy(position, finish_, position + n);
636 finish_ = new_finish;
637 _MSTL fill(position, old_finish, x);
638 }
639 } catch (...) {
640 if (new_finish.node_ != finish_.node_) {
641 this->destroy_nodes(finish_.node_ + 1, new_finish.node_);
642 }
643 throw;
644 }
645 }
646 }
647
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_;
655 ++front1;
656 iterator front2 = front1;
657 ++front2;
658 position = start_ + index;
659 iterator pos1 = position;
660 ++pos1;
661 _MSTL copy(front2, pos1, front1);
662 }
663 else {
664 this->push_back(this->back());
665 iterator back1 = finish_;
666 --back1;
667 iterator back2 = back1;
668 --back2;
669 position = start_ + index;
670 _MSTL copy_backward(position, back2, back1);
671 }
672 value_type val(_MSTL forward<Args>(args)...);
673 *position = _MSTL move(val);
674 return position;
675 }
676
677public:
678 deque() {
679 this->fill_initialize(0, _MSTL move(T()));
680 }
681 explicit deque(const size_type n) {
682 this->fill_initialize(n, T());
683 }
684 deque(const size_type n, const T& x) {
685 this->fill_initialize(n, x);
686 }
687
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);
691 }
692
693 deque(std::initializer_list<T> l) {
694 this->copy_initialize(l.begin(), l.end());
695 }
696
697 deque& operator =(std::initializer_list<T> l) {
698 deque tmp(l);
699 this->swap(tmp);
700 return *this;
701 }
702
703 deque(const deque& x) {
704 this->copy_initialize(x.cbegin(), x.cend());
705 }
706
707 deque& operator =(const deque& x) {
708 if (_MSTL addressof(x) == this) return *this;
709
710 const size_t len = size();
711 if (len >= x.size()) {
712 this->erase(_MSTL copy(x.start_, x.finish_, start_), finish_);
713 }
714 else {
715 iterator mid = x.cbegin() + len;
716 _MSTL copy(x.start_, mid, start_);
717 this->insert(finish_, mid, x.finish_);
718 }
719 return *this;
720 }
721
722 deque(deque&& x) noexcept {
723 this->swap(x);
724 }
725
726 deque& operator =(deque&& x) noexcept {
727 if (_MSTL addressof(x) == this) return *this;
728 this->clear();
729 this->swap(x);
730 return *this;
731 }
732
733 ~deque() {
734 if (map_pair_.value == nullptr) return;
735 this->clear();
736
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;
742 }
743 }
744
745 map_pair_.get_base().deallocate(map_pair_.value, map_size_pair_.value);
746 map_pair_.value = nullptr;
747 }
748 }
749
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()); }
762
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_; }
766
767 MSTL_NODISCARD allocator_type get_allocator() const noexcept { return allocator_type(); }
768
769 MSTL_NODISCARD reference front() noexcept {
770 MSTL_DEBUG_VERIFY(!empty(), "front called on empty deque");
771 return *start_;
772 }
773 MSTL_NODISCARD const_reference front() const noexcept {
774 MSTL_DEBUG_VERIFY(!empty(), "front called on empty deque");
775 return *start_;
776 }
777 MSTL_NODISCARD reference back() noexcept {
778 MSTL_DEBUG_VERIFY(!empty(), "back called on empty deque");
779 return *(finish_ - 1);
780 }
781 MSTL_NODISCARD const_reference back() const noexcept {
782 MSTL_DEBUG_VERIFY(!empty(), "back called on empty deque");
783 return *(finish_ - 1);
784 }
785
786 void resize(size_type new_size, const T& x) {
787 const auto size = this->size();
788 if (new_size < size)
789 this->erase(start_ + new_size, finish_);
790 else
791 this->insert(finish_, new_size - size, x);
792 }
793 void resize(const size_type new_size) {
794 this->resize(new_size, T());
795 }
796
797 template <typename... Args>
798 iterator emplace(iterator position, Args&& ...args) {
799 if (position.cur_ == start_.cur_) {
800 this->emplace_front(_MSTL forward<Args>(args)...);
801 return start_;
802 }
803 if (position.cur_ == finish_.cur_) {
804 this->emplace_back(_MSTL forward<Args>(args)...);
805 return finish_ - 1;
806 }
807 return this->insert_aux(position, _MSTL forward<Args>(args)...);
808 }
809
810 template <typename... Args>
811 void emplace_back(Args&&... args) {
812 if (finish_.cur_ != finish_.last_ - 1) {
813 _MSTL construct(finish_.cur_, _MSTL forward<Args>(args)...);
814 ++finish_.cur_;
815 }
816 else {
817 this->reallocate_map(1, false);
818 _MSTL construct(finish_.cur_, _MSTL forward<Args>(args)...);
819 ++finish_;
820 }
821 }
822
823 template <typename... Args>
824 void emplace_front(Args&&... args) {
825 if (start_.cur_ != start_.first_) {
826 _MSTL construct(start_.cur_ - 1, _MSTL forward<Args>(args)...);
827 --start_.cur_;
828 }
829 else {
830 this->reallocate_map(1, true);
831 --start_;
832 _MSTL construct(start_.cur_, _MSTL forward<Args>(args)...);
833 }
834 }
835
836 void push_back(const T& x) {
837 if (finish_.cur_ != finish_.last_ - 1) {
838 _MSTL construct(finish_.cur_, x);
839 ++finish_.cur_;
840 }
841 else {
842 reallocate_map(1, false);
843 _MSTL construct(finish_.cur_, x);
844 ++finish_;
845 }
846 }
847
848 void push_front(const T& x) {
849 if (start_.cur_ != start_.first_) {
850 _MSTL construct(start_.cur_ - 1, x);
851 --start_.cur_;
852 }
853 else {
854 this->reallocate_map(1, true);
855 --start_;
856 _MSTL construct(start_.cur_, x);
857 }
858 }
859
860 void push_back(T&& x) {
861 this->emplace_back(_MSTL forward<T>(x));
862 }
863
864 void push_front(T&& x) {
865 this->emplace_front(_MSTL forward<T>(x));
866 }
867
868 void pop_back() noexcept {
869 MSTL_DEBUG_VERIFY(!empty(), "pop_back called on empty deque");
870 if (finish_.cur_ != finish_.first_) {
871 --finish_.cur_;
872 _MSTL destroy(finish_.cur_);
873 }
874 else {
875 auto cur = finish_.node_;
876 --finish_;
877 _MSTL destroy(finish_.cur_);
878 map_size_pair_.get_base().deallocate(*cur, buffer_size_);
879 *cur = nullptr;
880 }
881 }
882
883 void pop_front() noexcept {
884 MSTL_DEBUG_VERIFY(!empty(), "pop_front called on empty deque");
885 if (start_.cur_ != start_.last_ - 1) {
886 _MSTL destroy(start_.cur_);
887 ++start_.cur_;
888 }
889 else {
890 _MSTL destroy(start_.cur_);
891 auto cur = start_.node_;
892 map_size_pair_.get_base().deallocate(start_.first_, buffer_size_);
893 *cur = nullptr;
894 ++start_;
895 }
896 }
897
898 void assign(const size_type count, const T& value) {
899 this->assign_aux_n(count, value);
900 }
901
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);
905 }
906
907 void assign(std::initializer_list<T> l) {
908 this->assign_ranges(l.begin(), l.end());
909 }
910
911 iterator insert(iterator position, const T& x) {
912 if (position.cur_ == start_.cur_) {
913 this->push_front(x);
914 return start_;
915 }
916 if (position.cur_ == finish_.cur_) {
917 this->push_back(x);
918 return _MSTL prev(finish_);
919 }
920 return this->insert_aux(position, x);
921 }
922
923 iterator insert(iterator position, T&& x) {
924 if (position.cur_ == start_.cur_) {
925 this->emplace_front(_MSTL move(x));
926 return start_;
927 }
928 if (position.cur_ == finish_.cur_) {
929 this->emplace_back(_MSTL move(x));
930 return _MSTL prev(finish_);
931 }
932 return this->insert_aux(position, _MSTL move(x));
933 }
934
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);
938 }
939
940 iterator insert(iterator position, std::initializer_list<T> l) {
941 return this->insert(position, l.begin(), l.end());
942 }
943
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;
948 _MSTL uninitialized_fill_n(new_start, n, x);
949 start_ = new_start;
950 }
951 else if (position.cur_ == finish_.cur_) {
952 this->reallocate_map(n, false);
953 auto new_finish = finish_ + n;
954 _MSTL uninitialized_fill_n(finish_, n, x);
955 finish_ = new_finish;
956 }
957 else
958 return this->insert_n_aux(position, n, x);
959 }
960
961 iterator erase(iterator position) noexcept {
962 iterator next = _MSTL next(position);
963 const size_type dest_before = position - start_;
964 if (dest_before < size() / 2) {
965 _MSTL copy_backward(start_, position, next);
966 this->pop_front();
967 }
968 else {
969 _MSTL copy(next, finish_, position);
970 this->pop_back();
971 }
972 return start_ + dest_before;
973 }
974
975 iterator erase(iterator first, iterator last) noexcept {
976 if (first == start_ && last == finish_) {
977 this->clear();
978 return finish_;
979 }
980
981 const size_type len = last - first;
982 const size_type dist_before = first - start_;
983 if (dist_before < (size() - len) / 2) {
984 _MSTL copy_backward(start_, first, last);
985 iterator new_start = start_ + len;
986 _MSTL destroy(start_.cur_, new_start.cur_);
987 start_ = new_start;
988 }
989 else {
990 _MSTL copy(last, finish_, first);
991 iterator new_finish = finish_ - len;
992 _MSTL destroy(new_finish.cur_, finish_.cur_);
993 finish_ = new_finish;
994 }
995 return start_ + dist_before;
996 }
997
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_);
1002 *cur = nullptr;
1003 }
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_);
1007 *cur = nullptr;
1008 }
1009 }
1010
1011 void clear() noexcept {
1012 for (map_pointer cur = start_.node_ + 1; cur < finish_.node_; ++cur) {
1013 _MSTL destroy(*cur, *cur + buffer_size_);
1014 }
1015
1016 if (start_.node_ == finish_.node_)
1017 _MSTL destroy(start_.cur_, finish_.cur_);
1018 else {
1019 _MSTL destroy(start_.cur_, start_.last_);
1020 _MSTL destroy(finish_.first_, finish_.cur_);
1021 }
1022
1023 shrink_to_fit();
1024 finish_ = start_;
1025 }
1026
1027 MSTL_NODISCARD const_reference at(size_type position) const {
1028 return const_iterator(start_)[position];
1029 }
1030 MSTL_NODISCARD reference at(const size_type position) {
1031 return const_cast<reference>(static_cast<const deque*>(this)->at(position));
1032 }
1033 MSTL_NODISCARD const_reference operator [](const size_type position) const {
1034 return this->at(position);
1035 }
1036 MSTL_NODISCARD reference operator [](const size_type position) {
1037 return this->at(position);
1038 }
1039
1040 void swap(deque& x) noexcept {
1041 if (_MSTL addressof(x) == this) return;
1042 _MSTL swap(start_, x.start_);
1043 _MSTL swap(finish_, x.finish_);
1044 _MSTL swap(map_pair_, x.map_pair_);
1045 _MSTL swap(map_size_pair_, x.map_size_pair_);
1046 }
1047
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());
1051 }
1052 MSTL_NODISCARD bool operator <(const deque& rhs) const
1053 noexcept(noexcept(_MSTL lexicographical_compare(this->cbegin(), this->cend(), rhs.cbegin(), rhs.cend()))) {
1054 return _MSTL lexicographical_compare(this->cbegin(), this->cend(), rhs.cbegin(), rhs.cend());
1055 }
1056};
1057#if MSTL_SUPPORT_DEDUCTION_GUIDES__
1058template <typename Iterator, typename Alloc>
1059deque(Iterator, Iterator, Alloc = Alloc()) -> deque<iter_value_t<Iterator>, Alloc>;
1060#endif
1061
1063#endif // MSTL_CORE_CONTAINER_DEQUE_HPP__
MSTL比较算法
MSTL压缩对实现
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
#define MSTL_BUILD_TYPE_ALIAS(TYPE)
快速构建标准类型别名
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集合器接口
MSTL标准分配器
集合器接口模板
MSTL_NODISCARD constexpr decltype(auto) size() const noexcept(noexcept(derived().size()))
获取集合大小
MSTL_NODISCARD constexpr bool empty() const noexcept(noexcept(derived().empty()))
检查集合是否为空
MSTL未初始化内存操作