Skip to content

[libc++] Refactor vector move constructor with allocator #116449

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 2 commits into from
Nov 26, 2024

Conversation

winner245
Copy link
Contributor

@winner245 winner245 commented Nov 15, 2024

This PR simplifies the implementation of std::vector move constructor with alternative allocator by invoking __init_with_size, instead of calling assign which ultimately calls __assign_with_size. The advantage of using __init_with_size lies in its internal use of exception guard, thus simplifying the code. Furthermore, from a semantic standpoint, it is more intuitive for a constructor to call an initialization function rather than an assignment function.

@winner245 winner245 requested a review from a team as a code owner November 15, 2024 23:10
@winner245 winner245 changed the title Refactor vector move constructor with allocator [libc++] Refactor vector move constructor with allocator Nov 15, 2024
@winner245 winner245 force-pushed the vector-move-ctor-with-alloc branch from 672e7cf to 85b1169 Compare November 16, 2024 03:47
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 16, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 16, 2024

@llvm/pr-subscribers-libcxx

Author: Peng Liu (winner245)

Changes

This PR simplifies the implementation of std::vector move constructor with alternative allocator by invoking __init_with_size, instead of calling assign which ultimately calls __assign_with_size. The advantage of using __init_with_size lies in its internal use of exception guard, thus simplifying the code. Furthermore, from a semantic standpoint, it is more intuitive for a constructor to call an initialization function rather than an assignment function.


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

1 Files Affected:

  • (modified) libcxx/include/__vector/vector.h (+1-3)
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index d2d707d8c913c0..ac07750d8ece2f 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -976,9 +976,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
     __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
   } else {
     typedef move_iterator<iterator> _Ip;
-    auto __guard = std::__make_exception_guard(__destroy_vector(*this));
-    assign(_Ip(__x.begin()), _Ip(__x.end()));
-    __guard.__complete();
+    __init_with_size(_Ip(__x.begin()), _Ip(__x.end()), __x.size());
   }
 }
 

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

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

LGTM assuming the CI is happy.

@winner245 winner245 force-pushed the vector-move-ctor-with-alloc branch from 85b1169 to 44c0814 Compare November 17, 2024 20:13
@ldionne
Copy link
Member

ldionne commented Nov 18, 2024

The advantage of using __init_with_size lies in its internal use of exception guard, thus simplifying the code.

Does this patch add an exception guard that wasn't there before? If so, are we fixing an exception safety issue that we were not handling before? If that's the case, this needs a test.

@philnik777
Copy link
Contributor

The advantage of using __init_with_size lies in its internal use of exception guard, thus simplifying the code.

Does this patch add an exception guard that wasn't there before? If so, are we fixing an exception safety issue that we were not handling before? If that's the case, this needs a test.

No, we're simply re-using a different one, which allows us to remove one.

@winner245
Copy link
Contributor Author

Does this patch add an exception guard that wasn't there before? If so, are we fixing an exception safety issue that we were not handling before? If that's the case, this needs a test.

The exception guard was there before, but the guard was applied around an assign call, which is more verbose than directly calling __init_with_size which has an internal exception guard already. So exception tests available in /vector/vector.cons/exceptions.pass.cpp also already covered this constructor.

@winner245 winner245 force-pushed the vector-move-ctor-with-alloc branch 3 times, most recently from 86a65d0 to 4c8fe79 Compare November 26, 2024 04:02
@winner245 winner245 force-pushed the vector-move-ctor-with-alloc branch from 4c8fe79 to e356689 Compare November 26, 2024 12:07
@winner245
Copy link
Contributor Author

The existing exception test for this constructor is problematic as it did not throw any exceptions. I have added a new test for this constructor. Additionally, I found other tests in exceptions.pass.cpp that are similarly problematic: either they did not throw exceptions at all, or they did not throw at the intended points. These issues have been separately addressed in #117662.

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. I pulled the patch locally and can confirm that the test before the patch doesn't actually test anything. So this both refactors the code and also makes sure that the test is working properly.

Since this is a small change, let's land this before the other vector refactorings.

@ldionne ldionne merged commit 5ce981e into llvm:main Nov 26, 2024
61 of 62 checks passed
@winner245 winner245 deleted the vector-move-ctor-with-alloc branch November 27, 2024 02:57
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.

4 participants