[libcxx-commits] [libcxx] [libc++] Simplify vector<bool>::__construct_at_end (Reopend) (PR #119632)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jan 20 12:19:04 PST 2025
https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/119632
>From ab4d3778c016e05a90c6f9afc6a67214ccfecd6c 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 2b721e00058bc6..b738bb9862475e 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -555,30 +555,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(__first, __last, __make_iter(__old_size));
+ this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
+ std::__copy(__first, __last, __old_end);
}
template <class _Allocator>
@@ -852,7 +842,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 4404d894ba559a4f5cbdaca19c2a9f19578cd042 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 b738bb9862475e..34090328efc33c 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -555,6 +555,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);
@@ -565,6 +566,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 4cb7d3b2d23a1cd8396c2d5d74f8c66de7039f17 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 34090328efc33c..31add59fa809de 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -549,28 +549,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(__first, __last, end());
this->__size_ += __n;
- this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0);
- std::__copy(__first, __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 6a668370874962c9f213db8b40f3c9ff0a181e6d 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 | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 31add59fa809de..36a6fa9e725759 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -845,9 +845,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