17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===-------------------------- hash_map ----------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_HASH_MAP
127a984708SDavid Chisnall#define _LIBCPP_HASH_MAP
137a984708SDavid Chisnall
147a984708SDavid Chisnall/*
157a984708SDavid Chisnall
167a984708SDavid Chisnall    hash_map synopsis
177a984708SDavid Chisnall
187a984708SDavid Chisnallnamespace __gnu_cxx
197a984708SDavid Chisnall{
207a984708SDavid Chisnall
217a984708SDavid Chisnalltemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
227a984708SDavid Chisnall          class Alloc = allocator<pair<const Key, T>>>
237a984708SDavid Chisnallclass hash_map
247a984708SDavid Chisnall{
257a984708SDavid Chisnallpublic:
267a984708SDavid Chisnall    // types
277a984708SDavid Chisnall    typedef Key                                                        key_type;
287a984708SDavid Chisnall    typedef T                                                          mapped_type;
297a984708SDavid Chisnall    typedef Hash                                                       hasher;
307a984708SDavid Chisnall    typedef Pred                                                       key_equal;
317a984708SDavid Chisnall    typedef Alloc                                                      allocator_type;
327a984708SDavid Chisnall    typedef pair<const key_type, mapped_type>                          value_type;
337a984708SDavid Chisnall    typedef value_type&                                                reference;
347a984708SDavid Chisnall    typedef const value_type&                                          const_reference;
357a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::pointer         pointer;
367a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
377a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::size_type       size_type;
387a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
397a984708SDavid Chisnall
407a984708SDavid Chisnall    typedef /unspecified/ iterator;
417a984708SDavid Chisnall    typedef /unspecified/ const_iterator;
427a984708SDavid Chisnall
437a984708SDavid Chisnall    explicit hash_map(size_type n = 193, const hasher& hf = hasher(),
447a984708SDavid Chisnall                           const key_equal& eql = key_equal(),
457a984708SDavid Chisnall                           const allocator_type& a = allocator_type());
467a984708SDavid Chisnall    template <class InputIterator>
477a984708SDavid Chisnall        hash_map(InputIterator f, InputIterator l,
487a984708SDavid Chisnall                      size_type n = 193, const hasher& hf = hasher(),
497a984708SDavid Chisnall                      const key_equal& eql = key_equal(),
507a984708SDavid Chisnall                      const allocator_type& a = allocator_type());
517a984708SDavid Chisnall    hash_map(const hash_map&);
527a984708SDavid Chisnall    ~hash_map();
537a984708SDavid Chisnall    hash_map& operator=(const hash_map&);
547a984708SDavid Chisnall
557a984708SDavid Chisnall    allocator_type get_allocator() const;
567a984708SDavid Chisnall
577a984708SDavid Chisnall    bool      empty() const;
587a984708SDavid Chisnall    size_type size() const;
597a984708SDavid Chisnall    size_type max_size() const;
607a984708SDavid Chisnall
617a984708SDavid Chisnall    iterator       begin();
627a984708SDavid Chisnall    iterator       end();
637a984708SDavid Chisnall    const_iterator begin()  const;
647a984708SDavid Chisnall    const_iterator end()    const;
657a984708SDavid Chisnall
667a984708SDavid Chisnall    pair<iterator, bool> insert(const value_type& obj);
677a984708SDavid Chisnall    template <class InputIterator>
687a984708SDavid Chisnall        void insert(InputIterator first, InputIterator last);
697a984708SDavid Chisnall
707a984708SDavid Chisnall    void erase(const_iterator position);
717a984708SDavid Chisnall    size_type erase(const key_type& k);
727a984708SDavid Chisnall    void erase(const_iterator first, const_iterator last);
737a984708SDavid Chisnall    void clear();
747a984708SDavid Chisnall
757a984708SDavid Chisnall    void swap(hash_map&);
767a984708SDavid Chisnall
777a984708SDavid Chisnall    hasher hash_funct() const;
787a984708SDavid Chisnall    key_equal key_eq() const;
797a984708SDavid Chisnall
807a984708SDavid Chisnall    iterator       find(const key_type& k);
817a984708SDavid Chisnall    const_iterator find(const key_type& k) const;
827a984708SDavid Chisnall    size_type count(const key_type& k) const;
837a984708SDavid Chisnall    pair<iterator, iterator>             equal_range(const key_type& k);
847a984708SDavid Chisnall    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
857a984708SDavid Chisnall
867a984708SDavid Chisnall    mapped_type& operator[](const key_type& k);
877a984708SDavid Chisnall
887a984708SDavid Chisnall    size_type bucket_count() const;
897a984708SDavid Chisnall    size_type max_bucket_count() const;
907a984708SDavid Chisnall
917a984708SDavid Chisnall    size_type elems_in_bucket(size_type n) const;
927a984708SDavid Chisnall
937a984708SDavid Chisnall    void resize(size_type n);
947a984708SDavid Chisnall};
957a984708SDavid Chisnall
967a984708SDavid Chisnalltemplate <class Key, class T, class Hash, class Pred, class Alloc>
977a984708SDavid Chisnall    void swap(hash_map<Key, T, Hash, Pred, Alloc>& x,
987a984708SDavid Chisnall              hash_map<Key, T, Hash, Pred, Alloc>& y);
997a984708SDavid Chisnall
1007a984708SDavid Chisnalltemplate <class Key, class T, class Hash, class Pred, class Alloc>
1017a984708SDavid Chisnall    bool
1027a984708SDavid Chisnall    operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x,
1037a984708SDavid Chisnall               const hash_map<Key, T, Hash, Pred, Alloc>& y);
1047a984708SDavid Chisnall
1057a984708SDavid Chisnalltemplate <class Key, class T, class Hash, class Pred, class Alloc>
1067a984708SDavid Chisnall    bool
1077a984708SDavid Chisnall    operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x,
1087a984708SDavid Chisnall               const hash_map<Key, T, Hash, Pred, Alloc>& y);
1097a984708SDavid Chisnall
1107a984708SDavid Chisnalltemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
1117a984708SDavid Chisnall          class Alloc = allocator<pair<const Key, T>>>
1127a984708SDavid Chisnallclass hash_multimap
1137a984708SDavid Chisnall{
1147a984708SDavid Chisnallpublic:
1157a984708SDavid Chisnall    // types
1167a984708SDavid Chisnall    typedef Key                                                        key_type;
1177a984708SDavid Chisnall    typedef T                                                          mapped_type;
1187a984708SDavid Chisnall    typedef Hash                                                       hasher;
1197a984708SDavid Chisnall    typedef Pred                                                       key_equal;
1207a984708SDavid Chisnall    typedef Alloc                                                      allocator_type;
1217a984708SDavid Chisnall    typedef pair<const key_type, mapped_type>                          value_type;
1227a984708SDavid Chisnall    typedef value_type&                                                reference;
1237a984708SDavid Chisnall    typedef const value_type&                                          const_reference;
1247a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::pointer         pointer;
1257a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
1267a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::size_type       size_type;
1277a984708SDavid Chisnall    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
1287a984708SDavid Chisnall
1297a984708SDavid Chisnall    typedef /unspecified/ iterator;
1307a984708SDavid Chisnall    typedef /unspecified/ const_iterator;
1317a984708SDavid Chisnall
1327a984708SDavid Chisnall    explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(),
1337a984708SDavid Chisnall                           const key_equal& eql = key_equal(),
1347a984708SDavid Chisnall                           const allocator_type& a = allocator_type());
1357a984708SDavid Chisnall    template <class InputIterator>
1367a984708SDavid Chisnall        hash_multimap(InputIterator f, InputIterator l,
1377a984708SDavid Chisnall                      size_type n = 193, const hasher& hf = hasher(),
1387a984708SDavid Chisnall                      const key_equal& eql = key_equal(),
1397a984708SDavid Chisnall                      const allocator_type& a = allocator_type());
1407a984708SDavid Chisnall    explicit hash_multimap(const allocator_type&);
1417a984708SDavid Chisnall    hash_multimap(const hash_multimap&);
1427a984708SDavid Chisnall    ~hash_multimap();
1437a984708SDavid Chisnall    hash_multimap& operator=(const hash_multimap&);
1447a984708SDavid Chisnall
1457a984708SDavid Chisnall    allocator_type get_allocator() const;
1467a984708SDavid Chisnall
1477a984708SDavid Chisnall    bool      empty() const;
1487a984708SDavid Chisnall    size_type size() const;
1497a984708SDavid Chisnall    size_type max_size() const;
1507a984708SDavid Chisnall
1517a984708SDavid Chisnall    iterator       begin();
1527a984708SDavid Chisnall    iterator       end();
1537a984708SDavid Chisnall    const_iterator begin()  const;
1547a984708SDavid Chisnall    const_iterator end()    const;
1557a984708SDavid Chisnall
1567a984708SDavid Chisnall    iterator insert(const value_type& obj);
1577a984708SDavid Chisnall    template <class InputIterator>
1587a984708SDavid Chisnall        void insert(InputIterator first, InputIterator last);
1597a984708SDavid Chisnall
1607a984708SDavid Chisnall    void erase(const_iterator position);
1617a984708SDavid Chisnall    size_type erase(const key_type& k);
1627a984708SDavid Chisnall    void erase(const_iterator first, const_iterator last);
1637a984708SDavid Chisnall    void clear();
1647a984708SDavid Chisnall
1657a984708SDavid Chisnall    void swap(hash_multimap&);
1667a984708SDavid Chisnall
1677a984708SDavid Chisnall    hasher hash_funct() const;
1687a984708SDavid Chisnall    key_equal key_eq() const;
1697a984708SDavid Chisnall
1707a984708SDavid Chisnall    iterator       find(const key_type& k);
1717a984708SDavid Chisnall    const_iterator find(const key_type& k) const;
1727a984708SDavid Chisnall    size_type count(const key_type& k) const;
1737a984708SDavid Chisnall    pair<iterator, iterator>             equal_range(const key_type& k);
1747a984708SDavid Chisnall    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
1757a984708SDavid Chisnall
1767a984708SDavid Chisnall    size_type bucket_count() const;
1777a984708SDavid Chisnall    size_type max_bucket_count() const;
1787a984708SDavid Chisnall
1797a984708SDavid Chisnall    size_type elems_in_bucket(size_type n) const;
1807a984708SDavid Chisnall
1817a984708SDavid Chisnall    void resize(size_type n);
1827a984708SDavid Chisnall};
1837a984708SDavid Chisnall
1847a984708SDavid Chisnalltemplate <class Key, class T, class Hash, class Pred, class Alloc>
1857a984708SDavid Chisnall    void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x,
1867a984708SDavid Chisnall              hash_multimap<Key, T, Hash, Pred, Alloc>& y);
1877a984708SDavid Chisnall
1887a984708SDavid Chisnalltemplate <class Key, class T, class Hash, class Pred, class Alloc>
1897a984708SDavid Chisnall    bool
1907a984708SDavid Chisnall    operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
1917a984708SDavid Chisnall               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
1927a984708SDavid Chisnall
1937a984708SDavid Chisnalltemplate <class Key, class T, class Hash, class Pred, class Alloc>
1947a984708SDavid Chisnall    bool
1957a984708SDavid Chisnall    operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
1967a984708SDavid Chisnall               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
1977a984708SDavid Chisnall
1987a984708SDavid Chisnall}  // __gnu_cxx
1997a984708SDavid Chisnall
2007a984708SDavid Chisnall*/
2017a984708SDavid Chisnall
2027a984708SDavid Chisnall#include <__config>
2037a984708SDavid Chisnall#include <__hash_table>
2047a984708SDavid Chisnall#include <functional>
2057a984708SDavid Chisnall#include <stdexcept>
206854fa44bSDimitry Andric#include <type_traits>
2077a984708SDavid Chisnall#include <ext/__hash>
2087a984708SDavid Chisnall
2097a984708SDavid Chisnall#if __DEPRECATED
210*5517e702SDimitry Andric#if defined(_LIBCPP_WARNING)
2114f7ab58eSDimitry Andric    _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>")
2124f7ab58eSDimitry Andric#else
2137a984708SDavid Chisnall#   warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
2147a984708SDavid Chisnall#endif
2154f7ab58eSDimitry Andric#endif
2167a984708SDavid Chisnall
217854fa44bSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2187a984708SDavid Chisnall#pragma GCC system_header
219854fa44bSDimitry Andric#endif
2207a984708SDavid Chisnall
2217a984708SDavid Chisnallnamespace __gnu_cxx {
2227a984708SDavid Chisnall
2237a984708SDavid Chisnallusing namespace std;
2247a984708SDavid Chisnall
225854fa44bSDimitry Andrictemplate <class _Tp, class _Hash,
226854fa44bSDimitry Andric          bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value
22794e3ee44SDavid Chisnall        >
2287a984708SDavid Chisnallclass __hash_map_hasher
2297a984708SDavid Chisnall    : private _Hash
2307a984708SDavid Chisnall{
2317a984708SDavid Chisnallpublic:
2327a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {}
2337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
2347a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;}
2357a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2367a984708SDavid Chisnall    size_t operator()(const _Tp& __x) const
2377a984708SDavid Chisnall        {return static_cast<const _Hash&>(*this)(__x.first);}
2387a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2397a984708SDavid Chisnall    size_t operator()(const typename _Tp::first_type& __x) const
2407a984708SDavid Chisnall        {return static_cast<const _Hash&>(*this)(__x);}
2417a984708SDavid Chisnall};
2427a984708SDavid Chisnall
2437a984708SDavid Chisnalltemplate <class _Tp, class _Hash>
2447a984708SDavid Chisnallclass __hash_map_hasher<_Tp, _Hash, false>
2457a984708SDavid Chisnall{
2467a984708SDavid Chisnall    _Hash __hash_;
2477a984708SDavid Chisnallpublic:
2487a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {}
2497a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}
2507a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;}
2517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2527a984708SDavid Chisnall    size_t operator()(const _Tp& __x) const
2537a984708SDavid Chisnall        {return __hash_(__x.first);}
2547a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2557a984708SDavid Chisnall    size_t operator()(const typename _Tp::first_type& __x) const
2567a984708SDavid Chisnall        {return __hash_(__x);}
2577a984708SDavid Chisnall};
2587a984708SDavid Chisnall
259854fa44bSDimitry Andrictemplate <class _Tp, class _Pred,
260854fa44bSDimitry Andric          bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
26194e3ee44SDavid Chisnall         >
2627a984708SDavid Chisnallclass __hash_map_equal
2637a984708SDavid Chisnall    : private _Pred
2647a984708SDavid Chisnall{
2657a984708SDavid Chisnallpublic:
2667a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {}
2677a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
2687a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;}
2697a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2707a984708SDavid Chisnall    bool operator()(const _Tp& __x, const _Tp& __y) const
2717a984708SDavid Chisnall        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
2727a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2737a984708SDavid Chisnall    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
2747a984708SDavid Chisnall        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
2757a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2767a984708SDavid Chisnall    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
2777a984708SDavid Chisnall        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
2787a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2797a984708SDavid Chisnall    bool operator()(const typename _Tp::first_type& __x,
2807a984708SDavid Chisnall                    const typename _Tp::first_type& __y) const
2817a984708SDavid Chisnall        {return static_cast<const _Pred&>(*this)(__x, __y);}
2827a984708SDavid Chisnall};
2837a984708SDavid Chisnall
2847a984708SDavid Chisnalltemplate <class _Tp, class _Pred>
2857a984708SDavid Chisnallclass __hash_map_equal<_Tp, _Pred, false>
2867a984708SDavid Chisnall{
2877a984708SDavid Chisnall    _Pred __pred_;
2887a984708SDavid Chisnallpublic:
2897a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {}
2907a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {}
2917a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;}
2927a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2937a984708SDavid Chisnall    bool operator()(const _Tp& __x, const _Tp& __y) const
2947a984708SDavid Chisnall        {return __pred_(__x.first, __y.first);}
2957a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2967a984708SDavid Chisnall    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
2977a984708SDavid Chisnall        {return __pred_(__x, __y.first);}
2987a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
2997a984708SDavid Chisnall    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
3007a984708SDavid Chisnall        {return __pred_(__x.first, __y);}
3017a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3027a984708SDavid Chisnall    bool operator()(const typename _Tp::first_type& __x,
3037a984708SDavid Chisnall                    const typename _Tp::first_type& __y) const
3047a984708SDavid Chisnall        {return __pred_(__x, __y);}
3057a984708SDavid Chisnall};
3067a984708SDavid Chisnall
3077a984708SDavid Chisnalltemplate <class _Alloc>
3087a984708SDavid Chisnallclass __hash_map_node_destructor
3097a984708SDavid Chisnall{
3107a984708SDavid Chisnall    typedef _Alloc                              allocator_type;
3117a984708SDavid Chisnall    typedef allocator_traits<allocator_type>    __alloc_traits;
3127c82a1ecSDimitry Andric    typedef typename __alloc_traits::value_type::__node_value_type value_type;
3137a984708SDavid Chisnallpublic:
3147a984708SDavid Chisnall    typedef typename __alloc_traits::pointer    pointer;
3157a984708SDavid Chisnallprivate:
3167a984708SDavid Chisnall    typedef typename value_type::first_type     first_type;
3177a984708SDavid Chisnall    typedef typename value_type::second_type    second_type;
3187a984708SDavid Chisnall
3197a984708SDavid Chisnall    allocator_type& __na_;
3207a984708SDavid Chisnall
3217a984708SDavid Chisnall    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);
3227a984708SDavid Chisnall
3237a984708SDavid Chisnallpublic:
3247a984708SDavid Chisnall    bool __first_constructed;
3257a984708SDavid Chisnall    bool __second_constructed;
3267a984708SDavid Chisnall
3277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3287a984708SDavid Chisnall    explicit __hash_map_node_destructor(allocator_type& __na)
3297a984708SDavid Chisnall        : __na_(__na),
3307a984708SDavid Chisnall          __first_constructed(false),
3317a984708SDavid Chisnall          __second_constructed(false)
3327a984708SDavid Chisnall        {}
3337a984708SDavid Chisnall
334540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
3357a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3367a984708SDavid Chisnall    __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)
3377a984708SDavid Chisnall        : __na_(__x.__na_),
3387a984708SDavid Chisnall          __first_constructed(__x.__value_constructed),
3397a984708SDavid Chisnall          __second_constructed(__x.__value_constructed)
3407a984708SDavid Chisnall        {
3417a984708SDavid Chisnall            __x.__value_constructed = false;
3427a984708SDavid Chisnall        }
343540d2a8bSDimitry Andric#else  // _LIBCPP_CXX03_LANG
3447a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3457a984708SDavid Chisnall    __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)
3467a984708SDavid Chisnall        : __na_(__x.__na_),
3477a984708SDavid Chisnall          __first_constructed(__x.__value_constructed),
3487a984708SDavid Chisnall          __second_constructed(__x.__value_constructed)
3497a984708SDavid Chisnall        {
3507a984708SDavid Chisnall            const_cast<bool&>(__x.__value_constructed) = false;
3517a984708SDavid Chisnall        }
352540d2a8bSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
3537a984708SDavid Chisnall
3547a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3557a984708SDavid Chisnall    void operator()(pointer __p)
3567a984708SDavid Chisnall    {
3577a984708SDavid Chisnall        if (__second_constructed)
3587a984708SDavid Chisnall            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
3597a984708SDavid Chisnall        if (__first_constructed)
3607a984708SDavid Chisnall            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
3617a984708SDavid Chisnall        if (__p)
3627a984708SDavid Chisnall            __alloc_traits::deallocate(__na_, __p, 1);
3637a984708SDavid Chisnall    }
3647a984708SDavid Chisnall};
3657a984708SDavid Chisnall
3667a984708SDavid Chisnalltemplate <class _HashIterator>
367aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_iterator
3687a984708SDavid Chisnall{
3697a984708SDavid Chisnall    _HashIterator __i_;
3707a984708SDavid Chisnall
3717a984708SDavid Chisnall    typedef const typename _HashIterator::value_type::first_type key_type;
3727a984708SDavid Chisnall    typedef typename _HashIterator::value_type::second_type      mapped_type;
3737a984708SDavid Chisnallpublic:
3747a984708SDavid Chisnall    typedef forward_iterator_tag                                 iterator_category;
3757a984708SDavid Chisnall    typedef pair<key_type, mapped_type>                          value_type;
3767a984708SDavid Chisnall    typedef typename _HashIterator::difference_type              difference_type;
3777a984708SDavid Chisnall    typedef value_type&                                          reference;
3789729cf09SDimitry Andric    typedef typename __rebind_pointer<typename _HashIterator::pointer, value_type>::type
3797a984708SDavid Chisnall        pointer;
3807a984708SDavid Chisnall
3817a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}
3827a984708SDavid Chisnall
3837a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
3847a984708SDavid Chisnall
3857a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();}
3867a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();}
3877a984708SDavid Chisnall
3887a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;}
3897a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3907a984708SDavid Chisnall    __hash_map_iterator operator++(int)
3917a984708SDavid Chisnall    {
3927a984708SDavid Chisnall        __hash_map_iterator __t(*this);
3937a984708SDavid Chisnall        ++(*this);
3947a984708SDavid Chisnall        return __t;
3957a984708SDavid Chisnall    }
3967a984708SDavid Chisnall
3977a984708SDavid Chisnall    friend _LIBCPP_INLINE_VISIBILITY
3987a984708SDavid Chisnall    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
3997a984708SDavid Chisnall        {return __x.__i_ == __y.__i_;}
4007a984708SDavid Chisnall    friend _LIBCPP_INLINE_VISIBILITY
4017a984708SDavid Chisnall    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
4027a984708SDavid Chisnall        {return __x.__i_ != __y.__i_;}
4037a984708SDavid Chisnall
404aed8d94eSDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
405aed8d94eSDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
406aed8d94eSDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
407aed8d94eSDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
408aed8d94eSDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator;
4097a984708SDavid Chisnall};
4107a984708SDavid Chisnall
4117a984708SDavid Chisnalltemplate <class _HashIterator>
412aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator
4137a984708SDavid Chisnall{
4147a984708SDavid Chisnall    _HashIterator __i_;
4157a984708SDavid Chisnall
4167a984708SDavid Chisnall    typedef const typename _HashIterator::value_type::first_type key_type;
4177a984708SDavid Chisnall    typedef typename _HashIterator::value_type::second_type      mapped_type;
4187a984708SDavid Chisnallpublic:
4197a984708SDavid Chisnall    typedef forward_iterator_tag                                 iterator_category;
4207a984708SDavid Chisnall    typedef pair<key_type, mapped_type>                          value_type;
4217a984708SDavid Chisnall    typedef typename _HashIterator::difference_type              difference_type;
4227a984708SDavid Chisnall    typedef const value_type&                                    reference;
4239729cf09SDimitry Andric    typedef typename __rebind_pointer<typename _HashIterator::pointer, const value_type>::type
4247a984708SDavid Chisnall        pointer;
4257a984708SDavid Chisnall
4267a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}
4277a984708SDavid Chisnall
4287a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4297a984708SDavid Chisnall    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
4307a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4317a984708SDavid Chisnall    __hash_map_const_iterator(
4327a984708SDavid Chisnall            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
4337a984708SDavid Chisnall                : __i_(__i.__i_) {}
4347a984708SDavid Chisnall
4357a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4367a984708SDavid Chisnall    reference operator*() const {return *operator->();}
4377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4387a984708SDavid Chisnall    pointer operator->() const {return (pointer)__i_.operator->();}
4397a984708SDavid Chisnall
4407a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4417a984708SDavid Chisnall    __hash_map_const_iterator& operator++() {++__i_; return *this;}
4427a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
4437a984708SDavid Chisnall    __hash_map_const_iterator operator++(int)
4447a984708SDavid Chisnall    {
4457a984708SDavid Chisnall        __hash_map_const_iterator __t(*this);
4467a984708SDavid Chisnall        ++(*this);
4477a984708SDavid Chisnall        return __t;
4487a984708SDavid Chisnall    }
4497a984708SDavid Chisnall
4507a984708SDavid Chisnall    friend _LIBCPP_INLINE_VISIBILITY
4517a984708SDavid Chisnall    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
4527a984708SDavid Chisnall        {return __x.__i_ == __y.__i_;}
4537a984708SDavid Chisnall    friend _LIBCPP_INLINE_VISIBILITY
4547a984708SDavid Chisnall    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
4557a984708SDavid Chisnall        {return __x.__i_ != __y.__i_;}
4567a984708SDavid Chisnall
457aed8d94eSDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_map;
458aed8d94eSDimitry Andric    template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS hash_multimap;
459aed8d94eSDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator;
460aed8d94eSDimitry Andric    template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator;
4617a984708SDavid Chisnall};
4627a984708SDavid Chisnall
4637a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
4647a984708SDavid Chisnall          class _Alloc = allocator<pair<const _Key, _Tp> > >
465aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_map
4667a984708SDavid Chisnall{
4677a984708SDavid Chisnallpublic:
4687a984708SDavid Chisnall    // types
4697a984708SDavid Chisnall    typedef _Key                                           key_type;
4707a984708SDavid Chisnall    typedef _Tp                                            mapped_type;
4717a984708SDavid Chisnall    typedef _Tp                                            data_type;
4727a984708SDavid Chisnall    typedef _Hash                                          hasher;
4737a984708SDavid Chisnall    typedef _Pred                                          key_equal;
4747a984708SDavid Chisnall    typedef _Alloc                                         allocator_type;
4757a984708SDavid Chisnall    typedef pair<const key_type, mapped_type>              value_type;
4767a984708SDavid Chisnall    typedef value_type&                                    reference;
4777a984708SDavid Chisnall    typedef const value_type&                              const_reference;
4787a984708SDavid Chisnall
4797a984708SDavid Chisnallprivate:
4807a984708SDavid Chisnall    typedef pair<key_type, mapped_type>                    __value_type;
4817a984708SDavid Chisnall    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
4827a984708SDavid Chisnall    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
483854fa44bSDimitry Andric    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __value_type>::type __allocator_type;
4847a984708SDavid Chisnall
4857a984708SDavid Chisnall    typedef __hash_table<__value_type, __hasher,
4867a984708SDavid Chisnall                         __key_equal,  __allocator_type>   __table;
4877a984708SDavid Chisnall
4887a984708SDavid Chisnall    __table __table_;
4897a984708SDavid Chisnall
4907a984708SDavid Chisnall    typedef typename __table::__node_pointer               __node_pointer;
4917a984708SDavid Chisnall    typedef typename __table::__node_const_pointer         __node_const_pointer;
4927a984708SDavid Chisnall    typedef typename __table::__node_traits                __node_traits;
4937a984708SDavid Chisnall    typedef typename __table::__node_allocator             __node_allocator;
4947a984708SDavid Chisnall    typedef typename __table::__node                       __node;
49594e3ee44SDavid Chisnall    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
49694e3ee44SDavid Chisnall    typedef unique_ptr<__node, _Dp>                         __node_holder;
4977a984708SDavid Chisnall    typedef allocator_traits<allocator_type>               __alloc_traits;
4987a984708SDavid Chisnallpublic:
4997a984708SDavid Chisnall    typedef typename __alloc_traits::pointer         pointer;
5007a984708SDavid Chisnall    typedef typename __alloc_traits::const_pointer   const_pointer;
5017a984708SDavid Chisnall    typedef typename __alloc_traits::size_type       size_type;
5027a984708SDavid Chisnall    typedef typename __alloc_traits::difference_type difference_type;
5037a984708SDavid Chisnall
5047a984708SDavid Chisnall    typedef __hash_map_iterator<typename __table::iterator>       iterator;
5057a984708SDavid Chisnall    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
5067a984708SDavid Chisnall
5077a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);}
5087a984708SDavid Chisnall    explicit hash_map(size_type __n, const hasher& __hf = hasher(),
5097a984708SDavid Chisnall                           const key_equal& __eql = key_equal());
5107a984708SDavid Chisnall    hash_map(size_type __n, const hasher& __hf,
5117a984708SDavid Chisnall                  const key_equal& __eql,
5127a984708SDavid Chisnall                  const allocator_type& __a);
5137a984708SDavid Chisnall    template <class _InputIterator>
5147a984708SDavid Chisnall        hash_map(_InputIterator __first, _InputIterator __last);
5157a984708SDavid Chisnall    template <class _InputIterator>
5167a984708SDavid Chisnall        hash_map(_InputIterator __first, _InputIterator __last,
5177a984708SDavid Chisnall                      size_type __n, const hasher& __hf = hasher(),
5187a984708SDavid Chisnall                      const key_equal& __eql = key_equal());
5197a984708SDavid Chisnall    template <class _InputIterator>
5207a984708SDavid Chisnall        hash_map(_InputIterator __first, _InputIterator __last,
5217a984708SDavid Chisnall                      size_type __n, const hasher& __hf,
5227a984708SDavid Chisnall                      const key_equal& __eql,
5237a984708SDavid Chisnall                      const allocator_type& __a);
5247a984708SDavid Chisnall    hash_map(const hash_map& __u);
5257a984708SDavid Chisnall
5267a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5277a984708SDavid Chisnall    allocator_type get_allocator() const
5287a984708SDavid Chisnall        {return allocator_type(__table_.__node_alloc());}
5297a984708SDavid Chisnall
5307a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5317a984708SDavid Chisnall    bool      empty() const {return __table_.size() == 0;}
5327a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5337a984708SDavid Chisnall    size_type size() const  {return __table_.size();}
5347a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5357a984708SDavid Chisnall    size_type max_size() const {return __table_.max_size();}
5367a984708SDavid Chisnall
5377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5387a984708SDavid Chisnall    iterator       begin()        {return __table_.begin();}
5397a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5407a984708SDavid Chisnall    iterator       end()          {return __table_.end();}
5417a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5427a984708SDavid Chisnall    const_iterator begin()  const {return __table_.begin();}
5437a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5447a984708SDavid Chisnall    const_iterator end()    const {return __table_.end();}
5457a984708SDavid Chisnall
5467a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5477a984708SDavid Chisnall    pair<iterator, bool> insert(const value_type& __x)
5487a984708SDavid Chisnall        {return __table_.__insert_unique(__x);}
5497a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5507a984708SDavid Chisnall    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
5517a984708SDavid Chisnall    template <class _InputIterator>
5527c82a1ecSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
5537a984708SDavid Chisnall        void insert(_InputIterator __first, _InputIterator __last);
5547a984708SDavid Chisnall
5557a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5567a984708SDavid Chisnall    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
5577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5587a984708SDavid Chisnall    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
5597a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5607a984708SDavid Chisnall    void erase(const_iterator __first, const_iterator __last)
5617a984708SDavid Chisnall        {__table_.erase(__first.__i_, __last.__i_);}
5627a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5637a984708SDavid Chisnall    void clear() {__table_.clear();}
5647a984708SDavid Chisnall
5657a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5667a984708SDavid Chisnall    void swap(hash_map& __u) {__table_.swap(__u.__table_);}
5677a984708SDavid Chisnall
5687a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5697a984708SDavid Chisnall    hasher hash_funct() const
5707a984708SDavid Chisnall        {return __table_.hash_function().hash_function();}
5717a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5727a984708SDavid Chisnall    key_equal key_eq() const
5737a984708SDavid Chisnall        {return __table_.key_eq().key_eq();}
5747a984708SDavid Chisnall
5757a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5767a984708SDavid Chisnall    iterator       find(const key_type& __k)       {return __table_.find(__k);}
5777a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5787a984708SDavid Chisnall    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
5797a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5807a984708SDavid Chisnall    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
5817a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5827a984708SDavid Chisnall    pair<iterator, iterator>             equal_range(const key_type& __k)
5837a984708SDavid Chisnall        {return __table_.__equal_range_unique(__k);}
5847a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5857a984708SDavid Chisnall    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
5867a984708SDavid Chisnall        {return __table_.__equal_range_unique(__k);}
5877a984708SDavid Chisnall
5887a984708SDavid Chisnall    mapped_type& operator[](const key_type& __k);
5897a984708SDavid Chisnall
5907a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5917a984708SDavid Chisnall    size_type bucket_count() const {return __table_.bucket_count();}
5927a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5937a984708SDavid Chisnall    size_type max_bucket_count() const {return __table_.max_bucket_count();}
5947a984708SDavid Chisnall
5957a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5967a984708SDavid Chisnall    size_type elems_in_bucket(size_type __n) const
5977a984708SDavid Chisnall        {return __table_.bucket_size(__n);}
5987a984708SDavid Chisnall
5997a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
6007a984708SDavid Chisnall    void resize(size_type __n) {__table_.rehash(__n);}
6017a984708SDavid Chisnall
6027a984708SDavid Chisnallprivate:
6037a984708SDavid Chisnall    __node_holder __construct_node(const key_type& __k);
6047a984708SDavid Chisnall};
6057a984708SDavid Chisnall
6067a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6077a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6087a984708SDavid Chisnall        size_type __n, const hasher& __hf, const key_equal& __eql)
6097a984708SDavid Chisnall    : __table_(__hf, __eql)
6107a984708SDavid Chisnall{
6117a984708SDavid Chisnall    __table_.rehash(__n);
6127a984708SDavid Chisnall}
6137a984708SDavid Chisnall
6147a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6157a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6167a984708SDavid Chisnall        size_type __n, const hasher& __hf, const key_equal& __eql,
6177a984708SDavid Chisnall        const allocator_type& __a)
6187a984708SDavid Chisnall    : __table_(__hf, __eql, __a)
6197a984708SDavid Chisnall{
6207a984708SDavid Chisnall    __table_.rehash(__n);
6217a984708SDavid Chisnall}
6227a984708SDavid Chisnall
6237a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6247a984708SDavid Chisnalltemplate <class _InputIterator>
6257a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6267a984708SDavid Chisnall        _InputIterator __first, _InputIterator __last)
6277a984708SDavid Chisnall{
6287a984708SDavid Chisnall    __table_.rehash(193);
6297a984708SDavid Chisnall    insert(__first, __last);
6307a984708SDavid Chisnall}
6317a984708SDavid Chisnall
6327a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6337a984708SDavid Chisnalltemplate <class _InputIterator>
6347a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6357a984708SDavid Chisnall        _InputIterator __first, _InputIterator __last, size_type __n,
6367a984708SDavid Chisnall        const hasher& __hf, const key_equal& __eql)
6377a984708SDavid Chisnall    : __table_(__hf, __eql)
6387a984708SDavid Chisnall{
6397a984708SDavid Chisnall    __table_.rehash(__n);
6407a984708SDavid Chisnall    insert(__first, __last);
6417a984708SDavid Chisnall}
6427a984708SDavid Chisnall
6437a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6447a984708SDavid Chisnalltemplate <class _InputIterator>
6457a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6467a984708SDavid Chisnall        _InputIterator __first, _InputIterator __last, size_type __n,
6477a984708SDavid Chisnall        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
6487a984708SDavid Chisnall    : __table_(__hf, __eql, __a)
6497a984708SDavid Chisnall{
6507a984708SDavid Chisnall    __table_.rehash(__n);
6517a984708SDavid Chisnall    insert(__first, __last);
6527a984708SDavid Chisnall}
6537a984708SDavid Chisnall
6547a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6557a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
6567a984708SDavid Chisnall        const hash_map& __u)
6577a984708SDavid Chisnall    : __table_(__u.__table_)
6587a984708SDavid Chisnall{
6597a984708SDavid Chisnall    __table_.rehash(__u.bucket_count());
6607a984708SDavid Chisnall    insert(__u.begin(), __u.end());
6617a984708SDavid Chisnall}
6627a984708SDavid Chisnall
6637a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6647a984708SDavid Chisnalltypename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
6657a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
6667a984708SDavid Chisnall{
6677a984708SDavid Chisnall    __node_allocator& __na = __table_.__node_alloc();
66894e3ee44SDavid Chisnall    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
6697a984708SDavid Chisnall    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
6707a984708SDavid Chisnall    __h.get_deleter().__first_constructed = true;
6717a984708SDavid Chisnall    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
6727a984708SDavid Chisnall    __h.get_deleter().__second_constructed = true;
6739729cf09SDimitry Andric    return _LIBCPP_EXPLICIT_MOVE(__h);  // explicitly moved for C++03
6747a984708SDavid Chisnall}
6757a984708SDavid Chisnall
6767a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6777a984708SDavid Chisnalltemplate <class _InputIterator>
6787c82a1ecSDimitry Andricinline
6797a984708SDavid Chisnallvoid
6807a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
6817a984708SDavid Chisnall                                                       _InputIterator __last)
6827a984708SDavid Chisnall{
6837a984708SDavid Chisnall    for (; __first != __last; ++__first)
6847a984708SDavid Chisnall        __table_.__insert_unique(*__first);
6857a984708SDavid Chisnall}
6867a984708SDavid Chisnall
6877a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
6887a984708SDavid Chisnall_Tp&
6897a984708SDavid Chisnallhash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
6907a984708SDavid Chisnall{
6917a984708SDavid Chisnall    iterator __i = find(__k);
6927a984708SDavid Chisnall    if (__i != end())
6937a984708SDavid Chisnall        return __i->second;
6947a984708SDavid Chisnall    __node_holder __h = __construct_node(__k);
6957a984708SDavid Chisnall    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
6967a984708SDavid Chisnall    __h.release();
6977a984708SDavid Chisnall    return __r.first->second;
6987a984708SDavid Chisnall}
6997a984708SDavid Chisnall
7007a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
7017a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
7027a984708SDavid Chisnallvoid
7037a984708SDavid Chisnallswap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
7047a984708SDavid Chisnall     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
7057a984708SDavid Chisnall{
7067a984708SDavid Chisnall    __x.swap(__y);
7077a984708SDavid Chisnall}
7087a984708SDavid Chisnall
7097a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
7107a984708SDavid Chisnallbool
7117a984708SDavid Chisnalloperator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
7127a984708SDavid Chisnall           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
7137a984708SDavid Chisnall{
7147a984708SDavid Chisnall    if (__x.size() != __y.size())
7157a984708SDavid Chisnall        return false;
7167a984708SDavid Chisnall    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
7177a984708SDavid Chisnall                                                                 const_iterator;
7187a984708SDavid Chisnall    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
7197a984708SDavid Chisnall            __i != __ex; ++__i)
7207a984708SDavid Chisnall    {
7217a984708SDavid Chisnall        const_iterator __j = __y.find(__i->first);
7227a984708SDavid Chisnall        if (__j == __ey || !(*__i == *__j))
7237a984708SDavid Chisnall            return false;
7247a984708SDavid Chisnall    }
7257a984708SDavid Chisnall    return true;
7267a984708SDavid Chisnall}
7277a984708SDavid Chisnall
7287a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
7297a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
7307a984708SDavid Chisnallbool
7317a984708SDavid Chisnalloperator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
7327a984708SDavid Chisnall           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
7337a984708SDavid Chisnall{
7347a984708SDavid Chisnall    return !(__x == __y);
7357a984708SDavid Chisnall}
7367a984708SDavid Chisnall
7377a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
7387a984708SDavid Chisnall          class _Alloc = allocator<pair<const _Key, _Tp> > >
739aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_multimap
7407a984708SDavid Chisnall{
7417a984708SDavid Chisnallpublic:
7427a984708SDavid Chisnall    // types
7437a984708SDavid Chisnall    typedef _Key                                           key_type;
7447a984708SDavid Chisnall    typedef _Tp                                            mapped_type;
7457a984708SDavid Chisnall    typedef _Tp                                            data_type;
7467a984708SDavid Chisnall    typedef _Hash                                          hasher;
7477a984708SDavid Chisnall    typedef _Pred                                          key_equal;
7487a984708SDavid Chisnall    typedef _Alloc                                         allocator_type;
7497a984708SDavid Chisnall    typedef pair<const key_type, mapped_type>              value_type;
7507a984708SDavid Chisnall    typedef value_type&                                    reference;
7517a984708SDavid Chisnall    typedef const value_type&                              const_reference;
7527a984708SDavid Chisnall
7537a984708SDavid Chisnallprivate:
7547a984708SDavid Chisnall    typedef pair<key_type, mapped_type>                    __value_type;
7557a984708SDavid Chisnall    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
7567a984708SDavid Chisnall    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
757854fa44bSDimitry Andric    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __value_type>::type __allocator_type;
7587a984708SDavid Chisnall
7597a984708SDavid Chisnall    typedef __hash_table<__value_type, __hasher,
7607a984708SDavid Chisnall                         __key_equal,  __allocator_type>   __table;
7617a984708SDavid Chisnall
7627a984708SDavid Chisnall    __table __table_;
7637a984708SDavid Chisnall
7647a984708SDavid Chisnall    typedef typename __table::__node_traits                __node_traits;
7657a984708SDavid Chisnall    typedef typename __table::__node_allocator             __node_allocator;
7667a984708SDavid Chisnall    typedef typename __table::__node                       __node;
76794e3ee44SDavid Chisnall    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
76894e3ee44SDavid Chisnall    typedef unique_ptr<__node, _Dp>                         __node_holder;
7697a984708SDavid Chisnall    typedef allocator_traits<allocator_type>               __alloc_traits;
7707a984708SDavid Chisnallpublic:
7717a984708SDavid Chisnall    typedef typename __alloc_traits::pointer         pointer;
7727a984708SDavid Chisnall    typedef typename __alloc_traits::const_pointer   const_pointer;
7737a984708SDavid Chisnall    typedef typename __alloc_traits::size_type       size_type;
7747a984708SDavid Chisnall    typedef typename __alloc_traits::difference_type difference_type;
7757a984708SDavid Chisnall
7767a984708SDavid Chisnall    typedef __hash_map_iterator<typename __table::iterator>       iterator;
7777a984708SDavid Chisnall    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
7787a984708SDavid Chisnall
7797a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
7807a984708SDavid Chisnall    hash_multimap() {__table_.rehash(193);}
7817a984708SDavid Chisnall    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
7827a984708SDavid Chisnall                                const key_equal& __eql = key_equal());
7837a984708SDavid Chisnall    hash_multimap(size_type __n, const hasher& __hf,
7847a984708SDavid Chisnall                                const key_equal& __eql,
7857a984708SDavid Chisnall                                const allocator_type& __a);
7867a984708SDavid Chisnall    template <class _InputIterator>
7877a984708SDavid Chisnall        hash_multimap(_InputIterator __first, _InputIterator __last);
7887a984708SDavid Chisnall    template <class _InputIterator>
7897a984708SDavid Chisnall        hash_multimap(_InputIterator __first, _InputIterator __last,
7907a984708SDavid Chisnall                      size_type __n, const hasher& __hf = hasher(),
7917a984708SDavid Chisnall                      const key_equal& __eql = key_equal());
7927a984708SDavid Chisnall    template <class _InputIterator>
7937a984708SDavid Chisnall        hash_multimap(_InputIterator __first, _InputIterator __last,
7947a984708SDavid Chisnall                      size_type __n, const hasher& __hf,
7957a984708SDavid Chisnall                      const key_equal& __eql,
7967a984708SDavid Chisnall                      const allocator_type& __a);
7977a984708SDavid Chisnall    hash_multimap(const hash_multimap& __u);
7987a984708SDavid Chisnall
7997a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8007a984708SDavid Chisnall    allocator_type get_allocator() const
8017a984708SDavid Chisnall        {return allocator_type(__table_.__node_alloc());}
8027a984708SDavid Chisnall
8037a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8047a984708SDavid Chisnall    bool      empty() const {return __table_.size() == 0;}
8057a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8067a984708SDavid Chisnall    size_type size() const  {return __table_.size();}
8077a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8087a984708SDavid Chisnall    size_type max_size() const {return __table_.max_size();}
8097a984708SDavid Chisnall
8107a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8117a984708SDavid Chisnall    iterator       begin()        {return __table_.begin();}
8127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8137a984708SDavid Chisnall    iterator       end()          {return __table_.end();}
8147a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8157a984708SDavid Chisnall    const_iterator begin()  const {return __table_.begin();}
8167a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8177a984708SDavid Chisnall    const_iterator end()    const {return __table_.end();}
8187a984708SDavid Chisnall
8197a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8207a984708SDavid Chisnall    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
8217a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8227a984708SDavid Chisnall    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
8237a984708SDavid Chisnall    template <class _InputIterator>
8247c82a1ecSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
8257a984708SDavid Chisnall        void insert(_InputIterator __first, _InputIterator __last);
8267a984708SDavid Chisnall
8277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8287a984708SDavid Chisnall    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
8297a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8307a984708SDavid Chisnall    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
8317a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8327a984708SDavid Chisnall    void erase(const_iterator __first, const_iterator __last)
8337a984708SDavid Chisnall        {__table_.erase(__first.__i_, __last.__i_);}
8347a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8357a984708SDavid Chisnall    void clear() {__table_.clear();}
8367a984708SDavid Chisnall
8377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8387a984708SDavid Chisnall    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}
8397a984708SDavid Chisnall
8407a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8417a984708SDavid Chisnall    hasher hash_funct() const
8427a984708SDavid Chisnall        {return __table_.hash_function().hash_function();}
8437a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8447a984708SDavid Chisnall    key_equal key_eq() const
8457a984708SDavid Chisnall        {return __table_.key_eq().key_eq();}
8467a984708SDavid Chisnall
8477a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8487a984708SDavid Chisnall    iterator       find(const key_type& __k)       {return __table_.find(__k);}
8497a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8507a984708SDavid Chisnall    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
8517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8527a984708SDavid Chisnall    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
8537a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8547a984708SDavid Chisnall    pair<iterator, iterator>             equal_range(const key_type& __k)
8557a984708SDavid Chisnall        {return __table_.__equal_range_multi(__k);}
8567a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8577a984708SDavid Chisnall    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
8587a984708SDavid Chisnall        {return __table_.__equal_range_multi(__k);}
8597a984708SDavid Chisnall
8607a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8617a984708SDavid Chisnall    size_type bucket_count() const {return __table_.bucket_count();}
8627a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8637a984708SDavid Chisnall    size_type max_bucket_count() const {return __table_.max_bucket_count();}
8647a984708SDavid Chisnall
8657a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8667a984708SDavid Chisnall    size_type elems_in_bucket(size_type __n) const
8677a984708SDavid Chisnall        {return __table_.bucket_size(__n);}
8687a984708SDavid Chisnall
8697a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
8707a984708SDavid Chisnall    void resize(size_type __n) {__table_.rehash(__n);}
8717a984708SDavid Chisnall};
8727a984708SDavid Chisnall
8737a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8747a984708SDavid Chisnallhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
8757a984708SDavid Chisnall        size_type __n, const hasher& __hf, const key_equal& __eql)
8767a984708SDavid Chisnall    : __table_(__hf, __eql)
8777a984708SDavid Chisnall{
8787a984708SDavid Chisnall    __table_.rehash(__n);
8797a984708SDavid Chisnall}
8807a984708SDavid Chisnall
8817a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8827a984708SDavid Chisnallhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
8837a984708SDavid Chisnall        size_type __n, const hasher& __hf, const key_equal& __eql,
8847a984708SDavid Chisnall        const allocator_type& __a)
8857a984708SDavid Chisnall    : __table_(__hf, __eql, __a)
8867a984708SDavid Chisnall{
8877a984708SDavid Chisnall    __table_.rehash(__n);
8887a984708SDavid Chisnall}
8897a984708SDavid Chisnall
8907a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
8917a984708SDavid Chisnalltemplate <class _InputIterator>
8927a984708SDavid Chisnallhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
8937a984708SDavid Chisnall        _InputIterator __first, _InputIterator __last)
8947a984708SDavid Chisnall{
8957a984708SDavid Chisnall    __table_.rehash(193);
8967a984708SDavid Chisnall    insert(__first, __last);
8977a984708SDavid Chisnall}
8987a984708SDavid Chisnall
8997a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9007a984708SDavid Chisnalltemplate <class _InputIterator>
9017a984708SDavid Chisnallhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
9027a984708SDavid Chisnall        _InputIterator __first, _InputIterator __last, size_type __n,
9037a984708SDavid Chisnall        const hasher& __hf, const key_equal& __eql)
9047a984708SDavid Chisnall    : __table_(__hf, __eql)
9057a984708SDavid Chisnall{
9067a984708SDavid Chisnall    __table_.rehash(__n);
9077a984708SDavid Chisnall    insert(__first, __last);
9087a984708SDavid Chisnall}
9097a984708SDavid Chisnall
9107a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9117a984708SDavid Chisnalltemplate <class _InputIterator>
9127a984708SDavid Chisnallhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
9137a984708SDavid Chisnall        _InputIterator __first, _InputIterator __last, size_type __n,
9147a984708SDavid Chisnall        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
9157a984708SDavid Chisnall    : __table_(__hf, __eql, __a)
9167a984708SDavid Chisnall{
9177a984708SDavid Chisnall    __table_.rehash(__n);
9187a984708SDavid Chisnall    insert(__first, __last);
9197a984708SDavid Chisnall}
9207a984708SDavid Chisnall
9217a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9227a984708SDavid Chisnallhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
9237a984708SDavid Chisnall        const hash_multimap& __u)
9247a984708SDavid Chisnall    : __table_(__u.__table_)
9257a984708SDavid Chisnall{
9267a984708SDavid Chisnall    __table_.rehash(__u.bucket_count());
9277a984708SDavid Chisnall    insert(__u.begin(), __u.end());
9287a984708SDavid Chisnall}
9297a984708SDavid Chisnall
9307a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9317a984708SDavid Chisnalltemplate <class _InputIterator>
9327c82a1ecSDimitry Andricinline
9337a984708SDavid Chisnallvoid
9347a984708SDavid Chisnallhash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
9357a984708SDavid Chisnall                                                            _InputIterator __last)
9367a984708SDavid Chisnall{
9377a984708SDavid Chisnall    for (; __first != __last; ++__first)
9387a984708SDavid Chisnall        __table_.__insert_multi(*__first);
9397a984708SDavid Chisnall}
9407a984708SDavid Chisnall
9417a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9427a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
9437a984708SDavid Chisnallvoid
9447a984708SDavid Chisnallswap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
9457a984708SDavid Chisnall     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
9467a984708SDavid Chisnall{
9477a984708SDavid Chisnall    __x.swap(__y);
9487a984708SDavid Chisnall}
9497a984708SDavid Chisnall
9507a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9517a984708SDavid Chisnallbool
9527a984708SDavid Chisnalloperator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
9537a984708SDavid Chisnall           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
9547a984708SDavid Chisnall{
9557a984708SDavid Chisnall    if (__x.size() != __y.size())
9567a984708SDavid Chisnall        return false;
9577a984708SDavid Chisnall    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
9587a984708SDavid Chisnall                                                                 const_iterator;
9597a984708SDavid Chisnall    typedef pair<const_iterator, const_iterator> _EqRng;
9607a984708SDavid Chisnall    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
9617a984708SDavid Chisnall    {
9627a984708SDavid Chisnall        _EqRng __xeq = __x.equal_range(__i->first);
9637a984708SDavid Chisnall        _EqRng __yeq = __y.equal_range(__i->first);
9647a984708SDavid Chisnall        if (_VSTD::distance(__xeq.first, __xeq.second) !=
9657a984708SDavid Chisnall            _VSTD::distance(__yeq.first, __yeq.second) ||
9667a984708SDavid Chisnall                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
9677a984708SDavid Chisnall            return false;
9687a984708SDavid Chisnall        __i = __xeq.second;
9697a984708SDavid Chisnall    }
9707a984708SDavid Chisnall    return true;
9717a984708SDavid Chisnall}
9727a984708SDavid Chisnall
9737a984708SDavid Chisnalltemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
9747a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
9757a984708SDavid Chisnallbool
9767a984708SDavid Chisnalloperator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
9777a984708SDavid Chisnall           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
9787a984708SDavid Chisnall{
9797a984708SDavid Chisnall    return !(__x == __y);
9807a984708SDavid Chisnall}
9817a984708SDavid Chisnall
9827a984708SDavid Chisnall} // __gnu_cxx
9837a984708SDavid Chisnall
9847a984708SDavid Chisnall#endif  // _LIBCPP_HASH_MAP
985