1#ifndef MSTL_CORE_CONTAINER_SET_HPP__
2#define MSTL_CORE_CONTAINER_SET_HPP__
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.");
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.");
15 using base_type = rb_tree<Key, Key, identity<Key>, Compare, Alloc>;
19 using value_type = Key;
20 using key_compare = Compare;
21 using value_compare = Compare;
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;
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;
35 using allocator_type =
typename base_type::allocator_type;
41 set() : tree_(Compare()) {}
42 explicit set(
const key_compare& comp) : tree_(comp) {}
44 set(
const set& x) : tree_(x.tree_) {}
46 set& operator =(
const set& x) =
default;
48 set(set&& x)
noexcept(is_nothrow_move_constructible_v<base_type>)
51 set& operator =(set&& x)
noexcept(
noexcept(
swap(x))) {
56 template <
typename Iterator>
57 set(Iterator first, Iterator last) : tree_(Compare()) {
58 tree_.insert_unique(first, last);
60 template <
typename Iterator>
61 set(Iterator first, Iterator last,
const key_compare& comp) : tree_(comp) {
62 tree_.insert_unique(first, last);
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) {}
68 set& operator =(std::initializer_list<value_type> l) {
70 insert(l.begin(), l.end());
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(); }
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(); }
88 MSTL_NODISCARD allocator_type get_allocator() const noexcept {
return allocator_type(); }
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()); }
93 template <
typename... Args>
94 pair<iterator, bool> emplace(Args&&... args) {
97 pair<iterator, bool> insert(
const value_type& x) {
98 return tree_.insert_unique(x);
100 pair<iterator, bool> insert(value_type&& x) {
101 return tree_.insert_unique(
_MSTL move(x));
104 template <
typename... Args>
105 iterator emplace_hint(iterator position, Args&&... args) {
108 iterator insert(iterator position,
const value_type& x) {
109 return tree_.insert_unique(position, x);
111 iterator insert(iterator position, value_type&& x) {
112 return tree_.insert_unique(position,
_MSTL move(x));
115 template <
typename Iterator>
116 void insert(Iterator first, Iterator last) {
117 tree_.insert_unique(first, last);
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); }
124 void clear() noexcept { tree_.clear(); }
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); }
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); }
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);
140 void swap(set& x)
noexcept(
noexcept(tree_.swap(x.tree_))) { tree_.swap(x.tree_); }
142 MSTL_NODISCARD
bool operator ==(
const set& rhs)
const
143 noexcept(
noexcept(tree_ == rhs.tree_)) {
144 return tree_ == rhs.tree_;
146 MSTL_NODISCARD
bool operator <(
const set& rhs)
const
147 noexcept(
noexcept(tree_ < rhs.tree_)) {
148 return tree_ < rhs.tree_;
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>;
156template <
typename Key,
typename Compare = less<Key>,
typename Alloc = allocator<Key>>
157set(std::initializer_list<Key>, Compare = Compare(), Alloc = Alloc()) -> set<Key, Compare, Alloc>;
159template <
typename Iterator,
typename Alloc>
162template <
typename Key,
typename Alloc>
163set(std::initializer_list<Key>, Alloc) -> set<Key, less<Key>, Alloc>;
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反向结束迭代器