aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-11-01 23:53:52 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2024-11-13 20:21:40 +0000
commit0935d0d6e6c244031117f3fd7fea2bfa78295f75 (patch)
treeb571efdbe3a8bc3237e6397caa1ee58c525b71ed
parentd2970e86c4de89b4ba38fa935f1be65681970c69 (diff)
downloadgcc-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.h164
-rw-r--r--libstdc++-v3/include/bits/hashtable_policy.h195
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;