[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