Skip to content

[libc++][test] Improve tests for assign in std::vector and vector<bool> #119163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 19, 2024

Conversation

winner245
Copy link
Contributor

@winner245 winner245 commented Dec 9, 2024

This PR enhances the test coverage for the assign function of std::vector by adding new tests for several important test cases that were previously missing, as shown in the following table:

test cases forward_iterator input_iterator
new_size > capacity() Yes Yes
size() < new_size <= capacity() No No
new_size <= size() No No

Similarly, no tests have previously covered assign(_InputIterator __first, _InputIterator __last) and assign(size_type __n, const value_type& __x) for vector<bool>.

With this patch applied, all missing tests will be covered.

@winner245 winner245 force-pushed the add-tests-for-assign branch 2 times, most recently from f7b86bf to e478ce3 Compare December 9, 2024 12:04
@winner245 winner245 marked this pull request as ready for review December 9, 2024 14:42
@winner245 winner245 requested a review from a team as a code owner December 9, 2024 14:42
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Dec 9, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 9, 2024

@llvm/pr-subscribers-libcxx

Author: Peng Liu (winner245)

Changes

This PR enhances the test coverage for the assign function of std::vector by adding new tests for several important test cases that were previously missing, as shown in the following table:

test cases forward_iterator input_iterator
new_size > capacity() Yes Yes
size() < new_size <= capacity() No No
new_size <= size() No No

With this patch applied, all missing test cases will be covered.


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

1 Files Affected:

  • (modified) libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp (+100-7)
diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp
index 9b52885b9bf8d2..584f641edd7c52 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp
@@ -18,17 +18,16 @@
 #include "asan_testing.h"
 #include "test_iterators.h"
 #if TEST_STD_VER >= 11
-#include "emplace_constructible.h"
-#include "container_test_types.h"
+#  include "emplace_constructible.h"
+#  include "container_test_types.h"
 #endif
 
-
 TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   int arr1[] = {42};
   int arr2[] = {1, 101, 42};
-  {
-    using T = EmplaceConstructibleMoveableAndAssignable<int>;
+  { // Test with new_size > capacity() == 0 for forward_iterator, resulting in reallocation during assign
+    using T  = EmplaceConstructibleMoveableAndAssignable<int>;
     using It = forward_iterator<int*>;
     {
       std::vector<T> v;
@@ -43,8 +42,8 @@ TEST_CONSTEXPR_CXX20 bool test() {
       assert(v[2].value == 42);
     }
   }
-  {
-    using T = EmplaceConstructibleMoveableAndAssignable<int>;
+  { // Test with new_size > capacity() == 0 for input_iterator, resulting in reallocation during assign
+    using T  = EmplaceConstructibleMoveableAndAssignable<int>;
     using It = cpp17_input_iterator<int*>;
     {
       std::vector<T> v;
@@ -63,6 +62,100 @@ TEST_CONSTEXPR_CXX20 bool test() {
       assert(v[2].value == 42);
     }
   }
+
+  { // Test with new_size < size() for forward_iterator, resulting in destruction at end during assign
+    using T  = EmplaceConstructibleMoveableAndAssignable<int>;
+    using It = forward_iterator<int*>;
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      for (std::size_t i = 0; i < v.capacity(); ++i)
+        v.emplace_back(99);
+      v.assign(It(arr1), It(std::end(arr1)));
+      assert(v.size() == 1);
+      assert(v[0].value == 42);
+    }
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      for (std::size_t i = 0; i < v.capacity(); ++i)
+        v.emplace_back(99);
+      v.assign(It(arr2), It(std::end(arr2)));
+      assert(v.size() == 3);
+      assert(v[0].value == 1);
+      assert(v[1].value == 101);
+      assert(v[2].value == 42);
+    }
+  }
+  { // Test with new_size < size() for input_iterator, resulting in destruction at end during assign
+    using T  = EmplaceConstructibleMoveableAndAssignable<int>;
+    using It = cpp17_input_iterator<int*>;
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      for (std::size_t i = 0; i < v.capacity(); ++i)
+        v.emplace_back(99);
+      v.assign(It(arr1), It(std::end(arr1)));
+      assert(v.size() == 1);
+      assert(v[0].value == 42);
+    }
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      for (std::size_t i = 0; i < v.capacity(); ++i)
+        v.emplace_back(99);
+      v.assign(It(arr2), It(std::end(arr2)));
+      assert(v.size() == 3);
+      assert(v[0].value == 1);
+      assert(v[1].value == 101);
+      assert(v[2].value == 42);
+    }
+  }
+
+  { // Test with size() < new_size < capacity() for forward_iterator, resulting in construction at end during assign
+    using T  = EmplaceConstructibleMoveableAndAssignable<int>;
+    using It = forward_iterator<int*>;
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      v.assign(It(arr1), It(std::end(arr1)));
+      assert(v.size() == 1);
+      assert(v[0].value == 42);
+    }
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      for (std::size_t i = 0; i < 2; ++i)
+        v.emplace_back(99);
+      v.assign(It(arr2), It(std::end(arr2)));
+      assert(v.size() == 3);
+      assert(v[0].value == 1);
+      assert(v[1].value == 101);
+      assert(v[2].value == 42);
+    }
+  }
+  { // Test with size() < new_size < capacity() for inputs_iterator, resulting in construction at end during assign
+    using T  = EmplaceConstructibleMoveableAndAssignable<int>;
+    using It = cpp17_input_iterator<int*>;
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      v.assign(It(arr1), It(std::end(arr1)));
+      assert(v.size() == 1);
+      assert(v[0].value == 42);
+    }
+    {
+      std::vector<T> v;
+      v.reserve(5);
+      for (std::size_t i = 0; i < 2; ++i)
+        v.emplace_back(99);
+      v.assign(It(arr2), It(std::end(arr2)));
+      assert(v.size() == 3);
+      assert(v[0].value == 1);
+      assert(v[1].value == 101);
+      assert(v[2].value == 42);
+    }
+  }
 #endif
 
   // Test with a number of elements in the source range that is greater than capacity

