diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-11-01 23:53:52 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2024-11-13 20:21:40 +0000 |
commit | 0935d0d6e6c244031117f3fd7fea2bfa78295f75 (patch) | |
tree | b571efdbe3a8bc3237e6397caa1ee58c525b71ed | |
parent | d2970e86c4de89b4ba38fa935f1be65681970c69 (diff) | |
download | gcc-0935d0d6e6c244031117f3fd7fea2bfa78295f75.zip gcc-0935d0d6e6c244031117f3fd7fea2bfa78295f75.tar.gz gcc-0935d0d6e6c244031117f3fd7fea2bfa78295f75.tar.bz2 |
libstdc++: Remove _Insert base class from _Hashtable
There's no reason to have a separate base class defining the insert
member functions now. They can all be moved into the _Hashtable class,
which simplifies them slightly.
libstdc++-v3/ChangeLog:
* include/bits/hashtable.h (_Hashtable): Remove inheritance from
__detail::_Insert and move its members into _Hashtable.
* include/bits/hashtable_policy.h (__detail::_Insert): Remove.
Reviewed-by: François Dumont <fdumont@gcc.gnu.org>
-rw-r--r-- | libstdc++-v3/include/bits/hashtable.h | 164 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/hashtable_policy.h | 195 |
2 files changed, 144 insertions, 215 deletions
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index a46a94e..9db568a 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -169,7 +169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * * Functionality is implemented by decomposition into base classes, * where the derived _Hashtable class is used in _Map_base, - * _Insert, _Rehash_base, and _Equality base classes to access the + * _Rehash_base, and _Equality base classes to access the * "this" pointer. _Hashtable_base is used in the base classes as a * non-recursive, fully-completed-type so that detailed nested type * information, such as iterator type and node type, can be @@ -180,7 +180,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Base class templates are: * - __detail::_Hashtable_base * - __detail::_Map_base - * - __detail::_Insert * - __detail::_Rehash_base * - __detail::_Equality */ @@ -194,9 +193,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>, - public __detail::_Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, - _Hash, _RangeHash, _Unused, - _RehashPolicy, _Traits>, public __detail::_Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>, @@ -237,10 +233,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __node_base_ptr = typename __hashtable_alloc::__node_base_ptr; using __buckets_ptr = typename __hashtable_alloc::__buckets_ptr; - using __insert_base = __detail::_Insert<_Key, _Value, _Alloc, _ExtractKey, - _Equal, _Hash, - _RangeHash, _Unused, - _RehashPolicy, _Traits>; using __enable_default_ctor = _Hashtable_enable_default_ctor<_Equal, _Hash, _Alloc>; using __rehash_guard_t @@ -259,9 +251,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef value_type& reference; typedef const value_type& const_reference; - using iterator = typename __insert_base::iterator; + using iterator + = __detail::_Node_iterator<_Value, __constant_iterators::value, + __hash_cached::value>; - using const_iterator = typename __insert_base::const_iterator; + using const_iterator + = __detail::_Node_const_iterator<_Value, __constant_iterators::value, + __hash_cached::value>; using local_iterator = __detail::_Local_iterator<key_type, _Value, _ExtractKey, _Hash, _RangeHash, _Unused, @@ -284,7 +280,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __hash_code_base = typename __hashtable_base::__hash_code_base; using __hash_code = typename __hashtable_base::__hash_code; - using __ireturn_type = typename __insert_base::__ireturn_type; + using __ireturn_type = __conditional_t<__unique_keys::value, + std::pair<iterator, bool>, + iterator>; using __map_base = __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, @@ -358,12 +356,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Keya, typename _Valuea, typename _Alloca, typename _ExtractKeya, typename _Equala, typename _Hasha, typename _RangeHasha, typename _Unuseda, - typename _RehashPolicya, typename _Traitsa> - friend struct __detail::_Insert; - - template<typename _Keya, typename _Valuea, typename _Alloca, - typename _ExtractKeya, typename _Equala, - typename _Hasha, typename _RangeHasha, typename _Unuseda, typename _RehashPolicya, typename _Traitsa, bool _Unique_keysa> friend struct __detail::_Equality; @@ -957,6 +949,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION iterator _M_erase(size_type __bkt, __node_base_ptr __prev_n, __node_ptr __n); + template<typename _InputIterator> + void + _M_insert_range_multi(_InputIterator __first, _InputIterator __last); + public: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr @@ -980,9 +976,107 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else return _M_emplace_multi(__hint, std::forward<_Args>(__args)...); } -#pragma GCC diagnostic pop - // Insert member functions via inheritance. + // Insert + __ireturn_type + insert(const value_type& __v) + { + if constexpr (__unique_keys::value) + return _M_emplace_uniq(__v); + else + return _M_emplace_multi(cend(), __v); + } + + iterator + insert(const_iterator __hint, const value_type& __v) + { + if constexpr (__unique_keys::value) + return _M_emplace_uniq(__v).first; + else + return _M_emplace_multi(__hint, __v); + } + + __ireturn_type + insert(value_type&& __v) + { + if constexpr (__unique_keys::value) + return _M_emplace_uniq(std::move(__v)); + else + return _M_emplace_multi(cend(), std::move(__v)); + } + + iterator + insert(const_iterator __hint, value_type&& __v) + { + if constexpr (__unique_keys::value) + return _M_emplace_uniq(std::move(__v)).first; + else + return _M_emplace_multi(__hint, std::move(__v)); + } + +#ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED + template<typename _KType, typename... _Args> + std::pair<iterator, bool> + try_emplace(const_iterator, _KType&& __k, _Args&&... __args) + { + auto __code = this->_M_hash_code(__k); + std::size_t __bkt = _M_bucket_index(__code); + if (auto __node = _M_find_node(__bkt, __k, __code)) + return { iterator(__node), false }; + + _Scoped_node __node { + this, + std::piecewise_construct, + std::forward_as_tuple(std::forward<_KType>(__k)), + std::forward_as_tuple(std::forward<_Args>(__args)...) + }; + auto __it = _M_insert_unique_node(__bkt, __code, __node._M_node); + __node._M_node = nullptr; + return { __it, true }; + } +#endif + + void + insert(initializer_list<value_type> __l) + { this->insert(__l.begin(), __l.end()); } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + if constexpr (__unique_keys::value) + for (; __first != __last; ++__first) + _M_emplace_uniq(*__first); + else + return _M_insert_range_multi(__first, __last); + } + + // This overload is only defined for maps, not sets. + template<typename _Pair, + typename = _Require<__not_<is_same<_Key, _Value>>, + is_constructible<value_type, _Pair&&>>> + __ireturn_type + insert(_Pair&& __v) + { + if constexpr (__unique_keys::value) + return _M_emplace_uniq(std::forward<_Pair>(__v)); + else + return _M_emplace_multi(cend(), std::forward<_Pair>(__v)); + } + + // This overload is only defined for maps, not sets. + template<typename _Pair, + typename = _Require<__not_<is_same<_Key, _Value>>, + is_constructible<value_type, _Pair&&>>> + iterator + insert(const_iterator __hint, _Pair&& __v) + { + if constexpr (__unique_keys::value) + return _M_emplace_uniq(std::forward<_Pair>(__v)); + else + return _M_emplace_multi(__hint, std::forward<_Pair>(__v)); + } +#pragma GCC diagnostic pop // Erase iterator @@ -2216,6 +2310,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _ExtractKey, typename _Equal, typename _Hash, typename _RangeHash, typename _Unused, typename _RehashPolicy, typename _Traits> + template<typename _InputIterator> + void + _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, + _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: + _M_insert_range_multi(_InputIterator __first, _InputIterator __last) + { + using __pair_type = std::pair<bool, std::size_t>; + + size_type __n_elt = __detail::__distance_fw(__first, __last); + if (__n_elt == 0) + return; + + __rehash_guard_t __rehash_guard(_M_rehash_policy); + __pair_type __do_rehash + = _M_rehash_policy._M_need_rehash(_M_bucket_count, + _M_element_count, + __n_elt); + + if (__do_rehash.first) + _M_rehash(__do_rehash.second, false_type{}); + + __rehash_guard._M_guarded_obj = nullptr; + for (; __first != __last; ++__first) + _M_emplace_multi(cend(), *__first); + } + + template<typename _Key, typename _Value, typename _Alloc, + typename _ExtractKey, typename _Equal, + typename _Hash, typename _RangeHash, typename _Unused, + typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>:: diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index cf97e57..3fd85bf 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -947,201 +947,6 @@ namespace __detail _RangeHash, _Unused, _RehashPolicy, _Traits, __uniq> { }; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr - - // Defines `insert` member functions for _Hashtables. - template<typename _Key, typename _Value, typename _Alloc, - typename _ExtractKey, typename _Equal, - typename _Hash, typename _RangeHash, typename _Unused, - typename _RehashPolicy, typename _Traits> - struct _Insert - { - protected: - using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey, - _Equal, _Hash, _RangeHash, - _Unused, _Traits>; - - using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, - _Hash, _RangeHash, - _Unused, _RehashPolicy, _Traits>; - - using __hash_cached = typename _Traits::__hash_cached; - using __constant_iterators = typename _Traits::__constant_iterators; - - using __hashtable_alloc = _Hashtable_alloc< - __alloc_rebind<_Alloc, _Hash_node<_Value, - __hash_cached::value>>>; - - using value_type = typename __hashtable_base::value_type; - using size_type = typename __hashtable_base::size_type; - - using __unique_keys = typename _Traits::__unique_keys; - using __node_alloc_type = typename __hashtable_alloc::__node_alloc_type; - - [[__gnu__::__always_inline__]] - __hashtable& - _M_conjure_hashtable() - { return *(static_cast<__hashtable*>(this)); } - - template<typename _InputIterator> - void - _M_insert_range_multi(_InputIterator __first, _InputIterator __last); - - public: - using iterator = _Node_iterator<_Value, __constant_iterators::value, - __hash_cached::value>; - - using const_iterator = _Node_const_iterator<_Value, - __constant_iterators::value, - __hash_cached::value>; - - using __ireturn_type = __conditional_t<__unique_keys::value, - std::pair<iterator, bool>, - iterator>; - - __ireturn_type - insert(const value_type& __v) - { - __hashtable& __h = _M_conjure_hashtable(); - if constexpr (__unique_keys::value) - return __h._M_emplace_uniq(__v); - else - return __h._M_emplace_multi(__h.cend(), __v); - } - - iterator - insert(const_iterator __hint, const value_type& __v) - { - __hashtable& __h = _M_conjure_hashtable(); - if constexpr (__unique_keys::value) - return __h._M_emplace_uniq(__v).first; - else - return __h._M_emplace_multi(__hint, __v); - } - - __ireturn_type - insert(value_type&& __v) - { - __hashtable& __h = _M_conjure_hashtable(); - if constexpr (__unique_keys::value) - return __h._M_emplace_uniq(std::move(__v)); - else - return __h._M_emplace_multi(__h.cend(), std::move(__v)); - } - - iterator - insert(const_iterator __hint, value_type&& __v) - { - __hashtable& __h = _M_conjure_hashtable(); - if constexpr (__unique_keys::value) - return __h._M_emplace_uniq(std::move(__v)).first; - else - return __h._M_emplace_multi(__hint, std::move(__v)); - } - -#ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED - template<typename _KType, typename... _Args> - std::pair<iterator, bool> - try_emplace(const_iterator, _KType&& __k, _Args&&... __args) - { - __hashtable& __h = _M_conjure_hashtable(); - auto __code = __h._M_hash_code(__k); - std::size_t __bkt = __h._M_bucket_index(__code); - if (auto __node = __h._M_find_node(__bkt, __k, __code)) - return { iterator(__node), false }; - - typename __hashtable::_Scoped_node __node { - &__h, - std::piecewise_construct, - std::forward_as_tuple(std::forward<_KType>(__k)), - std::forward_as_tuple(std::forward<_Args>(__args)...) - }; - auto __it - = __h._M_insert_unique_node(__bkt, __code, __node._M_node); - __node._M_node = nullptr; - return { __it, true }; - } -#endif - - void - insert(initializer_list<value_type> __l) - { this->insert(__l.begin(), __l.end()); } - - template<typename _InputIterator> - void - insert(_InputIterator __first, _InputIterator __last) - { - __hashtable& __h = _M_conjure_hashtable(); - if constexpr (__unique_keys::value) - for (; __first != __last; ++__first) - __h._M_emplace_uniq(*__first); - else - return _M_insert_range_multi(__first, __last); - } - - // This overload is only defined for maps, not sets. - template<typename _Pair, - typename = _Require<__not_<is_same<_Key, _Value>>, - is_constructible<value_type, _Pair&&>>> - __ireturn_type - insert(_Pair&& __v) - { - __hashtable& __h = this->_M_conjure_hashtable(); - if constexpr (__unique_keys::value) - return __h._M_emplace_uniq(std::forward<_Pair>(__v)); - else - return __h._M_emplace_multi(__h.cend(), std::forward<_Pair>(__v)); - } - - // This overload is only defined for maps, not sets. - template<typename _Pair, - typename = _Require<__not_<is_same<_Key, _Value>>, - is_constructible<value_type, _Pair&&>>> - iterator - insert(const_iterator __hint, _Pair&& __v) - { - __hashtable& __h = this->_M_conjure_hashtable(); - if constexpr (__unique_keys::value) - return __h._M_emplace_uniq(std::forward<_Pair>(__v)); - else - return __h._M_emplace_multi(__hint, std::forward<_Pair>(__v)); - } - }; -#pragma GCC diagnostic pop - - template<typename _Key, typename _Value, typename _Alloc, - typename _ExtractKey, typename _Equal, - typename _Hash, typename _RangeHash, typename _Unused, - typename _RehashPolicy, typename _Traits> - template<typename _InputIterator> - void - _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, - _Unused, _RehashPolicy, _Traits>:: - _M_insert_range_multi(_InputIterator __first, _InputIterator __last) - { - using __rehash_guard_t = typename __hashtable::__rehash_guard_t; - using __pair_type = std::pair<bool, std::size_t>; - - size_type __n_elt = __detail::__distance_fw(__first, __last); - if (__n_elt == 0) - return; - - __hashtable& __h = _M_conjure_hashtable(); - __rehash_guard_t __rehash_guard(__h._M_rehash_policy); - __pair_type __do_rehash - = __h._M_rehash_policy._M_need_rehash(__h._M_bucket_count, - __h._M_element_count, - __n_elt); - - if (__do_rehash.first) - __h._M_rehash(__do_rehash.second, false_type{}); - - __rehash_guard._M_guarded_obj = nullptr; - for (; __first != __last; ++__first) - __h._M_emplace_multi(__h.cend(), *__first); - } - template<typename _Policy> using __has_load_factor = typename _Policy::__has_load_factor; |