Thank you.
On 2/27/26 5:05 AM, Tomasz Kaminski wrote:
Resending to libstdc++-patches, that I have accidentally dropped.
On Fri, Feb 27, 2026 at 11:03 AM Tomasz Kaminski <[email protected]
<mailto:[email protected]>> wrote:
On Thu, Feb 26, 2026 at 2:33 PM Nathan Myers <[email protected]
<mailto:[email protected]>> wrote:
Changes in v9:
...
LGTM only small changes:
* remove the abort (and related includes) or replace with glibcxx assert
* some copy-pasted comment about DR to be removed
* stylistic suggestion regarding --/++
I wondered about delegating non-TR functions to the tr ones (we can
check
if K type is not same key_type to check for equivalent elements),
but I think
such change to existing function would be too late for GCC-16, and
something
we could consider doing at bengining of GCC-17. This change is more
conservative
and does not affect pre-C++20 changes.
OK
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 761. unordered_map needs an at() member function.
I doubt this defect applied to heterogeneous overloads of at,
remove the comment.
OK
+ template <typename _Kt>
+ mapped_type&
+ _M_at_tr(const _Kt& __k)
+ {
+ auto __ite = static_cast<__hashtable*>(this)-
...
#endif
+#ifdef __glibcxx_associative_heterogeneous_insertion // C++26
+#include <cstdlib> // for abort
+#endif
Remove it.
ACK. This was just test instrumentation not intended for release.
#if __cplusplus < 201103L
# undef _GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE
@@ -1470,6 +1473,20 @@ namespace __rb_tree
_M_get_insert_hint_equal_pos(const_iterator __pos,
const key_type& __k);
...
@@ -2936,6 +2947,57 @@ namespace __rb_tree
return _Res(__position._M_node, _Base_ptr());
}
+#ifdef __glibcxx_associative_heterogeneous_insertion // C++26
+ template <typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ template <typename _Kt>
+ auto
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_get_insert_hint_unique_pos_tr(const_iterator __hint,
const _Kt& __k)
+ -> pair<_Base_ptr, _Base_ptr>
+ {
+ auto __node =__hint._M_node;
+ if (__node == _M_end())
+ {
+ if (size() > 0 &&
_M_key_compare(_S_key(_M_rightmost()), __k))
+ return { {}, _M_rightmost() };
+ return _M_get_insert_unique_pos_tr(__k);
+ }
+ if (_M_key_compare(__k, _S_key(__node)))
+ { // First, try before...
+ if (__node == _M_leftmost()) // begin()
+ return { _M_leftmost(), _M_leftmost() };
+ iterator __before(__node);
Put --__before as separate statemnt before if, the -- is easy to miss,
and line count is not metric to optimize for. I am ok if that get's
changed
only in this new function.
OK.
+ if (_M_key_compare(_S_key((--__before)._M_node), __k))
+ {
+ if (!_S_right(__before._M_node))
+ return { {}, __before._M_node }; // put right
+ return { __node, __node }; // put left;
+ }
+ return _M_get_insert_unique_pos_tr(__k);
+ }
+ if (_M_key_compare(_S_key(__node), __k))
+ { // ... then try after.
+ if (__node == _M_rightmost())
+ return { {}, _M_rightmost() };
+ iterator __after(__node);
Same comment about ++.
OK.
+ if (_M_key_compare(__k, _S_key((++__after)._M_node)))
+ {
+ if (!_S_right(__node))
+ return { {}, __node };
+ return { __after._M_node, __after._M_node };
+ }
+ return _M_get_insert_unique_pos_tr(__k);
+ }
+ // Equal to __k; check if any more to the left.
+ iterator __before(__node);
+ if (__node == _M_leftmost() ||
+ _M_key_compare(_S_key((--__before)._M_node), __k))
+ { return { __node, {} }; }
+ return _M_get_insert_unique_pos_tr(__k);
+ }
+#endif