MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
container/set.hpp
1#ifndef MSTL_CORE_CONTAINER_SET_HPP__
2#define MSTL_CORE_CONTAINER_SET_HPP__
3#include "rb_tree.hpp"
5
6template <typename Key, typename Compare = less<Key>, typename Alloc = allocator<rb_tree_node<Key>>>
7class set : public icollector<set<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>, "set 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 set() : tree_(Compare()) {}
42 explicit set(const key_compare& comp) : tree_(comp) {}
43
44 set(const set& x) : tree_(x.tree_) {}
45
46 set& operator =(const set& x) = default;
47
48 set(set&& x) noexcept(is_nothrow_move_constructible_v<base_type>)
49 : tree_(_MSTL move(x.tree_)) {}
50
51 set& operator =(set&& x) noexcept(noexcept(swap(x))) {
52 tree_ = _MSTL move(x.tree_);
53 return *this;
54 }
55
56 template <typename Iterator>
57 set(Iterator first, Iterator last) : tree_(Compare()) {
58 tree_.insert_unique(first, last);
59 }
60 template <typename Iterator>
61 set(Iterator first, Iterator last, const key_compare& comp) : tree_(comp) {
62 tree_.insert_unique(first, last);
63 }
64
65 set(std::initializer_list<value_type> l) : set(l.begin(), l.end()) {}
66 set(std::initializer_list<value_type> l, const key_compare& comp) : set(l.begin(), l.end(), comp) {}
67
68 set& operator =(std::initializer_list<value_type> l) {
69 clear();
70 insert(l.begin(), l.end());
71 return *this;
72 }
73 ~set() = default;
74
75 MSTL_NODISCARD iterator begin() noexcept { return tree_.begin(); }
76 MSTL_NODISCARD iterator end() noexcept { return tree_.end(); }
77 MSTL_NODISCARD const_iterator cbegin() const noexcept { return tree_.cbegin(); }
78 MSTL_NODISCARD const_iterator cend() const noexcept { return tree_.cend(); }
79 MSTL_NODISCARD reverse_iterator rbegin() noexcept { return tree_.rbegin(); }
80 MSTL_NODISCARD reverse_iterator rend() noexcept { return tree_.rend(); }
81 MSTL_NODISCARD const_reverse_iterator crbegin() const noexcept { return tree_.crbegin(); }
82 MSTL_NODISCARD const_reverse_iterator crend() const noexcept { return tree_.crend(); }
83
84 MSTL_NODISCARD size_type size() const noexcept { return tree_.size(); }
85 MSTL_NODISCARD size_type max_size() const noexcept { return tree_.max_size(); }
86 MSTL_NODISCARD bool empty() const noexcept { return tree_.empty(); }
87
88 MSTL_NODISCARD allocator_type get_allocator() const noexcept { return allocator_type(); }
89
90 MSTL_NODISCARD key_compare key_comp() const noexcept { return tree_.key_comp(); }
91 MSTL_NODISCARD value_compare value_comp() const noexcept { return value_compare(tree_.key_comp()); }
92
93 template <typename... Args>
94 pair<iterator, bool> emplace(Args&&... args) {
95 return tree_.emplace_unique(_MSTL forward<Args>(args)...);
96 }
97 pair<iterator, bool> insert(const value_type& x) {
98 return tree_.insert_unique(x);
99 }
100 pair<iterator, bool> insert(value_type&& x) {
101 return tree_.insert_unique(_MSTL move(x));
102 }
103
104 template <typename... Args>
105 iterator emplace_hint(iterator position, Args&&... args) {
106 return tree_.emplace_unique_hint(position, _MSTL forward<Args>(args)...);
107 }
108 iterator insert(iterator position, const value_type& x) {
109 return tree_.insert_unique(position, x);
110 }
111 iterator insert(iterator position, value_type&& x) {
112 return tree_.insert_unique(position, _MSTL move(x));
113 }
114
115 template <typename Iterator>
116 void insert(Iterator first, Iterator last) {
117 tree_.insert_unique(first, last);
118 }
119
120 void erase(iterator position) noexcept { tree_.erase(position); }
121 size_type erase(const key_type& x) noexcept { return tree_.erase(x); }
122 void erase(iterator first, iterator last) noexcept { tree_.erase(first, last); }
123
124 void clear() noexcept { tree_.clear(); }
125
126 MSTL_NODISCARD iterator find(const key_type& x) { return tree_.find(x); }
127 MSTL_NODISCARD const_iterator find(const key_type& x) const { return tree_.find(x); }
128 MSTL_NODISCARD size_type count(const key_type& x) const { return tree_.count(x); }
129
130 MSTL_NODISCARD iterator lower_bound(const key_type& x) { return tree_.lower_bound(x); }
131 MSTL_NODISCARD const_iterator lower_bound(const key_type& x) const { return tree_.lower_bound(x); }
132 MSTL_NODISCARD iterator upper_bound(const key_type& x) { return tree_.upper_bound(x); }
133 MSTL_NODISCARD const_iterator upper_bound(const key_type& x) const { return tree_.upper_bound(x); }
134
135 MSTL_NODISCARD pair<iterator, iterator> equal_range(const key_type& x) { return tree_.equal_range(x); }
136 MSTL_NODISCARD pair<const_iterator, const_iterator> equal_range(const key_type& x) const {
137 return tree_.equal_range(x);
138 }
139
140 void swap(set& x) noexcept(noexcept(tree_.swap(x.tree_))) { tree_.swap(x.tree_); }
141
142 MSTL_NODISCARD bool operator ==(const set& rhs) const
143 noexcept(noexcept(tree_ == rhs.tree_)) {
144 return tree_ == rhs.tree_;
145 }
146 MSTL_NODISCARD bool operator <(const set& rhs) const
147 noexcept(noexcept(tree_ < rhs.tree_)) {
148 return tree_ < rhs.tree_;
149 }
150};
151#if MSTL_SUPPORT_DEDUCTION_GUIDES__
152template <typename Iterator, typename Compare = less<iter_value_t<Iterator>>,
153 typename Alloc = allocator<iter_value_t<Iterator>>>
154set(Iterator, Iterator, Compare = Compare(), Alloc = Alloc()) -> set<iter_value_t<Iterator>, Compare, Alloc>;
155
156template <typename Key, typename Compare = less<Key>, typename Alloc = allocator<Key>>
157set(std::initializer_list<Key>, Compare = Compare(), Alloc = Alloc()) -> set<Key, Compare, Alloc>;
158
159template <typename Iterator, typename Alloc>
160set(Iterator, Iterator, Alloc) -> set<iter_value_t<Iterator>, less<iter_value_t<Iterator>>, Alloc>;
161
162template <typename Key, typename Alloc>
163set(std::initializer_list<Key>, Alloc) -> set<Key, less<Key>, Alloc>;
164#endif
165
167#endif // MSTL_CORE_CONTAINER_SET_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反向结束迭代器
集合器接口模板
小于比较仿函数