// -*- C++ -*-
//===-------------------------- hash_map ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_HASH_MAP
#define _LIBCPP_HASH_MAP

/*

    hash_map synopsis

namespace __gnu_cxx
{

template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
          class Alloc = allocator<pair<const Key, T>>>
class hash_map
{
public:
    // types
    typedef Key                                                        key_type;
    typedef T                                                          mapped_type;
    typedef Hash                                                       hasher;
    typedef Pred                                                       key_equal;
    typedef Alloc                                                      allocator_type;
    typedef pair<const key_type, mapped_type>                          value_type;
    typedef value_type&                                                reference;
    typedef const value_type&                                          const_reference;
    typedef typename allocator_traits<allocator_type>::pointer         pointer;
    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
    typedef typename allocator_traits<allocator_type>::size_type       size_type;
    typedef typename allocator_traits<allocator_type>::difference_type difference_type;

    typedef /unspecified/ iterator;
    typedef /unspecified/ const_iterator;

    explicit hash_map(size_type n = 193, const hasher& hf = hasher(),
                           const key_equal& eql = key_equal(),
                           const allocator_type& a = allocator_type());
    template <class InputIterator>
        hash_map(InputIterator f, InputIterator l,
                      size_type n = 193, const hasher& hf = hasher(),
                      const key_equal& eql = key_equal(),
                      const allocator_type& a = allocator_type());
    hash_map(const hash_map&);
    ~hash_map();
    hash_map& operator=(const hash_map&);

    allocator_type get_allocator() const;

    bool      empty() const;
    size_type size() const;
    size_type max_size() const;

    iterator       begin();
    iterator       end();
    const_iterator begin()  const;
    const_iterator end()    const;

    pair<iterator, bool> insert(const value_type& obj);
    template <class InputIterator>
        void insert(InputIterator first, InputIterator last);

    void erase(const_iterator position);
    size_type erase(const key_type& k);
    void erase(const_iterator first, const_iterator last);
    void clear();

    void swap(hash_map&);

    hasher hash_funct() const;
    key_equal key_eq() const;

    iterator       find(const key_type& k);
    const_iterator find(const key_type& k) const;
    size_type count(const key_type& k) const;
    pair<iterator, iterator>             equal_range(const key_type& k);
    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;

    mapped_type& operator[](const key_type& k);

    size_type bucket_count() const;
    size_type max_bucket_count() const;

    size_type elems_in_bucket(size_type n) const;

    void resize(size_type n);
};

template <class Key, class T, class Hash, class Pred, class Alloc>
    void swap(hash_map<Key, T, Hash, Pred, Alloc>& x,
              hash_map<Key, T, Hash, Pred, Alloc>& y);

template <class Key, class T, class Hash, class Pred, class Alloc>
    bool
    operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x,
               const hash_map<Key, T, Hash, Pred, Alloc>& y);

template <class Key, class T, class Hash, class Pred, class Alloc>
    bool
    operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x,
               const hash_map<Key, T, Hash, Pred, Alloc>& y);

template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
          class Alloc = allocator<pair<const Key, T>>>
class hash_multimap
{
public:
    // types
    typedef Key                                                        key_type;
    typedef T                                                          mapped_type;
    typedef Hash                                                       hasher;
    typedef Pred                                                       key_equal;
    typedef Alloc                                                      allocator_type;
    typedef pair<const key_type, mapped_type>                          value_type;
    typedef value_type&                                                reference;
    typedef const value_type&                                          const_reference;
    typedef typename allocator_traits<allocator_type>::pointer         pointer;
    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
    typedef typename allocator_traits<allocator_type>::size_type       size_type;
    typedef typename allocator_traits<allocator_type>::difference_type difference_type;

    typedef /unspecified/ iterator;
    typedef /unspecified/ const_iterator;

    explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(),
                           const key_equal& eql = key_equal(),
                           const allocator_type& a = allocator_type());
    template <class InputIterator>
        hash_multimap(InputIterator f, InputIterator l,
                      size_type n = 193, const hasher& hf = hasher(),
                      const key_equal& eql = key_equal(),
                      const allocator_type& a = allocator_type());
    explicit hash_multimap(const allocator_type&);
    hash_multimap(const hash_multimap&);
    ~hash_multimap();
    hash_multimap& operator=(const hash_multimap&);

    allocator_type get_allocator() const;

    bool      empty() const;
    size_type size() const;
    size_type max_size() const;

    iterator       begin();
    iterator       end();
    const_iterator begin()  const;
    const_iterator end()    const;

    iterator insert(const value_type& obj);
    template <class InputIterator>
        void insert(InputIterator first, InputIterator last);

    void erase(const_iterator position);
    size_type erase(const key_type& k);
    void erase(const_iterator first, const_iterator last);
    void clear();

    void swap(hash_multimap&);

    hasher hash_funct() const;
    key_equal key_eq() const;

    iterator       find(const key_type& k);
    const_iterator find(const key_type& k) const;
    size_type count(const key_type& k) const;
    pair<iterator, iterator>             equal_range(const key_type& k);
    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;

    size_type bucket_count() const;
    size_type max_bucket_count() const;

    size_type elems_in_bucket(size_type n) const;

    void resize(size_type n);
};

template <class Key, class T, class Hash, class Pred, class Alloc>
    void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x,
              hash_multimap<Key, T, Hash, Pred, Alloc>& y);

template <class Key, class T, class Hash, class Pred, class Alloc>
    bool
    operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);

template <class Key, class T, class Hash, class Pred, class Alloc>
    bool
    operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);

}  // __gnu_cxx

*/

