diff options
author | hiddenpath <hiddenpath@yandex-team.com> | 2024-02-21 23:16:42 +0300 |
---|---|---|
committer | hiddenpath <hiddenpath@yandex-team.com> | 2024-02-21 23:33:25 +0300 |
commit | 9052eb5cc304b8da8885fc4e3364ebddc16945f3 (patch) | |
tree | 3c252f6161dd0745c7732d74c9304c000645ab47 /contrib/libs/cxxsupp/libcxx/include/unordered_set | |
parent | f5eb715f103692e7c7536e13bef3f281fd78e5e7 (diff) | |
download | ydb-9052eb5cc304b8da8885fc4e3364ebddc16945f3.tar.gz |
Update libcxx to llvmorg-17.0.6
Update libcxx to llvmorg-17.0.6
c871ef572c71b4fef22d4a9e65bcebc57e625aea
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/include/unordered_set')
-rw-r--r-- | contrib/libs/cxxsupp/libcxx/include/unordered_set | 484 |
1 files changed, 321 insertions, 163 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/unordered_set b/contrib/libs/cxxsupp/libcxx/include/unordered_set index b4203c08a9..5e47f12446 100644 --- a/contrib/libs/cxxsupp/libcxx/include/unordered_set +++ b/contrib/libs/cxxsupp/libcxx/include/unordered_set @@ -58,6 +58,10 @@ public: size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); + template<container-compatible-range<value_type> R> + unordered_set(from_range_t, R&& rg, size_type n = see below, + const hasher& hf = hasher(), const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); // C++23 explicit unordered_set(const allocator_type&); unordered_set(const unordered_set&); unordered_set(const unordered_set&, const Allocator&); @@ -77,6 +81,12 @@ public: template <class InputIterator> unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); // C++14 + template<container-compatible-range<value_type> R> + unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) + : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23 + template<container-compatible-range<value_type> R> + unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) + : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23 unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14 unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf, const allocator_type& a); // C++14 @@ -113,6 +123,8 @@ public: iterator insert(const_iterator hint, value_type&& obj); template <class InputIterator> void insert(InputIterator first, InputIterator last); + template<container-compatible-range<value_type> R> + void insert_range(R&& rg); // C++23 void insert(initializer_list<value_type>); node_type extract(const_iterator position); // C++17 @@ -191,6 +203,13 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type = see -> unordered_set<typename iterator_traits<InputIterator>::value_type, Hash, Pred, Allocator>; // C++17 +template<ranges::input_range R, + class Hash = hash<ranges::range_value_t<R>>, + class Pred = equal_to<ranges::range_value_t<R>>, + class Allocator = allocator<ranges::range_value_t<R>>> + unordered_set(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23 + template<class T, class Hash = hash<T>, class Pred = equal_to<T>, class Allocator = allocator<T>> unordered_set(initializer_list<T>, typename see below::size_type = see below, @@ -211,6 +230,21 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type, equal_to<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 +template<ranges::input_range R, class Allocator> + unordered_set(from_range_t, R&&, typename see below::size_type, Allocator) + -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, + equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 + +template<ranges::input_range R, class Allocator> + unordered_set(from_range_t, R&&, Allocator) + -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, + equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 + +template<ranges::input_range R, class Hash, class Allocator> + unordered_set(from_range_t, R&&, typename see below::size_type, Hash, Allocator) + -> unordered_set<ranges::range_value_t<R>, Hash, + equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 + template<class T, class Allocator> unordered_set(initializer_list<T>, typename see below::size_type, Allocator) -> unordered_set<T, hash<T>, equal_to<T>, Allocator>; // C++17 @@ -232,7 +266,7 @@ template <class Value, class Hash, class Pred, class Alloc> template <class Value, class Hash, class Pred, class Alloc> bool operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x, - const unordered_set<Value, Hash, Pred, Alloc>& y); + const unordered_set<Value, Hash, Pred, Alloc>& y); // removed in C++20 template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, class Alloc = allocator<Value>> @@ -272,6 +306,10 @@ public: size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); + template<container-compatible-range<value_type> R> + unordered_multiset(from_range_t, R&& rg, size_type n = see below, + const hasher& hf = hasher(), const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); // C++23 explicit unordered_multiset(const allocator_type&); unordered_multiset(const unordered_multiset&); unordered_multiset(const unordered_multiset&, const Allocator&); @@ -291,6 +329,12 @@ public: template <class InputIterator> unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); // C++14 + template<container-compatible-range<value_type> R> + unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) + : unordered_multiset(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23 + template<container-compatible-range<value_type> R> + unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) + : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23 unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14 unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf, const allocator_type& a); // C++14 @@ -327,6 +371,8 @@ public: iterator insert(const_iterator hint, value_type&& obj); template <class InputIterator> void insert(InputIterator first, InputIterator last); + template<container-compatible-range<value_type> R> + void insert_range(R&& rg); // C++23 void insert(initializer_list<value_type>); node_type extract(const_iterator position); // C++17 @@ -405,6 +451,13 @@ unordered_multiset(InputIterator, InputIterator, see below::size_type = see belo -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash, Pred, Allocator>; // C++17 +template<ranges::input_range R, + class Hash = hash<ranges::range_value_t<R>>, + class Pred = equal_to<ranges::range_value_t<R>>, + class Allocator = allocator<ranges::range_value_t<R>>> + unordered_multiset(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23 + template<class T, class Hash = hash<T>, class Pred = equal_to<T>, class Allocator = allocator<T>> unordered_multiset(initializer_list<T>, typename see below::size_type = see below, @@ -424,6 +477,21 @@ unordered_multiset(InputIterator, InputIterator, typename see below::size_type, -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash, equal_to<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 +template<ranges::input_range R, class Allocator> + unordered_multiset(from_range_t, R&&, typename see below::size_type, Allocator) + -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, + equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 + +template<ranges::input_range R, class Allocator> + unordered_multiset(from_range_t, R&&, Allocator) + -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, + equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 + +template<ranges::input_range R, class Hash, class Allocator> + unordered_multiset(from_range_t, R&&, typename see below::size_type, Hash, Allocator) + -> unordered_multiset<ranges::range_value_t<R>, Hash, + equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 + template<class T, class Allocator> unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator) -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>; // C++17 @@ -454,25 +522,29 @@ template <class Value, class Hash, class Pred, class Alloc> template <class Value, class Hash, class Pred, class Alloc> bool operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x, - const unordered_multiset<Value, Hash, Pred, Alloc>& y); + const unordered_multiset<Value, Hash, Pred, Alloc>& y); // removed in C++20 } // std */ #include <__algorithm/is_permutation.h> #include <__assert> // all public C++ headers provide the assertion handler +#include <__availability> #include <__config> -#include <__debug> #include <__functional/is_transparent.h> #include <__functional/operations.h> #include <__hash_table> #include <__iterator/distance.h> #include <__iterator/erase_if_container.h> #include <__iterator/iterator_traits.h> +#include <__iterator/ranges_iterator_traits.h> #include <__memory/addressof.h> #include <__memory/allocator.h> #include <__memory_resource/polymorphic_allocator.h> #include <__node_handle> +#include <__ranges/concepts.h> +#include <__ranges/container_compatible_range.h> +#include <__ranges/from_range.h> #include <__type_traits/is_allocator.h> #include <__utility/forward.h> #include <version> @@ -513,7 +585,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), - "Invalid allocator::value_type"); + "Allocator::value_type must be same type as value_type"); static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value, "[allocator.requirements] states that rebinding an allocator to the same type should result in the " @@ -535,7 +607,7 @@ public: typedef typename __table::const_local_iterator local_iterator; typedef typename __table::const_local_iterator const_local_iterator; -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 17 typedef __set_node_handle<typename __table::__node, allocator_type> node_type; typedef __insert_return_type<iterator, node_type> insert_return_type; #endif @@ -549,11 +621,10 @@ public: unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { - _VSTD::__debug_db_insert_c(this); } - explicit unordered_set(size_type __n, const hasher& __hf = hasher(), + explicit _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER >= 14 inline _LIBCPP_INLINE_VISIBILITY unordered_set(size_type __n, const allocator_type& __a) : unordered_set(__n, hasher(), key_equal(), __a) {} @@ -561,46 +632,74 @@ public: unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__n, __hf, key_equal(), __a) {} #endif - unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, + _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last); + _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last); template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last, + _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last, + _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 + +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + unordered_set(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0, + const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : __table_(__hf, __eql, __a) { + if (__n > 0) { + __table_.__rehash_unique(__n); + } + insert_range(std::forward<_Range>(__range)); + } +#endif + +#if _LIBCPP_STD_VER >= 14 template <class _InputIterator> inline _LIBCPP_INLINE_VISIBILITY unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {} template <class _InputIterator> - unordered_set(_InputIterator __first, _InputIterator __last, + _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {} #endif + +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + unordered_set(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) + : unordered_set(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} + + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + unordered_set(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) + : unordered_set(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} +#endif + _LIBCPP_INLINE_VISIBILITY explicit unordered_set(const allocator_type& __a); - unordered_set(const unordered_set& __u); - unordered_set(const unordered_set& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u); + _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY unordered_set(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); - unordered_set(unordered_set&& __u, const allocator_type& __a); - unordered_set(initializer_list<value_type> __il); - unordered_set(initializer_list<value_type> __il, size_type __n, + _LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il); + _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); - unordered_set(initializer_list<value_type> __il, size_type __n, + _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER >= 14 inline _LIBCPP_INLINE_VISIBILITY unordered_set(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) @@ -661,11 +760,7 @@ public: {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);} template <class... _Args> _LIBCPP_INLINE_VISIBILITY - iterator emplace_hint(const_iterator __p, _Args&&... __args) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this, - "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered_set"); - (void)__p; + iterator emplace_hint(const_iterator, _Args&&... __args) { return __table_.__emplace_unique(std::forward<_Args>(__args)...).first; } @@ -673,11 +768,7 @@ public: pair<iterator, bool> insert(value_type&& __x) {return __table_.__insert_unique(_VSTD::move(__x));} _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, value_type&& __x) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this, - "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" - " referring to this unordered_set"); - (void)__p; + iterator insert(const_iterator, value_type&& __x) { return insert(std::move(__x)).first; } @@ -690,17 +781,23 @@ public: {return __table_.__insert_unique(__x);} _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, const value_type& __x) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this, - "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_set"); - (void)__p; + iterator insert(const_iterator, const value_type& __x) { return insert(__x).first; } template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + void insert_range(_Range&& __range) { + for (auto&& __element : __range) { + __table_.__insert_unique(std::forward<decltype(__element)>(__element)); + } + } +#endif + _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p);} _LIBCPP_INLINE_VISIBILITY @@ -711,11 +808,11 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT {__table_.clear();} -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 17 _LIBCPP_INLINE_VISIBILITY insert_return_type insert(node_type&& __nh) { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_set::insert()"); return __table_.template __node_handle_insert_unique< node_type, insert_return_type>(_VSTD::move(__nh)); @@ -723,7 +820,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __h, node_type&& __nh) { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_set::insert()"); return __table_.template __node_handle_insert_unique<node_type>( __h, _VSTD::move(__nh)); @@ -743,32 +840,32 @@ public: _LIBCPP_INLINE_VISIBILITY void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } template<class _H2, class _P2> _LIBCPP_INLINE_VISIBILITY void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } template<class _H2, class _P2> _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } template<class _H2, class _P2> _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); __table_.__node_handle_merge_unique(__source.__table_); } #endif @@ -787,31 +884,31 @@ public: 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);} -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY iterator find(const _K2& __k) {return __table_.find(__k);} template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY const_iterator find(const _K2& __k) const {return __table_.find(__k);} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY size_type count(const _K2& __k) const {return __table_.__count_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY bool contains(const key_type& __k) const {return find(__k) != end();} template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY bool contains(const _K2& __k) const {return find(__k) != end();} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const key_type& __k) @@ -819,7 +916,7 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {return __table_.__equal_range_unique(__k);} -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const _K2& __k) @@ -828,7 +925,7 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {return __table_.__equal_range_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} @@ -863,20 +960,6 @@ public: void rehash(size_type __n) {__table_.__rehash_unique(__n);} _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.__reserve_unique(__n);} - -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(__i);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(__i);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - -#endif // _LIBCPP_ENABLE_DEBUG_MODE - }; #if _LIBCPP_STD_VER >= 17 @@ -884,7 +967,7 @@ template<class _InputIterator, class _Hash = hash<__iter_value_type<_InputIterator>>, class _Pred = equal_to<__iter_value_type<_InputIterator>>, class _Allocator = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, class = enable_if_t<!__is_allocator<_Hash>::value>, class = enable_if_t<!is_integral<_Hash>::value>, class = enable_if_t<!__is_allocator<_Pred>::value>, @@ -893,6 +976,20 @@ unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocat _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>; +#if _LIBCPP_STD_VER >= 23 +template <ranges::input_range _Range, + class _Hash = hash<ranges::range_value_t<_Range>>, + class _Pred = equal_to<ranges::range_value_t<_Range>>, + class _Allocator = allocator<ranges::range_value_t<_Range>>, + class = enable_if_t<!__is_allocator<_Hash>::value>, + class = enable_if_t<!is_integral<_Hash>::value>, + class = enable_if_t<!__is_allocator<_Pred>::value>, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0, + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) + -> unordered_set<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23 +#endif + template<class _Tp, class _Hash = hash<_Tp>, class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>, @@ -905,7 +1002,7 @@ unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size -> unordered_set<_Tp, _Hash, _Pred, _Allocator>; template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, class = enable_if_t<__is_allocator<_Allocator>::value>> unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) @@ -915,7 +1012,7 @@ unordered_set(_InputIterator, _InputIterator, _Allocator>; template<class _InputIterator, class _Hash, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, class = enable_if_t<!__is_allocator<_Hash>::value>, class = enable_if_t<!is_integral<_Hash>::value>, class = enable_if_t<__is_allocator<_Allocator>::value>> @@ -925,6 +1022,29 @@ unordered_set(_InputIterator, _InputIterator, equal_to<__iter_value_type<_InputIterator>>, _Allocator>; +#if _LIBCPP_STD_VER >= 23 + +template <ranges::input_range _Range, class _Allocator, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, + equal_to<ranges::range_value_t<_Range>>, _Allocator>; + +template <ranges::input_range _Range, class _Allocator, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_set(from_range_t, _Range&&, _Allocator) + -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, + equal_to<ranges::range_value_t<_Range>>, _Allocator>; + +template <ranges::input_range _Range, class _Hash, class _Allocator, + class = enable_if_t<!__is_allocator<_Hash>::value>, + class = enable_if_t<!is_integral<_Hash>::value>, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) + -> unordered_set<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>; + +#endif + template<class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>> unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) @@ -943,7 +1063,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__n); } @@ -952,7 +1071,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__n); } @@ -961,7 +1079,6 @@ template <class _InputIterator> unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _InputIterator __first, _InputIterator __last) { - _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -972,7 +1089,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__n); insert(__first, __last); } @@ -984,7 +1100,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__n); insert(__first, __last); } @@ -995,7 +1110,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const allocator_type& __a) : __table_(__a) { - _VSTD::__debug_db_insert_c(this); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1003,7 +1117,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const unordered_set& __u) : __table_(__u.__table_) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1013,7 +1126,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const unordered_set& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1027,8 +1139,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { - _VSTD::__debug_db_insert_c(this); - std::__debug_db_swap(this, std::addressof(__u)); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1036,22 +1146,18 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( unordered_set&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { - _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); while (__u.size() != 0) __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_)); } - else - std::__debug_db_swap(this, std::addressof(__u)); } template <class _Value, class _Hash, class _Pred, class _Alloc> unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( initializer_list<value_type> __il) { - _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1061,7 +1167,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const key_equal& __eql) : __table_(__hf, __eql) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__n); insert(__il.begin(), __il.end()); } @@ -1072,7 +1177,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_unique(__n); insert(__il.begin(), __il.end()); } @@ -1120,7 +1224,7 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> inline _LIBCPP_INLINE_VISIBILITY @@ -1150,6 +1254,8 @@ operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, return true; } +#if _LIBCPP_STD_VER <= 17 + template <class _Value, class _Hash, class _Pred, class _Alloc> inline _LIBCPP_INLINE_VISIBILITY bool @@ -1159,6 +1265,8 @@ operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, return !(__x == __y); } +#endif + template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>, class _Alloc = allocator<_Value> > class _LIBCPP_TEMPLATE_VIS unordered_multiset @@ -1173,7 +1281,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), - "Invalid allocator::value_type"); + "Allocator::value_type must be same type as value_type"); private: typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; @@ -1191,7 +1299,7 @@ public: typedef typename __table::const_local_iterator local_iterator; typedef typename __table::const_local_iterator const_local_iterator; -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 17 typedef __set_node_handle<typename __table::__node, allocator_type> node_type; #endif @@ -1204,13 +1312,12 @@ public: unordered_multiset() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { - _VSTD::__debug_db_insert_c(this); } - explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), + explicit _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); - unordered_multiset(size_type __n, const hasher& __hf, + _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER >= 14 inline _LIBCPP_INLINE_VISIBILITY unordered_multiset(size_type __n, const allocator_type& __a) : unordered_multiset(__n, hasher(), key_equal(), __a) {} @@ -1219,16 +1326,31 @@ public: : unordered_multiset(__n, __hf, key_equal(), __a) {} #endif template <class _InputIterator> - unordered_multiset(_InputIterator __first, _InputIterator __last); + _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last); template <class _InputIterator> - unordered_multiset(_InputIterator __first, _InputIterator __last, + _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); template <class _InputIterator> - unordered_multiset(_InputIterator __first, _InputIterator __last, + _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n , const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 + +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + unordered_multiset(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0, + const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), + const allocator_type& __a = allocator_type()) + : __table_(__hf, __eql, __a) { + if (__n > 0) { + __table_.__rehash_multi(__n); + } + insert_range(std::forward<_Range>(__range)); + } +#endif + +#if _LIBCPP_STD_VER >= 14 template <class _InputIterator> inline _LIBCPP_INLINE_VISIBILITY unordered_multiset(_InputIterator __first, _InputIterator __last, @@ -1240,23 +1362,36 @@ public: size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {} #endif + +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + unordered_multiset(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) + : unordered_multiset(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} + + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + unordered_multiset(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) + : unordered_multiset(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} +#endif + _LIBCPP_INLINE_VISIBILITY explicit unordered_multiset(const allocator_type& __a); - unordered_multiset(const unordered_multiset& __u); - unordered_multiset(const unordered_multiset& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u); + _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY unordered_multiset(unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); - unordered_multiset(unordered_multiset&& __u, const allocator_type& __a); - unordered_multiset(initializer_list<value_type> __il); - unordered_multiset(initializer_list<value_type> __il, size_type __n, + _LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il); + _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); - unordered_multiset(initializer_list<value_type> __il, size_type __n, + _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -#if _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER >= 14 inline _LIBCPP_INLINE_VISIBILITY unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {} @@ -1280,7 +1415,7 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multiset& operator=(unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); - unordered_multiset& operator=(initializer_list<value_type> __il); + _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY @@ -1338,11 +1473,21 @@ public: _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 23 + template <_ContainerCompatibleRange<value_type> _Range> + _LIBCPP_HIDE_FROM_ABI + void insert_range(_Range&& __range) { + for (auto&& __element : __range) { + __table_.__insert_multi(std::forward<decltype(__element)>(__element)); + } + } +#endif + +#if _LIBCPP_STD_VER >= 17 _LIBCPP_INLINE_VISIBILITY iterator insert(node_type&& __nh) { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_multiset::insert()"); return __table_.template __node_handle_insert_multi<node_type>( _VSTD::move(__nh)); @@ -1350,7 +1495,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __hint, node_type&& __nh) { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), "node_type with incompatible allocator passed to unordered_multiset::insert()"); return __table_.template __node_handle_insert_multi<node_type>( __hint, _VSTD::move(__nh)); @@ -1371,32 +1516,32 @@ public: _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template <class _H2, class _P2> _LIBCPP_INLINE_VISIBILITY void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template <class _H2, class _P2> _LIBCPP_INLINE_VISIBILITY void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } template <class _H2, class _P2> _LIBCPP_INLINE_VISIBILITY void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); return __table_.__node_handle_merge_multi(__source.__table_); } #endif @@ -1425,31 +1570,31 @@ public: 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);} -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY iterator find(const _K2& __k) {return __table_.find(__k);} template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY const_iterator find(const _K2& __k) const {return __table_.find(__k);} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY size_type count(const _K2& __k) const {return __table_.__count_multi(__k);} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY bool contains(const key_type& __k) const {return find(__k) != end();} template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY bool contains(const _K2& __k) const {return find(__k) != end();} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const key_type& __k) @@ -1457,7 +1602,7 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {return __table_.__equal_range_multi(__k);} -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> _LIBCPP_INLINE_VISIBILITY pair<iterator, iterator> equal_range(const _K2& __k) @@ -1466,7 +1611,7 @@ public: _LIBCPP_INLINE_VISIBILITY pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {return __table_.__equal_range_multi(__k);} -#endif // _LIBCPP_STD_VER > 17 +#endif // _LIBCPP_STD_VER >= 20 _LIBCPP_INLINE_VISIBILITY size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} @@ -1501,20 +1646,6 @@ public: void rehash(size_type __n) {__table_.__rehash_multi(__n);} _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.__reserve_multi(__n);} - -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(__i);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(__i);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - -#endif // _LIBCPP_ENABLE_DEBUG_MODE - }; #if _LIBCPP_STD_VER >= 17 @@ -1522,7 +1653,7 @@ template<class _InputIterator, class _Hash = hash<__iter_value_type<_InputIterator>>, class _Pred = equal_to<__iter_value_type<_InputIterator>>, class _Allocator = allocator<__iter_value_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, class = enable_if_t<!__is_allocator<_Hash>::value>, class = enable_if_t<!is_integral<_Hash>::value>, class = enable_if_t<!__is_allocator<_Pred>::value>, @@ -1531,6 +1662,20 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>; +#if _LIBCPP_STD_VER >= 23 +template <ranges::input_range _Range, + class _Hash = hash<ranges::range_value_t<_Range>>, + class _Pred = equal_to<ranges::range_value_t<_Range>>, + class _Allocator = allocator<ranges::range_value_t<_Range>>, + class = enable_if_t<!__is_allocator<_Hash>::value>, + class = enable_if_t<!is_integral<_Hash>::value>, + class = enable_if_t<!__is_allocator<_Pred>::value>, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0, + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) + -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23 +#endif + template<class _Tp, class _Hash = hash<_Tp>, class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>, class = enable_if_t<!__is_allocator<_Hash>::value>, @@ -1542,7 +1687,7 @@ unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>: -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>; template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, class = enable_if_t<__is_allocator<_Allocator>::value>> unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) -> unordered_multiset<__iter_value_type<_InputIterator>, @@ -1551,7 +1696,7 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al _Allocator>; template<class _InputIterator, class _Hash, class _Allocator, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, + class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, class = enable_if_t<!__is_allocator<_Hash>::value>, class = enable_if_t<!is_integral<_Hash>::value>, class = enable_if_t<__is_allocator<_Allocator>::value>> @@ -1561,6 +1706,29 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al equal_to<__iter_value_type<_InputIterator>>, _Allocator>; +#if _LIBCPP_STD_VER >= 23 + +template <ranges::input_range _Range, class _Allocator, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator) + -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, + equal_to<ranges::range_value_t<_Range>>, _Allocator>; + +template <ranges::input_range _Range, class _Allocator, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_multiset(from_range_t, _Range&&, _Allocator) + -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, + equal_to<ranges::range_value_t<_Range>>, _Allocator>; + +template <ranges::input_range _Range, class _Hash, class _Allocator, + class = enable_if_t<!__is_allocator<_Hash>::value>, + class = enable_if_t<!is_integral<_Hash>::value>, + class = enable_if_t<__is_allocator<_Allocator>::value>> +unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) + -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>; + +#endif + template<class _Tp, class _Allocator, class = enable_if_t<__is_allocator<_Allocator>::value>> unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) @@ -1579,7 +1747,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__n); } @@ -1589,7 +1756,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__hf, __eql, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__n); } @@ -1598,7 +1764,6 @@ template <class _InputIterator> unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _InputIterator __first, _InputIterator __last) { - _VSTD::__debug_db_insert_c(this); insert(__first, __last); } @@ -1609,7 +1774,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__n); insert(__first, __last); } @@ -1621,7 +1785,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__n); insert(__first, __last); } @@ -1632,7 +1795,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__a) { - _VSTD::__debug_db_insert_c(this); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1640,7 +1802,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const unordered_multiset& __u) : __table_(__u.__table_) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1650,7 +1811,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const unordered_multiset& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1664,8 +1824,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { - _VSTD::__debug_db_insert_c(this); - std::__debug_db_swap(this, std::addressof(__u)); } template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1673,22 +1831,18 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( unordered_multiset&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { - _VSTD::__debug_db_insert_c(this); if (__a != __u.get_allocator()) { iterator __i = __u.begin(); while (__u.size() != 0) __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_)); } - else - std::__debug_db_swap(this, std::addressof(__u)); } template <class _Value, class _Hash, class _Pred, class _Alloc> unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( initializer_list<value_type> __il) { - _VSTD::__debug_db_insert_c(this); insert(__il.begin(), __il.end()); } @@ -1698,7 +1852,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const key_equal& __eql) : __table_(__hf, __eql) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__n); insert(__il.begin(), __il.end()); } @@ -1709,7 +1862,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { - _VSTD::__debug_db_insert_c(this); __table_.__rehash_multi(__n); insert(__il.begin(), __il.end()); } @@ -1758,7 +1910,7 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } -#if _LIBCPP_STD_VER > 17 +#if _LIBCPP_STD_VER >= 20 template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> inline _LIBCPP_INLINE_VISIBILITY @@ -1792,6 +1944,8 @@ operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, return true; } +#if _LIBCPP_STD_VER <= 17 + template <class _Value, class _Hash, class _Pred, class _Alloc> inline _LIBCPP_INLINE_VISIBILITY bool @@ -1801,24 +1955,28 @@ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, return !(__x == __y); } +#endif + _LIBCPP_END_NAMESPACE_STD -#if _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_STD namespace pmr { template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>> -using unordered_set = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; +using unordered_set _LIBCPP_AVAILABILITY_PMR = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>> -using unordered_multiset = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; +using unordered_multiset _LIBCPP_AVAILABILITY_PMR = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; } // namespace pmr _LIBCPP_END_NAMESPACE_STD #endif #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 # include <concepts> +# include <cstdlib> # include <functional> # include <iterator> +# include <type_traits> #endif #endif // _LIBCPP_UNORDERED_SET |