[libcxx-commits] [libcxx] [libc++] Flat containers should reject `vector<bool, Alloc>` (PR #224886)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Sep 20 01:30:10 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Hristo Hristov (H-G-Hristov)

<details>
<summary>Changes</summary>

1. Updates the error condition
2. Updates the error messages

A follow-up to https://github.com/llvm/llvm-project/commit/08daaa8e376a5dcd9be7894dbd071920a7de154a

References:
- https://wg21.link/flat.map.overview#<!-- -->7
- https://wg21.link/flat.multimap.overview#<!-- -->7
- https://wg21.link/flat.multiset.overview#<!-- -->7
- https://wg21.link/flat.set.overview#<!-- -->7

---
Full diff: https://github.com/llvm/llvm-project/pull/224886.diff


9 Files Affected:

- (modified) libcxx/include/__flat_map/flat_map.h (+4-2) 
- (modified) libcxx/include/__flat_map/flat_multimap.h (+4-2) 
- (modified) libcxx/include/__flat_set/flat_multiset.h (+2-1) 
- (modified) libcxx/include/__flat_set/flat_set.h (+2-1) 
- (modified) libcxx/include/__fwd/vector.h (+10) 
- (modified) libcxx/test/std/containers/container.adaptors/flat.map/types.verify.cpp (+11-3) 
- (modified) libcxx/test/std/containers/container.adaptors/flat.multimap/types.verify.cpp (+11-3) 
- (modified) libcxx/test/std/containers/container.adaptors/flat.multiset/types.verify.cpp (+6-1) 
- (modified) libcxx/test/std/containers/container.adaptors/flat.set/types.verify.cpp (+6-1) 


``````````diff
diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index 27964aa421d21..005ca1565de12 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -89,8 +89,10 @@ class flat_map {
                 "The stored elements' key type must match the underlying key container's value_type.");
   static_assert(is_same_v<_Tp, typename _MappedContainer::value_type>,
                 "The stored elements' mapped type must match the underlying mapped container's value_type.");
-  static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
-  static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
+  static_assert(!__is_vector_bool_v<_KeyContainer>,
+                "The underlying key container must not be std::vector<bool>, which is not a sequence container.");
+  static_assert(!__is_vector_bool_v<_MappedContainer>,
+                "The underlying mapped container must not be std::vector<bool>, which is not a sequence container.");
 
   template <bool _Const>
   using __iterator _LIBCPP_NODEBUG = __key_value_iterator<flat_map, _KeyContainer, _MappedContainer, _Const>;
diff --git a/libcxx/include/__flat_map/flat_multimap.h b/libcxx/include/__flat_map/flat_multimap.h
index 9acaedf0772a0..c989b4cc584d2 100644
--- a/libcxx/include/__flat_map/flat_multimap.h
+++ b/libcxx/include/__flat_map/flat_multimap.h
@@ -86,8 +86,10 @@ class flat_multimap {
                 "The stored elements' key type must match the underlying key container's value_type.");
   static_assert(is_same_v<_Tp, typename _MappedContainer::value_type>,
                 "The stored elements' mapped type must match the underlying mapped container's value_type.");
-  static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
-  static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
+  static_assert(!__is_vector_bool_v<_KeyContainer>,
+                "The underlying key container must not be std::vector<bool>, which is not a sequence container.");
+  static_assert(!__is_vector_bool_v<_MappedContainer>,
+                "The underlying mapped container must not be std::vector<bool>, which is not a sequence container.");
 
   template <bool _Const>
   using __iterator _LIBCPP_NODEBUG = __key_value_iterator<flat_multimap, _KeyContainer, _MappedContainer, _Const>;
diff --git a/libcxx/include/__flat_set/flat_multiset.h b/libcxx/include/__flat_set/flat_multiset.h
index 74c0427eae928..ca36fd6925d5c 100644
--- a/libcxx/include/__flat_set/flat_multiset.h
+++ b/libcxx/include/__flat_set/flat_multiset.h
@@ -76,7 +76,8 @@ class flat_multiset {
 
   static_assert(is_same_v<_Key, typename _KeyContainer::value_type>,
                 "The stored elements' key type must match the underlying key container's value_type.");
-  static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
+  static_assert(!__is_vector_bool_v<_KeyContainer>,
+                "The underlying key container must not be std::vector<bool>, which is not a sequence container.");
 
 public:
   // types
diff --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h
index 988ffbe1b4a70..ba6624b4b4427 100644
--- a/libcxx/include/__flat_set/flat_set.h
+++ b/libcxx/include/__flat_set/flat_set.h
@@ -78,7 +78,8 @@ class flat_set {
 
   static_assert(is_same_v<_Key, typename _KeyContainer::value_type>,
                 "The stored elements' key type must match the underlying key container's value_type.");
-  static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
+  static_assert(!__is_vector_bool_v<_KeyContainer>,
+                "The underlying key container must not be std::vector<bool>, which is not a sequence container.");
 
   using __key_iterator _LIBCPP_NODEBUG = typename _KeyContainer::const_iterator;
 
diff --git a/libcxx/include/__fwd/vector.h b/libcxx/include/__fwd/vector.h
index 31084ec995b69..eb0b13d28d944 100644
--- a/libcxx/include/__fwd/vector.h
+++ b/libcxx/include/__fwd/vector.h
@@ -24,6 +24,16 @@ class vector;
 template <class _Allocator>
 class vector<bool, _Allocator>;
 
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Tp>
+inline constexpr bool __is_vector_bool_v = false;
+
+template <class _Allocator>
+inline constexpr bool __is_vector_bool_v<vector<bool, _Allocator>> = true;
+
+#endif // _LIBCPP_STD_VER >= 23
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___FWD_VECTOR_H
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/types.verify.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/types.verify.cpp
index 3e02678f09623..51db2a8f9c7c1 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/types.verify.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/types.verify.cpp
@@ -18,6 +18,8 @@
 #include <functional>
 #include <vector>
 
+#include "min_allocator.h"
+
 void test() {
   // expected-error-re@*:* {{static assertion failed{{.*}}The stored elements' key type must match the underlying key container's value_type.}}
   std::flat_map<double, int, std::less<double>, std::vector<char>> fm1;
@@ -25,9 +27,15 @@ void test() {
   // expected-error-re@*:* {{static assertion failed{{.*}}The stored elements' mapped type must match the underlying mapped container's value_type.}}
   std::flat_map<int, double, std::less<int>, std::vector<int>, std::vector<char>> fm2;
 
-  // expected-error-re@*:* {{static assertion failed{{.*}}vector<bool> is not a sequence container}}
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
   std::flat_map<bool, int, std::less<bool>, std::vector<bool>> fm3;
 
-  // expected-error-re@*:* {{static assertion failed{{.*}}vector<bool> is not a sequence container}}
-  std::flat_map<int, bool, std::less<int>, std::vector<int>, std::vector<bool>> fm4;
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_map<bool, int, std::less<bool>, std::vector<bool, min_allocator<bool>>> fm4;
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying mapped container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_map<int, bool, std::less<int>, std::vector<int>, std::vector<bool>> fm5;
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying mapped container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_map<int, bool, std::less<int>, std::vector<int>, std::vector<bool, min_allocator<bool>>> fm6;
 }
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/types.verify.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/types.verify.cpp
index ad6f701f9034c..147cbdea3e210 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multimap/types.verify.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/types.verify.cpp
@@ -18,6 +18,8 @@
 #include <functional>
 #include <vector>
 
+#include "min_allocator.h"
+
 void test() {
   // expected-error-re@*:* {{static assertion failed{{.*}}The stored elements' key type must match the underlying key container's value_type.}}
   std::flat_multimap<double, int, std::less<double>, std::vector<char>> fmm1;
@@ -25,9 +27,15 @@ void test() {
   // expected-error-re@*:* {{static assertion failed{{.*}}The stored elements' mapped type must match the underlying mapped container's value_type.}}
   std::flat_multimap<int, double, std::less<int>, std::vector<int>, std::vector<char>> fmm2;
 
-  // expected-error-re@*:* {{static assertion failed{{.*}}vector<bool> is not a sequence container}}
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
   std::flat_multimap<bool, int, std::less<bool>, std::vector<bool>> fmm3;
 
-  // expected-error-re@*:* {{static assertion failed{{.*}}vector<bool> is not a sequence container}}
-  std::flat_multimap<int, bool, std::less<int>, std::vector<int>, std::vector<bool>> fmm4;
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_multimap<bool, int, std::less<bool>, std::vector<bool, min_allocator<bool>>> fmm4;
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying mapped container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_multimap<int, bool, std::less<int>, std::vector<int>, std::vector<bool>> fmm5;
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying mapped container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_multimap<int, bool, std::less<int>, std::vector<int>, std::vector<bool, min_allocator<bool>>> fmm6;
 }
diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/types.verify.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/types.verify.cpp
index b70d193841e06..ffe9dc3284f8e 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.multiset/types.verify.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/types.verify.cpp
@@ -17,10 +17,15 @@
 #include <functional>
 #include <vector>
 
+#include "min_allocator.h"
+
 void test() {
   // expected-error-re@*:* {{static assertion failed{{.*}}The stored elements' key type must match the underlying key container's value_type.}}
   std::flat_multiset<double, std::less<double>, std::vector<int>> fms1;
 
-  // expected-error-re@*:* {{static assertion failed{{.*}}vector<bool> is not a sequence container}}
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
   std::flat_multiset<bool, std::less<bool>, std::vector<bool>> fms2;
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_multiset<bool, std::less<bool>, std::vector<bool, min_allocator<bool>>> fms3;
 }
diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/types.verify.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/types.verify.cpp
index 78621182a45f3..76755b19fe8ea 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/types.verify.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/types.verify.cpp
@@ -17,10 +17,15 @@
 #include <functional>
 #include <vector>
 
+#include "min_allocator.h"
+
 void test() {
   // expected-error-re@*:* {{static assertion failed{{.*}}The stored elements' key type must match the underlying key container's value_type.}}
   std::flat_set<double, std::less<double>, std::vector<int>> fs1;
 
-  // expected-error-re@*:* {{static assertion failed{{.*}}vector<bool> is not a sequence container}}
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
   std::flat_set<bool, std::less<bool>, std::vector<bool>> fs2;
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}The underlying key container must not be std::vector<bool>, which is not a sequence container.}}
+  std::flat_set<bool, std::less<bool>, std::vector<bool, min_allocator<bool>>> fs3;
 }

``````````

</details>


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


More information about the libcxx-commits mailing list