#include <__config>
#include <__hash_table>
#include <functional>
#include <stdexcept>
#include <ext/__hash>

#if __DEPRECATED
#warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
#endif

#pragma GCC system_header

namespace __gnu_cxx {

using namespace std;

template <class _Tp, class _Hash, bool = is_empty<_Hash>::value
#if __has_feature(is_final)
                                         && !__is_final(_Hash)
#endif
        >
class __hash_map_hasher
    : private _Hash
{
public:
    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {}
    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;}
    _LIBCPP_INLINE_VISIBILITY
    size_t operator()(const _Tp& __x) const
        {return static_cast<const _Hash&>(*this)(__x.first);}
    _LIBCPP_INLINE_VISIBILITY
    size_t operator()(const typename _Tp::first_type& __x) const
        {return static_cast<const _Hash&>(*this)(__x);}
};

template <class _Tp, class _Hash>
class __hash_map_hasher<_Tp, _Hash, false>
{
    _Hash __hash_;
public:
    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {}
    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}
    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;}
    _LIBCPP_INLINE_VISIBILITY
    size_t operator()(const _Tp& __x) const
        {return __hash_(__x.first);}
    _LIBCPP_INLINE_VISIBILITY
    size_t operator()(const typename _Tp::first_type& __x) const
        {return __hash_(__x);}
};

template <class _Tp, class _Pred, bool = is_empty<_Pred>::value
#if __has_feature(is_final)
                                         && !__is_final(_Pred)
#endif
         >
class __hash_map_equal
    : private _Pred
{
public:
    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {}
    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _Tp& __x, const _Tp& __y) const
        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const typename _Tp::first_type& __x,
                    const typename _Tp::first_type& __y) const
        {return static_cast<const _Pred&>(*this)(__x, __y);}
};

