1#ifndef NEFORCE_CORE_CONTAINER_BITMAP_HPP__
2#define NEFORCE_CORE_CONTAINER_BITMAP_HPP__
15NEFORCE_BEGIN_NAMESPACE__
39 NEFORCE_CONSTEXPR20 bit_reference() =
default;
40 NEFORCE_CONSTEXPR20 ~bit_reference() =
default;
55 NEFORCE_CONSTEXPR20
bit_reference(
const bit_reference& other) noexcept :
64 NEFORCE_CONSTEXPR20 bit_reference&
operator=(
const bit_reference& other)
noexcept {
68 return *
this =
static_cast<bool>(other);
87 NEFORCE_CONSTEXPR20 bit_reference&
operator=(bit_reference&& other)
noexcept {
91 *
this =
static_cast<bool>(other);
102 NEFORCE_CONSTEXPR20 bit_reference&
operator=(
const bool value)
noexcept {
103 if (ptr_ ==
nullptr) {
106 *ptr_ = (*ptr_ & ~mask_) | (value ? mask_ : 0);
114 NEFORCE_CONSTEXPR20
explicit operator bool() const noexcept {
115 if (ptr_ ==
nullptr) {
118 return (*ptr_ & mask_) != 0U;
124 NEFORCE_CONSTEXPR20
void flip() const noexcept {
125 if (ptr_ ==
nullptr) {
135 NEFORCE_CONSTEXPR20
void swap(bit_reference& other)
noexcept {
139 const bool tmp =
static_cast<bool>(other);
149 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool equal_to(
const bit_reference& rhs)
const noexcept {
150 return static_cast<bool>(*this) ==
static_cast<bool>(rhs);
158 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool less_than(
const bit_reference& rhs)
const noexcept {
159 return !
static_cast<bool>(*this) &&
static_cast<bool>(rhs);
166 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
size_t to_hash() const noexcept {
167 return hash<bool>()(
static_cast<bool>(*this));
174 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
string to_string()
const {
return static_cast<bool>(*this) ?
"1"_s :
"0"_s; }
186template <
bool IsConst,
typename BitMap>
187struct bitmap_iterator :
iiterator<bitmap_iterator<IsConst, BitMap>> {
195 typename container_type::reference>;
197 typename container_type::pointer>;
205 template <
bool,
typename>
206 friend struct bitmap_iterator;
209 template <
typename Ref>
211 return (*ptr_ & (1ULL << off_)) != 0;
214 template <
typename Ref>
216 return Ref(ptr_, 1ULL << off_);
220 NEFORCE_CONSTEXPR20 bitmap_iterator() noexcept = default;
221 NEFORCE_CONSTEXPR20 ~bitmap_iterator() = default;
223 NEFORCE_CONSTEXPR20 bitmap_iterator(const bitmap_iterator&) noexcept = default;
224 NEFORCE_CONSTEXPR20 bitmap_iterator& operator=(const bitmap_iterator&) noexcept = default;
225 NEFORCE_CONSTEXPR20 bitmap_iterator(bitmap_iterator&&) noexcept = default;
226 NEFORCE_CONSTEXPR20 bitmap_iterator& operator=(bitmap_iterator&&) noexcept = default;
232 explicit NEFORCE_CONSTEXPR20 bitmap_iterator(const
container_type* bm) noexcept :
251 template <
bool IsConst2>
252 NEFORCE_CONSTEXPR20
explicit bitmap_iterator(
const bitmap_iterator<IsConst2, BitMap>& other) noexcept :
255 container_(other.container_) {}
262 NEFORCE_DEBUG_VERIFY(ptr_ && container_,
"Attempting to dereference on a null pointer");
263 return reference_dispatch<reference>();
270 NEFORCE_DEBUG_VERIFY(ptr_ && container_,
"Attempting to increment a null pointer");
281 NEFORCE_DEBUG_VERIFY(ptr_ && container_,
"Attempting to increment a null pointer");
293 NEFORCE_DEBUG_VERIFY((off == 0 || (ptr_ !=
nullptr && container_ !=
nullptr)),
294 "Attempting to advance a null pointer");
312 NEFORCE_DEBUG_VERIFY(container_ == other.container_,
"Attempting to distance to a different container");
329 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool equal_to(
const bitmap_iterator& rhs)
const noexcept {
330 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_,
"Attempting to equal to a different container");
331 return ptr_ == rhs.ptr_ && off_ == rhs.off_;
339 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool less_than(
const bitmap_iterator& rhs)
const noexcept {
340 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_,
"Attempting to equal to a different container");
341 return ptr_ < rhs.ptr_ || (ptr_ == rhs.ptr_ && off_ < rhs.off_);
348 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
decltype(
auto)
base() const noexcept {
return ptr_; }
394 NEFORCE_CONSTEXPR20 bit_storage()
noexcept =
default;
400 explicit NEFORCE_CONSTEXPR20 bit_storage(
const size_t word) {
404 ptr = cpair.
get_base().allocate(word);
412 NEFORCE_CONSTEXPR20 ~bit_storage() {
413 if (ptr !=
nullptr) {
418 bit_storage(
const bit_storage&) =
delete;
419 bit_storage&
operator=(
const bit_storage&) =
delete;
425 NEFORCE_CONSTEXPR20 bit_storage(bit_storage&& other) noexcept :
427 cpair(_NEFORCE
move(other.cpair)) {
429 other.cpair.
value = 0;
437 NEFORCE_CONSTEXPR20 bit_storage&
operator=(bit_storage&& other)
noexcept {
444 cpair = _NEFORCE
move(other.cpair);
446 other.cpair.value = 0;
456 NEFORCE_CONSTEXPR20
void reset(
uint32_t* new_ptr =
nullptr,
const size_t cap = 0) {
457 if (ptr !=
nullptr) {
468 NEFORCE_CONSTEXPR20
void allocate(
const size_t word) { reset(cpair.
get_base().allocate(word), word); }
474 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
uint32_t*
get()
const noexcept {
return ptr; }
480 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
size_t capacity()
const noexcept {
return cpair.
value; }
485 bit_storage storage_;
493 static constexpr size_t word_count(
const size_type word)
noexcept {
501 NEFORCE_CONSTEXPR20
void allocate_storage(
const size_type word) {
505 storage_.allocate(word_count(word));
512 NEFORCE_CONSTEXPR20
void set_iterators(
const size_type word)
noexcept {
513 start_ =
iterator(storage_.get(), 0,
this);
526 template <
typename Iterator1,
typename Iterator2>
527 NEFORCE_CONSTEXPR20 Iterator2 bit_copy(Iterator1 first, Iterator1 last, Iterator2 result) {
529 for (; n > 0; --n, ++first, ++result) {
544 template <
typename Iterator1,
typename Iterator2>
545 NEFORCE_CONSTEXPR20 Iterator2 bit_copy_backward(Iterator1 first, Iterator1 last, Iterator2 result) {
559 void reallocate_insert(
const iterator& position,
const size_type extra_len,
const bool value) {
561 const size_type new_size = old_size + extra_len;
562 const size_type new_words = word_count(new_size);
563 bit_storage new_storage(new_words);
565 const iterator new_start(new_storage.get(), 0,
this);
566 auto new_finish = bitmap::bit_copy(
begin(), position, new_start);
569 new_finish = bitmap::bit_copy(position,
end(), new_finish);
571 storage_ = _NEFORCE
move(new_storage);
573 finish_ = new_finish;
584 template <
typename Iterator>
585 void reallocate_insert_range(
const iterator position, Iterator first, Iterator last,
const size_type extra_len) {
587 const size_type new_size = old_size + extra_len;
588 const size_type new_words = word_count(new_size);
589 bit_storage new_storage(new_words);
591 const iterator new_start(new_storage.get(), 0,
this);
592 auto new_finish = bitmap::bit_copy(
begin(), position, new_start);
593 new_finish = bitmap::bit_copy(first, last, new_finish);
594 new_finish = bitmap::bit_copy(position,
end(), new_finish);
596 storage_ = _NEFORCE
move(new_storage);
598 finish_ = new_finish;
606 void insert_aux(
const iterator& position,
const bool value) {
607 if (finish_.ptr_ != storage_.get() + storage_.capacity()) {
608 bit_copy_backward(position, finish_, finish_ + 1);
612 reallocate_insert(position, 1, value);
622 template <
typename Iterator>
629 while (first != last) {
644 template <
typename Iterator>
651 bit_storage tmp_storage(word_count(n));
652 iterator tmp_start(tmp_storage.get(), 0,
this);
653 const iterator tmp_finish = bitmap::bit_copy(first, last, tmp_start);
655 storage_ = _NEFORCE
move(tmp_storage);
657 finish_ = tmp_finish;
668 template <
typename Iterator>
674 insert_range(position, tmp.
begin(), tmp.
end());
685 template <
typename Iterator>
692 bitmap::bit_copy_backward(position,
end(), finish_ +
static_cast<difference_type>(n));
693 bitmap::bit_copy(first, last, position);
696 bitmap::reallocate_insert_range(position, first, last, n);
707 NEFORCE_CONSTEXPR20
bitmap() noexcept = default;
719 allocate_storage(word);
721 _NEFORCE
fill_n(storage_.get(),
static_cast<ptrdiff_t>(storage_.capacity()), 0);
733 allocate_storage(word);
735 _NEFORCE
fill(storage_.get(), storage_.get() + storage_.capacity(), value ? ~0U : 0U);
764 bit_storage tmp(word_count(n));
765 const iterator tmp_start(tmp.get(), 0,
this);
766 const auto tmp_finish = bit_copy(other.
cbegin(), other.
cend(), tmp_start);
768 storage_ = _NEFORCE
move(tmp);
770 finish_ = tmp_finish;
783 *
this = _NEFORCE
move(tmp);
793 start_(other.start_.ptr_, other.start_.off_,
this),
794 finish_(other.finish_.ptr_, other.finish_.off_,
this),
795 storage_(_NEFORCE
move(other.storage_)) {
819 template <
typename Iterator, enable_if_t<is_iter_v<Iterator>,
int> = 0>
820 NEFORCE_CONSTEXPR20
bitmap(Iterator first, Iterator last) {
821 bitmap::range_init(first, last);
833 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
iterator begin() noexcept {
return start_; }
839 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
iterator end() noexcept {
return finish_; }
921 NEFORCE_NODISCARD NEFORCE_CONSTEXPR20
bool empty() const noexcept {
return start_ == finish_; }
981 const size_type new_words = word_count(n);
982 bit_storage new_storage(new_words);
983 const iterator new_start(new_storage.get(), 0,
this);
984 const auto new_finish = bit_copy(
begin(),
end(), new_start);
986 storage_ = _NEFORCE
move(new_storage);
988 finish_ = new_finish;
997 if (finish_.ptr_ != storage_.get() + storage_.capacity()) {
1000 insert_aux(
end(), value);
1012 if (finish_.ptr_ != storage_.get() + storage_.capacity() && position ==
end()) {
1015 insert_aux(position, value);
1027 template <
typename Iterator>
1029 bitmap::insert_range(position, first, last);
1038 NEFORCE_CONSTEXPR20
void insert(
const iterator& position,
const bool* first,
const bool* last) {
1039 if (first == last) {
1044 bitmap::bit_copy_backward(position,
end(), finish_ +
static_cast<difference_type>(n));
1045 bitmap::bit_copy(first, last, position);
1048 bitmap::reallocate_insert_range(position, first, last, n);
1063 bitmap::bit_copy_backward(position,
end(), finish_ +
static_cast<difference_type>(n));
1067 bitmap::reallocate_insert(position, n, value);
1102 if (position + 1 !=
end()) {
1103 bitmap::bit_copy(position + 1,
end(), position);
1116 finish_ = bitmap::bit_copy(last,
end(), first);
1143 if (_NEFORCE
addressof(other) ==
this) {
1146 _NEFORCE
swap(start_, other.start_);
1147 _NEFORCE
swap(finish_, other.finish_);
1148 _NEFORCE
swap(storage_, other.storage_);
1149 start_.container_ =
this;
1150 finish_.container_ =
this;
1151 other.start_.container_ = &other;
1152 other.finish_.container_ = &other;
1161 noexcept(
noexcept(_NEFORCE
equal(this->
cbegin(), this->
cend(), rhs.cbegin()))) {
1162 return this->
size() == rhs.size() && _NEFORCE
equal(this->
cbegin(), this->
cend(), rhs.cbegin());
1179NEFORCE_END_NAMESPACE__
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
bit_reference reference
引用类型
constexpr void insert(const iterator &position, const size_type n, const bool value)
插入n个相同的位
constexpr reference operator[](const size_type n)
下标访问操作符
constexpr const_iterator cbegin() const noexcept
获取常量起始迭代器
bitmap_iterator< false, bitmap > iterator
迭代器类型
constexpr void insert(const iterator &pos, const int64_t n, const bool value)
插入n个相同的位
constexpr bool less_than(const bitmap &rhs) const noexcept(noexcept(_NEFORCE lexicographical_compare(this->cbegin(), this->cend(), rhs.cbegin(), rhs.cend())))
小于比较操作符
constexpr void insert(iterator position, Iterator first, Iterator last)
范围插入
allocator< uint32_t > allocator_type
分配器类型
constexpr void push_back(const bool value)
在末尾插入位
constexpr const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
ptrdiff_t difference_type
差值类型
constexpr const_iterator begin() const noexcept
获取常量起始迭代器
constexpr reverse_iterator rend() noexcept
获取反向结束迭代器
constexpr const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
constexpr iterator erase(const iterator &position)
删除指定位置的位
constexpr size_type capacity() const noexcept
获取容量(位数)
bitmap_iterator< true, bitmap > const_iterator
常量迭代器类型
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
constexpr bitmap(const bitmap &other)
拷贝构造函数
bit_reference * pointer
指针类型
constexpr bitmap() noexcept=default
默认构造函数
constexpr reference back()
访问最后一个位
const bool const_reference
常量引用类型
constexpr bitmap(bitmap &&other) noexcept
移动构造函数
constexpr iterator erase(const iterator &first, const iterator &last)
删除指定范围内的位
constexpr const_reference operator[](const size_type n) const
常量下标访问操作符
const bool * const_pointer
常量指针类型
constexpr iterator end() noexcept
获取结束迭代器
constexpr reverse_iterator rbegin() noexcept
获取反向起始迭代器
constexpr bool empty() const noexcept
检查是否为空
constexpr const_iterator end() const noexcept
获取常量结束迭代器
constexpr void pop_back()
删除末尾位
constexpr size_type size() const noexcept
获取位数
constexpr ~bitmap()=default
析构函数
constexpr void swap(bitmap &other) noexcept
交换两个位图的内容
constexpr bitmap & operator=(bitmap &&other) noexcept
移动赋值运算符
constexpr void clear()
清空位图
constexpr bitmap(Iterator first, Iterator last)
范围构造函数
constexpr const_reference front() const
常量版本,访问第一个位
constexpr bitmap(const int64_t word, const bool value)
64位整数构造函数
constexpr bitmap(const size_type word, const bool value)
构造函数,指定大小和初始值
constexpr void resize(const size_type n, const bool value=bool())
调整大小
constexpr size_type max_size() const noexcept
获取最大可能位数
constexpr const_iterator cend() const noexcept
获取常量结束迭代器
constexpr iterator insert(const iterator &position, const bool value)
在指定位置插入位
constexpr const_reference back() const
常量版本,访问最后一个位
constexpr iterator begin() noexcept
获取起始迭代器
constexpr reference front()
访问第一个位
constexpr void reserve(const size_type n)
预留容量
constexpr void insert(const iterator &position, const bool *first, const bool *last)
插入布尔数组范围
constexpr const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
constexpr const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
constexpr bitmap(const int32_t word, const bool value)
32位整数构造函数
constexpr bitmap & operator=(const bitmap &other)
拷贝赋值运算符
constexpr void insert(const iterator &pos, const int32_t n, const bool value)
插入n个相同的位
constexpr bool equal_to(const bitmap &rhs) const noexcept(noexcept(_NEFORCE equal(this->cbegin(), this->cend(), rhs.cbegin())))
相等比较操作符
constexpr T * addressof(T &x) noexcept
获取对象的地址
enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
constexpr uint32_t BITMAP_WORD_SIZE
每个字的位数
constexpr bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(comp(*first1, *first2)) &&noexcept(first1==last1 &&first2 !=last2))
字典序比较两个范围
constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
unsigned int uint32_t
32位无符号整数类型
long long int64_t
64位有符号整数类型
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
typename iterator_traits< Iterator >::difference_type iter_difference_t
获取迭代器的差值类型
standard_allocator< T > allocator
标准分配器别名
constexpr void * allocate(const inner::alloc_size_t bytes)
内存分配函数
constexpr void memory_zero(void *dest, const size_t count) noexcept
将内存区域清零
constexpr void fill(Iterator first, Iterator last, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr Iterator fill_n(Iterator first, iter_difference_t< Iterator > n, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充指定数量的元素
void swap()=delete
删除无参数的swap重载
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr bit_reference & operator=(bit_reference &&other) noexcept
移动赋值运算符
constexpr bool equal_to(const bit_reference &rhs) const noexcept
相等比较操作符
constexpr bit_reference & operator=(const bit_reference &other) noexcept
拷贝赋值运算符
constexpr bit_reference & operator=(const bool value) noexcept
赋值布尔值
constexpr void flip() const noexcept
翻转位值
constexpr bit_reference(const bit_reference &other) noexcept
拷贝构造函数
constexpr bit_reference(uint32_t *ptr, const uint32_t mask) noexcept
构造函数
constexpr void swap(bit_reference &other) noexcept
交换两个位引用
constexpr bit_reference(bit_reference &&other) noexcept
移动构造函数
constexpr bool less_than(const bit_reference &rhs) const noexcept
小于比较操作符
constexpr string to_string() const
转换为字符串
constexpr size_t to_hash() const noexcept
计算哈希值
typename container_type::value_type value_type
值类型
BitMap container_type
容器类型
constexpr reference operator[](const difference_type n) const noexcept
下标访问操作符
constexpr bool equal_to(const bitmap_iterator &rhs) const noexcept
相等比较
constexpr decltype(auto) base() const noexcept
获取底层指针
random_access_iterator_tag iterator_category
迭代器类别
constexpr difference_type distance_to(const bitmap_iterator &other) const noexcept
计算距离操作
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
constexpr void advance(difference_type off) noexcept
前进操作
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
constexpr reference dereference() const noexcept
解引用操作
constexpr bitmap_iterator(const bitmap_iterator< IsConst2, BitMap > &other) noexcept
从另一个迭代器转换构造
constexpr bool less_than(const bitmap_iterator &rhs) const noexcept
小于比较
typename container_type::size_type size_type
大小类型
constexpr bitmap_iterator(uint32_t *ptr, const uint32_t offset, const container_type *bm) noexcept
构造函数
constexpr void increment() noexcept
递增操作
constexpr void decrement() noexcept
递减操作
constexpr const container_type * container() const noexcept
获取关联容器
typename container_type::difference_type difference_type
差值类型
constexpr compressed_pair & get_base() &noexcept
获取基类引用