From acc1d1a9546115629e50bcb9e09a7bd85291b652 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Mon, 20 Jan 2020 19:23:09 +0100 Subject: [PATCH] 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. --- libstdc++-v3/include/bits/hashtable_policy.h | 92 ++++++++------------ libstdc++-v3/include/debug/unordered_map | 4 +- libstdc++-v3/include/debug/unordered_set | 4 +- 3 files changed, 39 insertions(+), 61 deletions(-) diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index 26ea9bf29ce..8031966f2f7 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -291,27 +291,26 @@ 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 - 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; } - template - 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; } + +#if __cpp_impl_three_way_comparison < 201907L + friend bool + operator!=(const _Node_iterator_base& __x, const _Node_iterator_base& __y) + noexcept + { return __x._M_cur != __y._M_cur; } +#endif + }; /// Node iterators, used to iterate through all the hashtable. template @@ -334,7 +333,7 @@ namespace __detail const _Value&, _Value&>::type; _Node_iterator() noexcept - : __base_type(0) { } + : __base_type(nullptr) { } explicit _Node_iterator(__node_type* __p) noexcept @@ -382,7 +381,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 @@ -1431,9 +1430,11 @@ namespace __detail struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true> : private _Hashtable_ebo_helper<0, _H2> + , _Node_iterator_base<_Value, true> { protected: 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, _H1, _H2, _Hash, true>; @@ -1441,31 +1442,27 @@ namespace __detail _Local_iterator_base(const __hash_code_base& __base, _Hash_node<_Value, true>* __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, true>* _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 }; @@ -1513,17 +1510,19 @@ namespace __detail struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false> : __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash> + , _Node_iterator_base<_Value, false> { protected: using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false>; + using __node_iter_base = _Node_iterator_base<_Value, false>; _Local_iterator_base() : _M_bucket_count(-1) { } _Local_iterator_base(const __hash_code_base& __base, _Hash_node<_Value, false>* __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() @@ -1533,8 +1532,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()); @@ -1545,7 +1544,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) @@ -1556,17 +1555,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, false>* _M_cur; std::size_t _M_bucket; std::size_t _M_bucket_count; @@ -1578,31 +1576,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 - 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 - 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 template; using __hash_code_base = typename __base_type::__hash_code_base; + public: typedef _Value value_type; typedef typename std::conditional<__constant_iterators, diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index 4fa5c124d5a..bae179b58ac 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -630,7 +630,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 @@ -1246,7 +1246,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 94dde0d0ded..97e6a74ebb4 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -515,7 +515,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 @@ -1085,7 +1085,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 -- 2.30.2