[libcxx-commits] [libcxx] [libc++] Avoid double comparisons when uniquing flat_set/flat_map (PR #214118)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Tue Aug 4 20:10:12 PDT 2026


================
@@ -938,13 +938,30 @@ class flat_map {
     return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container);
   }
 
+  template <class _Iter, class _Sent, class _Predicate>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Iter
+  __deduplicate_sorted(_Iter __first, _Sent __last, _Predicate __pred) {
+    __first = ranges::adjacent_find(__first, __last, __pred);
+    if (__first == __last) {
+      return __first;
+    }
+
+    _Iter __i = __first;
+    for (++__i; ++__i != __last;) {
+      if (!__pred(*__first, *__i)) {
+        *++__first = _IterOps<_RangeAlgPolicy>::__iter_move(__i);
+      }
+    }
+    return ++__first;
+  }
+
   // This function is only used in constructors. So there is not exception handling in this function.
   // If the function exits via an exception, there will be no flat_map object constructed, thus, there
   // is no invariant state to preserve
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort_and_unique() {
     auto __zv = ranges::views::zip(__containers_.keys, __containers_.values);
     ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); });
-    auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin();
+    auto __dup_start = __deduplicate_sorted(__zv.begin(), __zv.end(), __key_not_less(__compare_));
----------------
frederick-vs-ja wrote:

I believe we shouldn't use unqualified function call here, which causes undesired argument-dependent lookup.

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


More information about the libcxx-commits mailing list