set 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #ifndef __GBLIBCPP_SET__
  2. #define __GBLIBCPP_SET__
  3. #include <bits/iter_ops>
  4. #include <bits/rbtree>
  5. #include <functional>
  6. #include <initializer_list>
  7. #include <memory>
  8. #include <cstddef>
  9. namespace std {
  10. template <typename Key,
  11. typename Compare = std::less<Key>,
  12. typename Allocator = std::allocator<Key>>
  13. class set {
  14. private:
  15. using rbtree_type = impl::rbtree<Key, Compare, Allocator>;
  16. using node_allocator = typename rbtree_type::node_allocator;
  17. private:
  18. rbtree_type tree;
  19. public:
  20. using key_type = Key;
  21. using value_type = Key;
  22. using size_type = std::size_t;
  23. using allocator_type = Allocator;
  24. using iterator = typename rbtree_type::iterator;
  25. using const_iterator = typename rbtree_type::const_iterator;
  26. public:
  27. __GBLIBCPP_CONSTEXPR
  28. iterator end(void) noexcept { return tree.end(); }
  29. __GBLIBCPP_CONSTEXPR
  30. const_iterator end(void) const noexcept { return tree.cend(); }
  31. __GBLIBCPP_CONSTEXPR
  32. const_iterator cend(void) const noexcept { return tree.cend(); }
  33. __GBLIBCPP_CONSTEXPR
  34. iterator begin(void) noexcept { return tree.begin(); }
  35. __GBLIBCPP_CONSTEXPR
  36. const_iterator begin(void) const noexcept { return tree.cbegin(); }
  37. __GBLIBCPP_CONSTEXPR
  38. const_iterator cbegin(void) const noexcept { return tree.cbegin(); }
  39. explicit __GBLIBCPP_CONSTEXPR
  40. set(const Compare& comp,
  41. const Allocator& alloc = Allocator())
  42. : tree(comp, alloc) {}
  43. explicit __GBLIBCPP_CONSTEXPR
  44. set(const Allocator& alloc)
  45. : set(Compare(), alloc) {}
  46. __GBLIBCPP_CONSTEXPR
  47. set() : set(Compare()) {}
  48. template <typename InputIter>
  49. __GBLIBCPP_CONSTEXPR
  50. set(InputIter first, InputIter last,
  51. const Compare& comp = Compare(),
  52. const Allocator& alloc = Allocator())
  53. : set(comp, alloc)
  54. {
  55. insert(first, last);
  56. }
  57. template <typename InputIter>
  58. __GBLIBCPP_CONSTEXPR
  59. set(InputIter first, InputIter last,
  60. const Allocator& alloc = Allocator())
  61. : set(first, last, Compare(), alloc) {}
  62. __GBLIBCPP_CONSTEXPR
  63. set(const set& other) : tree(other.tree) {}
  64. __GBLIBCPP_CONSTEXPR
  65. set(const set& other, const Allocator& alloc)
  66. : tree(other.tree, alloc) { }
  67. __GBLIBCPP_CONSTEXPR
  68. set(set&& other) : tree(std::move(other.tree)) {}
  69. __GBLIBCPP_CONSTEXPR
  70. set(set&& other, const Allocator& alloc)
  71. : tree(std::move(other.tree), alloc) {}
  72. __GBLIBCPP_CONSTEXPR
  73. set(std::initializer_list<Key> ilist,
  74. const Compare& comp = Compare(),
  75. const Allocator& alloc = Allocator())
  76. : set(comp, alloc)
  77. { insert(ilist.begin(), ilist.end()); }
  78. __GBLIBCPP_CONSTEXPR
  79. set(std::initializer_list<Key> ilist,
  80. const Allocator& alloc)
  81. : set(ilist, Compare(), alloc) {}
  82. __GBLIBCPP_CONSTEXPR
  83. ~set() { clear(); }
  84. __GBLIBCPP_CONSTEXPR
  85. set& operator=(const set& other) = default;
  86. __GBLIBCPP_CONSTEXPR
  87. set& operator=(set&& other) = default;
  88. __GBLIBCPP_CONSTEXPR
  89. set& operator=(std::initializer_list<Key> ilist)
  90. {
  91. clear();
  92. insert(ilist.begin(), ilist.end());
  93. return *this;
  94. }
  95. __GBLIBCPP_CONSTEXPR
  96. iterator find(const Key& key) { return tree.find(key); }
  97. __GBLIBCPP_CONSTEXPR
  98. const_iterator find(const Key& key) const { return tree.find(key); }
  99. template <typename K>
  100. __GBLIBCPP_CONSTEXPR
  101. iterator find(const K& key) { return tree.find(key); }
  102. template <typename K>
  103. __GBLIBCPP_CONSTEXPR
  104. const_iterator find(const K& key) const { return tree.find(key); }
  105. __GBLIBCPP_CONSTEXPR
  106. std::pair<iterator, bool> insert(const value_type& value)
  107. { return tree.insert(value); }
  108. __GBLIBCPP_CONSTEXPR
  109. std::pair<iterator, bool> insert(value_type&& value)
  110. { return tree.insert(std::move(value)); }
  111. template <typename InputIter>
  112. __GBLIBCPP_CONSTEXPR
  113. void insert(InputIter first, InputIter last)
  114. {
  115. for ( ; first != last; ++first)
  116. insert(*first);
  117. }
  118. template <typename... Args>
  119. __GBLIBCPP_CONSTEXPR
  120. std::pair<iterator, bool> emplace(Args&&... args)
  121. { return tree.emplace(std::forward<Args>(args)...); }
  122. __GBLIBCPP_CONSTEXPR
  123. iterator erase(iterator pos) noexcept { return tree.erase(pos); }
  124. __GBLIBCPP_CONSTEXPR
  125. iterator erase(const_iterator pos) noexcept { return tree.erase(pos); }
  126. __GBLIBCPP_CONSTEXPR
  127. iterator erase(const_iterator first, const_iterator last) noexcept
  128. {
  129. while (first != last)
  130. first = erase(first);
  131. return first;
  132. }
  133. __GBLIBCPP_CONSTEXPR
  134. size_type erase(const Key& key)
  135. {
  136. auto iter = find(key);
  137. if (!iter)
  138. return 0;
  139. erase(iter);
  140. return 1;
  141. }
  142. __GBLIBCPP_CONSTEXPR
  143. void clear() noexcept { tree.destroy(); }
  144. __GBLIBCPP_CONSTEXPR
  145. bool empty() const noexcept { return tree.empty(); }
  146. __GBLIBCPP_CONSTEXPR
  147. size_type size() const noexcept { return tree.size(); }
  148. __GBLIBCPP_CONSTEXPR
  149. void swap(set& other) { tree.swap(other.tree); }
  150. __GBLIBCPP_CONSTEXPR
  151. size_type count(const Key& key) const
  152. { return find(key) ? 1 : 0; }
  153. __GBLIBCPP_CONSTEXPR
  154. bool contains(const Key& key) const { return count(key) != 0; }
  155. __GBLIBCPP_CONSTEXPR
  156. iterator upper_bound(const Key& key)
  157. { return tree.upper_bound(key); }
  158. __GBLIBCPP_CONSTEXPR
  159. const_iterator upper_bound(const Key& key) const
  160. { return tree.upper_bound(key); }
  161. template <typename K>
  162. __GBLIBCPP_CONSTEXPR
  163. iterator upper_bound(const K& key)
  164. { return tree.upper_bound(key); }
  165. template <typename K>
  166. __GBLIBCPP_CONSTEXPR
  167. const_iterator upper_bound(const K& key) const
  168. { return tree.upper_bound(key); }
  169. __GBLIBCPP_CONSTEXPR
  170. iterator lower_bound(const Key& key)
  171. { return tree.lower_bound(key); }
  172. __GBLIBCPP_CONSTEXPR
  173. const_iterator lower_bound(const Key& key) const
  174. { return tree.lower_bound(key); }
  175. template <typename K>
  176. __GBLIBCPP_CONSTEXPR
  177. iterator lower_bound(const K& key)
  178. { return tree.lower_bound(key); }
  179. template <typename K>
  180. __GBLIBCPP_CONSTEXPR
  181. const_iterator lower_bound(const K& key) const
  182. { return tree.lower_bound(key); }
  183. };
  184. template <typename Key, typename Compare, typename Allocator>
  185. void swap(std::set<Key, Compare, Allocator>& lhs,
  186. std::set<Key, Compare, Allocator>& rhs)
  187. { lhs.swap(rhs); }
  188. template <typename Key, typename Compare,
  189. typename Allocator, typename Pred>
  190. typename std::set<Key, Compare, Allocator>::size_type
  191. erase_if(std::set<Key, Compare, Allocator>& set, Pred pred)
  192. {
  193. auto iter = set.begin();
  194. typename std::set<Key, Compare, Allocator>::size_type count = 0;
  195. while (iter != set.end()) {
  196. if (pred(*iter)) {
  197. iter = set.erase(iter);
  198. ++count;
  199. } else {
  200. ++iter;
  201. }
  202. }
  203. return count;
  204. }
  205. template <typename Key,
  206. typename Compare = std::less<Key>,
  207. typename Allocator = std::allocator<Key>>
  208. set(std::initializer_list<Key>, Compare = Compare(),
  209. Allocator = Allocator()) -> set<Key, Compare, Allocator>;
  210. template <typename Key, typename Allocator>
  211. set(std::initializer_list<Key>, Allocator)
  212. -> set<Key, std::less<Key>, Allocator>;
  213. } // namespace std
  214. #endif