MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
multiset.hpp
1#ifndef MSTL_CORE_CONTAINER_MULTISET_HPP__
2#define MSTL_CORE_CONTAINER_MULTISET_HPP__
3#include "rb_tree.hpp"
5
6template <typename Key, typename Compare = less<Key>, typename Alloc = allocator<rb_tree_node<Key>>>
7class multiset : icollector<multiset<Key, Compare, Alloc>> {
8#ifdef MSTL_STANDARD_20__
9 static_assert(is_allocator_v<Alloc>, "Alloc type is not a standard allocator type.");
10#endif
11 static_assert(is_same_v<rb_tree_node<Key>, typename Alloc::value_type>,
12 "allocator type mismatch.");
13 static_assert(is_object_v<Key>, "multiset only contains object types.");
14
15 using base_type = rb_tree<Key, Key, identity<Key>, Compare, Alloc>;
16
17public:
18 using key_type = Key;
19 using value_type = Key;
20 using key_compare = Compare;
21 using value_compare = Compare;
22
23 using size_type = typename base_type::size_type;
24 using difference_type = typename base_type::difference_type;
25 using pointer = typename base_type::pointer;
26 using const_pointer = typename base_type::const_pointer;
27 using reference = typename base_type::reference;
28 using const_reference = typename base_type::const_reference;
29
30 using iterator = typename base_type::iterator;
31 using const_iterator = typename base_type::const_iterator;
32 using reverse_iterator = typename base_type::reverse_iterator;
33 using const_reverse_iterator = typename base_type::const_reverse_iterator;
34
35 using allocator_type = typename base_type::allocator_type;
36
37private:
38 base_type tree_;
39
40public:
41 multiset() : tree_(Compare()) {}
42 explicit multiset(const key_compare& comp) : tree_(comp) {}
43
44 multiset(const multiset& x) : tree_(x.tree_) {}
45
46 multiset& operator =(const multiset& x) = default;
47
48 multiset(multiset&& x) noexcept(is_nothrow_move_constructible_v<base_type>)
49 : tree_(_MSTL move(x.tree_)) {
50 }
51
52 multiset& operator =(multiset&& x) noexcept(noexcept(swap(x))) {
53 tree_ = _MSTL move(x.tree_);
54 return *this;
55 }
56
57 template <typename Iterator>
58 multiset(Iterator first, Iterator last) : tree_(Compare()) {
59 tree_.insert_equal(first, last);
60 }
61 template <typename Iterator>
62 multiset(Iterator first, Iterator last, const key_compare& comp) : tree_(comp) {
63 tree_.insert_equal(first, last);
64 }
65
66 multiset(std::initializer_list<value_type> l) : multiset(l.begin(), l.end()) {}
67 multiset(std::initializer_list<value_type> l, const key_compare& comp) : multiset(l.begin(), l.end(), comp) {}
68
69 multiset& operator =(std::initializer_list<value_type> l) {
70 clear();
71 insert(l.begin(), l.end());
72 return *this;
73 }
74 ~multiset() = default;
75
76 MSTL_NODISCARD iterator begin() noexcept { return tree_.begin(); }
77 MSTL_NODISCARD iterator end() noexcept { return tree_.end(); }
78 MSTL_NODISCARD const_iterator cbegin() const noexcept { return tree_.cbegin(); }
79 MSTL_NODISCARD const_iterator cend() const noexcept { return tree_.cend(); }
80 MSTL_NODISCARD reverse_iterator rbegin() noexcept { return reverse_iterator(tree_.begin()); }
81 MSTL_NODISCARD reverse_iterator rend() noexcept { return reverse_iterator(tree_.end()); }
82 MSTL_NODISCARD const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(tree_.cbegin()); }
83 MSTL_NODISCARD const_reverse_iterator crend() const noexcept { return const_reverse_iterator(tree_.cend()); }
84
85 MSTL_NODISCARD size_type size() const noexcept { return tree_.size(); }
86 MSTL_NODISCARD size_type max_size() const noexcept { return tree_.max_size(); }
87 MSTL_NODISCARD bool empty() const noexcept { return tree_.empty(); }
88
89 MSTL_NODISCARD allocator_type get_allocator() const noexcept { return allocator_type(); }
90
91 MSTL_NODISCARD key_compare key_comp() const noexcept { return tree_.key_comp(); }
92 MSTL_NODISCARD value_compare value_comp() const noexcept { return value_compare(tree_.key_comp()); }
93
94 template <typename... Args>
95 iterator emplace(Args&&... args) {
96 return tree_.emplace_equal(_MSTL forward<Args>(args)...);
97 }
98 iterator insert(const value_type& x) {
99 return tree_.insert_equal(x);
100 }
101 iterator insert(value_type&& x) {
102 return tree_.insert_equal(_MSTL move(x));
103 }
104
105 template <typename... Args>
106 iterator emplace_hint(iterator position, Args&&... args) {
107 return tree_.emplace_equal_hint(position, _MSTL forward<Args>(args)...);
108 }
109 iterator insert(iterator position, const value_type& x) {
110 return tree_.insert_equal(position, x);
111 }
112 iterator insert(iterator position, value_type&& x) {
113 return tree_.insert_equal(position, _MSTL move(x));
114 }
115
116 template <typename Iterator>
117 void insert(Iterator first, Iterator last) {
118 tree_.insert_equal(first, last);
119 }
120
121 void erase(iterator position) noexcept { tree_.erase(position); }
122 size_type erase(const key_type& x) noexcept { return tree_.erase(x); }
123 void erase(iterator first, iterator last) noexcept { tree_.erase(first, last); }
124
125 void clear() noexcept { tree_.clear(); }
126
127 MSTL_NODISCARD iterator find(const key_type& x) { return tree_.find(x); }
128 MSTL_NODISCARD const_iterator find(const key_type& x) const { return tree_.find(x); }
129 MSTL_NODISCARD size_type count(const key_type& x) const { return tree_.count(x); }
130
131 MSTL_NODISCARD iterator lower_bound(const key_type& x) { return tree_.lower_bound(x); }
132 MSTL_NODISCARD const_iterator lower_bound(const key_type& x) const { return tree_.lower_bound(x); }
133 MSTL_NODISCARD iterator upper_bound(const key_type& x) { return tree_.upper_bound(x); }
134 MSTL_NODISCARD const_iterator upper_bound(const key_type& x) const { return tree_.upper_bound(x); }
135
136 MSTL_NODISCARD pair<iterator, iterator> equal_range(const key_type& x) { return tree_.equal_range(x); }
137 MSTL_NODISCARD pair<const_iterator, const_iterator> equal_range(const key_type& x) const {
138 return tree_.equal_range(x);
139 }
140
141 void swap(multiset& x) noexcept(noexcept(tree_.swap(x.tree_))) { tree_.swap(x.tree_); }
142
143 MSTL_NODISCARD bool operator ==(const multiset& rhs) const
144 noexcept(noexcept(tree_ == rhs.tree_)) {
145 return tree_ == rhs.tree_;
146 }
147 MSTL_NODISCARD bool operator <(const multiset& rhs) const
148 noexcept(noexcept(tree_ < rhs.tree_)) {
149 return tree_ < rhs.tree_;
150 }
151};
152#if MSTL_SUPPORT_DEDUCTION_GUIDES__
153template <typename Iterator, typename Compare = less<iter_value_t<Iterator>>,
154 typename Alloc = allocator<iter_value_t<Iterator>>>
155multiset(Iterator, Iterator, Compare = Compare(), Alloc = Alloc())
156-> multiset<iter_value_t<Iterator>, Compare, Alloc>;
157
158template <typename Key, typename Compare = less<Key>, typename Alloc = allocator<Key>>
159multiset(std::initializer_list<Key>, Compare = Compare(), Alloc = Alloc()) -> multiset<Key, Compare, Alloc>;
160
161template <typename Iterator, typename Alloc>
162multiset(Iterator, Iterator, Alloc) -> multiset<iter_value_t<Iterator>, less<iter_value_t<Iterator>>, Alloc>;
163
164template <typename Key, typename Alloc>
165multiset(std::initializer_list<Key>, Alloc) -> multiset<Key, less<Key>, Alloc>;
166#endif
167
169#endif // MSTL_CORE_CONTAINER_MULTISET_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
等于空指针比较
#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反向结束迭代器
集合器接口模板
小于比较仿函数