map 7.8 KB

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