Simplify local_iterator implementation. It makes local_iterator and
iterator comparable which is used in debug containers.
* 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.
Tested under Linux x86_64.
François
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index f330f7f811b..5cc943b3d22 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -301,27 +301,24 @@ namespace __detail
__node_type* _M_cur;
+ _Node_iterator_base() = default;
_Node_iterator_base(__node_type* __p) noexcept
: _M_cur(__p) { }
void
_M_incr() noexcept
{ _M_cur = _M_cur->_M_next(); }
- };
- template<typename _Value, typename _Cache_hash_code>
- inline bool
- operator==(const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
- const _Node_iterator_base<_Value, _Cache_hash_code >& __y)
- noexcept
- { return __x._M_cur == __y._M_cur; }
+ friend bool
+ operator==(const _Node_iterator_base& __x, const _Node_iterator_base& __y)
+ noexcept
+ { return __x._M_cur == __y._M_cur; }
- template<typename _Value, typename _Cache_hash_code>
- inline bool
- operator!=(const _Node_iterator_base<_Value, _Cache_hash_code>& __x,
- const _Node_iterator_base<_Value, _Cache_hash_code>& __y)
- noexcept
- { return __x._M_cur != __y._M_cur; }
+ friend bool
+ operator!=(const _Node_iterator_base& __x, const _Node_iterator_base& __y)
+ noexcept
+ { return __x._M_cur != __y._M_cur; }
+ };
/// Node iterators, used to iterate through all the hashtable.
template<typename _Value, typename _Constant_iterators,
@@ -345,7 +342,7 @@ namespace __detail
const _Value&, _Value&>::type;
_Node_iterator() noexcept
- : __base_type(0) { }
+ : __base_type(nullptr) { }
explicit
_Node_iterator(__node_type* __p) noexcept
@@ -394,7 +391,7 @@ namespace __detail
typedef const _Value& reference;
_Node_const_iterator() noexcept
- : __base_type(0) { }
+ : __base_type(nullptr) { }
explicit
_Node_const_iterator(__node_type* __p) noexcept
@@ -1426,9 +1423,11 @@ namespace __detail
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
_H1, _H2, _Hash, __hash_cached_t>
: private _Hashtable_ebo_helper<0, _H2>
+ , _Node_iterator_base<_Value, __hash_cached_t>
{
protected:
using __base_type = _Hashtable_ebo_helper<0, _H2>;
+ using __base_node_iter = _Node_iterator_base<_Value, __hash_cached_t>;
using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
_H1, _H2, _Hash,
__hash_cached_t>;
@@ -1437,31 +1436,27 @@ namespace __detail
_Local_iterator_base(const __hash_code_base& __base,
_Hash_node<_Value, __hash_cached_t>* __p,
std::size_t __bkt, std::size_t __bkt_count)
- : __base_type(__base._M_h2()),
- _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
+ : __base_type(__base._M_h2()), __base_node_iter(__p)
+ , _M_bucket(__bkt), _M_bucket_count(__bkt_count) { }
void
_M_incr()
{
- _M_cur = _M_cur->_M_next();
- if (_M_cur)
+ __base_node_iter::_M_incr();
+ if (this->_M_cur)
{
std::size_t __bkt
- = __base_type::_M_get()(_M_cur->_M_hash_code,
- _M_bucket_count);
+ = __base_type::_M_get()(this->_M_cur->_M_hash_code,
+ _M_bucket_count);
if (__bkt != _M_bucket)
- _M_cur = nullptr;
+ this->_M_cur = nullptr;
}
}
- _Hash_node<_Value, __hash_cached_t>* _M_cur;
std::size_t _M_bucket;
std::size_t _M_bucket_count;
public:
- const void*
- _M_curr() const { return _M_cur; } // for equality ops
-
std::size_t
_M_get_bucket() const { return _M_bucket; } // for debug mode
};
@@ -1510,18 +1505,20 @@ namespace __detail
struct _Local_iterator_base<_Key, _Value, _ExtractKey,
_H1, _H2, _Hash, __hash_not_cached_t>
: __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash>
+ , _Node_iterator_base<_Value, __hash_not_cached_t>
{
protected:
using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey,
_H1, _H2, _Hash,
__hash_not_cached_t>;
+ using __node_iter_base = _Node_iterator_base<_Value, __hash_not_cached_t>;
_Local_iterator_base() : _M_bucket_count(-1) { }
_Local_iterator_base(const __hash_code_base& __base,
_Hash_node<_Value, __hash_not_cached_t>* __p,
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); }
~_Local_iterator_base()
@@ -1531,8 +1528,8 @@ namespace __detail
}
_Local_iterator_base(const _Local_iterator_base& __iter)
- : _M_cur(__iter._M_cur), _M_bucket(__iter._M_bucket),
- _M_bucket_count(__iter._M_bucket_count)
+ : __node_iter_base(__iter), _M_bucket(__iter._M_bucket)
+ , _M_bucket_count(__iter._M_bucket_count)
{
if (_M_bucket_count != -1)
_M_init(*__iter._M_h());
@@ -1543,7 +1540,7 @@ namespace __detail
{
if (_M_bucket_count != -1)
_M_destroy();
- _M_cur = __iter._M_cur;
+ this->_M_cur = __iter._M_cur;
_M_bucket = __iter._M_bucket;
_M_bucket_count = __iter._M_bucket_count;
if (_M_bucket_count != -1)
@@ -1554,17 +1551,16 @@ namespace __detail
void
_M_incr()
{
- _M_cur = _M_cur->_M_next();
- if (_M_cur)
+ __node_iter_base::_M_incr();
+ 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);
if (__bkt != _M_bucket)
- _M_cur = nullptr;
+ this->_M_cur = nullptr;
}
}
- _Hash_node<_Value, __hash_not_cached_t>* _M_cur;
std::size_t _M_bucket;
std::size_t _M_bucket_count;
@@ -1576,33 +1572,10 @@ namespace __detail
_M_destroy() { this->_M_h()->~__hash_code_base(); }
public:
- const void*
- _M_curr() const { return _M_cur; } // for equality ops and debug mode
-
std::size_t
_M_get_bucket() const { return _M_bucket; } // for debug mode
};
- template<typename _Key, typename _Value, typename _ExtractKey,
- typename _H1, typename _H2, typename _Hash,
- typename _Cache_hash_code>
- inline bool
- operator==(const _Local_iterator_base<_Key, _Value, _ExtractKey,
- _H1, _H2, _Hash, _Cache_hash_code>& __x,
- const _Local_iterator_base<_Key, _Value, _ExtractKey,
- _H1, _H2, _Hash, _Cache_hash_code>& __y)
- { return __x._M_curr() == __y._M_curr(); }
-
- template<typename _Key, typename _Value, typename _ExtractKey,
- typename _H1, typename _H2, typename _Hash,
- typename _Cache_hash_code>
- inline bool
- operator!=(const _Local_iterator_base<_Key, _Value, _ExtractKey,
- _H1, _H2, _Hash, _Cache_hash_code>& __x,
- const _Local_iterator_base<_Key, _Value, _ExtractKey,
- _H1, _H2, _Hash, _Cache_hash_code>& __y)
- { return __x._M_curr() != __y._M_curr(); }
-
/// local iterators
template<typename _Key, typename _Value, typename _ExtractKey,
typename _H1, typename _H2, typename _Hash,
@@ -1615,6 +1588,7 @@ namespace __detail
using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey,
_H1, _H2, _Hash, _Cache_hash_code>;
using __hash_code_base = typename __base_type::__hash_code_base;
+
public:
typedef _Value value_type;
typedef typename std::conditional<_Constant_iterators::value,
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index d844ee9fa0e..157349ea4f9 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -621,7 +621,7 @@ namespace __debug
[__victim](_Base_const_iterator __it) { return __it == __victim; });
this->_M_invalidate_local_if(
[__victim](_Base_const_local_iterator __it)
- { return __it._M_curr() == __victim._M_cur; });
+ { return __it == __victim; });
}
_Base_iterator
@@ -1227,7 +1227,7 @@ namespace __debug
[__victim](_Base_const_iterator __it) { return __it == __victim; });
this->_M_invalidate_local_if(
[__victim](_Base_const_local_iterator __it)
- { return __it._M_curr() == __victim._M_cur; });
+ { return __it == __victim; });
}
_Base_iterator
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index ecc084e3846..924ff7671ee 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -506,7 +506,7 @@ namespace __debug
[__victim](_Base_const_iterator __it) { return __it == __victim; });
this->_M_invalidate_local_if(
[__victim](_Base_const_local_iterator __it)
- { return __it._M_curr() == __victim._M_cur; });
+ { return __it == __victim; });
}
_Base_iterator
@@ -1066,7 +1066,7 @@ namespace __debug
[__victim](_Base_const_iterator __it) { return __it == __victim; });
this->_M_invalidate_local_if(
[__victim](_Base_const_local_iterator __it)
- { return __it._M_curr() == __victim._M_cur; });
+ { return __it == __victim; });
}
_Base_iterator