10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_HASH_MAP 110b57cec5SDimitry Andric#define _LIBCPP_HASH_MAP 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric hash_map synopsis 160b57cec5SDimitry Andric 170b57cec5SDimitry Andricnamespace __gnu_cxx 180b57cec5SDimitry Andric{ 190b57cec5SDimitry Andric 200b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, 210b57cec5SDimitry Andric class Alloc = allocator<pair<const Key, T>>> 220b57cec5SDimitry Andricclass hash_map 230b57cec5SDimitry Andric{ 240b57cec5SDimitry Andricpublic: 250b57cec5SDimitry Andric // types 260b57cec5SDimitry Andric typedef Key key_type; 270b57cec5SDimitry Andric typedef T mapped_type; 280b57cec5SDimitry Andric typedef Hash hasher; 290b57cec5SDimitry Andric typedef Pred key_equal; 300b57cec5SDimitry Andric typedef Alloc allocator_type; 310b57cec5SDimitry Andric typedef pair<const key_type, mapped_type> value_type; 320b57cec5SDimitry Andric typedef value_type& reference; 330b57cec5SDimitry Andric typedef const value_type& const_reference; 340b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::pointer pointer; 350b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 360b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::size_type size_type; 370b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::difference_type difference_type; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric typedef /unspecified/ iterator; 400b57cec5SDimitry Andric typedef /unspecified/ const_iterator; 410b57cec5SDimitry Andric 42e40139ffSDimitry Andric hash_map(); 43e40139ffSDimitry Andric explicit hash_map(size_type n, const hasher& hf = hasher(), 440b57cec5SDimitry Andric const key_equal& eql = key_equal(), 450b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 460b57cec5SDimitry Andric template <class InputIterator> 47e40139ffSDimitry Andric hash_map(InputIterator f, InputIterator l); 48e40139ffSDimitry Andric template <class InputIterator> 490b57cec5SDimitry Andric hash_map(InputIterator f, InputIterator l, 50e40139ffSDimitry Andric size_type n, const hasher& hf = hasher(), 510b57cec5SDimitry Andric const key_equal& eql = key_equal(), 520b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 530b57cec5SDimitry Andric hash_map(const hash_map&); 540b57cec5SDimitry Andric ~hash_map(); 550b57cec5SDimitry Andric hash_map& operator=(const hash_map&); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric allocator_type get_allocator() const; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric bool empty() const; 600b57cec5SDimitry Andric size_type size() const; 610b57cec5SDimitry Andric size_type max_size() const; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric iterator begin(); 640b57cec5SDimitry Andric iterator end(); 650b57cec5SDimitry Andric const_iterator begin() const; 660b57cec5SDimitry Andric const_iterator end() const; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric pair<iterator, bool> insert(const value_type& obj); 690b57cec5SDimitry Andric template <class InputIterator> 700b57cec5SDimitry Andric void insert(InputIterator first, InputIterator last); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric void erase(const_iterator position); 730b57cec5SDimitry Andric size_type erase(const key_type& k); 740b57cec5SDimitry Andric void erase(const_iterator first, const_iterator last); 750b57cec5SDimitry Andric void clear(); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric void swap(hash_map&); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric hasher hash_funct() const; 800b57cec5SDimitry Andric key_equal key_eq() const; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric iterator find(const key_type& k); 830b57cec5SDimitry Andric const_iterator find(const key_type& k) const; 840b57cec5SDimitry Andric size_type count(const key_type& k) const; 850b57cec5SDimitry Andric pair<iterator, iterator> equal_range(const key_type& k); 860b57cec5SDimitry Andric pair<const_iterator, const_iterator> equal_range(const key_type& k) const; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric mapped_type& operator[](const key_type& k); 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric size_type bucket_count() const; 910b57cec5SDimitry Andric size_type max_bucket_count() const; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric size_type elems_in_bucket(size_type n) const; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric void resize(size_type n); 960b57cec5SDimitry Andric}; 970b57cec5SDimitry Andric 980b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 990b57cec5SDimitry Andric void swap(hash_map<Key, T, Hash, Pred, Alloc>& x, 1000b57cec5SDimitry Andric hash_map<Key, T, Hash, Pred, Alloc>& y); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 1030b57cec5SDimitry Andric bool 1040b57cec5SDimitry Andric operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x, 1050b57cec5SDimitry Andric const hash_map<Key, T, Hash, Pred, Alloc>& y); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 1080b57cec5SDimitry Andric bool 1090b57cec5SDimitry Andric operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x, 1100b57cec5SDimitry Andric const hash_map<Key, T, Hash, Pred, Alloc>& y); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andrictemplate <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, 1130b57cec5SDimitry Andric class Alloc = allocator<pair<const Key, T>>> 1140b57cec5SDimitry Andricclass hash_multimap 1150b57cec5SDimitry Andric{ 1160b57cec5SDimitry Andricpublic: 1170b57cec5SDimitry Andric // types 1180b57cec5SDimitry Andric typedef Key key_type; 1190b57cec5SDimitry Andric typedef T mapped_type; 1200b57cec5SDimitry Andric typedef Hash hasher; 1210b57cec5SDimitry Andric typedef Pred key_equal; 1220b57cec5SDimitry Andric typedef Alloc allocator_type; 1230b57cec5SDimitry Andric typedef pair<const key_type, mapped_type> value_type; 1240b57cec5SDimitry Andric typedef value_type& reference; 1250b57cec5SDimitry Andric typedef const value_type& const_reference; 1260b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::pointer pointer; 1270b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::const_pointer const_pointer; 1280b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::size_type size_type; 1290b57cec5SDimitry Andric typedef typename allocator_traits<allocator_type>::difference_type difference_type; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric typedef /unspecified/ iterator; 1320b57cec5SDimitry Andric typedef /unspecified/ const_iterator; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(), 1350b57cec5SDimitry Andric const key_equal& eql = key_equal(), 1360b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 1370b57cec5SDimitry Andric template <class InputIterator> 1380b57cec5SDimitry Andric hash_multimap(InputIterator f, InputIterator l, 1390b57cec5SDimitry Andric size_type n = 193, const hasher& hf = hasher(), 1400b57cec5SDimitry Andric const key_equal& eql = key_equal(), 1410b57cec5SDimitry Andric const allocator_type& a = allocator_type()); 1420b57cec5SDimitry Andric explicit hash_multimap(const allocator_type&); 1430b57cec5SDimitry Andric hash_multimap(const hash_multimap&); 1440b57cec5SDimitry Andric ~hash_multimap(); 1450b57cec5SDimitry Andric hash_multimap& operator=(const hash_multimap&); 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric allocator_type get_allocator() const; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric bool empty() const; 1500b57cec5SDimitry Andric size_type size() const; 1510b57cec5SDimitry Andric size_type max_size() const; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric iterator begin(); 1540b57cec5SDimitry Andric iterator end(); 1550b57cec5SDimitry Andric const_iterator begin() const; 1560b57cec5SDimitry Andric const_iterator end() const; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric iterator insert(const value_type& obj); 1590b57cec5SDimitry Andric template <class InputIterator> 1600b57cec5SDimitry Andric void insert(InputIterator first, InputIterator last); 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric void erase(const_iterator position); 1630b57cec5SDimitry Andric size_type erase(const key_type& k); 1640b57cec5SDimitry Andric void erase(const_iterator first, const_iterator last); 1650b57cec5SDimitry Andric void clear(); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric void swap(hash_multimap&); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric hasher hash_funct() const; 1700b57cec5SDimitry Andric key_equal key_eq() const; 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric iterator find(const key_type& k); 1730b57cec5SDimitry Andric const_iterator find(const key_type& k) const; 1740b57cec5SDimitry Andric size_type count(const key_type& k) const; 1750b57cec5SDimitry Andric pair<iterator, iterator> equal_range(const key_type& k); 1760b57cec5SDimitry Andric pair<const_iterator, const_iterator> equal_range(const key_type& k) const; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric size_type bucket_count() const; 1790b57cec5SDimitry Andric size_type max_bucket_count() const; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric size_type elems_in_bucket(size_type n) const; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric void resize(size_type n); 1840b57cec5SDimitry Andric}; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 1870b57cec5SDimitry Andric void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x, 1880b57cec5SDimitry Andric hash_multimap<Key, T, Hash, Pred, Alloc>& y); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 1910b57cec5SDimitry Andric bool 1920b57cec5SDimitry Andric operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x, 1930b57cec5SDimitry Andric const hash_multimap<Key, T, Hash, Pred, Alloc>& y); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andrictemplate <class Key, class T, class Hash, class Pred, class Alloc> 1960b57cec5SDimitry Andric bool 1970b57cec5SDimitry Andric operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x, 1980b57cec5SDimitry Andric const hash_multimap<Key, T, Hash, Pred, Alloc>& y); 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric} // __gnu_cxx 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric*/ 2030b57cec5SDimitry Andric 20481ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 2050b57cec5SDimitry Andric#include <__config> 2060b57cec5SDimitry Andric#include <__hash_table> 20781ad6265SDimitry Andric#include <algorithm> 20804eeddc0SDimitry Andric#include <ext/__hash> 2090b57cec5SDimitry Andric#include <functional> 2100b57cec5SDimitry Andric 211fe6060f1SDimitry Andric#if defined(__DEPRECATED) && __DEPRECATED 2120b57cec5SDimitry Andric# if defined(_LIBCPP_WARNING) 2130b57cec5SDimitry Andric_LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map>") 2140b57cec5SDimitry Andric# else 2150b57cec5SDimitry Andric# warning Use of the header <ext/hash_map> is deprecated. Migrate to <unordered_map> 2160b57cec5SDimitry Andric# endif 2170b57cec5SDimitry Andric#endif 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2200b57cec5SDimitry Andric# pragma GCC system_header 2210b57cec5SDimitry Andric#endif 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andricnamespace __gnu_cxx { 2240b57cec5SDimitry Andric 225*cb14a3feSDimitry Andrictemplate <class _Tp, class _Hash, bool = std::is_empty<_Hash>::value && !std::__libcpp_is_final<_Hash>::value > 226*cb14a3feSDimitry Andricclass __hash_map_hasher : private _Hash { 2270b57cec5SDimitry Andricpublic: 2285f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : _Hash() {} 2295f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_hasher(const _Hash& __h) : _Hash(__h) {} 2305f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const { return *this; } 231*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Tp& __x) const { return static_cast<const _Hash&>(*this)(__x.first); } 232*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const typename _Tp::first_type& __x) const { 233*cb14a3feSDimitry Andric return static_cast<const _Hash&>(*this)(__x); 234*cb14a3feSDimitry Andric } 2350b57cec5SDimitry Andric}; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andrictemplate <class _Tp, class _Hash> 238*cb14a3feSDimitry Andricclass __hash_map_hasher<_Tp, _Hash, false> { 2390b57cec5SDimitry Andric _Hash __hash_; 240*cb14a3feSDimitry Andric 2410b57cec5SDimitry Andricpublic: 2425f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_hasher() : __hash_() {} 2435f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_hasher(const _Hash& __h) : __hash_(__h) {} 2445f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Hash& hash_function() const { return __hash_; } 245*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const _Tp& __x) const { return __hash_(__x.first); } 246*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const typename _Tp::first_type& __x) const { return __hash_(__x); } 2470b57cec5SDimitry Andric}; 2480b57cec5SDimitry Andric 249*cb14a3feSDimitry Andrictemplate <class _Tp, class _Pred, bool = std::is_empty<_Pred>::value && !std::__libcpp_is_final<_Pred>::value > 250*cb14a3feSDimitry Andricclass __hash_map_equal : private _Pred { 2510b57cec5SDimitry Andricpublic: 2525f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : _Pred() {} 2535f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_equal(const _Pred& __p) : _Pred(__p) {} 2545f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const { return *this; } 255*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { 256*cb14a3feSDimitry Andric return static_cast<const _Pred&>(*this)(__x.first, __y.first); 257*cb14a3feSDimitry Andric } 258*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const { 259*cb14a3feSDimitry Andric return static_cast<const _Pred&>(*this)(__x, __y.first); 260*cb14a3feSDimitry Andric } 261*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const { 262*cb14a3feSDimitry Andric return static_cast<const _Pred&>(*this)(__x.first, __y); 263*cb14a3feSDimitry Andric } 264*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 265*cb14a3feSDimitry Andric operator()(const typename _Tp::first_type& __x, const typename _Tp::first_type& __y) const { 266*cb14a3feSDimitry Andric return static_cast<const _Pred&>(*this)(__x, __y); 267*cb14a3feSDimitry Andric } 2680b57cec5SDimitry Andric}; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andrictemplate <class _Tp, class _Pred> 271*cb14a3feSDimitry Andricclass __hash_map_equal<_Tp, _Pred, false> { 2720b57cec5SDimitry Andric _Pred __pred_; 273*cb14a3feSDimitry Andric 2740b57cec5SDimitry Andricpublic: 2755f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_equal() : __pred_() {} 2765f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_equal(const _Pred& __p) : __pred_(__p) {} 2775f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI const _Pred& key_eq() const { return __pred_; } 278*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { return __pred_(__x.first, __y.first); } 279*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const { 280*cb14a3feSDimitry Andric return __pred_(__x, __y.first); 281*cb14a3feSDimitry Andric } 282*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const { 283*cb14a3feSDimitry Andric return __pred_(__x.first, __y); 284*cb14a3feSDimitry Andric } 285*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 286*cb14a3feSDimitry Andric operator()(const typename _Tp::first_type& __x, const typename _Tp::first_type& __y) const { 287*cb14a3feSDimitry Andric return __pred_(__x, __y); 288*cb14a3feSDimitry Andric } 2890b57cec5SDimitry Andric}; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andrictemplate <class _Alloc> 292*cb14a3feSDimitry Andricclass __hash_map_node_destructor { 2930b57cec5SDimitry Andric typedef _Alloc allocator_type; 2940b57cec5SDimitry Andric typedef std::allocator_traits<allocator_type> __alloc_traits; 2950b57cec5SDimitry Andric typedef typename __alloc_traits::value_type::__node_value_type value_type; 296*cb14a3feSDimitry Andric 2970b57cec5SDimitry Andricpublic: 2980b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 299*cb14a3feSDimitry Andric 3000b57cec5SDimitry Andricprivate: 3010b57cec5SDimitry Andric typedef typename value_type::first_type first_type; 3020b57cec5SDimitry Andric typedef typename value_type::second_type second_type; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric allocator_type& __na_; 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andricpublic: 3070b57cec5SDimitry Andric bool __first_constructed; 3080b57cec5SDimitry Andric bool __second_constructed; 3090b57cec5SDimitry Andric 31006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(__hash_map_node_destructor const&) = default; 311cd0c3137SDimitry Andric __hash_map_node_destructor& operator=(const __hash_map_node_destructor&) = delete; 312cd0c3137SDimitry Andric 313*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit __hash_map_node_destructor(allocator_type& __na) 314*cb14a3feSDimitry Andric : __na_(__na), __first_constructed(false), __second_constructed(false) {} 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 317*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(std::__hash_node_destructor<allocator_type>&& __x) 318*cb14a3feSDimitry Andric : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) { 3190b57cec5SDimitry Andric __x.__value_constructed = false; 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric#else // _LIBCPP_CXX03_LANG 322*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(const std::__hash_node_destructor<allocator_type>& __x) 323*cb14a3feSDimitry Andric : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) { 3240b57cec5SDimitry Andric const_cast<bool&>(__x.__value_constructed) = false; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 3270b57cec5SDimitry Andric 328*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) { 3290b57cec5SDimitry Andric if (__second_constructed) 3305f757f3fSDimitry Andric __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().second)); 3310b57cec5SDimitry Andric if (__first_constructed) 3325f757f3fSDimitry Andric __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().first)); 3330b57cec5SDimitry Andric if (__p) 3340b57cec5SDimitry Andric __alloc_traits::deallocate(__na_, __p, 1); 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric}; 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andrictemplate <class _HashIterator> 339*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_iterator { 3400b57cec5SDimitry Andric _HashIterator __i_; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric typedef const typename _HashIterator::value_type::first_type key_type; 3430b57cec5SDimitry Andric typedef typename _HashIterator::value_type::second_type mapped_type; 344*cb14a3feSDimitry Andric 3450b57cec5SDimitry Andricpublic: 3460b57cec5SDimitry Andric typedef std::forward_iterator_tag iterator_category; 3470b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> value_type; 3480b57cec5SDimitry Andric typedef typename _HashIterator::difference_type difference_type; 3490b57cec5SDimitry Andric typedef value_type& reference; 350*cb14a3feSDimitry Andric typedef std::__rebind_pointer_t<typename _HashIterator::pointer, value_type> pointer; 3510b57cec5SDimitry Andric 3525f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_iterator() {} 3530b57cec5SDimitry Andric 3545f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_iterator(_HashIterator __i) : __i_(__i) {} 3550b57cec5SDimitry Andric 3565f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *operator->(); } 3575f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return (pointer)__i_.operator->(); } 3580b57cec5SDimitry Andric 359*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_iterator& operator++() { 360*cb14a3feSDimitry Andric ++__i_; 361*cb14a3feSDimitry Andric return *this; 362*cb14a3feSDimitry Andric } 363*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_iterator operator++(int) { 3640b57cec5SDimitry Andric __hash_map_iterator __t(*this); 3650b57cec5SDimitry Andric ++(*this); 3660b57cec5SDimitry Andric return __t; 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 369*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) { 370*cb14a3feSDimitry Andric return __x.__i_ == __y.__i_; 371*cb14a3feSDimitry Andric } 372*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) { 373*cb14a3feSDimitry Andric return __x.__i_ != __y.__i_; 374*cb14a3feSDimitry Andric } 3750b57cec5SDimitry Andric 376*cb14a3feSDimitry Andric template <class, class, class, class, class> 377*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS hash_map; 378*cb14a3feSDimitry Andric template <class, class, class, class, class> 379*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS hash_multimap; 380*cb14a3feSDimitry Andric template <class> 381*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 382*cb14a3feSDimitry Andric template <class> 383*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 384*cb14a3feSDimitry Andric template <class> 385*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; 3860b57cec5SDimitry Andric}; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andrictemplate <class _HashIterator> 389*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator { 3900b57cec5SDimitry Andric _HashIterator __i_; 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric typedef const typename _HashIterator::value_type::first_type key_type; 3930b57cec5SDimitry Andric typedef typename _HashIterator::value_type::second_type mapped_type; 394*cb14a3feSDimitry Andric 3950b57cec5SDimitry Andricpublic: 3960b57cec5SDimitry Andric typedef std::forward_iterator_tag iterator_category; 3970b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> value_type; 3980b57cec5SDimitry Andric typedef typename _HashIterator::difference_type difference_type; 3990b57cec5SDimitry Andric typedef const value_type& reference; 400*cb14a3feSDimitry Andric typedef std::__rebind_pointer_t<typename _HashIterator::pointer, const value_type> pointer; 4010b57cec5SDimitry Andric 4025f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator() {} 4030b57cec5SDimitry Andric 404*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {} 405*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator(__hash_map_iterator<typename _HashIterator::__non_const_iterator> __i) 4060b57cec5SDimitry Andric : __i_(__i.__i_) {} 4070b57cec5SDimitry Andric 408*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *operator->(); } 409*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return (pointer)__i_.operator->(); } 4100b57cec5SDimitry Andric 411*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator& operator++() { 412*cb14a3feSDimitry Andric ++__i_; 413*cb14a3feSDimitry Andric return *this; 414*cb14a3feSDimitry Andric } 415*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator operator++(int) { 4160b57cec5SDimitry Andric __hash_map_const_iterator __t(*this); 4170b57cec5SDimitry Andric ++(*this); 4180b57cec5SDimitry Andric return __t; 4190b57cec5SDimitry Andric } 4200b57cec5SDimitry Andric 421*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool 422*cb14a3feSDimitry Andric operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) { 423*cb14a3feSDimitry Andric return __x.__i_ == __y.__i_; 424*cb14a3feSDimitry Andric } 425*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool 426*cb14a3feSDimitry Andric operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) { 427*cb14a3feSDimitry Andric return __x.__i_ != __y.__i_; 428*cb14a3feSDimitry Andric } 4290b57cec5SDimitry Andric 430*cb14a3feSDimitry Andric template <class, class, class, class, class> 431*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS hash_map; 432*cb14a3feSDimitry Andric template <class, class, class, class, class> 433*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS hash_multimap; 434*cb14a3feSDimitry Andric template <class> 435*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; 436*cb14a3feSDimitry Andric template <class> 437*cb14a3feSDimitry Andric friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; 4380b57cec5SDimitry Andric}; 4390b57cec5SDimitry Andric 440*cb14a3feSDimitry Andrictemplate <class _Key, 441*cb14a3feSDimitry Andric class _Tp, 442*cb14a3feSDimitry Andric class _Hash = hash<_Key>, 443*cb14a3feSDimitry Andric class _Pred = std::equal_to<_Key>, 4440b57cec5SDimitry Andric class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 445*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_map { 4460b57cec5SDimitry Andricpublic: 4470b57cec5SDimitry Andric // types 4480b57cec5SDimitry Andric typedef _Key key_type; 4490b57cec5SDimitry Andric typedef _Tp mapped_type; 4500b57cec5SDimitry Andric typedef _Tp data_type; 4510b57cec5SDimitry Andric typedef _Hash hasher; 4520b57cec5SDimitry Andric typedef _Pred key_equal; 4530b57cec5SDimitry Andric typedef _Alloc allocator_type; 4540b57cec5SDimitry Andric typedef std::pair<const key_type, mapped_type> value_type; 4550b57cec5SDimitry Andric typedef value_type& reference; 4560b57cec5SDimitry Andric typedef const value_type& const_reference; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andricprivate: 4590b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> __value_type; 4600b57cec5SDimitry Andric typedef __hash_map_hasher<__value_type, hasher> __hasher; 4610b57cec5SDimitry Andric typedef __hash_map_equal<__value_type, key_equal> __key_equal; 462bdd1243dSDimitry Andric typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type; 4630b57cec5SDimitry Andric 464*cb14a3feSDimitry Andric typedef std::__hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table; 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric __table __table_; 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric typedef typename __table::__node_pointer __node_pointer; 4690b57cec5SDimitry Andric typedef typename __table::__node_const_pointer __node_const_pointer; 4700b57cec5SDimitry Andric typedef typename __table::__node_traits __node_traits; 4710b57cec5SDimitry Andric typedef typename __table::__node_allocator __node_allocator; 4720b57cec5SDimitry Andric typedef typename __table::__node __node; 4730b57cec5SDimitry Andric typedef __hash_map_node_destructor<__node_allocator> _Dp; 4740b57cec5SDimitry Andric typedef std::unique_ptr<__node, _Dp> __node_holder; 4750b57cec5SDimitry Andric typedef std::allocator_traits<allocator_type> __alloc_traits; 476*cb14a3feSDimitry Andric 4770b57cec5SDimitry Andricpublic: 4780b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 4790b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 4800b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 4810b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric typedef __hash_map_iterator<typename __table::iterator> iterator; 4840b57cec5SDimitry Andric typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; 4850b57cec5SDimitry Andric 4865f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_map() {} 487*cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI 488*cb14a3feSDimitry Andric hash_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); 489*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); 4900b57cec5SDimitry Andric template <class _InputIterator> 49106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last); 4920b57cec5SDimitry Andric template <class _InputIterator> 493*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI 494*cb14a3feSDimitry Andric hash_map(_InputIterator __first, 495*cb14a3feSDimitry Andric _InputIterator __last, 496*cb14a3feSDimitry Andric size_type __n, 497*cb14a3feSDimitry Andric const hasher& __hf = hasher(), 4980b57cec5SDimitry Andric const key_equal& __eql = key_equal()); 4990b57cec5SDimitry Andric template <class _InputIterator> 500*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI 501*cb14a3feSDimitry Andric hash_map(_InputIterator __first, 502*cb14a3feSDimitry Andric _InputIterator __last, 503*cb14a3feSDimitry Andric size_type __n, 504*cb14a3feSDimitry Andric const hasher& __hf, 5050b57cec5SDimitry Andric const key_equal& __eql, 5060b57cec5SDimitry Andric const allocator_type& __a); 50706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_map(const hash_map& __u); 5080b57cec5SDimitry Andric 509*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); } 5100b57cec5SDimitry Andric 511*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; } 512*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); } 513*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); } 5140b57cec5SDimitry Andric 515*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); } 516*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); } 517*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); } 518*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); } 5190b57cec5SDimitry Andric 520*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI std::pair<iterator, bool> insert(const value_type& __x) { 521*cb14a3feSDimitry Andric return __table_.__insert_unique(__x); 522*cb14a3feSDimitry Andric } 523*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x).first; } 5240b57cec5SDimitry Andric template <class _InputIterator> 525*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last); 5260b57cec5SDimitry Andric 527*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p.__i_); } 528*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_unique(__k); } 529*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) { 530*cb14a3feSDimitry Andric __table_.erase(__first.__i_, __last.__i_); 531*cb14a3feSDimitry Andric } 532*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); } 5330b57cec5SDimitry Andric 534*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(hash_map& __u) { __table_.swap(__u.__table_); } 5350b57cec5SDimitry Andric 536*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function().hash_function(); } 537*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); } 5380b57cec5SDimitry Andric 539*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); } 540*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); } 541*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_unique(__k); } 542*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) { 543*cb14a3feSDimitry Andric return __table_.__equal_range_unique(__k); 544*cb14a3feSDimitry Andric } 545*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const { 546*cb14a3feSDimitry Andric return __table_.__equal_range_unique(__k); 547*cb14a3feSDimitry Andric } 5480b57cec5SDimitry Andric 54906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k); 5500b57cec5SDimitry Andric 551*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); } 552*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); } 5530b57cec5SDimitry Andric 554*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); } 5550b57cec5SDimitry Andric 556*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_unique(__n); } 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andricprivate: 55906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(const key_type& __k); 5600b57cec5SDimitry Andric}; 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 563*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(size_type __n, const hasher& __hf, const key_equal& __eql) 564*cb14a3feSDimitry Andric : __table_(__hf, __eql) { 565753f127fSDimitry Andric __table_.__rehash_unique(__n); 5660b57cec5SDimitry Andric} 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 5690b57cec5SDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 570*cb14a3feSDimitry Andric size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) 571*cb14a3feSDimitry Andric : __table_(__hf, __eql, __a) { 572*cb14a3feSDimitry Andric __table_.__rehash_unique(__n); 573*cb14a3feSDimitry Andric} 574*cb14a3feSDimitry Andric 575*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 576*cb14a3feSDimitry Andrictemplate <class _InputIterator> 577*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(_InputIterator __first, _InputIterator __last) { 578*cb14a3feSDimitry Andric insert(__first, __last); 579*cb14a3feSDimitry Andric} 580*cb14a3feSDimitry Andric 581*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 582*cb14a3feSDimitry Andrictemplate <class _InputIterator> 583*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 584*cb14a3feSDimitry Andric _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql) 585*cb14a3feSDimitry Andric : __table_(__hf, __eql) { 586*cb14a3feSDimitry Andric __table_.__rehash_unique(__n); 587*cb14a3feSDimitry Andric insert(__first, __last); 588*cb14a3feSDimitry Andric} 589*cb14a3feSDimitry Andric 590*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 591*cb14a3feSDimitry Andrictemplate <class _InputIterator> 592*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( 593*cb14a3feSDimitry Andric _InputIterator __first, 594*cb14a3feSDimitry Andric _InputIterator __last, 595*cb14a3feSDimitry Andric size_type __n, 596*cb14a3feSDimitry Andric const hasher& __hf, 597*cb14a3feSDimitry Andric const key_equal& __eql, 5980b57cec5SDimitry Andric const allocator_type& __a) 599*cb14a3feSDimitry Andric : __table_(__hf, __eql, __a) { 600753f127fSDimitry Andric __table_.__rehash_unique(__n); 6010b57cec5SDimitry Andric insert(__first, __last); 6020b57cec5SDimitry Andric} 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 605*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(const hash_map& __u) : __table_(__u.__table_) { 606753f127fSDimitry Andric __table_.__rehash_unique(__u.bucket_count()); 6070b57cec5SDimitry Andric insert(__u.begin(), __u.end()); 6080b57cec5SDimitry Andric} 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 6110b57cec5SDimitry Andrictypename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder 612*cb14a3feSDimitry Andrichash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k) { 6130b57cec5SDimitry Andric __node_allocator& __na = __table_.__node_alloc(); 6140b57cec5SDimitry Andric __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 6155f757f3fSDimitry Andric __node_traits::construct(__na, std::addressof(__h->__get_value().first), __k); 6160b57cec5SDimitry Andric __h.get_deleter().__first_constructed = true; 6175f757f3fSDimitry Andric __node_traits::construct(__na, std::addressof(__h->__get_value().second)); 6180b57cec5SDimitry Andric __h.get_deleter().__second_constructed = true; 619e8d8bef9SDimitry Andric return __h; 6200b57cec5SDimitry Andric} 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 6230b57cec5SDimitry Andrictemplate <class _InputIterator> 624*cb14a3feSDimitry Andricinline void hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) { 6250b57cec5SDimitry Andric for (; __first != __last; ++__first) 6260b57cec5SDimitry Andric __table_.__insert_unique(*__first); 6270b57cec5SDimitry Andric} 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 630*cb14a3feSDimitry Andric_Tp& hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) { 6310b57cec5SDimitry Andric iterator __i = find(__k); 6320b57cec5SDimitry Andric if (__i != end()) 6330b57cec5SDimitry Andric return __i->second; 6340b57cec5SDimitry Andric __node_holder __h = __construct_node(__k); 6350b57cec5SDimitry Andric std::pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get()); 6360b57cec5SDimitry Andric __h.release(); 6370b57cec5SDimitry Andric return __r.first->second; 6380b57cec5SDimitry Andric} 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 641*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void 642*cb14a3feSDimitry Andricswap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { 6430b57cec5SDimitry Andric __x.swap(__y); 6440b57cec5SDimitry Andric} 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 647bdd1243dSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool 648*cb14a3feSDimitry Andricoperator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { 6490b57cec5SDimitry Andric if (__x.size() != __y.size()) 6500b57cec5SDimitry Andric return false; 651*cb14a3feSDimitry Andric typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator const_iterator; 652*cb14a3feSDimitry Andric for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end(); __i != __ex; ++__i) { 6530b57cec5SDimitry Andric const_iterator __j = __y.find(__i->first); 6540b57cec5SDimitry Andric if (__j == __ey || !(*__i == *__j)) 6550b57cec5SDimitry Andric return false; 6560b57cec5SDimitry Andric } 6570b57cec5SDimitry Andric return true; 6580b57cec5SDimitry Andric} 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 661*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 662*cb14a3feSDimitry Andricoperator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { 6630b57cec5SDimitry Andric return !(__x == __y); 6640b57cec5SDimitry Andric} 6650b57cec5SDimitry Andric 666*cb14a3feSDimitry Andrictemplate <class _Key, 667*cb14a3feSDimitry Andric class _Tp, 668*cb14a3feSDimitry Andric class _Hash = hash<_Key>, 669*cb14a3feSDimitry Andric class _Pred = std::equal_to<_Key>, 6700b57cec5SDimitry Andric class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > 671*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS hash_multimap { 6720b57cec5SDimitry Andricpublic: 6730b57cec5SDimitry Andric // types 6740b57cec5SDimitry Andric typedef _Key key_type; 6750b57cec5SDimitry Andric typedef _Tp mapped_type; 6760b57cec5SDimitry Andric typedef _Tp data_type; 6770b57cec5SDimitry Andric typedef _Hash hasher; 6780b57cec5SDimitry Andric typedef _Pred key_equal; 6790b57cec5SDimitry Andric typedef _Alloc allocator_type; 6800b57cec5SDimitry Andric typedef std::pair<const key_type, mapped_type> value_type; 6810b57cec5SDimitry Andric typedef value_type& reference; 6820b57cec5SDimitry Andric typedef const value_type& const_reference; 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andricprivate: 6850b57cec5SDimitry Andric typedef std::pair<key_type, mapped_type> __value_type; 6860b57cec5SDimitry Andric typedef __hash_map_hasher<__value_type, hasher> __hasher; 6870b57cec5SDimitry Andric typedef __hash_map_equal<__value_type, key_equal> __key_equal; 688bdd1243dSDimitry Andric typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type; 6890b57cec5SDimitry Andric 690*cb14a3feSDimitry Andric typedef std::__hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table; 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric __table __table_; 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric typedef typename __table::__node_traits __node_traits; 6950b57cec5SDimitry Andric typedef typename __table::__node_allocator __node_allocator; 6960b57cec5SDimitry Andric typedef typename __table::__node __node; 6970b57cec5SDimitry Andric typedef __hash_map_node_destructor<__node_allocator> _Dp; 6980b57cec5SDimitry Andric typedef std::unique_ptr<__node, _Dp> __node_holder; 6990b57cec5SDimitry Andric typedef std::allocator_traits<allocator_type> __alloc_traits; 700*cb14a3feSDimitry Andric 7010b57cec5SDimitry Andricpublic: 7020b57cec5SDimitry Andric typedef typename __alloc_traits::pointer pointer; 7030b57cec5SDimitry Andric typedef typename __alloc_traits::const_pointer const_pointer; 7040b57cec5SDimitry Andric typedef typename __alloc_traits::size_type size_type; 7050b57cec5SDimitry Andric typedef typename __alloc_traits::difference_type difference_type; 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric typedef __hash_map_iterator<typename __table::iterator> iterator; 7080b57cec5SDimitry Andric typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; 7090b57cec5SDimitry Andric 710*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_multimap() {} 711*cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI 712*cb14a3feSDimitry Andric hash_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); 7135f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 714*cb14a3feSDimitry Andric hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); 7150b57cec5SDimitry Andric template <class _InputIterator> 71606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last); 7170b57cec5SDimitry Andric template <class _InputIterator> 718*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI 719*cb14a3feSDimitry Andric hash_multimap(_InputIterator __first, 720*cb14a3feSDimitry Andric _InputIterator __last, 721*cb14a3feSDimitry Andric size_type __n, 722*cb14a3feSDimitry Andric const hasher& __hf = hasher(), 7230b57cec5SDimitry Andric const key_equal& __eql = key_equal()); 7240b57cec5SDimitry Andric template <class _InputIterator> 725*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_multimap( 726*cb14a3feSDimitry Andric _InputIterator __first, 727*cb14a3feSDimitry Andric _InputIterator __last, 728*cb14a3feSDimitry Andric size_type __n, 729*cb14a3feSDimitry Andric const hasher& __hf, 7300b57cec5SDimitry Andric const key_equal& __eql, 7310b57cec5SDimitry Andric const allocator_type& __a); 73206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI hash_multimap(const hash_multimap& __u); 7330b57cec5SDimitry Andric 734*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return allocator_type(__table_.__node_alloc()); } 7350b57cec5SDimitry Andric 736*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool empty() const { return __table_.size() == 0; } 737*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type size() const { return __table_.size(); } 738*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const { return __table_.max_size(); } 7390b57cec5SDimitry Andric 740*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() { return __table_.begin(); } 741*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() { return __table_.end(); } 742*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __table_.begin(); } 743*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __table_.end(); } 7440b57cec5SDimitry Andric 745*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return __table_.__insert_multi(__x); } 746*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { return insert(__x); } 7470b57cec5SDimitry Andric template <class _InputIterator> 748*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last); 7490b57cec5SDimitry Andric 750*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __p) { __table_.erase(__p.__i_); } 751*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __table_.__erase_multi(__k); } 752*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void erase(const_iterator __first, const_iterator __last) { 753*cb14a3feSDimitry Andric __table_.erase(__first.__i_, __last.__i_); 754*cb14a3feSDimitry Andric } 755*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() { __table_.clear(); } 7560b57cec5SDimitry Andric 757*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(hash_multimap& __u) { __table_.swap(__u.__table_); } 7580b57cec5SDimitry Andric 759*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI hasher hash_funct() const { return __table_.hash_function().hash_function(); } 760*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI key_equal key_eq() const { return __table_.key_eq().key_eq(); } 7610b57cec5SDimitry Andric 762*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __table_.find(__k); } 763*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __table_.find(__k); } 764*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __table_.__count_multi(__k); } 765*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI std::pair<iterator, iterator> equal_range(const key_type& __k) { 766*cb14a3feSDimitry Andric return __table_.__equal_range_multi(__k); 767*cb14a3feSDimitry Andric } 768*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const { 769*cb14a3feSDimitry Andric return __table_.__equal_range_multi(__k); 770*cb14a3feSDimitry Andric } 7710b57cec5SDimitry Andric 772*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const { return __table_.bucket_count(); } 773*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const { return __table_.max_bucket_count(); } 7740b57cec5SDimitry Andric 775*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type elems_in_bucket(size_type __n) const { return __table_.bucket_size(__n); } 7760b57cec5SDimitry Andric 777*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void resize(size_type __n) { __table_.__rehash_multi(__n); } 7780b57cec5SDimitry Andric}; 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 781*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql) 782*cb14a3feSDimitry Andric : __table_(__hf, __eql) { 783753f127fSDimitry Andric __table_.__rehash_multi(__n); 7840b57cec5SDimitry Andric} 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 7870b57cec5SDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 788*cb14a3feSDimitry Andric size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) 789*cb14a3feSDimitry Andric : __table_(__hf, __eql, __a) { 790*cb14a3feSDimitry Andric __table_.__rehash_multi(__n); 791*cb14a3feSDimitry Andric} 792*cb14a3feSDimitry Andric 793*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 794*cb14a3feSDimitry Andrictemplate <class _InputIterator> 795*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(_InputIterator __first, _InputIterator __last) { 796*cb14a3feSDimitry Andric insert(__first, __last); 797*cb14a3feSDimitry Andric} 798*cb14a3feSDimitry Andric 799*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 800*cb14a3feSDimitry Andrictemplate <class _InputIterator> 801*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 802*cb14a3feSDimitry Andric _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql) 803*cb14a3feSDimitry Andric : __table_(__hf, __eql) { 804*cb14a3feSDimitry Andric __table_.__rehash_multi(__n); 805*cb14a3feSDimitry Andric insert(__first, __last); 806*cb14a3feSDimitry Andric} 807*cb14a3feSDimitry Andric 808*cb14a3feSDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 809*cb14a3feSDimitry Andrictemplate <class _InputIterator> 810*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( 811*cb14a3feSDimitry Andric _InputIterator __first, 812*cb14a3feSDimitry Andric _InputIterator __last, 813*cb14a3feSDimitry Andric size_type __n, 814*cb14a3feSDimitry Andric const hasher& __hf, 815*cb14a3feSDimitry Andric const key_equal& __eql, 8160b57cec5SDimitry Andric const allocator_type& __a) 817*cb14a3feSDimitry Andric : __table_(__hf, __eql, __a) { 818753f127fSDimitry Andric __table_.__rehash_multi(__n); 8190b57cec5SDimitry Andric insert(__first, __last); 8200b57cec5SDimitry Andric} 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 823*cb14a3feSDimitry Andrichash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(const hash_multimap& __u) : __table_(__u.__table_) { 824753f127fSDimitry Andric __table_.__rehash_multi(__u.bucket_count()); 8250b57cec5SDimitry Andric insert(__u.begin(), __u.end()); 8260b57cec5SDimitry Andric} 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 8290b57cec5SDimitry Andrictemplate <class _InputIterator> 830*cb14a3feSDimitry Andricinline void hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) { 8310b57cec5SDimitry Andric for (; __first != __last; ++__first) 8320b57cec5SDimitry Andric __table_.__insert_multi(*__first); 8330b57cec5SDimitry Andric} 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 836*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void 837*cb14a3feSDimitry Andricswap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { 8380b57cec5SDimitry Andric __x.swap(__y); 8390b57cec5SDimitry Andric} 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 842*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 843*cb14a3feSDimitry Andric const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { 8440b57cec5SDimitry Andric if (__x.size() != __y.size()) 8450b57cec5SDimitry Andric return false; 846*cb14a3feSDimitry Andric typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator const_iterator; 8470b57cec5SDimitry Andric typedef std::pair<const_iterator, const_iterator> _EqRng; 848*cb14a3feSDimitry Andric for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) { 8490b57cec5SDimitry Andric _EqRng __xeq = __x.equal_range(__i->first); 8500b57cec5SDimitry Andric _EqRng __yeq = __y.equal_range(__i->first); 851*cb14a3feSDimitry Andric if (std::distance(__xeq.first, __xeq.second) != std::distance(__yeq.first, __yeq.second) || 8525f757f3fSDimitry Andric !std::is_permutation(__xeq.first, __xeq.second, __yeq.first)) 8530b57cec5SDimitry Andric return false; 8540b57cec5SDimitry Andric __i = __xeq.second; 8550b57cec5SDimitry Andric } 8560b57cec5SDimitry Andric return true; 8570b57cec5SDimitry Andric} 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andrictemplate <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> 860*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, 861*cb14a3feSDimitry Andric const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { 8620b57cec5SDimitry Andric return !(__x == __y); 8630b57cec5SDimitry Andric} 8640b57cec5SDimitry Andric 8650eae32dcSDimitry Andric} // namespace __gnu_cxx 8660b57cec5SDimitry Andric 867bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 868bdd1243dSDimitry Andric# include <concepts> 869bdd1243dSDimitry Andric# include <iterator> 87006c3fb27SDimitry Andric# include <type_traits> 871bdd1243dSDimitry Andric#endif 872bdd1243dSDimitry Andric 8730b57cec5SDimitry Andric#endif // _LIBCPP_HASH_MAP 874