1#ifndef MSTL_CORE_CONTAINER_BITMAP_HPP__
2#define MSTL_CORE_CONTAINER_BITMAP_HPP__
3#include "../utility/packages.hpp"
9struct MSTL_API bit_reference :
icommon<bit_reference>, istringify<bit_reference> {
11 using super = iobject<bit_reference>;
17 MSTL_CONSTEXPR20 bit_reference() =
default;
18 MSTL_CONSTEXPR20 bit_reference(
uint32_t* x,
const uint32_t y) noexcept : ptr_(x), mask_(y) {}
20 MSTL_CONSTEXPR20 bit_reference(
const bit_reference& x) noexcept : ptr_(x.ptr_), mask_(x.mask_) {}
21 MSTL_CONSTEXPR20 bit_reference(bit_reference&& x) noexcept : ptr_(x.ptr_), mask_(x.mask_) {
26 MSTL_CONSTEXPR20
operator bool() const noexcept {
27 MSTL_DEBUG_VERIFY(ptr_, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(bit_reference, __MSTL_DEBUG_TAG_DEREFERENCE));
31 MSTL_CONSTEXPR20 bit_reference& operator =(
const bool x)
noexcept {
40 MSTL_CONSTEXPR20 bit_reference& operator =(
const bit_reference& x)
noexcept {
41 return *
this =
static_cast<bool>(x);
43 MSTL_CONSTEXPR20 bit_reference& operator =(bit_reference&& x)
noexcept {
44 *
this =
static_cast<bool>(x);
50 MSTL_CONSTEXPR20
void flip() const noexcept { *ptr_ ^= mask_; }
52 MSTL_CONSTEXPR20
void swap(bit_reference& x)
noexcept {
59 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator ==(
const bit_reference& x)
const noexcept {
60 return static_cast<bool>(*this) ==
static_cast<bool>(x);
62 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator <(
const bit_reference& x)
const noexcept {
63 return static_cast<bool>(*this) <
static_cast<bool>(x);
66 MSTL_NODISCARD MSTL_CONSTEXPR20
size_t to_hash() const noexcept {
67 return hash<bool>()(
static_cast<bool>(*this));
70 MSTL_NODISCARD MSTL_CONSTEXPR20
string to_string()
const {
71 return _MSTL to_string(
static_cast<bool>(*
this));
76template <
bool IsConst,
typename BitMap>
77struct bitmap_iterator {
79 using container_type = BitMap;
80 using iterator = bitmap_iterator<false, container_type>;
81 using const_iterator = bitmap_iterator<true, container_type>;
84 using iterator_category = random_access_iterator_tag;
85 using value_type =
typename container_type::value_type;
88 using difference_type =
typename container_type::difference_type;
89 using size_type =
typename container_type::size_type;
96 template <
bool,
typename>
friend struct bitmap_iterator;
99 MSTL_CONSTEXPR20
void bump_up() noexcept {
100 if (off_++ == WORD_BIT_SIZE - 1) {
105 MSTL_CONSTEXPR20
void bump_down() noexcept {
107 off_ = WORD_BIT_SIZE - 1;
112 template <
typename Ref1, enable_if_t<is_
boolean_v<Ref1>,
int> = 0>
113 MSTL_NODISCARD MSTL_CONSTEXPR20 Ref1 reference_dispatch() const noexcept {
114 return (*ptr_ & (1U << off_)) != 0;
116 template <
typename Ref1, enable_if_t<!is_
boolean_v<Ref1>,
int> = 0>
117 MSTL_NODISCARD MSTL_CONSTEXPR20 Ref1 reference_dispatch() const noexcept {
118 return Ref1(ptr_, 1U << off_);
122 MSTL_CONSTEXPR20 bitmap_iterator() =
default;
123 MSTL_CONSTEXPR20 bitmap_iterator(
uint32_t* ptr,
const uint32_t offset) noexcept : ptr_(ptr), off_(offset) {}
125 MSTL_CONSTEXPR20 bitmap_iterator(
const iterator& other) noexcept
126 : ptr_(other.ptr_), off_(other.off_) {}
128 MSTL_NODISCARD MSTL_CONSTEXPR20 reference
operator *() const noexcept {
129 MSTL_DEBUG_VERIFY(ptr_ !=
nullptr, __MSTL_DEBUG_MESG_OPERATE_NULLPTR(bitmap_iterator, __MSTL_DEBUG_TAG_DEREFERENCE));
130 return reference_dispatch<reference>();
133 MSTL_CONSTEXPR20 bitmap_iterator& operator ++() noexcept {
137 MSTL_CONSTEXPR20 bitmap_iterator operator ++(
int)
noexcept {
138 const auto tmp = *
this;
142 MSTL_CONSTEXPR20 bitmap_iterator& operator --() noexcept {
146 MSTL_CONSTEXPR20 bitmap_iterator operator --(
int)
noexcept {
147 const auto tmp = *
this;
152 MSTL_CONSTEXPR20 bitmap_iterator& operator +=(difference_type i)
noexcept {
153 difference_type n = i + off_;
154 ptr_ += n / WORD_BIT_SIZE;
155 n = n % WORD_BIT_SIZE;
157 off_ =
static_cast<uint32_t>(n) + WORD_BIT_SIZE;
163 MSTL_CONSTEXPR20 bitmap_iterator& operator -=(
const difference_type i)
noexcept {
167 MSTL_CONSTEXPR20 bitmap_iterator
operator +(
const difference_type i)
const noexcept {
171 MSTL_CONSTEXPR20
friend bitmap_iterator
operator +(
const difference_type i,
const bitmap_iterator& x)
noexcept {
174 MSTL_CONSTEXPR20 bitmap_iterator
operator -(
const difference_type i)
const noexcept {
178 MSTL_CONSTEXPR20 difference_type
operator -(
const bitmap_iterator x)
const noexcept {
179 return WORD_BIT_SIZE * (ptr_ - x.ptr_) + off_ - x.off_;
182 MSTL_CONSTEXPR20 reference operator [](
const difference_type i)
const noexcept {
186 MSTL_CONSTEXPR20
bool operator ==(
const bitmap_iterator& x)
const noexcept {
187 return ptr_ == x.ptr_ && off_ == x.off_;
189 MSTL_CONSTEXPR20
bool operator !=(
const bitmap_iterator& x)
const noexcept {
190 return !(*
this == x);
192 MSTL_CONSTEXPR20
bool operator <(
const bitmap_iterator& x)
const noexcept {
193 return ptr_ < x.ptr_ || (ptr_ == x.ptr_ && off_ < x.off_);
195 MSTL_CONSTEXPR20
bool operator >(
const bitmap_iterator& x)
const noexcept {
198 MSTL_CONSTEXPR20
bool operator <=(
const bitmap_iterator& x)
const noexcept {
201 MSTL_CONSTEXPR20
bool operator >=(
const bitmap_iterator& x)
const noexcept {
205 MSTL_NODISCARD MSTL_CONSTEXPR20 pointer base() const noexcept {
211class MSTL_API bitmap :
public icollector<bitmap> {
212 using super = icollector<bitmap>;
215 using value_type = bool;
216 using pointer = bit_reference*;
217 using reference = bit_reference;
218 using const_pointer =
const bool*;
219 using const_reference =
const bool;
223 using iterator = bitmap_iterator<false, bitmap>;
224 using const_iterator = bitmap_iterator<true, bitmap>;
225 using reverse_iterator =
_MSTL reverse_iterator<iterator>;
226 using const_reverse_iterator =
_MSTL reverse_iterator<const_iterator>;
233 compressed_pair<allocator_type, uint32_t*> capacity_pair_{default_construct_tag{},
nullptr};
236 MSTL_CONSTEXPR20
uint32_t* bit_alloc(
const size_type n) {
237 return capacity_pair_.
get_base().allocate((n + WORD_BIT_SIZE - 1) / WORD_BIT_SIZE);
242 capacity_pair_.
get_base().deallocate(start_.ptr_,
static_cast<size_type
>(capacity_pair_.
value - start_.ptr_));
246 template <
typename Iterator1,
typename Iterator2>
247 MSTL_CONSTEXPR20 Iterator2 bit_copy(Iterator1 first, Iterator1 last, Iterator2 result) {
249 for (; n > 0; --n, ++first, ++result)
253 template <
typename Iterator1,
typename Iterator2>
254 MSTL_CONSTEXPR20 Iterator2 bit_copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) {
261 MSTL_CONSTEXPR20
void initialize(
const size_type n) {
263 capacity_pair_.
value = q + (n + WORD_BIT_SIZE - 1) / WORD_BIT_SIZE;
264 start_ = iterator(q, 0);
265 finish_ = start_ +
static_cast<difference_type
>(n);
267 MSTL_CONSTEXPR20
void insert_aux(
const iterator& position,
const bool x) {
268 if (finish_.ptr_ != capacity_pair_.
value) {
269 bit_copy_backward(position, finish_, finish_ + 1);
274 const size_type len =
size() ? 2 *
size() : WORD_BIT_SIZE;
276 auto i = bit_copy(
begin(), position, iterator(q, 0));
278 finish_ = bit_copy(position,
end(), i);
280 capacity_pair_.
value = q + (len + WORD_BIT_SIZE - 1)/WORD_BIT_SIZE;
281 start_ = iterator(q, 0);
285 template <
typename Iterator, enable_if_t<!is_ranges_fwd_iter_v<Iterator>,
int> = 0>
286 MSTL_CONSTEXPR20
void initialize_range(Iterator first, Iterator last) {
288 finish_ = iterator();
289 capacity_pair_.
value =
nullptr;
290 for ( ; first != last; ++first)
293 template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
294 MSTL_CONSTEXPR20
void initialize_range(Iterator first, Iterator last) {
297 bit_copy(first, last, start_);
300 template <
typename Iterator, enable_if_t<!is_ranges_fwd_iter_v<Iterator>,
int> = 0>
301 MSTL_CONSTEXPR20
void insert_range(iterator pos, Iterator first, Iterator last) {
302 for ( ; first != last; ++first) {
303 pos = insert(pos, *first);
307 template <
typename Iterator, enable_if_t<is_ranges_fwd_iter_v<Iterator>,
int> = 0>
308 MSTL_CONSTEXPR20
void insert_range(iterator position, Iterator first, Iterator last) {
312 if (capacity() -
size() >= n) {
313 bit_copy_backward(position,
end(), finish_ +
static_cast<difference_type
>(n));
314 bit_copy(first, last, position);
315 finish_ +=
static_cast<difference_type
>(n);
320 auto i = bit_copy(
begin(), position, iterator(q, 0));
321 i = bit_copy(first, last, i);
322 finish_ = bit_copy(position,
end(), i);
324 capacity_pair_.
value = q + (len + WORD_BIT_SIZE - 1) / WORD_BIT_SIZE;
325 start_ = iterator(q, 0);
331 MSTL_CONSTEXPR20 bitmap() noexcept = default;
333 MSTL_CONSTEXPR20 explicit bitmap(const size_type n) {
335 fill(start_.ptr_, capacity_pair_.
value, 0);
337 MSTL_CONSTEXPR20
explicit bitmap(
const size_type n,
const bool value) {
342 MSTL_CONSTEXPR20
explicit bitmap(
const int n,
const bool value) {
344 fill(start_.ptr_, capacity_pair_.
value, value ? ~0 : 0);
346 MSTL_CONSTEXPR20
explicit bitmap(
const long n,
const bool value) {
348 fill(start_.ptr_, capacity_pair_.
value, value ? ~0 : 0);
351 MSTL_CONSTEXPR20 bitmap(
const bitmap& x) {
353 bit_copy(x.cbegin(), x.cend(), start_);
356 MSTL_CONSTEXPR20 bitmap& operator =(
const bitmap& x) {
358 if (x.size() > capacity()) {
362 bit_copy(x.cbegin(), x.cend(),
begin());
363 finish_ =
begin() +
static_cast<difference_type
>(x.size());
367 MSTL_CONSTEXPR20 bitmap(bitmap&& x)
noexcept {
371 MSTL_CONSTEXPR20 bitmap& operator =(bitmap&& x)
noexcept {
377 template <
typename InputIterator>
378 MSTL_CONSTEXPR20 bitmap(InputIterator first, InputIterator last) {
379 this->initialize_range(first, last);
382 MSTL_CONSTEXPR20 bitmap(
const const_iterator &first,
const const_iterator &last) {
385 bit_copy(first, last, start_);
388 MSTL_CONSTEXPR20 bitmap(
const bool* first,
const bool* last) {
391 bit_copy(first, last, start_);
397 MSTL_NODISCARD MSTL_CONSTEXPR20 iterator
begin() noexcept {
return start_; }
398 MSTL_NODISCARD MSTL_CONSTEXPR20 iterator
end() noexcept {
return finish_; }
399 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator
begin() const noexcept {
return cbegin(); }
400 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator
end() const noexcept {
return cend(); }
401 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator
cbegin() const noexcept {
return {start_}; }
402 MSTL_NODISCARD MSTL_CONSTEXPR20 const_iterator
cend() const noexcept {
return finish_; }
403 MSTL_NODISCARD MSTL_CONSTEXPR20 reverse_iterator
rbegin() noexcept {
return reverse_iterator(
end()); }
404 MSTL_NODISCARD MSTL_CONSTEXPR20 reverse_iterator
rend() noexcept {
return reverse_iterator(
begin()); }
405 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator
rbegin() const noexcept {
return crbegin(); }
406 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator
rend() const noexcept {
return crend(); }
407 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator
crbegin() const noexcept {
return const_reverse_iterator(
cend()); }
408 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reverse_iterator
crend() const noexcept {
return const_reverse_iterator(
cbegin()); }
410 MSTL_NODISCARD MSTL_CONSTEXPR20 size_type
size() const noexcept {
return cend() -
cbegin(); }
411 MSTL_NODISCARD MSTL_CONSTEXPR20 size_type max_size() const noexcept {
return static_cast<size_type
>(-1); }
412 MSTL_NODISCARD MSTL_CONSTEXPR20 size_type capacity() const noexcept {
413 return const_iterator(capacity_pair_.
value, 0) -
cbegin();
415 MSTL_NODISCARD MSTL_CONSTEXPR20
bool empty() const noexcept {
return start_ == finish_; }
417 MSTL_NODISCARD MSTL_CONSTEXPR20 reference operator [](
const size_type n) {
418 return *(
begin() +
static_cast<difference_type
>(n));
420 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reference operator [](
const size_type n)
const {
421 return *(
cbegin() +
static_cast<difference_type
>(n));
424 MSTL_NODISCARD MSTL_CONSTEXPR20 reference front() {
return *
begin(); }
425 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reference front()
const {
return *
cbegin(); }
426 MSTL_NODISCARD MSTL_CONSTEXPR20 reference back() {
return *(
end() - 1); }
427 MSTL_NODISCARD MSTL_CONSTEXPR20 const_reference back()
const {
return *(
cend() - 1); }
430 MSTL_CONSTEXPR20
void reserve(
const size_type n) {
431 if (capacity() < n) {
433 finish_ = bit_copy(
begin(),
end(), iterator(q, 0));
435 start_ = iterator(q, 0);
436 capacity_pair_.
value = q + (n + WORD_BIT_SIZE - 1)/WORD_BIT_SIZE;
440 MSTL_CONSTEXPR20
void push_back(
const bool x) {
441 if (finish_.ptr_ != capacity_pair_.
value)
444 insert_aux(
end(), x);
447 MSTL_CONSTEXPR20 iterator insert(
const iterator& position,
const bool x =
bool()) {
448 const difference_type n = position -
begin();
449 if (finish_.ptr_ != capacity_pair_.
value && position ==
end())
452 insert_aux(position, x);
456 template <
typename Iterator>
457 MSTL_CONSTEXPR20
void insert(iterator position, Iterator first, Iterator last) {
458 this->insert_range(position, first, last);
461 MSTL_CONSTEXPR20
void insert(
const iterator& position,
const bool* first,
const bool* last) {
462 if (first == last)
return;
463 const size_type n =
distance(first, last);
464 if (capacity() -
size() >= n) {
465 bit_copy_backward(position,
end(), finish_ +
static_cast<difference_type
>(n));
466 bit_copy(first, last, position);
467 finish_ +=
static_cast<difference_type
>(n);
472 auto i = bit_copy(
begin(), position, iterator(q, 0));
473 i = bit_copy(first, last, i);
474 finish_ = bit_copy(position,
end(), i);
476 capacity_pair_.
value = q + (len + WORD_BIT_SIZE - 1) / WORD_BIT_SIZE;
477 start_ = iterator(q, 0);
481 MSTL_CONSTEXPR20
void insert(
const iterator& position,
const size_type n,
const bool x) {
483 if (capacity() -
size() >= n) {
484 bit_copy_backward(position,
end(), finish_ +
static_cast<difference_type
>(n));
485 _MSTL fill(position, position +
static_cast<difference_type
>(n), x);
486 finish_ +=
static_cast<difference_type
>(n);
491 const auto i = bit_copy(
begin(), position, iterator(q, 0));
493 finish_ = bit_copy(position,
end(), i +
static_cast<difference_type
>(n));
495 capacity_pair_.
value = q + (len + WORD_BIT_SIZE - 1)/WORD_BIT_SIZE;
496 start_ = iterator(q, 0);
500 MSTL_CONSTEXPR20
void insert(
const iterator& pos,
const int n,
const bool x) { insert(pos,
static_cast<size_type
>(n), x); }
501 MSTL_CONSTEXPR20
void insert(
const iterator& pos,
const long n,
const bool x) { insert(pos,
static_cast<size_type
>(n), x); }
503 MSTL_CONSTEXPR20
void pop_back() { --finish_; }
505 MSTL_CONSTEXPR20 iterator
erase(
const iterator& position) {
506 if (position + 1 !=
end())
507 bit_copy(position + 1,
end(), position);
511 MSTL_CONSTEXPR20 iterator
erase(
const iterator& first,
const iterator& last) {
512 finish_ = bit_copy(last,
end(), first);
515 MSTL_CONSTEXPR20
void resize(
const size_type new_size,
const bool x =
bool()) {
516 if (new_size <
size())
517 erase(
begin() +
static_cast<difference_type
>(new_size),
end());
519 insert(
end(), new_size -
size(), x);
521 MSTL_CONSTEXPR20
void clear() {
525 MSTL_CONSTEXPR20
void swap(bitmap& x)
noexcept {
529 _MSTL swap(capacity_pair_, x.capacity_pair_);
532 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator ==(
const bitmap& rhs)
const
536 MSTL_NODISCARD MSTL_CONSTEXPR20
bool operator <(
const bitmap& rhs)
const
MSTL_NODISCARD constexpr T * addressof(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))
字典序比较两个范围
unsigned int uint32_t
32位无符号整数类型
constexpr duration< _INNER __common_rep_t< Rep1, Rep2 >, Period > operator*(const duration< Rep1, Period > &value, const Rep2 &scalar)
乘法运算符(持续时间 * 标量)
bool operator!=(const function< Res(Args...)> &f, nullptr_t null) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
standard_allocator< T > allocator
标准分配器别名
MSTL_CONSTEXPR20 void deallocate(void *ptr, _INNER alloc_size_t bytes) noexcept
内存释放函数
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
MSTL_NODISCARD constexpr normal_iterator< Iterator > operator+(iter_difference_t< normal_iterator< Iterator > > n, const normal_iterator< Iterator > &iter) noexcept
加法运算符
MSTL_NODISCARD constexpr bool operator<=(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于等于比较运算符
MSTL_NODISCARD constexpr bool operator>=(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
大于等于比较运算符
MSTL_NODISCARD constexpr bool operator>(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
大于比较运算符
MSTL_NODISCARD constexpr auto operator-(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept -> decltype(lhs.base() - rhs.base())
减法运算符
MSTL_NODISCARD constexpr bool operator<(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于比较运算符
constexpr size_t erase(Container &cont, const U &value)
从容器中删除所有等于指定值的元素
constexpr void fill(Iterator first, Iterator last, const T &value)
填充范围元素
constexpr Iterator fill_n(Iterator first, size_t n, const T &value)
填充指定数量的元素
void swap()=delete
删除无参数的swap重载
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr bool empty(const Container &cont) noexcept(noexcept(cont.empty()))
检查容器是否为空
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) rend(Container &cont) noexcept(noexcept(cont.rend()))
获取const容器的反向起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) cend(const Container &cont) noexcept(noexcept(cont.cend()))
获取const容器的const结束迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) begin(Container &cont) noexcept(noexcept(cont.begin()))
获取容器的起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) crbegin(const Container &cont) noexcept(noexcept(cont.crbegin()))
获取const容器的const反向起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) cbegin(const Container &cont) noexcept(noexcept(cont.cbegin()))
获取const容器的const起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) rbegin(Container &cont) noexcept(noexcept(cont.rbegin()))
获取容器的反向起始迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) crend(const Container &cont) noexcept(noexcept(cont.crend()))
获取const容器的const反向结束迭代器
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr compressed_pair & get_base() noexcept
获取基类引用
MSTL_NODISCARD constexpr bool operator==(const T &rhs) const noexcept(noexcept(derived()==rhs))
相等比较运算符
MSTL_NODISCARD constexpr bool operator<(const T &rhs) const noexcept(noexcept(derived()< rhs))
小于比较运算符
MSTL_NODISCARD constexpr size_t to_hash() const noexcept(noexcept(derived().to_hash()))
获取对象的哈希值