1#ifndef MSTL_CORE_CONTAINER_VECTOR_HPP__
2#define MSTL_CORE_CONTAINER_VECTOR_HPP__
10template <
bool IsConst,
typename Vector>
11struct vector_iterator {
13 using iterator = vector_iterator<false, Vector>;
14 using const_iterator = vector_iterator<true, Vector>;
17 using iterator_category = contiguous_iterator_tag;
18 using value_type =
typename Vector::value_type;
21 using difference_type =
typename Vector::difference_type;
22 using size_type =
typename Vector::size_type;
25 pointer ptr_ =
nullptr;
26 const Vector* vec_ =
nullptr;
28 template <
bool,
typename>
friend struct vector_iterator;
29 template <
typename,
typename>
friend class vector;
32 MSTL_CONSTEXPR20 vector_iterator() =
default;
33 MSTL_CONSTEXPR20 vector_iterator(pointer ptr,
const Vector* vec) : ptr_(ptr), vec_(vec) {}
35 MSTL_CONSTEXPR20 vector_iterator(
const iterator& x) noexcept
36 : ptr_(
const_cast<pointer
>(x.ptr_)), vec_(x.vec_) {}
38 MSTL_CONSTEXPR20 vector_iterator& operator =(
const iterator& rhs)
noexcept {
40 ptr_ =
const_cast<pointer
>(rhs.ptr_);
45 MSTL_CONSTEXPR20 vector_iterator(iterator&& x) noexcept
46 : ptr_(
const_cast<pointer
>(x.ptr_)), vec_(x.vec_) {
51 MSTL_CONSTEXPR20 vector_iterator& operator =(iterator&& rhs)
noexcept {
53 ptr_ =
const_cast<pointer
>(rhs.ptr_);
60 MSTL_CONSTEXPR20 vector_iterator(
const const_iterator& x) noexcept
61 : ptr_(
const_cast<pointer
>(x.ptr_)), vec_(x.vec_) {}
63 MSTL_CONSTEXPR20 vector_iterator& operator =(
const const_iterator& rhs)
noexcept {
65 ptr_ =
const_cast<pointer
>(rhs.ptr_);
70 MSTL_CONSTEXPR20 vector_iterator(const_iterator&& x) noexcept
71 : ptr_(
const_cast<pointer
>(x.ptr_)), vec_(x.vec_) {
76 MSTL_CONSTEXPR20 vector_iterator& operator =(const_iterator&& rhs)
noexcept {
78 ptr_ =
const_cast<pointer
>(rhs.ptr_);
85 MSTL_CONSTEXPR20 ~vector_iterator() noexcept = default;
87 MSTL_NODISCARD MSTL_CONSTEXPR20 reference operator *() const noexcept {
88 MSTL_DEBUG_VERIFY(ptr_ && vec_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(vector_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
89 MSTL_DEBUG_VERIFY(vec_->start_ <= ptr_ && ptr_ <= vec_->finish_, __MSTL_DEBUG_MESG_OUT_OF_RANGE(vector_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
93 MSTL_NODISCARD MSTL_CONSTEXPR20 pointer operator ->() const noexcept {
97 MSTL_CONSTEXPR20 vector_iterator& operator ++() noexcept {
98 MSTL_DEBUG_VERIFY(ptr_ && vec_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(vector_iterator, __MSTL_DEBUG_TAG_INCREMENT));
99 MSTL_DEBUG_VERIFY(ptr_ < vec_->finish_, __MSTL_DEBUG_MESG_OUT_OF_RANGE(vector_iterator, __MSTL_DEBUG_TAG_INCREMENT));
104 MSTL_CONSTEXPR20 vector_iterator operator ++(
int)
noexcept {
105 vector_iterator temp = *
this;
110 MSTL_CONSTEXPR20 vector_iterator& operator --() noexcept {
111 MSTL_DEBUG_VERIFY(ptr_ && vec_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(vector_iterator, __MSTL_DEBUG_TAG_DECREMENT));
112 MSTL_DEBUG_VERIFY(vec_->start_ < ptr_, __MSTL_DEBUG_MESG_OUT_OF_RANGE(vector_iterator, __MSTL_DEBUG_TAG_DECREMENT));
117 MSTL_CONSTEXPR20 vector_iterator operator --(
int)
noexcept {
118 vector_iterator temp = *
this;
123 MSTL_CONSTEXPR20 vector_iterator& operator +=(difference_type n)
noexcept {
125 MSTL_DEBUG_VERIFY((ptr_ && vec_) || n == 0, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(vector_iterator, __MSTL_DEBUG_TAG_DECREMENT));
126 MSTL_DEBUG_VERIFY(n >= vec_->start_ - ptr_, __MSTL_DEBUG_MESG_OUT_OF_RANGE(vector_iterator, __MSTL_DEBUG_TAG_DECREMENT));
129 MSTL_DEBUG_VERIFY((ptr_ && vec_) || n == 0, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(vector_iterator, __MSTL_DEBUG_TAG_INCREMENT));
130 MSTL_DEBUG_VERIFY(n <= vec_->finish_ - ptr_, __MSTL_DEBUG_MESG_OUT_OF_RANGE(vector_iterator, __MSTL_DEBUG_TAG_INCREMENT));
136 MSTL_NODISCARD MSTL_CONSTEXPR20 vector_iterator operator +(difference_type n)
const noexcept {
142 MSTL_NODISCARD
friend MSTL_CONSTEXPR20 vector_iterator operator +(difference_type n,
const vector_iterator& it) {
146 MSTL_CONSTEXPR20 vector_iterator& operator -=(difference_type n)
noexcept {
151 MSTL_NODISCARD MSTL_CONSTEXPR20 vector_iterator operator -(difference_type n)
const noexcept {
157 MSTL_NODISCARD MSTL_CONSTEXPR20 difference_type operator -(
const vector_iterator& x)
const noexcept {
158 MSTL_DEBUG_VERIFY(vec_ == x.vec_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(vector_iterator));
159 return static_cast<difference_type
>(ptr_ - x.ptr_);
162 MSTL_NODISCARD MSTL_CONSTEXPR20 reference operator [](difference_type n)
noexcept {
166 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator ==(
const vector_iterator& x)
const noexcept {
167 MSTL_DEBUG_VERIFY(vec_ == x.vec_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(vector_iterator));
168 return ptr_ == x.ptr_;
170 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator !=(
const vector_iterator& x)
const noexcept {
171 return !(*
this == x);
173 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator <(
const vector_iterator& x)
const noexcept {
174 MSTL_DEBUG_VERIFY(vec_ == x.vec_, __MSTL_DEBUG_MESG_CONTAINER_INCOMPATIBLE(vector_iterator));
175 return ptr_ < x.ptr_;
177 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator >(
const vector_iterator& x)
const noexcept {
180 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator <=(
const vector_iterator& x)
const noexcept {
183 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator >=(
const vector_iterator& x)
const noexcept {
187 MSTL_NODISCARD
constexpr pointer base() const noexcept {
192template <
typename T,
typename Alloc = allocator<T>>
193class vector :
public icollector<vector<T, Alloc>> {
194#ifdef MSTL_STANDARD_20__
195 static_assert(is_allocator_v<Alloc>,
"Alloc type is not a standard allocator type.");
197 static_assert(is_same_v<T, typename Alloc::value_type>,
"allocator type mismatch.");
198 static_assert(is_object_v<T>,
"vector only contains object types.");
202 using iterator = vector_iterator<false, vector<T, Alloc>>;
203 using const_iterator = vector_iterator<true, vector<T, Alloc>>;
204 using reverse_iterator =
_MSTL reverse_iterator<iterator>;
205 using const_reverse_iterator =
_MSTL reverse_iterator<const_iterator>;
206 using allocator_type = Alloc;
209 pointer start_ =
nullptr;
210 pointer finish_ =
nullptr;
211 compressed_pair<allocator_type, pointer> pair_{ default_construct_tag{},
nullptr };
213 template <
bool,
typename>
friend struct vector_iterator;
216 MSTL_CONSTEXPR20
void fill_initialize(size_type n,
const T& x) {
217 start_ = pair_.get_base().allocate(n);
219 finish_ = start_ + n;
220 pair_.value = finish_;
223 template <
typename Iterator>
224 MSTL_CONSTEXPR20 pointer allocate_and_copy(size_type n, Iterator first, Iterator last) {
225 pointer result = pair_.get_base().allocate(n);
226 pointer finish = result;
231 pair_.get_base().deallocate(result, n);
237 template <
typename Iterator>
238 MSTL_CONSTEXPR20 pointer allocate_and_move(size_type n, Iterator first, Iterator last) {
239 pointer result = pair_.get_base().allocate(n);
240 pointer finish = result;
245 pair_.get_base().deallocate(result, n);
253 MSTL_CONSTEXPR20
void range_initialize(Iterator first, Iterator last) {
254 for (; first != last; ++first)
255 this->push_back(*first);
258 template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
259 MSTL_CONSTEXPR20
void range_initialize(Iterator first, Iterator last) {
261 start_ = this->allocate_and_copy(n, first, last);
262 finish_ = start_ + n;
263 pair_.value = finish_;
266 MSTL_CONSTEXPR20
void deallocate() {
267 if (start_) pair_.get_base().deallocate(start_, pair_.value - start_);
270 template <
typename Iterator>
271 MSTL_CONSTEXPR20
void range_insert(iterator position, Iterator first, Iterator last) {
272 if (first == last)
return;
274 if (
static_cast<size_t>(pair_.value - finish_) >= n) {
275 const auto elems_after =
static_cast<size_t>(this->end() - position);
276 iterator old_finish = this->end();
277 if (elems_after > n) {
284 Iterator mid = first;
287 finish_ += (n - elems_after);
289 finish_ += elems_after;
294 const size_type old_size = this->
size();
295 const size_type len = old_size +
_MSTL max(old_size, n);
296 pointer new_start = pair_.get_base().allocate(len);
297 pointer new_finish = new_start;
304 finish_ = new_finish;
305 pair_.value = new_start + len;
309 template <
typename Iterator, enable_if_t<!is_ranges_fwd_iter_v<Iterator>,
int> = 0>
310 MSTL_CONSTEXPR20
void assign_aux(Iterator first, Iterator last) {
311 pointer cur = start_;
312 for (; first != last && cur != finish_; ++first, ++cur)
315 this->erase(cur, finish_);
317 this->insert(finish_, first, last);
320 template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
321 MSTL_CONSTEXPR20
void assign_aux(Iterator first, Iterator last) {
323 if (n > this->capacity()) {
325 this->range_insert(this->begin(), first, last);
327 else if (n >
size()) {
328 Iterator mid = first;
335 this->erase(this->begin() + n, this->end());
340 MSTL_CONSTEXPR20 vector() {
341 constexpr size_type init_cap = 1;
342 pointer result = pair_.get_base().allocate(init_cap);
343 finish_ = start_ = result;
344 pair_.value = finish_ + init_cap;
347 MSTL_CONSTEXPR20
explicit vector(
const size_type n) {
348 start_ = pair_.get_base().allocate(n);
351 for (size_type i = 0; i < n; ++i) {
357 pair_.get_base().deallocate(start_, n);
360 pair_.value = start_ + n;
362 MSTL_CONSTEXPR20
explicit vector(
const size_type n,
const T& value) {
363 this->fill_initialize(n, value);
365 MSTL_CONSTEXPR20
explicit vector(
const int16_t n,
const T& value) {
366 this->fill_initialize(n, value);
368 MSTL_CONSTEXPR20
explicit vector(
const int32_t n,
const T& value) {
369 this->fill_initialize(n, value);
371 MSTL_CONSTEXPR20
explicit vector(
const int64_t n,
const T& value) {
372 this->fill_initialize(n, value);
375 MSTL_CONSTEXPR20 vector(
const vector& x) {
376 start_ = this->allocate_and_copy(x.cend() - x.cbegin(), x.cbegin(), x.cend());
377 finish_ = start_ + (x.cend() - x.cbegin());
378 pair_.value = finish_;
380 MSTL_CONSTEXPR20 vector& operator =(
const vector& x) {
383 this->insert(this->end(), x.cbegin(), x.cend());
387 MSTL_CONSTEXPR20 vector(vector&& x)
noexcept {
390 MSTL_CONSTEXPR20 vector& operator =(vector&& x)
noexcept {
397 template <
typename Iterator>
398 MSTL_CONSTEXPR20 vector(Iterator first, Iterator last) {
399 MSTL_DEBUG_VERIFY(first <= last,
"vector iterator-constructor out of ranges.");
400 this->range_initialize(first, last);
403 MSTL_CONSTEXPR20 vector(std::initializer_list<T> x)
404 : vector(x.begin(), x.end()) {}
406 MSTL_CONSTEXPR20 vector& operator =(std::initializer_list<T> x) {
407 if (x.size() > this->capacity()) {
408 pointer new_ = this->allocate_and_move(x.end() - x.begin(), x.begin(), x.end());
412 finish_ = start_ + x.size();
413 pair_.value = start_ + x.size();
415 else if (
size() >= x.size()) {
416 iterator i =
_MSTL copy(x.begin(), x.end(), this->begin());
420 _MSTL copy(x.begin(), x.begin() + this->size(), start_);
423 finish_ = start_ + x.size();
427 MSTL_CONSTEXPR20 ~vector() {
432 MSTL_NODISCARD MSTL_CONSTEXPR20 iterator begin() noexcept {
return iterator(start_,
this); }
433 MSTL_NODISCARD MSTL_CONSTEXPR20 iterator end() noexcept {
return iterator(finish_,
this); }
434 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator begin() const noexcept {
return this->cbegin(); }
435 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator end() const noexcept {
return this->cend(); }
436 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator cbegin() const noexcept {
return const_iterator(start_,
this); }
437 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator cend() const noexcept {
return const_iterator(finish_,
this); }
438 MSTL_NODISCARD MSTL_CONSTEXPR20 reverse_iterator rbegin() noexcept {
return reverse_iterator(this->end()); }
439 MSTL_NODISCARD MSTL_CONSTEXPR20 reverse_iterator rend() noexcept {
return reverse_iterator(this->begin()); }
440 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator rbegin() const noexcept {
return this->crbegin(); }
441 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator rend() const noexcept {
return this->crend(); }
442 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(this->cend()); }
443 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(this->cbegin()); }
445 MSTL_NODISCARD MSTL_CONSTEXPR20 size_type
size() const noexcept {
446 return static_cast<size_type
>(finish_ - start_);
448 MSTL_NODISCARD
static constexpr size_type max_size() noexcept {
449 return static_cast<size_type
>(-1) /
sizeof(T);
451 MSTL_NODISCARD MSTL_CONSTEXPR20 size_type capacity() const noexcept {
452 return static_cast<size_type
>(pair_.value - start_);
454 MSTL_NODISCARD MSTL_CONSTEXPR20
bool empty() const noexcept {
455 return start_ == finish_;
458 MSTL_NODISCARD MSTL_CONSTEXPR20 pointer data() noexcept {
459 MSTL_DEBUG_VERIFY(!
empty(),
"data called on empty vector");
462 MSTL_NODISCARD MSTL_CONSTEXPR20 const_pointer data() const noexcept {
463 MSTL_DEBUG_VERIFY(!
empty(),
"data called on empty vector");
467 MSTL_NODISCARD MSTL_CONSTEXPR20 allocator_type get_allocator() const noexcept {
return allocator_type(); }
469 MSTL_NODISCARD MSTL_CONSTEXPR20 reference front() noexcept {
470 MSTL_DEBUG_VERIFY(!
empty(),
"front called on empty vector");
473 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reference front() const noexcept {
474 MSTL_DEBUG_VERIFY(!
empty(),
"front called on empty vector");
477 MSTL_NODISCARD MSTL_CONSTEXPR20 reference back() noexcept {
478 MSTL_DEBUG_VERIFY(!
empty(),
"back called on empty vector");
479 return *(finish_ - 1);
481 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reference back() const noexcept {
482 MSTL_DEBUG_VERIFY(!
empty(),
"back called on empty vector");
483 return *(finish_ - 1);
486 MSTL_CONSTEXPR20
void reserve(
const size_type n) {
487 MSTL_DEBUG_VERIFY(n < max_size(),
"vector reserve out of allocate bounds.");
488 if (this->capacity() >= n)
return;
490 size_type new_capacity =
_MSTL max(this->capacity() * 2, n);
491 pointer new_start = pair_.get_base().allocate(new_capacity);
492 pointer new_finish = new_start;
498 pair_.get_base().deallocate(new_start, new_capacity);
505 finish_ = new_finish;
506 pair_.value = start_ + new_capacity;
509 MSTL_CONSTEXPR20
void resize(size_type new_size,
const T& x) {
510 if (new_size < this->
size()) {
511 this->erase(this->begin() + new_size, this->end());
513 this->insert(this->end(), new_size - this->
size(), x);
516 MSTL_CONSTEXPR20
void resize(
const size_type new_size) {
517 this->resize(new_size, T());
520 template <
typename... Args>
521 MSTL_CONSTEXPR20
void emplace(iterator position, Args&&... args) {
522 if (finish_ != pair_.value) {
529 const size_type old_size = this->
size();
530 const size_type len = old_size != 0 ? 2 * old_size : 1;
531 pointer new_start = pair_.get_base().allocate(len);
539 finish_ = new_finish;
540 pair_.value = new_start + len;
543 template <
typename... Args>
544 MSTL_CONSTEXPR20
void emplace_back(Args&&... args) {
545 if (finish_ != pair_.value) {
552 MSTL_CONSTEXPR20
void push_back(
const T& val) {
553 if (finish_ != pair_.value) {
557 else this->emplace(this->end(), val);
559 MSTL_CONSTEXPR20
void push_back(T&& val) {
563 MSTL_CONSTEXPR20
void pop_back() noexcept {
564 MSTL_DEBUG_VERIFY(!
empty(),
"pop called in an empty vector")
569 MSTL_CONSTEXPR20
void assign(size_type n, const value_type& value) {
570 if (n > this->capacity()) {
573 this->insert(this->begin(), n, value);
575 else if (n > this->
size()) {
576 _MSTL fill(this->begin(), this->end(), value);
581 this->erase(this->begin() + n, this->end());
585 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
586 MSTL_CONSTEXPR20
void assign(Iterator first, Iterator last) {
587 this->assign_aux(first, last);
590 MSTL_CONSTEXPR20
void assign(std::initializer_list<value_type> l) {
591 this->assign(l.begin(), l.end());
594 MSTL_CONSTEXPR20 iterator insert(iterator position,
const value_type& x) {
595 size_type n = position - this->begin();
596 this->emplace(position, x);
597 return this->begin() + n;
599 MSTL_CONSTEXPR20 iterator insert(iterator position, value_type&& x) {
600 size_type n = position - this->begin();
602 return this->begin() + n;
605 MSTL_CONSTEXPR20 iterator insert(iterator position) {
606 return this->insert(position, T());
609 template <
typename Iterator>
610 MSTL_CONSTEXPR20
void insert(iterator position, Iterator first, Iterator last) {
612 _MSTL distance(first, last) >= 0,
"vector insert resource iterator out of ranges."
614 this->range_insert(position, first, last);
617 MSTL_CONSTEXPR20
void insert(iterator position, std::initializer_list<value_type> l) {
618 this->range_insert(position, l.begin(), l.end());
620 MSTL_CONSTEXPR20
void insert(iterator position, size_type n,
const value_type& x) {
622 if (
static_cast<size_type
>(pair_.value - finish_) >= n) {
623 const size_type elems_after =
_MSTL distance(this->begin(), position);
624 iterator old_finish = this->end();
625 if (elems_after > n) {
633 finish_ += n - elems_after;
635 finish_ += elems_after;
641 const size_type old_size = this->
size();
642 const size_type len = old_size +
_MSTL max(old_size, n);
643 pointer new_start = pair_.get_base().allocate(len);
650 finish_ = new_finish;
651 pair_.value = new_start + len;
655 MSTL_CONSTEXPR20 iterator erase(iterator first, iterator last)
656 noexcept(is_nothrow_move_assignable_v<value_type>) {
657 MSTL_DEBUG_VERIFY(
_MSTL distance(first, last) >= 0,
"vector erase out of ranges.");
659 const auto elems_after = this->end() - last;
660 if (elems_after > 0) {
663 pointer new_finish = finish_ - (last - first);
665 finish_ = new_finish;
669 MSTL_CONSTEXPR20 iterator erase(iterator position)
670 noexcept(is_nothrow_move_assignable_v<value_type>) {
671 if (position + 1 != this->end()) {
672 _MSTL move(position + 1, this->end(), position);
679 MSTL_CONSTEXPR20
void shrink_to_fit() {
680 if (this->capacity() == this->
size())
return;
681 if (this->
size() == 0) {
683 start_ = finish_ = pair_.value =
nullptr;
686 pointer new_start = pair_.get_base().allocate(this->
size());
687 pointer new_finish = new_start;
692 pair_.get_base().deallocate(new_start, this->
size());
698 finish_ = new_finish;
699 pair_.value = new_start + this->
size();
702 MSTL_CONSTEXPR20
void clear() noexcept {
703 if (this->
empty())
return;
708 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reference at(
const size_type position)
const noexcept {
709 MSTL_DEBUG_VERIFY(position < this->
size(),
"vector access out of range");
710 return *(start_ + position);
712 MSTL_NODISCARD MSTL_CONSTEXPR20 reference at(
const size_type position)
noexcept {
713 return const_cast<reference
>(
static_cast<const vector*
>(
this)->at(position));
715 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reference operator [](
const size_type position)
const noexcept {
716 return this->at(position);
718 MSTL_NODISCARD MSTL_CONSTEXPR20 reference operator [](
const size_type position)
noexcept {
719 return this->at(position);
722 MSTL_CONSTEXPR20
void swap(vector& x)
noexcept {
729 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator ==(
const vector& rhs)
const
730 noexcept(
noexcept(this->
size() == rhs.size() &&
_MSTL equal(this->cbegin(), this->cend(), rhs.cbegin()))) {
731 return this->
size() == rhs.size() &&
_MSTL equal(this->cbegin(), this->cend(), rhs.cbegin());
733 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator <(
const vector& rhs)
const
738#if MSTL_SUPPORT_DEDUCTION_GUIDES__
739template <
typename T,
typename Alloc>
740vector(T, Alloc = Alloc()) -> vector<T, Alloc>;
742template <
typename Iterator,
typename Alloc>
743vector(Iterator, Iterator, Alloc = Alloc()) -> vector<iter_value_t<Iterator>, Alloc>;
746using bvector = vector<byte_t>;
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))
字典序比较两个范围
long long int64_t
64位有符号整数类型
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 >)
销毁单个对象
MSTL_INLINE17 constexpr bool is_iter_v
检查类型是否为迭代器
MSTL_INLINE17 constexpr bool is_ranges_fwd_iter_v
检查是否为范围前向迭代器
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=-1)
获取迭代器的前一个位置
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
constexpr void advance(Iterator &i, Distance n)
将迭代器前进指定距离
#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_backward(Iterator1 first, Iterator1 last, Iterator2 result)
反向移动范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result)
复制范围元素
constexpr Iterator fill_n(Iterator first, size_t n, const T &value)
填充指定数量的元素
void swap()=delete
删除无参数的swap重载
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL_CONSTEXPR20 Iterator2 uninitialized_move(Iterator1 first, Iterator1 last, Iterator2 result)
在未初始化内存中移动元素
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()))
检查集合是否为空