[libcxx-commits] [libcxx] [libc++] Fix no-op shrink_to_fit for vector<bool> (PR #120495)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 14 10:35:46 PST 2025


================
@@ -20,21 +23,48 @@
 
 TEST_CONSTEXPR_CXX20 bool tests() {
   {
-    std::vector<bool> v(100);
+    using C = std::vector<bool>;
+    C v(100);
     v.push_back(1);
+    v.clear();
     v.shrink_to_fit();
-    assert(v.capacity() >= 101);
-    assert(v.size() >= 101);
+    assert(v.capacity() == 0);
+    assert(v.size() == 0);
   }
-#if TEST_STD_VER >= 11
   {
-    std::vector<bool, min_allocator<bool>> v(100);
+    using C = std::vector<bool, min_allocator<bool> >;
+    C v(100);
     v.push_back(1);
+    C::size_type before_cap = v.capacity();
     v.shrink_to_fit();
     assert(v.capacity() >= 101);
-    assert(v.size() >= 101);
+    assert(v.capacity() <= before_cap);
+    assert(v.size() == 101);
+  }
+  {
+    using C                = std::vector<bool>;
+    unsigned bits_per_word = static_cast<unsigned>(sizeof(C::__storage_type) * CHAR_BIT);
----------------
winner245 wrote:

Thank you for your insightful feedback. The three options you mentioned have provided me with some new and valuable information that I wasn't previously aware of.

Among the options, I believe using `#if defined(_LIBCPP_VERSION)` around the two tests that use `C::__storage_type` would be the most appropriate for my purpose. This is because libc++ and libstdc++ have different word sizes (libc++ uses `Alloc::size_type`, which is typically 64 bits, while libstdc++ uses `unsigned long`). Moreover, I don't find a way to extract this information from a public API. Even if I could, the decision on whether to shrink would be implementation-dependent as the request to shrink is non-binding. Therefore, I choose to use the `#if defined(_LIBCPP_VERSION)` option you suggested.

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


More information about the libcxx-commits mailing list