template <class _Tp, class _Pred>
class __hash_map_equal<_Tp, _Pred, false>
{
    _Pred __pred_;
public:
    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {}
    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {}
    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _Tp& __x, const _Tp& __y) const
        {return __pred_(__x.first, __y.first);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
        {return __pred_(__x, __y.first);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
        {return __pred_(__x.first, __y);}
    _LIBCPP_INLINE_VISIBILITY
    bool operator()(const typename _Tp::first_type& __x,
                    const typename _Tp::first_type& __y) const
        {return __pred_(__x, __y);}
};

template <class _Alloc>
class __hash_map_node_destructor
{
    typedef _Alloc                              allocator_type;
    typedef allocator_traits<allocator_type>    __alloc_traits;
    typedef typename __alloc_traits::value_type::value_type value_type;
public:
    typedef typename __alloc_traits::pointer    pointer;
private:
    typedef typename value_type::first_type     first_type;
    typedef typename value_type::second_type    second_type;

    allocator_type& __na_;

    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);

public:
    bool __first_constructed;
    bool __second_constructed;

    _LIBCPP_INLINE_VISIBILITY
    explicit __hash_map_node_destructor(allocator_type& __na)
        : __na_(__na),
          __first_constructed(false),
          __second_constructed(false)
        {}

#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    _LIBCPP_INLINE_VISIBILITY
    __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)
        : __na_(__x.__na_),
          __first_constructed(__x.__value_constructed),
          __second_constructed(__x.__value_constructed)
        {
            __x.__value_constructed = false;
        }
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    _LIBCPP_INLINE_VISIBILITY
    __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)
        : __na_(__x.__na_),
          __first_constructed(__x.__value_constructed),
          __second_constructed(__x.__value_constructed)
        {
            const_cast<bool&>(__x.__value_constructed) = false;
        }
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES

    _LIBCPP_INLINE_VISIBILITY
    void operator()(pointer __p)
    {
        if (__second_constructed)
            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
        if (__first_constructed)
            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
        if (__p)
            __alloc_traits::deallocate(__na_, __p, 1);
    }
};

template <class _HashIterator>
class _LIBCPP_VISIBLE __hash_map_iterator
{
    _HashIterator __i_;

    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
    typedef const typename _HashIterator::value_type::first_type key_type;
    typedef typename _HashIterator::value_type::second_type      mapped_type;
public:
    typedef forward_iterator_tag                                 iterator_category;
    typedef pair<key_type, mapped_type>                          value_type;
    typedef typename _HashIterator::difference_type              difference_type;
    typedef value_type&                                          reference;
    typedef typename __pointer_traits::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
            rebind<value_type>
#else
            rebind<value_type>::other
#endif
                                                                 pointer;

    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}

    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {}

    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();}
    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();}

    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;}
    _LIBCPP_INLINE_VISIBILITY
    __hash_map_iterator operator++(int)
    {
        __hash_map_iterator __t(*this);
        ++(*this);
        return __t;
    }

    friend _LIBCPP_INLINE_VISIBILITY 
    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
        {return __x.__i_ == __y.__i_;}
    friend _LIBCPP_INLINE_VISIBILITY 
    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
        {return __x.__i_ != __y.__i_;}

    template <class, class, class, class, class> friend class _LIBCPP_VISIBLE hash_map;
    template <class, class, class, class, class> friend class _LIBCPP_VISIBLE hash_multimap;
    template <class> friend class _LIBCPP_VISIBLE __hash_const_iterator;
    template <class> friend class _LIBCPP_VISIBLE __hash_const_local_iterator;
    template <class> friend class _LIBCPP_VISIBLE __hash_map_const_iterator;
};

template <class _HashIterator>
class _LIBCPP_VISIBLE __hash_map_const_iterator
{
    _HashIterator __i_;

    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
    typedef const typename _HashIterator::value_type::first_type key_type;
    typedef typename _HashIterator::value_type::second_type      mapped_type;
public:
    typedef forward_iterator_tag                                 iterator_category;
    typedef pair<key_type, mapped_type>                          value_type;
    typedef typename _HashIterator::difference_type              difference_type;
    typedef const value_type&                                    reference;
    typedef typename __pointer_traits::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
            rebind<value_type>
#else
            rebind<value_type>::other
#endif
                                                                 pointer;

    _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}

    _LIBCPP_INLINE_VISIBILITY
    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
    _LIBCPP_INLINE_VISIBILITY
    __hash_map_const_iterator(
            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
                : __i_(__i.__i_) {}

    _LIBCPP_INLINE_VISIBILITY
    reference operator*() const {return *operator->();}
    _LIBCPP_INLINE_VISIBILITY
    pointer operator->() const {return (pointer)__i_.operator->();}

    _LIBCPP_INLINE_VISIBILITY
    __hash_map_const_iterator& operator++() {++__i_; return *this;}
    _LIBCPP_INLINE_VISIBILITY
    __hash_map_const_iterator operator++(int)
    {
        __hash_map_const_iterator __t(*this);
        ++(*this);
        return __t;
    }

    friend _LIBCPP_INLINE_VISIBILITY
    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
        {return __x.__i_ == __y.__i_;}
    friend _LIBCPP_INLINE_VISIBILITY
    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
        {return __x.__i_ != __y.__i_;}

    template <class, class, class, class, class> friend class _LIBCPP_VISIBLE hash_map;
    template <class, class, class, class, class> friend class _LIBCPP_VISIBLE hash_multimap;
    template <class> friend class _LIBCPP_VISIBLE __hash_const_iterator;
    template <class> friend class _LIBCPP_VISIBLE __hash_const_local_iterator;
};

template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
          class _Alloc = allocator<pair<const _Key, _Tp> > >
class _LIBCPP_VISIBLE hash_map
{
public:
    // types
    typedef _Key                                           key_type;
    typedef _Tp                                            mapped_type;
    typedef _Tp                                            data_type;
    typedef _Hash                                          hasher;
    typedef _Pred                                          key_equal;
    typedef _Alloc                                         allocator_type;
    typedef pair<const key_type, mapped_type>              value_type;
    typedef value_type&                                    reference;
    typedef const value_type&                              const_reference;

private:
    typedef pair<key_type, mapped_type>                    __value_type;
    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
    typedef typename allocator_traits<allocator_type>::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
            rebind_alloc<__value_type>
#else
            rebind_alloc<__value_type>::other
#endif
                                                           __allocator_type;

    typedef __hash_table<__value_type, __hasher,
                         __key_equal,  __allocator_type>   __table;

    __table __table_;

    typedef typename __table::__node_pointer               __node_pointer;
    typedef typename __table::__node_const_pointer         __node_const_pointer;
    typedef typename __table::__node_traits                __node_traits;
    typedef typename __table::__node_allocator             __node_allocator;
    typedef typename __table::__node                       __node;
    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
    typedef unique_ptr<__node, _Dp>                         __node_holder;
    typedef allocator_traits<allocator_type>               __alloc_traits;
public:
    typedef typename __alloc_traits::pointer         pointer;
    typedef typename __alloc_traits::const_pointer   const_pointer;
    typedef typename __alloc_traits::size_type       size_type;
    typedef typename __alloc_traits::difference_type difference_type;

    typedef __hash_map_iterator<typename __table::iterator>       iterator;
    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;

