libstdc++: Review _Local_iterator/_Local_const_iterator implementations.
_Local_iterator_base inherits _Node_iterator_base and so share the same comparison operators. It avoids to expose special method _M_curr for debug mode to compare such iterators. libstdc++-v3/ChangeLog: * include/bits/hashtable_policy.h (_Node_iterator_base()): New. (operator==(const _Node_iterator_base&, const _Node_iterator_base&)): Make hidden friend. (operator!=(const _Node_iterator_base&, const _Node_iterator_base&)): Make hidden friend. (_Local_iterator_base<>): Inherits _Node_iterator_base. (_Local_iterator_base<>::_M_cur): Remove. (_Local_iterator_base<>::_M_curr()): Remove. (operator==(const _Local_iterator_base&, const _Local_iterator_base&)): Remove. (operator!=(const _Local_iterator_base&, const _Local_iterator_base&)): Remove. * include/debug/unordered_map (unordered_map<>::_M_invalidate): Adapt. (unordered_multimap<>::_M_invalidate): Adapt. * include/debug/unordered_set (unordered_set<>::_M_invalidate): Adapt. (unordered_multiset<>::_M_invalidate): Adapt.
This commit is contained in:
parent
1722e2013f
commit
acc1d1a954
|
@ -291,27 +291,26 @@ namespace __detail
|
||||||
|
|
||||||
__node_type* _M_cur;
|
__node_type* _M_cur;
|
||||||
|
|
||||||
|
_Node_iterator_base() = default;
|
||||||
_Node_iterator_base(__node_type* __p) noexcept
|
_Node_iterator_base(__node_type* __p) noexcept
|
||||||
: _M_cur(__p) { }
|
: _M_cur(__p) { }
|
||||||
|
|
||||||
void
|
void
|
||||||
_M_incr() noexcept
|
_M_incr() noexcept
|
||||||
{ _M_cur = _M_cur->_M_next(); }
|
{ _M_cur = _M_cur->_M_next(); }
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _Value, bool _Cache_hash_code>
|
friend bool
|
||||||
inline bool
|
operator==(const _Node_iterator_base& __x, const _Node_iterator_base& __y)
|
||||||
operator==(const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
|
|
||||||
const _Node_iterator_base<_Value, _Cache_hash_code >& __y)
|
|
||||||
noexcept
|
noexcept
|
||||||
{ return __x._M_cur == __y._M_cur; }
|
{ return __x._M_cur == __y._M_cur; }
|
||||||
|
|
||||||
template<typename _Value, bool _Cache_hash_code>
|
#if __cpp_impl_three_way_comparison < 201907L
|
||||||
inline bool
|
friend bool
|
||||||
operator!=(const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
|
operator!=(const _Node_iterator_base& __x, const _Node_iterator_base& __y)
|
||||||
const _Node_iterator_base<_Value, _Cache_hash_code>& __y)
|
|
||||||
noexcept
|
noexcept
|
||||||
{ return __x._M_cur != __y._M_cur; }
|
{ return __x._M_cur != __y._M_cur; }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/// Node iterators, used to iterate through all the hashtable.
|
/// Node iterators, used to iterate through all the hashtable.
|
||||||
template<typename _Value, bool __constant_iterators, bool __cache>
|
template<typename _Value, bool __constant_iterators, bool __cache>
|
||||||
|
@ -334,7 +333,7 @@ namespace __detail
|
||||||
const _Value&, _Value&>::type;
|
const _Value&, _Value&>::type;
|
||||||
|
|
||||||
_Node_iterator() noexcept
|
_Node_iterator() noexcept
|
||||||
: __base_type(0) { }
|
: __base_type(nullptr) { }
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
_Node_iterator(__node_type* __p) noexcept
|
_Node_iterator(__node_type* __p) noexcept
|
||||||
|
@ -382,7 +381,7 @@ namespace __detail
|
||||||
typedef const _Value& reference;
|
typedef const _Value& reference;
|
||||||
|
|
||||||
_Node_const_iterator() noexcept
|
_Node_const_iterator() noexcept
|
||||||
: __base_type(0) { }
|
: __base_type(nullptr) { }
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
_Node_const_iterator(__node_type* __p) noexcept
|
_Node_const_iterator(__node_type* __p) noexcept
|
||||||
|
@ -1431,9 +1430,11 @@ namespace __detail
|
||||||
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
|
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
|
||||||
_H1, _H2, _Hash, true>
|
_H1, _H2, _Hash, true>
|
||||||
: private _Hashtable_ebo_helper<0, _H2>
|
: private _Hashtable_ebo_helper<0, _H2>
|
||||||
|
, _Node_iterator_base<_Value, true>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
using __base_type = _Hashtable_ebo_helper<0, _H2>;
|
using __base_type = _Hashtable_ebo_helper<0, _H2>;
|
||||||
|
using __base_node_iter = _Node_iterator_base<_Value, true>;
|
||||||
using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
|
using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
|
||||||
_H1, _H2, _Hash, true>;
|
_H1, _H2, _Hash, true>;
|
||||||
|
|
||||||
|
@ -1441,31 +1442,27 @@ namespace __detail
|
||||||
_Local_iterator_base(const __hash_code_base& __base,
|
_Local_iterator_base(const __hash_code_base& __base,
|
||||||
_Hash_node<_Value, true>* __p,
|
_Hash_node<_Value, true>* __p,
|
||||||
std::size_t __bkt, std::size_t __bkt_count)
|
std::size_t __bkt, std::size_t __bkt_count)
|
||||||
: __base_type(__base._M_h2()),
|
: __base_type(__base._M_h2()), __base_node_iter(__p)
|
||||||
_M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
|
, _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
|
||||||
|
|
||||||
void
|
void
|
||||||
_M_incr()
|
_M_incr()
|
||||||
{
|
{
|
||||||
_M_cur = _M_cur->_M_next();
|
__base_node_iter::_M_incr();
|
||||||
if (_M_cur)
|
if (this->_M_cur)
|
||||||
{
|
{
|
||||||
std::size_t __bkt
|
std::size_t __bkt
|
||||||
= __base_type::_M_get()(_M_cur->_M_hash_code,
|
= __base_type::_M_get()(this->_M_cur->_M_hash_code,
|
||||||
_M_bucket_count);
|
_M_bucket_count);
|
||||||
if (__bkt != _M_bucket)
|
if (__bkt != _M_bucket)
|
||||||
_M_cur = nullptr;
|
this->_M_cur = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_Hash_node<_Value, true>* _M_cur;
|
|
||||||
std::size_t _M_bucket;
|
std::size_t _M_bucket;
|
||||||
std::size_t _M_bucket_count;
|
std::size_t _M_bucket_count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const void*
|
|
||||||
_M_curr() const { return _M_cur; } // for equality ops
|
|
||||||
|
|
||||||
std::size_t
|
std::size_t
|
||||||
_M_get_bucket() const { return _M_bucket; } // for debug mode
|
_M_get_bucket() const { return _M_bucket; } // for debug mode
|
||||||
};
|
};
|
||||||
|
@ -1513,17 +1510,19 @@ namespace __detail
|
||||||
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
|
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
|
||||||
_H1, _H2, _Hash, false>
|
_H1, _H2, _Hash, false>
|
||||||
: __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash>
|
: __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash>
|
||||||
|
, _Node_iterator_base<_Value, false>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
|
using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
|
||||||
_H1, _H2, _Hash, false>;
|
_H1, _H2, _Hash, false>;
|
||||||
|
using __node_iter_base = _Node_iterator_base<_Value, false>;
|
||||||
|
|
||||||
_Local_iterator_base() : _M_bucket_count(-1) { }
|
_Local_iterator_base() : _M_bucket_count(-1) { }
|
||||||
|
|
||||||
_Local_iterator_base(const __hash_code_base& __base,
|
_Local_iterator_base(const __hash_code_base& __base,
|
||||||
_Hash_node<_Value, false>* __p,
|
_Hash_node<_Value, false>* __p,
|
||||||
std::size_t __bkt, std::size_t __bkt_count)
|
std::size_t __bkt, std::size_t __bkt_count)
|
||||||
: _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
|
: __node_iter_base(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count)
|
||||||
{ _M_init(__base); }
|
{ _M_init(__base); }
|
||||||
|
|
||||||
~_Local_iterator_base()
|
~_Local_iterator_base()
|
||||||
|
@ -1533,8 +1532,8 @@ namespace __detail
|
||||||
}
|
}
|
||||||
|
|
||||||
_Local_iterator_base(const _Local_iterator_base& __iter)
|
_Local_iterator_base(const _Local_iterator_base& __iter)
|
||||||
: _M_cur(__iter._M_cur), _M_bucket(__iter._M_bucket),
|
: __node_iter_base(__iter), _M_bucket(__iter._M_bucket)
|
||||||
_M_bucket_count(__iter._M_bucket_count)
|
, _M_bucket_count(__iter._M_bucket_count)
|
||||||
{
|
{
|
||||||
if (_M_bucket_count != -1)
|
if (_M_bucket_count != -1)
|
||||||
_M_init(*__iter._M_h());
|
_M_init(*__iter._M_h());
|
||||||
|
@ -1545,7 +1544,7 @@ namespace __detail
|
||||||
{
|
{
|
||||||
if (_M_bucket_count != -1)
|
if (_M_bucket_count != -1)
|
||||||
_M_destroy();
|
_M_destroy();
|
||||||
_M_cur = __iter._M_cur;
|
this->_M_cur = __iter._M_cur;
|
||||||
_M_bucket = __iter._M_bucket;
|
_M_bucket = __iter._M_bucket;
|
||||||
_M_bucket_count = __iter._M_bucket_count;
|
_M_bucket_count = __iter._M_bucket_count;
|
||||||
if (_M_bucket_count != -1)
|
if (_M_bucket_count != -1)
|
||||||
|
@ -1556,17 +1555,16 @@ namespace __detail
|
||||||
void
|
void
|
||||||
_M_incr()
|
_M_incr()
|
||||||
{
|
{
|
||||||
_M_cur = _M_cur->_M_next();
|
__node_iter_base::_M_incr();
|
||||||
if (_M_cur)
|
if (this->_M_cur)
|
||||||
{
|
{
|
||||||
std::size_t __bkt = this->_M_h()->_M_bucket_index(_M_cur,
|
std::size_t __bkt = this->_M_h()->_M_bucket_index(this->_M_cur,
|
||||||
_M_bucket_count);
|
_M_bucket_count);
|
||||||
if (__bkt != _M_bucket)
|
if (__bkt != _M_bucket)
|
||||||
_M_cur = nullptr;
|
this->_M_cur = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_Hash_node<_Value, false>* _M_cur;
|
|
||||||
std::size_t _M_bucket;
|
std::size_t _M_bucket;
|
||||||
std::size_t _M_bucket_count;
|
std::size_t _M_bucket_count;
|
||||||
|
|
||||||
|
@ -1578,31 +1576,10 @@ namespace __detail
|
||||||
_M_destroy() { this->_M_h()->~__hash_code_base(); }
|
_M_destroy() { this->_M_h()->~__hash_code_base(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const void*
|
|
||||||
_M_curr() const { return _M_cur; } // for equality ops and debug mode
|
|
||||||
|
|
||||||
std::size_t
|
std::size_t
|
||||||
_M_get_bucket() const { return _M_bucket; } // for debug mode
|
_M_get_bucket() const { return _M_bucket; } // for debug mode
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Key, typename _Value, typename _ExtractKey,
|
|
||||||
typename _H1, typename _H2, typename _Hash, bool __cache>
|
|
||||||
inline bool
|
|
||||||
operator==(const _Local_iterator_base<_Key, _Value, _ExtractKey,
|
|
||||||
_H1, _H2, _Hash, __cache>& __x,
|
|
||||||
const _Local_iterator_base<_Key, _Value, _ExtractKey,
|
|
||||||
_H1, _H2, _Hash, __cache>& __y)
|
|
||||||
{ return __x._M_curr() == __y._M_curr(); }
|
|
||||||
|
|
||||||
template<typename _Key, typename _Value, typename _ExtractKey,
|
|
||||||
typename _H1, typename _H2, typename _Hash, bool __cache>
|
|
||||||
inline bool
|
|
||||||
operator!=(const _Local_iterator_base<_Key, _Value, _ExtractKey,
|
|
||||||
_H1, _H2, _Hash, __cache>& __x,
|
|
||||||
const _Local_iterator_base<_Key, _Value, _ExtractKey,
|
|
||||||
_H1, _H2, _Hash, __cache>& __y)
|
|
||||||
{ return __x._M_curr() != __y._M_curr(); }
|
|
||||||
|
|
||||||
/// local iterators
|
/// local iterators
|
||||||
template<typename _Key, typename _Value, typename _ExtractKey,
|
template<typename _Key, typename _Value, typename _ExtractKey,
|
||||||
typename _H1, typename _H2, typename _Hash,
|
typename _H1, typename _H2, typename _Hash,
|
||||||
|
@ -1615,6 +1592,7 @@ namespace __detail
|
||||||
using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
|
using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
|
||||||
_H1, _H2, _Hash, __cache>;
|
_H1, _H2, _Hash, __cache>;
|
||||||
using __hash_code_base = typename __base_type::__hash_code_base;
|
using __hash_code_base = typename __base_type::__hash_code_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef _Value value_type;
|
typedef _Value value_type;
|
||||||
typedef typename std::conditional<__constant_iterators,
|
typedef typename std::conditional<__constant_iterators,
|
||||||
|
|
|
@ -630,7 +630,7 @@ namespace __debug
|
||||||
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
||||||
this->_M_invalidate_local_if(
|
this->_M_invalidate_local_if(
|
||||||
[__victim](_Base_const_local_iterator __it)
|
[__victim](_Base_const_local_iterator __it)
|
||||||
{ return __it._M_curr() == __victim._M_cur; });
|
{ return __it == __victim; });
|
||||||
}
|
}
|
||||||
|
|
||||||
_Base_iterator
|
_Base_iterator
|
||||||
|
@ -1246,7 +1246,7 @@ namespace __debug
|
||||||
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
||||||
this->_M_invalidate_local_if(
|
this->_M_invalidate_local_if(
|
||||||
[__victim](_Base_const_local_iterator __it)
|
[__victim](_Base_const_local_iterator __it)
|
||||||
{ return __it._M_curr() == __victim._M_cur; });
|
{ return __it == __victim; });
|
||||||
}
|
}
|
||||||
|
|
||||||
_Base_iterator
|
_Base_iterator
|
||||||
|
|
|
@ -515,7 +515,7 @@ namespace __debug
|
||||||
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
||||||
this->_M_invalidate_local_if(
|
this->_M_invalidate_local_if(
|
||||||
[__victim](_Base_const_local_iterator __it)
|
[__victim](_Base_const_local_iterator __it)
|
||||||
{ return __it._M_curr() == __victim._M_cur; });
|
{ return __it == __victim; });
|
||||||
}
|
}
|
||||||
|
|
||||||
_Base_iterator
|
_Base_iterator
|
||||||
|
@ -1085,7 +1085,7 @@ namespace __debug
|
||||||
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
[__victim](_Base_const_iterator __it) { return __it == __victim; });
|
||||||
this->_M_invalidate_local_if(
|
this->_M_invalidate_local_if(
|
||||||
[__victim](_Base_const_local_iterator __it)
|
[__victim](_Base_const_local_iterator __it)
|
||||||
{ return __it._M_curr() == __victim._M_cur; });
|
{ return __it == __victim; });
|
||||||
}
|
}
|
||||||
|
|
||||||
_Base_iterator
|
_Base_iterator
|
||||||
|
|
Loading…
Reference in New Issue