[libcxx-commits] [libcxx] 5ce981e - [libc++] Refactor vector move constructor with allocator (#116449)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Nov 26 13:00:18 PST 2024


Author: Peng Liu
Date: 2024-11-26T16:00:14-05:00
New Revision: 5ce981e76da4094efd055ded54d1f756b1286f18

URL: https://github.com/llvm/llvm-project/commit/5ce981e76da4094efd055ded54d1f756b1286f18
DIFF: https://github.com/llvm/llvm-project/commit/5ce981e76da4094efd055ded54d1f756b1286f18.diff

LOG: [libc++] Refactor vector move constructor with allocator (#116449)

This PR simplifies the implementation of std::vector's move constructor
with an 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
an exception guard, which simplifies the code. Furthermore, from a
semantic standpoint, it is more intuitive for a constructor to call
an initialization function than an assignment function.

Added: 
    

Modified: 
    libcxx/include/__vector/vector.h
    libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index ae3ea1de61de01..4b9ba24e97f65e 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -964,9 +964,7 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
     __x.__begin_ = __x.__end_ = __x.__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());
   }
 }
 

diff  --git a/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp
index e2b0d691889c6c..09355688042f9a 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/exceptions.pass.cpp
@@ -17,6 +17,7 @@
 #include <vector>
 
 #include "count_new.h"
+#include "test_allocator.h"
 #include "test_iterators.h"
 
 template <class T>
@@ -36,7 +37,9 @@ struct Allocator {
   void deallocate(T* ptr, std::size_t n) { std::allocator<T>().deallocate(ptr, n); }
 
   template <class U>
-  friend bool operator==(const Allocator&, const Allocator<U>&) { return true; }
+  friend bool operator==(const Allocator&, const Allocator<U>&) {
+    return true;
+  }
 };
 
 struct ThrowingT {
@@ -138,7 +141,7 @@ int main(int, char**) {
   } catch (int) {
   }
   check_new_delete_called();
-#endif  // TEST_STD_VER >= 14
+#endif // TEST_STD_VER >= 14
 
   try { // Throw in vector(size_type, value_type, const allocator_type&) from the type
     int throw_after = 1;
@@ -217,11 +220,12 @@ int main(int, char**) {
   }
   check_new_delete_called();
 
-  try { // Throw in vector(vector&&, const allocator_type&) from type
-    std::vector<ThrowingT, Allocator<ThrowingT> > vec(Allocator<ThrowingT>(false));
-    int throw_after = 1;
-    vec.emplace_back(throw_after);
-    std::vector<ThrowingT, Allocator<ThrowingT> > vec2(std::move(vec), Allocator<ThrowingT>(false));
+  try { // Throw in vector(vector&&, const allocator_type&) from type during element-wise move
+    std::vector<ThrowingT, test_allocator<ThrowingT> > vec(test_allocator<ThrowingT>(1));
+    int throw_after = 10;
+    ThrowingT v(throw_after);
+    vec.insert(vec.end(), 6, v);
+    std::vector<ThrowingT, test_allocator<ThrowingT> > vec2(std::move(vec), test_allocator<ThrowingT>(2));
   } catch (int) {
   }
   check_new_delete_called();


        


More information about the libcxx-commits mailing list