    _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);}
    explicit hash_map(size_type __n, const hasher& __hf = hasher(),
                           const key_equal& __eql = key_equal());
    hash_map(size_type __n, const hasher& __hf,
                  const key_equal& __eql,
                  const allocator_type& __a);
    template <class _InputIterator>
        hash_map(_InputIterator __first, _InputIterator __last);
    template <class _InputIterator>
        hash_map(_InputIterator __first, _InputIterator __last,
                      size_type __n, const hasher& __hf = hasher(),
                      const key_equal& __eql = key_equal());
    template <class _InputIterator>
        hash_map(_InputIterator __first, _InputIterator __last,
                      size_type __n, const hasher& __hf,
                      const key_equal& __eql,
                      const allocator_type& __a);
    hash_map(const hash_map& __u);

    _LIBCPP_INLINE_VISIBILITY
    allocator_type get_allocator() const
        {return allocator_type(__table_.__node_alloc());}

    _LIBCPP_INLINE_VISIBILITY
    bool      empty() const {return __table_.size() == 0;}
    _LIBCPP_INLINE_VISIBILITY
    size_type size() const  {return __table_.size();}
    _LIBCPP_INLINE_VISIBILITY
    size_type max_size() const {return __table_.max_size();}

    _LIBCPP_INLINE_VISIBILITY
    iterator       begin()        {return __table_.begin();}
    _LIBCPP_INLINE_VISIBILITY
    iterator       end()          {return __table_.end();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator begin()  const {return __table_.begin();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator end()    const {return __table_.end();}

    _LIBCPP_INLINE_VISIBILITY
    pair<iterator, bool> insert(const value_type& __x)
        {return __table_.__insert_unique(__x);}
    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
    template <class _InputIterator>
        void insert(_InputIterator __first, _InputIterator __last);

    _LIBCPP_INLINE_VISIBILITY
    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
    _LIBCPP_INLINE_VISIBILITY
    void erase(const_iterator __first, const_iterator __last)
        {__table_.erase(__first.__i_, __last.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    void clear() {__table_.clear();}

    _LIBCPP_INLINE_VISIBILITY
    void swap(hash_map& __u) {__table_.swap(__u.__table_);}

    _LIBCPP_INLINE_VISIBILITY
    hasher hash_funct() const
        {return __table_.hash_function().hash_function();}
    _LIBCPP_INLINE_VISIBILITY
    key_equal key_eq() const
        {return __table_.key_eq().key_eq();}

    _LIBCPP_INLINE_VISIBILITY
    iterator       find(const key_type& __k)       {return __table_.find(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
    _LIBCPP_INLINE_VISIBILITY
    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
    _LIBCPP_INLINE_VISIBILITY
    pair<iterator, iterator>             equal_range(const key_type& __k)
        {return __table_.__equal_range_unique(__k);}
    _LIBCPP_INLINE_VISIBILITY
    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
        {return __table_.__equal_range_unique(__k);}

    mapped_type& operator[](const key_type& __k);

    _LIBCPP_INLINE_VISIBILITY
    size_type bucket_count() const {return __table_.bucket_count();}
    _LIBCPP_INLINE_VISIBILITY
    size_type max_bucket_count() const {return __table_.max_bucket_count();}

    _LIBCPP_INLINE_VISIBILITY
    size_type elems_in_bucket(size_type __n) const
        {return __table_.bucket_size(__n);}

    _LIBCPP_INLINE_VISIBILITY
    void resize(size_type __n) {__table_.rehash(__n);}

private:
    __node_holder __construct_node(const key_type& __k);
};

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
        size_type __n, const hasher& __hf, const key_equal& __eql)
    : __table_(__hf, __eql)
{
    __table_.rehash(__n);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
        size_type __n, const hasher& __hf, const key_equal& __eql,
        const allocator_type& __a)
    : __table_(__hf, __eql, __a)
{
    __table_.rehash(__n);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
        _InputIterator __first, _InputIterator __last)
{
    __table_.rehash(193);
    insert(__first, __last);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
        _InputIterator __first, _InputIterator __last, size_type __n,
        const hasher& __hf, const key_equal& __eql)
    : __table_(__hf, __eql)
{
    __table_.rehash(__n);
    insert(__first, __last);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
        _InputIterator __first, _InputIterator __last, size_type __n,
        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
    : __table_(__hf, __eql, __a)
{
    __table_.rehash(__n);
    insert(__first, __last);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
        const hash_map& __u)
    : __table_(__u.__table_)
{
    __table_.rehash(__u.bucket_count());
    insert(__u.begin(), __u.end());
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
{
    __node_allocator& __na = __table_.__node_alloc();
    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
    __h.get_deleter().__first_constructed = true;
    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
    __h.get_deleter().__second_constructed = true;
    return _VSTD::move(__h);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
inline _LIBCPP_INLINE_VISIBILITY
void
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
                                                       _InputIterator __last)
{
    for (; __first != __last; ++__first)
        __table_.__insert_unique(*__first);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
_Tp&
hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
{
    iterator __i = find(__k);
    if (__i != end())
        return __i->second;
    __node_holder __h = __construct_node(__k);
    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
    __h.release();
    return __r.first->second;
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{
    __x.swap(__y);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
bool
operator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{
    if (__x.size() != __y.size())
        return false;
    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
                                                                 const_iterator;
    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
            __i != __ex; ++__i)
    {
        const_iterator __j = __y.find(__i->first);
        if (__j == __ey || !(*__i == *__j))
            return false;
    }
    return true;
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{
    return !(__x == __y);
}

template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
          class _Alloc = allocator<pair<const _Key, _Tp> > >
class _LIBCPP_VISIBLE hash_multimap
{
public:
    // types
    typedef _Key                                           key_type;
    typedef _Tp                                            mapped_type;
    typedef _Tp                                            data_type;
    typedef _Hash                                          hasher;
    typedef _Pred                                          key_equal;
    typedef _Alloc                                         allocator_type;
    typedef pair<const key_type, mapped_type>              value_type;
    typedef value_type&                                    reference;
    typedef const value_type&                              const_reference;

private:
    typedef pair<key_type, mapped_type>                    __value_type;
    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
    typedef typename allocator_traits<allocator_type>::template
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
            rebind_alloc<__value_type>
#else
            rebind_alloc<__value_type>::other
#endif
                                                           __allocator_type;

    typedef __hash_table<__value_type, __hasher,
                         __key_equal,  __allocator_type>   __table;

    __table __table_;

    typedef typename __table::__node_traits                __node_traits;
    typedef typename __table::__node_allocator             __node_allocator;
    typedef typename __table::__node                       __node;
    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
    typedef unique_ptr<__node, _Dp>                         __node_holder;
    typedef allocator_traits<allocator_type>               __alloc_traits;
public:
    typedef typename __alloc_traits::pointer         pointer;
    typedef typename __alloc_traits::const_pointer   const_pointer;
    typedef typename __alloc_traits::size_type       size_type;
    typedef typename __alloc_traits::difference_type difference_type;

    typedef __hash_map_iterator<typename __table::iterator>       iterator;
    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;

    _LIBCPP_INLINE_VISIBILITY
    hash_multimap() {__table_.rehash(193);}
    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
                                const key_equal& __eql = key_equal());
    hash_multimap(size_type __n, const hasher& __hf,
                                const key_equal& __eql,
                                const allocator_type& __a);
    template <class _InputIterator>
        hash_multimap(_InputIterator __first, _InputIterator __last);
    template <class _InputIterator>
        hash_multimap(_InputIterator __first, _InputIterator __last,
                      size_type __n, const hasher& __hf = hasher(),
                      const key_equal& __eql = key_equal());
    template <class _InputIterator>
        hash_multimap(_InputIterator __first, _InputIterator __last,
                      size_type __n, const hasher& __hf,
                      const key_equal& __eql,
                      const allocator_type& __a);
    hash_multimap(const hash_multimap& __u);

    _LIBCPP_INLINE_VISIBILITY
    allocator_type get_allocator() const
        {return allocator_type(__table_.__node_alloc());}

    _LIBCPP_INLINE_VISIBILITY
    bool      empty() const {return __table_.size() == 0;}
    _LIBCPP_INLINE_VISIBILITY
    size_type size() const  {return __table_.size();}
    _LIBCPP_INLINE_VISIBILITY
    size_type max_size() const {return __table_.max_size();}

    _LIBCPP_INLINE_VISIBILITY
    iterator       begin()        {return __table_.begin();}
    _LIBCPP_INLINE_VISIBILITY
    iterator       end()          {return __table_.end();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator begin()  const {return __table_.begin();}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator end()    const {return __table_.end();}

    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
    _LIBCPP_INLINE_VISIBILITY
    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
    template <class _InputIterator>
        void insert(_InputIterator __first, _InputIterator __last);

    _LIBCPP_INLINE_VISIBILITY
    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
    _LIBCPP_INLINE_VISIBILITY
    void erase(const_iterator __first, const_iterator __last)
        {__table_.erase(__first.__i_, __last.__i_);}
    _LIBCPP_INLINE_VISIBILITY
    void clear() {__table_.clear();}

    _LIBCPP_INLINE_VISIBILITY
    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}

    _LIBCPP_INLINE_VISIBILITY
    hasher hash_funct() const
        {return __table_.hash_function().hash_function();}
    _LIBCPP_INLINE_VISIBILITY
    key_equal key_eq() const
        {return __table_.key_eq().key_eq();}

    _LIBCPP_INLINE_VISIBILITY
    iterator       find(const key_type& __k)       {return __table_.find(__k);}
    _LIBCPP_INLINE_VISIBILITY
    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
    _LIBCPP_INLINE_VISIBILITY
    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
    _LIBCPP_INLINE_VISIBILITY
    pair<iterator, iterator>             equal_range(const key_type& __k)
        {return __table_.__equal_range_multi(__k);}
    _LIBCPP_INLINE_VISIBILITY
    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
        {return __table_.__equal_range_multi(__k);}

    _LIBCPP_INLINE_VISIBILITY
    size_type bucket_count() const {return __table_.bucket_count();}
    _LIBCPP_INLINE_VISIBILITY
    size_type max_bucket_count() const {return __table_.max_bucket_count();}

    _LIBCPP_INLINE_VISIBILITY
    size_type elems_in_bucket(size_type __n) const
        {return __table_.bucket_size(__n);}

    _LIBCPP_INLINE_VISIBILITY
    void resize(size_type __n) {__table_.rehash(__n);}
};

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
        size_type __n, const hasher& __hf, const key_equal& __eql)
    : __table_(__hf, __eql)
{
    __table_.rehash(__n);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
        size_type __n, const hasher& __hf, const key_equal& __eql,
        const allocator_type& __a)
    : __table_(__hf, __eql, __a)
{
    __table_.rehash(__n);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
        _InputIterator __first, _InputIterator __last)
{
    __table_.rehash(193);
    insert(__first, __last);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
        _InputIterator __first, _InputIterator __last, size_type __n,
        const hasher& __hf, const key_equal& __eql)
    : __table_(__hf, __eql)
{
    __table_.rehash(__n);
    insert(__first, __last);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
        _InputIterator __first, _InputIterator __last, size_type __n,
        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
    : __table_(__hf, __eql, __a)
{
    __table_.rehash(__n);
    insert(__first, __last);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
        const hash_multimap& __u)
    : __table_(__u.__table_)
{
    __table_.rehash(__u.bucket_count());
    insert(__u.begin(), __u.end());
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _InputIterator>
inline _LIBCPP_INLINE_VISIBILITY
void
hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
                                                            _InputIterator __last)
{
    for (; __first != __last; ++__first)
        __table_.__insert_multi(*__first);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
void
swap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{
    __x.swap(__y);
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
bool
operator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{
    if (__x.size() != __y.size())
        return false;
    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
                                                                 const_iterator;
    typedef pair<const_iterator, const_iterator> _EqRng;
    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
    {
        _EqRng __xeq = __x.equal_range(__i->first);
        _EqRng __yeq = __y.equal_range(__i->first);
        if (_VSTD::distance(__xeq.first, __xeq.second) !=
            _VSTD::distance(__yeq.first, __yeq.second) ||
                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
            return false;
        __i = __xeq.second;
    }
    return true;
}

template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
bool
operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{
    return !(__x == __y);
}

} // __gnu_cxx

#endif  // _LIBCPP_HASH_MAP
