MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
multimap.hpp
1#ifndef MSTL_CORE_CONTAINER_MULTIMAP_HPP__
2#define MSTL_CORE_CONTAINER_MULTIMAP_HPP__
3#include "rb_tree.hpp"
5
6template <typename Key, typename T, typename Compare = less<Key>,
7 typename Alloc = allocator<rb_tree_node<pair<const Key, T>>>>
8class multimap : public icollector<multimap<Key, T, Compare, Alloc>> {
9#ifdef MSTL_STANDARD_20__
10 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
11#endif
12 static_assert(is_same_v<rb_tree_node<pair<const Key, T>>, typename Alloc::value_type>,
13 "allocator type mismatch.");
14 static_assert(is_object_v<T>, "multimap only contains object types.");
15
16 using base_type = rb_tree<Key, pair<const Key, T>, select1st<pair<const Key, T>>, Compare, Alloc>;
17
18public:
19 using key_type = Key;
20 using data_type = T;
21 using mapped_type = T;
22 using value_type = pair<const Key, T>;
23 using key_compare = Compare;
24
25 struct value_compare {
26 private:
27 Compare comp_;
28 friend class multimap;
29
30 public:
31 bool operator ()(const value_type& x, const value_type& y) const noexcept {
32 return comp_(x.first, y.first);
33 }
34 };
35
36public:
37 using size_type = typename base_type::size_type;
38 using difference_type = typename base_type::difference_type;
39 using pointer = typename base_type::pointer;
40 using const_pointer = typename base_type::const_pointer;
41 using reference = typename base_type::reference;
42 using const_reference = typename base_type::const_reference;
43
44 using iterator = typename base_type::iterator;
45 using const_iterator = typename base_type::const_iterator;
46 using reverse_iterator = typename base_type::reverse_iterator;
47 using const_reverse_iterator = typename base_type::const_reverse_iterator;
48
49 using allocator_type = typename base_type::allocator_type;
50
51private:
52 base_type tree_;
53
54 template <typename Key1, typename T1, typename Compare1, typename Alloc1>
55 friend bool operator ==(const multimap<Key1, T1, Compare1, Alloc1>&,
56 const multimap<Key1, T1, Compare1, Alloc1>&) noexcept;
57 template <typename Key1, typename T1, typename Compare1, typename Alloc1>
58 friend bool operator <(const multimap<Key1, T1, Compare1, Alloc1>&,
59 const multimap<Key1, T1, Compare1, Alloc1>&) noexcept;
60
61public:
62 multimap() : tree_(Compare()) {}
63 explicit multimap(const key_compare& comp) : tree_(comp) {}
64
65 multimap(const multimap& x) : tree_(x.tree_) {}
66
67 multimap& operator =(const multimap& x) = default;
68
69 multimap(multimap&& x) noexcept(is_nothrow_move_constructible_v<base_type>)
70 : tree_(_MSTL move(x.tree_)) {}
71
72 multimap& operator =(multimap&& x) noexcept(noexcept(swap(x))) {
73 tree_ = _MSTL move(x.tree_);
74 return *this;
75 }
76
77 template <typename Iterator>
78 multimap(Iterator first, Iterator last) : tree_(Compare()) {
79 tree_.insert_equal(first, last);
80 }
81 template <typename Iterator>
82 multimap(Iterator first, Iterator last, const key_compare& comp) : tree_(comp) {
83 tree_.insert_equal(first, last);
84 }
85
86 multimap(std::initializer_list<value_type> l) : multimap(l.begin(), l.end()) {}
87 multimap(std::initializer_list<value_type> l, const key_compare& comp) : multimap(l.begin(), l.end(), comp) {}
88
89 multimap& operator =(std::initializer_list<value_type> l) {
90 clear();
91 insert(l.begin(), l.end());
92 return *this;
93 }
94 ~multimap() = default;
95
96 MSTL_NODISCARD iterator begin() noexcept { return tree_.begin(); }
97 MSTL_NODISCARD iterator end() noexcept { return tree_.end(); }
98 MSTL_NODISCARD const_iterator begin() const noexcept { return tree_.cbegin(); }
99 MSTL_NODISCARD const_iterator end() const noexcept { return tree_.cend(); }
100 MSTL_NODISCARD const_iterator cbegin() const noexcept { return tree_.cbegin(); }
101 MSTL_NODISCARD const_iterator cend() const noexcept { return tree_.cend(); }
102 MSTL_NODISCARD reverse_iterator rbegin() noexcept { return tree_.rbegin(); }
103 MSTL_NODISCARD reverse_iterator rend() noexcept { return tree_.rend(); }
104 MSTL_NODISCARD const_reverse_iterator rbegin() const noexcept { return tree_.rbegin(); }
105 MSTL_NODISCARD const_reverse_iterator rend() const noexcept { return tree_.rend(); }
106 MSTL_NODISCARD const_reverse_iterator crbegin() const noexcept { return tree_.crbegin(); }
107 MSTL_NODISCARD const_reverse_iterator crend() const noexcept { return tree_.crend(); }
108
109 MSTL_NODISCARD size_type size() const noexcept { return tree_.size(); }
110 MSTL_NODISCARD size_type max_size() const noexcept { return tree_.max_size(); }
111 MSTL_NODISCARD bool empty() const noexcept { return tree_.empty(); }
112
113 MSTL_NODISCARD allocator_type get_allocator() const noexcept { return allocator_type(); }
114
115 MSTL_NODISCARD key_compare key_comp() const noexcept { return tree_.key_comp(); }
116 MSTL_NODISCARD value_compare value_comp() const noexcept { return value_compare(tree_.key_comp()); }
117
118 template <typename... Args>
119 iterator emplace(Args&&... args) {
120 return tree_.emplace_equal(_MSTL forward<Args>(args)...);
121 }
122 iterator insert(const value_type& x) {
123 return tree_.insert_equal(x);
124 }
125 iterator insert(value_type&& x) {
126 return tree_.insert_equal(_MSTL move(x));
127 }
128
129 template <typename... Args>
130 iterator emplace_hint(iterator position, Args&&... args) {
131 return tree_.emplace_equal_hint(position, _MSTL forward<Args>(args)...);
132 }
133 iterator insert(iterator position, const value_type& x) {
134 return tree_.insert_equal(position, x);
135 }
136 iterator insert(iterator position, value_type&& x) {
137 return tree_.insert_equal(position, _MSTL move(x));
138 }
139
140 template <typename Iterator>
141 void insert(Iterator first, Iterator last) {
142 tree_.insert_equal(first, last);
143 }
144
145 void erase(iterator position) noexcept { tree_.erase(position); }
146 size_type erase(const key_type& x) noexcept { return tree_.erase(x); }
147 void erase(iterator first, iterator last) noexcept { tree_.erase(first, last); }
148
149 void clear() noexcept { tree_.clear(); }
150
151 MSTL_NODISCARD iterator find(const key_type& x) { return tree_.find(x); }
152 MSTL_NODISCARD const_iterator find(const key_type& x) const { return tree_.find(x); }
153 MSTL_NODISCARD size_type count(const key_type& x) const { return tree_.count(x); }
154
155 MSTL_NODISCARD iterator lower_bound(const key_type& x) { return tree_.lower_bound(x); }
156 MSTL_NODISCARD const_iterator lower_bound(const key_type& x) const { return tree_.lower_bound(x); }
157 MSTL_NODISCARD iterator upper_bound(const key_type& x) { return tree_.upper_bound(x); }
158 MSTL_NODISCARD const_iterator upper_bound(const key_type& x) const { return tree_.upper_bound(x); }
159
160 MSTL_NODISCARD pair<iterator, iterator> equal_range(const key_type& x) { return tree_.equal_range(x); }
161 MSTL_NODISCARD pair<const_iterator, const_iterator> equal_range(const key_type& x) const {
162 return tree_.equal_range(x);
163 }
164
165 void swap(multimap& x) noexcept(noexcept(tree_.swap(x.tree_))) { tree_.swap(x.tree_); }
166
167 MSTL_NODISCARD bool operator ==(const multimap& rhs) const
168 noexcept(noexcept(tree_ == rhs.tree_)) {
169 return tree_ == rhs.tree_;
170 }
171 MSTL_NODISCARD bool operator <(const multimap& rhs) const
172 noexcept(noexcept(tree_ < rhs.tree_)) {
173 return tree_ < rhs.tree_;
174 }
175};
176#ifdef MSTL_SUPPORT_DEDUCTION_GUIDES__
177template <typename Iterator, typename Compare, typename Alloc
179multimap(Iterator, Iterator, Compare = Compare(), Alloc = Alloc()) ->
180 multimap<iter_map_key_t<Iterator>, iter_map_value_t<Iterator>, Compare, Alloc>;
181
182template <typename Key, typename T, typename Compare = less<Key>, typename Alloc
183 = allocator<pair<const Key, T>>>
184multimap(std::initializer_list<pair<Key, T>>, Compare = Compare(), Alloc = Alloc())
185-> multimap<Key, T, Compare, Alloc>;
186
187template <typename Iterator, typename Alloc>
188multimap(Iterator, Iterator, Alloc) ->
190
191template <typename Key, typename T, typename Alloc>
192multimap(std::initializer_list<pair<Key, T>>, Alloc) -> multimap<Key, T, less<Key>, Alloc>;
193#endif
194
196#endif // MSTL_CORE_CONTAINER_MULTIMAP_HPP__
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr Iterator lower_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个不小于指定值的元素位置
constexpr Iterator upper_bound(Iterator first, Iterator last, const T &value, Compare comp)
查找有序范围中第一个大于指定值的元素位置
constexpr pair< Iterator, Iterator > equal_range(Iterator first, Iterator last, const T &value, Compare comp)
查找值的相等范围
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
MSTL_NODISCARD constexpr Iterator find(Iterator first, Iterator last, const T &value)
查找范围内第一个等于指定值的元素
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
remove_const_t< typename iter_value_t< Iterator >::first_type > iter_map_key_t
从映射迭代器中提取键类型
typename iter_value_t< Iterator >::second_type iter_map_value_t
从映射迭代器中提取值类型
standard_allocator< T > allocator
标准分配器别名
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
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 Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
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反向结束迭代器
集合器接口模板
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))
小于比较运算符
小于比较仿函数
存储两个值的元组对