@winner245 winner245 changed the title Improve tests for assign in std::vector [libc++][test] Improve tests for assign in std::vector Dec 9, 2024
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! I played around and we indeed didn't catch bugs in the code paths you described, which is quite bad. Thanks for adding coverage!

assert(v[2].value == 42);
}
}
{ // Test with size() < new_size < capacity() for inputs_iterator, resulting in construction at end during assign
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{ // Test with size() < new_size < capacity() for inputs_iterator, resulting in construction at end during assign
{ // Test with size() < new_size < capacity() for input_iterator, resulting in construction at end during assign

@winner245 winner245 force-pushed the add-tests-for-assign branch from e478ce3 to 6e84df2 Compare December 9, 2024 18:05
@winner245 winner245 changed the title [libc++][test] Improve tests for assign in std::vector [libc++][test] Improve tests for assign in std::vector and vector<bool> Dec 9, 2024
@winner245 winner245 force-pushed the add-tests-for-assign branch 5 times, most recently from 7800225 to 734434a Compare December 11, 2024 11:47
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! Please rebase onto main (you'll get a small merge conflict in vector::assign tests because of a change I made, sorry about that).

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the many small reviews, I didn't do a good job looking at this patch the first time around and I found a few more nitpicks. This is great though, they're all minor comments.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, now this should be good to go for real once CI is green. Sorry for the multiple notifications. Thanks a lot for the patch!

@winner245
Copy link
Contributor Author

Thank you so much for your careful and thorough review! I truly appreciate the time and effort you've put into helping improve all my PRs. Your careful review has identified all my careless points and significantly improved my work. Please don't worry about the number of comments; they are indeed incredibly helpful! I'll go through all of them and make the necessary adjustments.

@winner245 winner245 force-pushed the add-tests-for-assign branch 2 times, most recently from d0ec83a to 6916a37 Compare December 14, 2024 12:27
@winner245 winner245 force-pushed the add-tests-for-assign branch from 6916a37 to 4ada49a Compare December 16, 2024 11:46
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with green CI. I merged main into your branch to get over a CI issue that was present in main.

@ldionne ldionne merged commit 4039a79 into llvm:main Dec 19, 2024
61 of 62 checks passed
@winner245 winner245 deleted the add-tests-for-assign branch December 19, 2024 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants