NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
sparse_map.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_CONTAINER_SPARSE_MAP_HPP__
2#define NEFORCE_CORE_CONTAINER_SPARSE_MAP_HPP__
3
18
20NEFORCE_BEGIN_NAMESPACE__
21
27
40template <typename Key, typename T, typename Compare = less<Key>, typename Alloc = allocator<pair<Key, T>>>
41class sparse_map : public icollector<sparse_map<Key, T, Compare, Alloc>> {
42 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
43 static_assert(is_same_v<pair<Key, T>, typename Alloc::value_type>, "allocator type mismatch.");
44 static_assert(is_object_v<T>, "sparse_map only contains object types.");
45
46public:
47 using key_type = Key;
48 using data_type = T;
49 using mapped_type = T;
51 using key_compare = Compare;
52
59 struct value_compare {
60 private:
61 Compare comp_;
62 friend class sparse_map;
63
64 public:
65 explicit value_compare(Compare comp) :
66 comp_(comp) {}
67
74 bool operator()(const value_type& lhs, const value_type& rhs) const noexcept {
75 return comp_(lhs.first, rhs.first);
76 }
77 };
78
79private:
80 using base_type = sparse_vector<Key, pair<Key, T>, select1st<pair<Key, T>>, Compare, Alloc>;
81
82public:
85 using pointer = typename base_type::pointer;
89 using iterator = typename base_type::iterator;
94
95private:
96 base_type data_;
97
98public:
105 data_(Compare()) {}
106
111 explicit sparse_map(const key_compare& comp) :
112 data_(comp) {}
113
118 sparse_map(const sparse_map& other) :
119 data_(other.data_) {}
120
127 if (_NEFORCE addressof(other) == this) {
128 return *this;
129 }
130 data_ = other.data_;
131 return *this;
132 }
133
139 data_(_NEFORCE move(other.data_)) {}
140
147 if (_NEFORCE addressof(other) == this) {
148 return *this;
149 }
150 data_ = _NEFORCE move(other.data_);
151 return *this;
152 }
153
160 template <typename Iterator>
161 sparse_map(Iterator first, Iterator last) :
162 data_(Compare()) {
163 data_.insert_unique(first, last);
164 }
165
173 template <typename Iterator>
174 sparse_map(Iterator first, Iterator last, const key_compare& comp) :
175 data_(comp) {
176 data_.insert_unique(first, last);
177 }
178
183 sparse_map(std::initializer_list<value_type> ilist) :
184 sparse_map(ilist.begin(), ilist.end()) {}
185
191 sparse_map(std::initializer_list<value_type> ilist, const key_compare& comp) :
192 sparse_map(ilist.begin(), ilist.end(), comp) {}
193
199 sparse_map& operator=(std::initializer_list<value_type> ilist) {
200 clear();
201 insert(ilist.begin(), ilist.end());
202 return *this;
203 }
204
208 ~sparse_map() = default;
209
214 NEFORCE_NODISCARD iterator begin() noexcept { return data_.begin(); }
215
220 NEFORCE_NODISCARD iterator end() noexcept { return data_.end(); }
221
226 NEFORCE_NODISCARD const_iterator begin() const noexcept { return data_.cbegin(); }
227
232 NEFORCE_NODISCARD const_iterator end() const noexcept { return data_.cend(); }
233
238 NEFORCE_NODISCARD const_iterator cbegin() const noexcept { return data_.cbegin(); }
239
244 NEFORCE_NODISCARD const_iterator cend() const noexcept { return data_.cend(); }
245
250 NEFORCE_NODISCARD reverse_iterator rbegin() noexcept { return data_.rbegin(); }
251
256 NEFORCE_NODISCARD reverse_iterator rend() noexcept { return data_.rend(); }
257
262 NEFORCE_NODISCARD const_reverse_iterator rbegin() const noexcept { return data_.rbegin(); }
263
268 NEFORCE_NODISCARD const_reverse_iterator rend() const noexcept { return data_.rend(); }
269
274 NEFORCE_NODISCARD const_reverse_iterator crbegin() const noexcept { return data_.crbegin(); }
275
280 NEFORCE_NODISCARD const_reverse_iterator crend() const noexcept { return data_.crend(); }
281
286 NEFORCE_NODISCARD size_type size() const noexcept { return data_.size(); }
287
292 NEFORCE_NODISCARD size_type max_size() const noexcept { return data_.max_size(); }
293
298 NEFORCE_NODISCARD bool empty() const noexcept { return data_.empty(); }
299
304 NEFORCE_NODISCARD key_compare key_comp() const noexcept { return data_.key_compare(); }
305
310 NEFORCE_NODISCARD value_compare value_comp() const noexcept { return value_compare(data_.key_compare()); }
311
318 template <typename... Args>
320 return data_.emplace_unique(_NEFORCE forward<Args>(args)...);
321 }
322
328 pair<iterator, bool> insert(const value_type& value) { return data_.insert_unique(value); }
329
335 pair<iterator, bool> insert(value_type&& value) { return data_.emplace_unique(_NEFORCE move(value)); }
336
344 template <typename... Args>
345 iterator emplace_hint(iterator position, Args&&... args) {
346 return data_.emplace_unique_hint(position, _NEFORCE forward<Args>(args)...);
347 }
348
355 iterator insert(iterator position, const value_type& value) { return data_.insert_unique(position, value); }
356
363 iterator insert(iterator position, value_type&& value) {
364 return data_.insert_unique(position, _NEFORCE move(value));
365 }
366
373 template <typename Iterator>
374 void insert(Iterator first, Iterator last) {
375 data_.insert_unique(first, last);
376 }
377
382 void erase(iterator position) noexcept(noexcept(data_.erase(position))) { data_.erase(position); }
383
389 size_type erase(const key_type& key) noexcept(noexcept(data_.erase(key))) { return data_.erase(key); }
390
396 void erase(iterator first, iterator last) noexcept(noexcept(data_.erase(first, last))) { data_.erase(first, last); }
397
401 void clear() noexcept(noexcept(data_.clear())) { data_.clear(); }
402
408 NEFORCE_NODISCARD iterator find(const key_type& key) { return data_.find(key); }
409
415 NEFORCE_NODISCARD const_iterator find(const key_type& key) const { return data_.find(key); }
416
422 NEFORCE_NODISCARD size_type count(const key_type& key) const { return data_.count(key); }
423
429 NEFORCE_NODISCARD iterator lower_bound(const key_type& key) { return data_.lower_bound(key); }
430
436 NEFORCE_NODISCARD const_iterator lower_bound(const key_type& key) const { return data_.lower_bound(key); }
437
443 NEFORCE_NODISCARD iterator upper_bound(const key_type& key) { return data_.upper_bound(key); }
444
450 NEFORCE_NODISCARD const_iterator upper_bound(const key_type& key) const { return data_.upper_bound(key); }
451
457 NEFORCE_NODISCARD pair<iterator, iterator> equal_range(const key_type& key) { return data_.equal_range(key); }
458
464 NEFORCE_NODISCARD pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
465 return data_.equal_range(key);
466 }
467
475 NEFORCE_NODISCARD mapped_type& operator[](const key_type& key) {
476 iterator iter = data_.lower_bound(key);
477 if (iter == end() || key_comp()(key, iter->first)) {
478 iter = data_.emplace_unique_hint(iter, key, initialize<T>());
479 }
480 return iter->second;
481 }
482
490 NEFORCE_NODISCARD mapped_type& operator[](key_type&& key) {
491 iterator iter = data_.lower_bound(key);
492 if (iter == end() || key_comp()(key, iter->first)) {
493 iter = data_.emplace_unique_hint(iter, _NEFORCE move(key), initialize<T>());
494 }
495 return iter->second;
496 }
497
504 NEFORCE_NODISCARD const mapped_type& at(const key_type& key) const {
505 const_iterator iter = data_.lower_bound(key);
506 if (iter == end() || key_comp()(key, iter->first)) {
507 NEFORCE_THROW_EXCEPTION(value_exception("the value of this key does not exists."));
508 }
509 return iter->second;
510 }
511
518 NEFORCE_NODISCARD mapped_type& at(const key_type& key) {
519 iterator iter = data_.lower_bound(key);
520 if (iter == end() || key_comp()(key, iter->first)) {
521 NEFORCE_THROW_EXCEPTION(value_exception("the value of this key does not exists."));
522 }
523 return iter->second;
524 }
525
530 void reserve(size_type n) { data_.reserve(n); }
531
536 NEFORCE_NODISCARD size_type capacity() const noexcept { return data_.capacity(); }
537
541 void shrink_to_fit() { data_.shrink_to_fit(); }
542
547 void swap(sparse_map& other) noexcept(noexcept(data_.swap(other.data_))) { data_.swap(other.data_); }
548
554 NEFORCE_NODISCARD bool equal_to(const sparse_map& rhs) const noexcept(noexcept(data_ == rhs.data_)) {
555 return data_ == rhs.data_;
556 }
557
563 NEFORCE_NODISCARD bool less_than(const sparse_map& rhs) const noexcept(noexcept(data_ < rhs.data_)) {
564 return data_ < rhs.data_;
565 }
566};
567
568#ifdef NEFORCE_STANDARD_17
569template <typename Iterator, typename Compare,
570 typename Alloc = allocator<pair<iter_map_key_t<Iterator>, iter_map_value_t<Iterator>>>>
571sparse_map(Iterator, Iterator, Compare = Compare(), Alloc = Alloc())
572 -> sparse_map<iter_map_key_t<Iterator>, iter_map_value_t<Iterator>, Compare, Alloc>;
573
574template <typename Key, typename T, typename Compare = less<Key>, typename Alloc = allocator<pair<Key, T>>>
575sparse_map(std::initializer_list<pair<Key, T>>, Compare = Compare(), Alloc = Alloc())
576 -> sparse_map<Key, T, Compare, Alloc>;
577
578template <typename Iterator, typename Alloc>
579sparse_map(Iterator, Iterator, Alloc)
580 -> sparse_map<iter_map_key_t<Iterator>, iter_map_value_t<Iterator>, less<iter_map_key_t<Iterator>>, Alloc>;
581
582template <typename Key, typename T, typename Alloc>
583sparse_map(std::initializer_list<pair<Key, T>>, Alloc) -> sparse_map<Key, T, less<Key>, Alloc>;
584#endif
585 // Container
587
588NEFORCE_END_NAMESPACE__
589#endif // NEFORCE_CORE_CONTAINER_SPARSE_MAP_HPP__
iterator end() noexcept
获取结束迭代器
mapped_type & operator[](const key_type &key)
下标访问操作符
void clear() noexcept(noexcept(data_.clear()))
清空sparse_map
iterator upper_bound(const key_type &key)
获取第一个大于指定键的元素位置
size_type count(const key_type &key) const
统计具有指定键的元素数量
typename base_type::const_reference const_reference
常量引用类型
bool less_than(const sparse_map &rhs) const noexcept(noexcept(data_< rhs.data_))
小于比较操作符
typename base_type::iterator iterator
迭代器类型
void shrink_to_fit()
收缩容量以适应实际大小
sparse_map(Iterator first, Iterator last, const key_compare &comp)
范围构造函数,指定比较函数
const_iterator cbegin() const noexcept
获取常量起始迭代器
typename base_type::allocator_type allocator_type
分配器类型
pair< Key, T > value_type
值类型
void swap(sparse_map &other) noexcept(noexcept(data_.swap(other.data_)))
交换两个sparse_map的内容
sparse_map & operator=(std::initializer_list< value_type > ilist)
初始化列表赋值运算符
mapped_type & at(const key_type &key)
带边界检查的访问
pair< iterator, bool > insert(const value_type &value)
拷贝插入元素
typename base_type::const_iterator const_iterator
常量迭代器类型
typename base_type::const_reverse_iterator const_reverse_iterator
常量反向迭代器类型
const_iterator begin() const noexcept
获取常量起始迭代器
iterator find(const key_type &key)
查找具有指定键的元素
size_type max_size() const noexcept
获取最大可能大小
const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
const_iterator lower_bound(const key_type &key) const
获取第一个不小于指定键的常量元素位置
mapped_type & operator[](key_type &&key)
右值键下标访问操作符
pair< iterator, iterator > equal_range(const key_type &key)
获取等于指定键的元素范围
typename base_type::difference_type difference_type
差值类型
void erase(iterator first, iterator last) noexcept(noexcept(data_.erase(first, last)))
删除指定范围内的元素
size_type erase(const key_type &key) noexcept(noexcept(data_.erase(key)))
删除所有具有指定键的元素
const_iterator end() const noexcept
获取常量结束迭代器
~sparse_map()=default
析构函数
void insert(Iterator first, Iterator last)
范围插入元素
sparse_map & operator=(sparse_map &&other) noexcept(is_nothrow_move_assignable_v< base_type >)
移动赋值运算符
bool empty() const noexcept
检查是否为空
void reserve(size_type n)
预留容量
const_iterator upper_bound(const key_type &key) const
获取第一个大于指定键的常量元素位置
sparse_map(const sparse_map &other)
拷贝构造函数
void erase(iterator position) noexcept(noexcept(data_.erase(position)))
删除指定位置的元素
iterator insert(iterator position, const value_type &value)
在提示位置附近拷贝插入元素
const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
typename base_type::const_pointer const_pointer
常量指针类型
const_iterator cend() const noexcept
获取常量结束迭代器
iterator begin() noexcept
获取起始迭代器
sparse_map()
默认构造函数
iterator emplace_hint(iterator position, Args &&... args)
在提示位置附近就地构造元素
reverse_iterator rend() noexcept
获取反向结束迭代器
sparse_map(std::initializer_list< value_type > ilist)
初始化列表构造函数
typename base_type::reverse_iterator reverse_iterator
反向迭代器类型
const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
sparse_map(std::initializer_list< value_type > ilist, const key_compare &comp)
初始化列表构造函数,指定比较函数
iterator lower_bound(const key_type &key)
获取第一个不小于指定键的元素位置
reverse_iterator rbegin() noexcept
获取反向起始迭代器
typename base_type::reference reference
引用类型
bool equal_to(const sparse_map &rhs) const noexcept(noexcept(data_==rhs.data_))
相等比较操作符
sparse_map(sparse_map &&other) noexcept(is_nothrow_move_constructible_v< base_type >)
移动构造函数
typename base_type::size_type size_type
大小类型
const_iterator find(const key_type &key) const
常量查找具有指定键的元素
typename base_type::pointer pointer
指针类型
key_compare key_comp() const noexcept
获取键比较函数对象
const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
size_type size() const noexcept
获取元素数量
value_compare value_comp() const noexcept
获取值比较函数对象
size_type capacity() const noexcept
获取当前容量
T mapped_type
映射值类型
sparse_map & operator=(const sparse_map &other)
拷贝赋值运算符
sparse_map(Iterator first, Iterator last)
范围构造函数
pair< const_iterator, const_iterator > equal_range(const key_type &key) const
获取等于指定键的常量元素范围
iterator insert(iterator position, value_type &&value)
在提示位置附近移动插入元素
const mapped_type & at(const key_type &key) const
带边界检查的常量访问
Compare key_compare
键比较函数类型
sparse_map(const key_compare &comp)
构造函数,指定比较函数
pair< iterator, bool > emplace(Args &&... args)
构造元素
pair< iterator, bool > insert(value_type &&value)
移动插入元素
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr bool is_object_v
is_object的便捷变量模板
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr bool is_allocator_v
is_allocator的便捷变量模板
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
constexpr bool is_nothrow_move_assignable_v
is_nothrow_move_assignable的便捷变量模板
constexpr bool is_nothrow_move_constructible_v
is_nothrow_move_constructible的便捷变量模板
constexpr bool is_same_v
is_same的便捷变量模板
稀疏向量容器
集合器接口模板
存储两个值的元组对
选择pair的第一个元素
bool operator()(const value_type &lhs, const value_type &rhs) const noexcept
比较两个键值对