map 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #ifndef __GBLIBCPP_MAP__
  2. #define __GBLIBCPP_MAP__
  3. #include <bits/rbtree>
  4. #include <functional>
  5. #include <memory>
  6. #include <utility>
  7. #include <cstddef>
  8. namespace std {
  9. template <typename Key, typename T,
  10. typename Compare = std::less<Key>,
  11. typename Allocator = std::allocator<std::pair<const Key, T>>>
  12. class map {
  13. public:
  14. using key_type = Key;
  15. using mapped_type = T;
  16. using value_type = std::pair<const Key, T>;
  17. using size_type = std::size_t;
  18. using allocator_type = Allocator;
  19. private:
  20. class value_compare {
  21. protected:
  22. Compare comp;
  23. constexpr value_compare(Compare c) : comp(c) {}
  24. friend class map;
  25. public:
  26. constexpr bool operator()(
  27. const value_type& lhs, const value_type& rhs) const
  28. { return comp(lhs.first, rhs.first); }
  29. constexpr bool operator()(
  30. const Key& lhs, const value_type& rhs) const
  31. { return comp(lhs, rhs.first); }
  32. constexpr bool operator()(
  33. const value_type& lhs, const Key& rhs) const
  34. { return comp(lhs.first, rhs); }
  35. };
  36. using rbtree_type = impl::rbtree<value_type, value_compare, Allocator>;
  37. using node_allocator = typename rbtree_type::node_allocator;
  38. private:
  39. rbtree_type tree;
  40. public:
  41. using iterator = typename rbtree_type::iterator;
  42. using const_iterator = typename rbtree_type::const_iterator;
  43. public:
  44. __GBLIBCPP_CONSTEXPR
  45. iterator end(void) noexcept { return tree.end(); }
  46. __GBLIBCPP_CONSTEXPR
  47. const_iterator end(void) const noexcept { return tree.cend(); }
  48. __GBLIBCPP_CONSTEXPR
  49. const_iterator cend(void) const noexcept { return tree.cend(); }
  50. __GBLIBCPP_CONSTEXPR
  51. iterator begin(void) noexcept { return tree.begin(); }
  52. __GBLIBCPP_CONSTEXPR
  53. const_iterator begin(void) const noexcept { return tree.cbegin(); }
  54. __GBLIBCPP_CONSTEXPR
  55. const_iterator cbegin(void) const noexcept { return tree.cbegin(); }
  56. explicit __GBLIBCPP_CONSTEXPR
  57. map(const Compare& comp,
  58. const Allocator& alloc = Allocator())
  59. : tree(comp, alloc) {}
  60. explicit __GBLIBCPP_CONSTEXPR
  61. map(const Allocator& alloc)
  62. : map(Compare(), alloc) {}
  63. __GBLIBCPP_CONSTEXPR
  64. map() : map(Compare()) {}
  65. template <typename InputIter>
  66. __GBLIBCPP_CONSTEXPR
  67. map(InputIter first, InputIter last,
  68. const Compare& comp = Compare(),
  69. const Allocator& alloc = Allocator())
  70. : map(comp, alloc)
  71. {
  72. insert(first, last);
  73. }
  74. template <typename InputIter>
  75. __GBLIBCPP_CONSTEXPR
  76. map(InputIter first, InputIter last,
  77. const Allocator& alloc = Allocator())
  78. : map(first, last, Compare(), alloc) {}
  79. __GBLIBCPP_CONSTEXPR
  80. map(const map& other) : tree(other) {}
  81. __GBLIBCPP_CONSTEXPR
  82. map(const map& other, const Allocator& alloc)
  83. : tree(other, alloc) { }
  84. __GBLIBCPP_CONSTEXPR
  85. map(map&& other) : tree(std::move(other.tree)) {}
  86. __GBLIBCPP_CONSTEXPR
  87. map(map&& other, const Allocator& alloc)
  88. : tree(std::move(other.tree), alloc) {}
  89. __GBLIBCPP_CONSTEXPR
  90. ~map() { clear(); }
  91. __GBLIBCPP_CONSTEXPR
  92. map& operator=(const map& other) = default;
  93. __GBLIBCPP_CONSTEXPR
  94. map& operator=(map&& other) = default;
  95. // TODO: std::initializer_list
  96. // set(std::initializer_list<Key> init,
  97. // const Compare& comp = Compare(),
  98. // const Allocator& alloc = Allocator());
  99. //
  100. // set(std::initializer_list<Key> init,
  101. // const Allocator& alloc = Allocator())
  102. // : set(init, Compare(), alloc) {}
  103. //
  104. // set& operator=(std::initializer_list<Key> ilist);
  105. __GBLIBCPP_CONSTEXPR
  106. iterator find(const Key& key) { return tree.find(key); }
  107. __GBLIBCPP_CONSTEXPR
  108. const_iterator find(const Key& key) const { return tree.find(key); }
  109. __GBLIBCPP_CONSTEXPR
  110. std::pair<iterator, bool> insert(const value_type& value)
  111. { return tree.insert(value); }
  112. __GBLIBCPP_CONSTEXPR
  113. std::pair<iterator, bool> insert(value_type&& value)
  114. { return tree.insert(std::move(value)); }
  115. template <typename InputIter>
  116. __GBLIBCPP_CONSTEXPR
  117. void insert(InputIter first, InputIter last)
  118. {
  119. for ( ; first != last; ++first)
  120. insert(*first);
  121. }
  122. template <typename... Args>
  123. std::pair<iterator, bool> emplace(Args&&... args)
  124. { return tree.emplace(std::forward<Args>(args)...); }
  125. __GBLIBCPP_CONSTEXPR
  126. iterator erase(iterator pos) noexcept { return tree.erase(pos); }
  127. __GBLIBCPP_CONSTEXPR
  128. iterator erase(const_iterator pos) noexcept { return tree.erase(pos); }
  129. __GBLIBCPP_CONSTEXPR
  130. iterator erase(const_iterator first, const_iterator last) noexcept
  131. {
  132. while (first != last)
  133. first = erase(first);
  134. return first;
  135. }
  136. __GBLIBCPP_CONSTEXPR
  137. size_type erase(const Key& key)
  138. {
  139. auto iter = find(key);
  140. if (!iter)
  141. return 0;
  142. erase(iter);
  143. return 1;
  144. }
  145. __GBLIBCPP_CONSTEXPR
  146. void clear() noexcept { tree.destroy(); }
  147. __GBLIBCPP_CONSTEXPR
  148. bool empty() const noexcept { return tree.empty(); }
  149. __GBLIBCPP_CONSTEXPR
  150. size_type size() const noexcept { return tree.size(); }
  151. __GBLIBCPP_CONSTEXPR
  152. void swap(map& other) { tree.swap(other.tree); }
  153. __GBLIBCPP_CONSTEXPR
  154. size_type count(const Key& key) const
  155. { return find(key) ? 1 : 0; }
  156. __GBLIBCPP_CONSTEXPR
  157. bool contains(const Key& key) const { return count(key) != 0; }
  158. };
  159. template <typename Key, typename T, typename Compare, typename Allocator>
  160. void swap(std::map<Key, T, Compare, Allocator>& lhs,
  161. std::map<Key, T, Compare, Allocator>& rhs)
  162. { lhs.swap(rhs); }
  163. } // namespace std
  164. #endif