| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | 
							- #ifndef __GBLIBCPP_MAP__
 
- #define __GBLIBCPP_MAP__
 
- #include <bits/iter_ops>
 
- #include <bits/rbtree>
 
- #include <functional>
 
- #include <memory>
 
- #include <initializer_list>
 
- #include <tuple>
 
- #include <type_traits>
 
- #include <utility>
 
- #include <cstddef>
 
- namespace std {
 
- template <typename Key, typename T,
 
-     typename Compare = std::less<Key>,
 
-     typename Allocator = std::allocator<std::pair<const Key, T>>>
 
- class map {
 
- public:
 
-     using key_type = Key;
 
-     using mapped_type = T;
 
-     using value_type = std::pair<const Key, T>;
 
-     using size_type = std::size_t;
 
-     using allocator_type = Allocator;
 
- private:
 
-     class value_compare : public Compare {
 
-     protected:
 
-         constexpr value_compare(Compare c): Compare{c} {}
 
-         friend class map;
 
-     public:
 
-         constexpr bool operator()(
 
-             const value_type& lhs, const value_type& rhs) const
 
-         { return Compare::operator()(lhs.first, rhs.first); }
 
-         constexpr bool operator()(
 
-             const Key& lhs, const value_type& rhs) const
 
-         { return Compare::operator()(lhs, rhs.first); }
 
-         constexpr bool operator()(
 
-             const value_type& lhs, const Key& rhs) const
 
-         { return Compare::operator()(lhs.first, rhs); }
 
-     };
 
-     using rbtree_type = impl::rbtree<value_type, value_compare, Allocator>;
 
-     using node_allocator = typename rbtree_type::node_allocator;
 
- private:
 
-     rbtree_type tree;
 
- public:
 
-     using iterator = typename rbtree_type::iterator;
 
-     using const_iterator = typename rbtree_type::const_iterator;
 
- public:
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator end(void) noexcept { return tree.end(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     const_iterator end(void) const noexcept { return tree.cend(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     const_iterator cend(void) const noexcept { return tree.cend(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator begin(void) noexcept { return tree.begin(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     const_iterator begin(void) const noexcept { return tree.cbegin(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     const_iterator cbegin(void) const noexcept { return tree.cbegin(); }
 
-     explicit __GBLIBCPP_CONSTEXPR
 
-     map(const Compare& comp,
 
-         const Allocator& alloc = Allocator())
 
-         : tree(comp, alloc) {}
 
-     explicit __GBLIBCPP_CONSTEXPR
 
-     map(const Allocator& alloc)
 
-         : map(Compare(), alloc) {}
 
-     __GBLIBCPP_CONSTEXPR
 
-     map() : map(Compare()) {}
 
-     template <typename InputIter>
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(InputIter first, InputIter last,
 
-         const Compare& comp = Compare(),
 
-         const Allocator& alloc = Allocator())
 
-         : map(comp, alloc)
 
-     {
 
-         insert(first, last);
 
-     }
 
-     template <typename InputIter>
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(InputIter first, InputIter last,
 
-         const Allocator& alloc = Allocator())
 
-         : map(first, last, Compare(), alloc) {}
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(const map& other) : tree(other.tree) {}
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(const map& other, const Allocator& alloc)
 
-         : tree(other.tree, alloc) { }
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(map&& other) : tree(std::move(other.tree)) {}
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(map&& other, const Allocator& alloc)
 
-         : tree(std::move(other.tree), alloc) {}
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(std::initializer_list<value_type> init,
 
-         const Compare& comp = Compare(),
 
-         const Allocator& alloc = Allocator())
 
-         : map(comp, alloc)
 
-     { insert(init.begin(), init.end()); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     map(std::initializer_list<value_type> init,
 
-         const Allocator& alloc)
 
-         : map(init, Compare(), alloc) {}
 
-     __GBLIBCPP_CONSTEXPR
 
-     ~map() { clear(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     map& operator=(const map& other) = default;
 
-     __GBLIBCPP_CONSTEXPR
 
-     map& operator=(map&& other) = default;
 
-     __GBLIBCPP_CONSTEXPR
 
-     map& operator=(std::initializer_list<value_type> ilist)
 
-     {
 
-         clear();
 
-         insert(ilist.begin(), ilist.end());
 
-         return *this;
 
-     }
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator find(const Key& key) { return tree.find(key); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     const_iterator find(const Key& key) const { return tree.find(key); }
 
-     // if the container does not have an element with
 
-     // the specified key, it should throw an exception
 
-     // TODO: exceptions
 
-     __GBLIBCPP_CONSTEXPR
 
-     T& at(const Key& key) { return find(key)->second; }
 
-     // if the container does not have an element with
 
-     // the specified key, it should throw an exception
 
-     // TODO: exceptions
 
-     __GBLIBCPP_CONSTEXPR
 
-     const T& at(const Key& key) const { return find(key)->second; }
 
-     __GBLIBCPP_CONSTEXPR
 
-     std::pair<iterator, bool> insert(const value_type& value)
 
-     { return tree.insert(value); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     std::pair<iterator, bool> insert(value_type&& value)
 
-     { return tree.insert(std::move(value)); }
 
-     template <typename Pair>
 
-     __GBLIBCPP_CONSTEXPR
 
-     std::enable_if_t<std::is_constructible_v<value_type, Pair&&>,
 
-         std::pair<iterator, bool>> insert(Pair&& p)
 
-     { return emplace(std::forward<Pair>(p)); }
 
-     template <typename InputIter>
 
-     __GBLIBCPP_CONSTEXPR
 
-     void insert(InputIter first, InputIter last)
 
-     {
 
-         for ( ; first != last; ++first)
 
-             insert(*first);
 
-     }
 
-     template <typename... Args>
 
-     __GBLIBCPP_CONSTEXPR
 
-     std::pair<iterator, bool> emplace(Args&&... args)
 
-     { return tree.emplace(std::forward<Args>(args)...); }
 
-     template <typename... Args>
 
-     __GBLIBCPP_CONSTEXPR
 
-     std::pair<iterator, bool> try_emplace(const Key& key, Args&&... args)
 
-     {
 
-         auto iter = find(key);
 
-         if (iter)
 
-             return { iter, false };
 
-         return emplace(
 
-             std::piecewise_construct,
 
-             std::forward_as_tuple(key),
 
-             std::forward_as_tuple(std::forward<Args>(args)...));
 
-     }
 
-     template <typename... Args>
 
-     __GBLIBCPP_CONSTEXPR
 
-     std::pair<iterator, bool> try_emplace(Key&& key, Args&&... args)
 
-     {
 
-         auto iter = find(key);
 
-         if (iter)
 
-             return { iter, false };
 
-         return emplace(
 
-             std::piecewise_construct,
 
-             std::forward_as_tuple(std::move(key)),
 
-             std::forward_as_tuple(std::forward<Args>(args)...));
 
-     }
 
-     __GBLIBCPP_CONSTEXPR
 
-     T& operator[](const Key& key)
 
-     { return try_emplace(key).first->second; }
 
-     __GBLIBCPP_CONSTEXPR
 
-     T& operator[](Key&& key)
 
-     { return try_emplace(std::move(key)).first->second; }
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator erase(iterator pos) noexcept { return tree.erase(pos); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator erase(const_iterator pos) noexcept { return tree.erase(pos); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator erase(const_iterator first, const_iterator last) noexcept
 
-     {
 
-         while (first != last)
 
-             first = erase(first);
 
-         return first;
 
-     }
 
-     __GBLIBCPP_CONSTEXPR
 
-     size_type erase(const Key& key)
 
-     {
 
-         auto iter = find(key);
 
-         if (!iter)
 
-             return 0;
 
-         erase(iter);
 
-         return 1;
 
-     }
 
-     __GBLIBCPP_CONSTEXPR
 
-     void clear() noexcept { tree.destroy(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     bool empty() const noexcept { return tree.empty(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     size_type size() const noexcept { return tree.size(); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     void swap(map& other) { tree.swap(other.tree); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     size_type count(const Key& key) const
 
-     { return find(key) ? 1 : 0; }
 
-     __GBLIBCPP_CONSTEXPR
 
-     bool contains(const Key& key) const { return count(key) != 0; }
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator upper_bound(const Key& key)
 
-     { return tree.upper_bound(key); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     const_iterator upper_bound(const Key& key) const
 
-     { return tree.upper_bound(key); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     iterator lower_bound(const Key& key)
 
-     { return tree.lower_bound(key); }
 
-     __GBLIBCPP_CONSTEXPR
 
-     const_iterator lower_bound(const Key& key) const
 
-     { return tree.lower_bound(key); }
 
- };
 
- template <typename Key, typename T, typename Compare, typename Allocator>
 
- void swap(std::map<Key, T, Compare, Allocator>& lhs,
 
-     std::map<Key, T, Compare, Allocator>& rhs)
 
- { lhs.swap(rhs); }
 
- template <typename Key, typename T,
 
-     typename Compare, typename Allocator, typename Pred>
 
- typename std::map<Key, T, Compare, Allocator>::size_type
 
- erase_if(std::map<Key, T, Compare, Allocator>& c, Pred pred)
 
- {
 
-     auto iter = c.begin();
 
-     typename std::map<Key, T, Compare, Allocator>::size_type count = 0;
 
-     while (iter != c.end()) {
 
-         if (pred(*iter)) {
 
-             iter = c.erase(iter);
 
-             ++count;
 
-         } else
 
-             ++iter;
 
-     }
 
-     return count;
 
- }
 
- template <typename Key, typename T,
 
-     typename Compare = std::less<Key>,
 
-     typename Allocator = std::allocator<std::pair<const Key, T>>>
 
- map(std::initializer_list<std::pair<Key, T>>,
 
-     Compare = Compare(), Allocator = Allocator())
 
-     -> map<Key, T, Compare, Allocator>;
 
- template <typename Key, typename T, typename Allocator>
 
- map(std::initializer_list<std::pair<Key, T>>, Allocator)
 
-     -> map<Key, T, std::less<Key>, Allocator>;
 
- } // namespace std
 
- #endif
 
 
  |