[libcxx-commits] [libcxx] [libc++] Simplify vector<bool>::__construct_at_end (Reopend) (PR #119632)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 24 08:17:43 PST 2025


https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/119632

>From 010d34ffa5a9d70c9c4ca0d914f21d7cd80096dc Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Wed, 11 Dec 2024 18:21:46 -0500
Subject: [PATCH 1/4] Simplify vector<bool>::__construct_at_end

---
 libcxx/include/__vector/vector_bool.h | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 4f1c442ce0be8d..3f4d443d386fe6 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -558,30 +558,20 @@ vector<bool, _Allocator>::__recommend(size_type __new_size) const {
 template <class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) {
-  size_type __old_size = this->__size_;
+  iterator __old_end = end();
   this->__size_ += __n;
-  if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) {
-    if (this->__size_ <= __bits_per_word)
-      this->__begin_[0] = __storage_type(0);
-    else
-      this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
-  }
-  std::fill_n(__make_iter(__old_size), __n, __x);
+  this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
+  std::fill_n(__old_end, __n, __x);
 }
 
 template <class _Allocator>
 template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
-  size_type __old_size = this->__size_;
+  iterator __old_end = end();
   this->__size_ += __n;
-  if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) {
-    if (this->__size_ <= __bits_per_word)
-      this->__begin_[0] = __storage_type(0);
-    else
-      this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
-  }
-  std::__copy(std::move(__first), std::move(__last), __make_iter(__old_size));
+  this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
+  std::__copy(std::move(__first), std::move(__last), __old_end);
 }
 
 template <class _Allocator>
@@ -855,7 +845,9 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
       this->__throw_length_error();
     vector __v(this->get_allocator());
     __v.__vallocate(__n);
-    __v.__construct_at_end(this->begin(), this->end(), this->size());
+    // Ensure that the call to __construct_at_end(first, last, n) meets the precondition of n > 0
+    if (this->size() > 0)
+      __v.__construct_at_end(this->begin(), this->end(), this->size());
     swap(__v);
   }
 }

>From bc9dad15ba528c0adbf1ac98cb78f2312d48c58c Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 13 Jan 2025 20:33:52 -0500
Subject: [PATCH 2/4] Add _LIBCPP_ASSERT_INTERNAL

---
 libcxx/include/__vector/vector_bool.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 3f4d443d386fe6..494f91e781166a 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -558,6 +558,7 @@ vector<bool, _Allocator>::__recommend(size_type __new_size) const {
 template <class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) {
+  _LIBCPP_ASSERT_INTERNAL(__n > 0, "This function expects __n > 0");
   iterator __old_end = end();
   this->__size_ += __n;
   this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
@@ -568,6 +569,7 @@ template <class _Allocator>
 template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
+  _LIBCPP_ASSERT_INTERNAL(__n > 0, "This function expects __n > 0");
   iterator __old_end = end();
   this->__size_ += __n;
   this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);

>From 16a92bc120f94524fd399b296746249e8964c3fe Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 20 Jan 2025 14:45:49 -0500
Subject: [PATCH 3/4] Add explicit precondition check

---
 libcxx/include/__vector/vector_bool.h | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 494f91e781166a..698f6c2658d100 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -552,28 +552,29 @@ vector<bool, _Allocator>::__recommend(size_type __new_size) const {
 }
 
 //  Default constructs __n objects starting at __end_
-//  Precondition:  __n > 0
 //  Precondition:  size() + __n <= capacity()
 //  Postcondition:  size() == size() + __n
 template <class _Allocator>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) {
-  _LIBCPP_ASSERT_INTERNAL(__n > 0, "This function expects __n > 0");
-  iterator __old_end = end();
+  _LIBCPP_ASSERT_INTERNAL(
+      capacity() >= size() + __n, "vector<bool>::__construct_at_end called with insufficient capacity");
+  std::fill_n(end(), __n, __x);
   this->__size_ += __n;
-  this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
-  std::fill_n(__old_end, __n, __x);
+  if (end().__ctz_ != 0) // has uninitialized trailing bits in the last word
+    std::fill_n(end(), __bits_per_word - end().__ctz_, 0);
 }
 
 template <class _Allocator>
 template <class _InputIterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 void
 vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
-  _LIBCPP_ASSERT_INTERNAL(__n > 0, "This function expects __n > 0");
-  iterator __old_end = end();
+  _LIBCPP_ASSERT_INTERNAL(
+      capacity() >= size() + __n, "vector<bool>::__construct_at_end called with insufficient capacity");
+  std::__copy(std::move(__first), std::move(__last), end());
   this->__size_ += __n;
-  this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
-  std::__copy(std::move(__first), std::move(__last), __old_end);
+  if (end().__ctz_ != 0) // has uninitialized trailing bits in the last word
+    std::fill_n(end(), __bits_per_word - end().__ctz_, 0);
 }
 
 template <class _Allocator>

>From e3a0995566c287de12ca744bb082ec4998e8a717 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 20 Jan 2025 15:16:22 -0500
Subject: [PATCH 4/4] Remove unnecessary if condition and comment

---
 libcxx/include/__vector/vector_bool.h | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 698f6c2658d100..8d9257eddfcd2d 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -561,7 +561,7 @@ vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) {
       capacity() >= size() + __n, "vector<bool>::__construct_at_end called with insufficient capacity");
   std::fill_n(end(), __n, __x);
   this->__size_ += __n;
-  if (end().__ctz_ != 0) // has uninitialized trailing bits in the last word
+  if (end().__ctz_ != 0) // Ensure uninitialized leading bits in the last word are set to zero
     std::fill_n(end(), __bits_per_word - end().__ctz_, 0);
 }
 
@@ -573,7 +573,7 @@ vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel _
       capacity() >= size() + __n, "vector<bool>::__construct_at_end called with insufficient capacity");
   std::__copy(std::move(__first), std::move(__last), end());
   this->__size_ += __n;
-  if (end().__ctz_ != 0) // has uninitialized trailing bits in the last word
+  if (end().__ctz_ != 0) // Ensure uninitialized leading bits in the last word are set to zero
     std::fill_n(end(), __bits_per_word - end().__ctz_, 0);
 }
 
@@ -848,9 +848,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
       this->__throw_length_error();
     vector __v(this->get_allocator());
     __v.__vallocate(__n);
-    // Ensure that the call to __construct_at_end(first, last, n) meets the precondition of n > 0
-    if (this->size() > 0)
-      __v.__construct_at_end(this->begin(), this->end(), this->size());
+    __v.__construct_at_end(this->begin(), this->end(), this->size());
     swap(__v);
   }
 }



More information about the libcxx-commits mailing list