[libcxx-commits] [libcxx] 19358ca - [libc++] Make sure `flat_set::key_compare` handle `boolean-testable` correctly (#132622)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jan 3 06:50:49 PST 2026


Author: Hewill Kang
Date: 2026-01-03T14:50:45Z
New Revision: 19358ca38ca1b92022ceafaf552ec892c09d9e43

URL: https://github.com/llvm/llvm-project/commit/19358ca38ca1b92022ceafaf552ec892c09d9e43
DIFF: https://github.com/llvm/llvm-project/commit/19358ca38ca1b92022ceafaf552ec892c09d9e43.diff

LOG: [libc++] Make sure `flat_set::key_compare` handle `boolean-testable` correctly (#132622)

Also add test for `flat_multiset` to avoid regression.

---------

Co-authored-by: Hui Xie <hui.xie1990 at gmail.com>
Co-authored-by: A. Jiang <de34 at live.cn>

Added: 
    libcxx/test/std/containers/container.adaptors/flat.multiset/robust_against_nonbool.compile.pass.cpp
    libcxx/test/std/containers/container.adaptors/flat.set/robust_against_nonbool.compile.pass.cpp

Modified: 
    libcxx/include/__flat_set/flat_set.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h
index dad747e7857cd..57c3926e33b68 100644
--- a/libcxx/include/__flat_set/flat_set.h
+++ b/libcxx/include/__flat_set/flat_set.h
@@ -679,7 +679,7 @@ class flat_set {
 
 private:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const {
-    auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); };
+    auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) -> bool { return !__compare_(__x, __y); };
     return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container);
   }
 

diff  --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/robust_against_nonbool.compile.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/robust_against_nonbool.compile.pass.cpp
new file mode 100644
index 0000000000000..e312ec6766218
--- /dev/null
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/robust_against_nonbool.compile.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// <flat_set>
+//
+// flat_multiset should support comparator that return a non-boolean value
+// as long as the returned type is implicitly convertible to bool.
+
+#include <flat_set>
+#include <vector>
+#include <ranges>
+
+#include "boolean_testable.h"
+
+void test() {
+  using Key = StrictComparable<int>;
+  std::vector<Key> v;
+  std::flat_multiset<Key> m1;
+  std::flat_multiset m2(std::from_range, v, StrictBinaryPredicate);
+  std::flat_multiset m3(std::sorted_equivalent, v, StrictBinaryPredicate);
+  std::flat_multiset m4(m1.begin(), m1.end(), StrictBinaryPredicate);
+  m2.insert(m1.begin(), m1.end());
+  m2.insert(std::sorted_equivalent, m1.begin(), m1.end());
+  m2.insert_range(m1);
+  m3.insert(1);
+  m2.emplace(1);
+  m2.emplace_hint(m2.begin(), 1);
+  for (const auto& k : m2) {
+    (void)k;
+  }
+  (void)m2.find(Key{1});
+  (void)m2.equal_range(Key{1});
+  (void)(m2 == m2);
+  m2.erase(m2.begin());
+  m2.erase(m2.begin(), m2.end());
+  std::erase_if(m2, []<class T>(const StrictComparable<T>&) -> const BooleanTestable& { return yes; });
+}

diff  --git a/libcxx/test/std/containers/container.adaptors/flat.set/robust_against_nonbool.compile.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/robust_against_nonbool.compile.pass.cpp
new file mode 100644
index 0000000000000..84f96d38ed3fa
--- /dev/null
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/robust_against_nonbool.compile.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// <flat_set>
+//
+// flat_set should support comparator that return a non-boolean
+// value as long as the returned type is implicitly convertible to bool.
+
+#include <flat_set>
+#include <vector>
+#include <ranges>
+
+#include "boolean_testable.h"
+
+void test() {
+  using Key = StrictComparable<int>;
+  std::vector<Key> v;
+  std::flat_set<Key> m1;
+  std::flat_set m2(std::from_range, v, StrictBinaryPredicate);
+  std::flat_set m3(std::sorted_unique, v, StrictBinaryPredicate);
+  std::flat_set m4(m1.begin(), m1.end(), StrictBinaryPredicate);
+  m2.insert(m1.begin(), m1.end());
+  m2.insert(std::sorted_unique, m1.begin(), m1.end());
+  m2.insert_range(m1);
+  m3.insert(1);
+  m2.emplace(1);
+  m2.emplace_hint(m2.begin(), 1);
+  for (const auto& k : m2) {
+    (void)k;
+  }
+  (void)m2.find(Key{1});
+  (void)m2.equal_range(Key{1});
+  (void)(m2 == m2);
+  m2.erase(m2.begin());
+  m2.erase(m2.begin(), m2.end());
+  std::erase_if(m2, []<class T>(const StrictComparable<T>&) -> BooleanTestable const& { return yes; });
+}


        


More information about the libcxx-commits mailing list