mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
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>
This commit is contained in:
parent
d2970e86c4
commit
0935d0d6e6
@ -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,
|
||||
@ -355,12 +353,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
bool _Unique_keysa>
|
||||
friend struct __detail::_Map_base;
|
||||
|
||||
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,
|
||||
@ -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
|
||||
@ -2212,6 +2306,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
return __pos;
|
||||
}
|
||||
|
||||
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
|
||||
_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,
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user