[libcxx-commits] [libcxx] [libc++] Fix `ranges::for_each` taking whole associative containers (PR #172605)

Nico Weber via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 17 04:25:31 PST 2025


nico wrote:

Thanks!

Have you considered making __tree_iterate_from_root check the root pointer? That allows removing a few other checks and looks like it might be less code (and you don't need the `size()` call). Something like this (untested):

```diff
diff --git a/include/__tree b/include/__tree
index 2b93ea6603..ec04b2c2e5 100644
--- a/include/__tree
+++ b/include/__tree
@@ -664,16 +664,14 @@ template <class _Reference, class _Break, class _NodePtr, class _Func, class _Pr
 _LIBCPP_HIDE_FROM_ABI
 #endif
 bool __tree_iterate_from_root(_Break __break, _NodePtr __root, _Func& __func, _Proj& __proj) {
-  if (__root->__left_) {
-    if (std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__left_), __func, __proj))
-      return true;
-  }
+  if (!__root)
+    return true;
+  if (std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__left_), __func, __proj))
+    return true;
   if (__break(__root))
     return true;
   std::__invoke(__func, std::__invoke(__proj, static_cast<_Reference>(__root->__get_value())));
-  if (__root->__right_)
-    return std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__right_), __func, __proj);
-  return false;
+  return std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__right_), __func, __proj);
 }
 
 // Do an in-order traversal of the tree from __first to __last.
@@ -691,14 +689,12 @@ __tree_iterate_subrange(_NodeIter __first_it, _NodeIter __last_it, _Func& __func
       return;
     const auto __nfirst = static_cast<_NodePtr>(__first);
     std::__invoke(__func, std::__invoke(__proj, static_cast<_Reference>(__nfirst->__get_value())));
-    if (__nfirst->__right_) {
-      if (std::__tree_iterate_from_root<_Reference>(
-              [&](_NodePtr __node) -> bool { return __node == __last; },
-              static_cast<_NodePtr>(__nfirst->__right_),
-              __func,
-              __proj))
-        return;
-    }
+    if (std::__tree_iterate_from_root<_Reference>(
+            [&](_NodePtr __node) -> bool { return __node == __last; },
+            static_cast<_NodePtr>(__nfirst->__right_),
+            __func,
+            __proj))
+      return;
     while (!std::__tree_is_left_child(static_cast<_NodePtr>(__first)))
       __first = static_cast<_NodePtr>(__first)->__parent_;
     __first = static_cast<_NodePtr>(__first)->__parent_;
```

https://github.com/llvm/llvm-project/pull/172605


More information about the libcxx-commits mailing list