6464#include < __utility/is_pointer_in_range.h>
6565#include < __utility/move.h>
6666#include < __utility/pair.h>
67+ #include < __utility/scope_guard.h>
6768#include < __utility/swap.h>
6869#include < initializer_list>
6970#include < limits>
@@ -481,9 +482,10 @@ class vector {
481482 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __emplace_back_assume_capacity (_Args&&... __args) {
482483 _LIBCPP_ASSERT_INTERNAL (
483484 size () < capacity (), " We assume that we have enough space to insert an element at the end of the vector" );
484- _ConstructTransaction __tx (*this , 1 );
485- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__tx.__pos_ ), std::forward<_Args>(__args)...);
486- ++__tx.__pos_ ;
485+ __annotate_delete ();
486+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
487+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_), std::forward<_Args>(__args)...);
488+ ++__end_;
487489 }
488490
489491#if _LIBCPP_STD_VER >= 23
@@ -550,9 +552,9 @@ class vector {
550552 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase (const_iterator __first, const_iterator __last);
551553
552554 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear () _NOEXCEPT {
553- size_type __old_size = size ();
555+ __annotate_delete ();
556+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
554557 __base_destruct_at_end (this ->__begin_ );
555- __annotate_shrink (__old_size);
556558 }
557559
558560 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize (size_type __sz);
@@ -601,7 +603,7 @@ class vector {
601603
602604 if (__n > 0 ) {
603605 __vallocate (__n);
604- __construct_at_end (std::move (__first), std::move (__last), __n );
606+ __construct_at_end (std::move (__first), std::move (__last));
605607 }
606608
607609 __guard.__complete ();
@@ -661,8 +663,7 @@ class vector {
661663 __insert_with_size (const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
662664
663665 template <class _InputIterator , class _Sentinel >
664- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
665- __construct_at_end (_InputIterator __first, _Sentinel __last, size_type __n);
666+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end (_InputIterator __first, _Sentinel __last);
666667
667668 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append (size_type __n);
668669 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append (size_type __n, const_reference __x);
@@ -710,9 +711,9 @@ class vector {
710711 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign (vector& __c, false_type)
711712 _NOEXCEPT_(__alloc_traits::is_always_equal::value);
712713 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end (pointer __new_last) _NOEXCEPT {
713- size_type __old_size = size ();
714+ __annotate_delete ();
715+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
714716 __base_destruct_at_end (__new_last);
715- __annotate_shrink (__old_size);
716717 }
717718
718719 template <class ... _Args>
@@ -739,33 +740,11 @@ class vector {
739740 __annotate_contiguous_container (data () + size (), data () + capacity ());
740741 }
741742
742- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_increase (size_type __n) const _NOEXCEPT {
743- __annotate_contiguous_container (data () + size (), data () + size () + __n);
744- }
745-
746- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_shrink (size_type __old_size) const _NOEXCEPT {
747- __annotate_contiguous_container (data () + __old_size, data () + size ());
748- }
749-
750- struct _ConstructTransaction {
751- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction (vector& __v, size_type __n)
752- : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) {
753- __v_.__annotate_increase (__n);
754- }
755-
756- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction () {
757- __v_.__end_ = __pos_;
758- if (__pos_ != __new_end_) {
759- __v_.__annotate_shrink (__new_end_ - __v_.__begin_ );
760- }
761- }
762-
763- vector& __v_;
764- pointer __pos_;
765- const_pointer const __new_end_;
743+ struct __annotate_new_size {
744+ vector& __vec_;
766745
767- _ConstructTransaction (_ConstructTransaction const &) = delete ;
768- _ConstructTransaction& operator =(_ConstructTransaction const &) = delete ;
746+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __annotate_new_size (vector& __vec) : __vec_(__vec) {}
747+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator ()() { __vec_. __annotate_new (__vec_. size ()); }
769748 };
770749
771750 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end (pointer __new_last) _NOEXCEPT {
@@ -870,6 +849,7 @@ template <class _Tp, class _Allocator>
870849_LIBCPP_CONSTEXPR_SINCE_CXX20 void
871850vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) {
872851 __annotate_delete ();
852+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
873853 auto __new_begin = __v.begin () - size ();
874854 std::__uninitialized_allocator_relocate (
875855 this ->__alloc_ , std::__to_address (__begin_), std::__to_address (__end_), std::__to_address (__new_begin));
@@ -878,7 +858,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
878858
879859 __swap_layouts (__v);
880860 __v.__set_data (__v.begin ());
881- __annotate_new (size ());
882861}
883862
884863// __swap_out_circular_buffer relocates the objects in [__begin_, __p) into the front of __v, the objects in
@@ -889,6 +868,7 @@ template <class _Tp, class _Allocator>
889868_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
890869vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p) {
891870 __annotate_delete ();
871+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
892872 pointer __ret = __v.begin ();
893873
894874 // Relocate [__p, __end_) first to avoid having a hole in [__begin_, __end_)
@@ -906,7 +886,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
906886 __end_ = __begin_; // All the objects have been destroyed by relocating them.
907887 __swap_layouts (__v);
908888 __v.__set_data (__v.begin ());
909- __annotate_new (size ());
910889 return __ret;
911890}
912891
@@ -940,10 +919,12 @@ vector<_Tp, _Allocator>::__recommend(size_type __new_size) const {
940919// Postcondition: size() == size() + __n
941920template <class _Tp , class _Allocator >
942921_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) {
943- _ConstructTransaction __tx (*this , __n);
944- const_pointer __new_end = __tx.__new_end_ ;
945- for (pointer __pos = __tx.__pos_ ; __pos != __new_end; __tx.__pos_ = ++__pos) {
946- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__pos));
922+ __annotate_delete ();
923+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
924+
925+ for (size_t __i = 0 ; __i != __n; ++__i) {
926+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_));
927+ ++__end_;
947928 }
948929}
949930
@@ -956,19 +937,22 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(s
956937template <class _Tp , class _Allocator >
957938_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
958939vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
959- _ConstructTransaction __tx (*this , __n);
960- const_pointer __new_end = __tx.__new_end_ ;
961- for (pointer __pos = __tx.__pos_ ; __pos != __new_end; __tx.__pos_ = ++__pos) {
962- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__pos), __x);
940+ __annotate_delete ();
941+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
942+
943+ for (size_t __i = 0 ; __i != __n; ++__i) {
944+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_), __x);
945+ ++__end_;
963946 }
964947}
965948
966949template <class _Tp , class _Allocator >
967950template <class _InputIterator , class _Sentinel >
968951_LIBCPP_CONSTEXPR_SINCE_CXX20 void
969- vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
970- _ConstructTransaction __tx (*this , __n);
971- __tx.__pos_ = std::__uninitialized_allocator_copy (this ->__alloc_ , std::move (__first), std::move (__last), __tx.__pos_ );
952+ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last) {
953+ __annotate_delete ();
954+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
955+ __end_ = std::__uninitialized_allocator_copy (this ->__alloc_ , std::move (__first), std::move (__last), __end_);
972956}
973957
974958// Default constructs __n objects starting at __end_
@@ -1085,20 +1069,19 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
10851069 if (__new_size > size ()) {
10861070#if _LIBCPP_STD_VER >= 23
10871071 auto __mid = ranges::copy_n (std::move (__first), size (), this ->__begin_ ).in ;
1088- __construct_at_end (std::move (__mid), std::move (__last), __new_size - size ());
10891072#else
10901073 _Iterator __mid = std::next (__first, size ());
10911074 std::copy (__first, __mid, this ->__begin_ );
1092- __construct_at_end (__mid, __last, __new_size - size ());
10931075#endif
1076+ __construct_at_end (std::move (__mid), std::move (__last));
10941077 } else {
10951078 pointer __m = std::__copy (std::move (__first), __last, this ->__begin_ ).second ;
10961079 this ->__destruct_at_end (__m);
10971080 }
10981081 } else {
10991082 __vdeallocate ();
11001083 __vallocate (__recommend (__new_size));
1101- __construct_at_end (std::move (__first), std::move (__last), __new_size );
1084+ __construct_at_end (std::move (__first), std::move (__last));
11021085 }
11031086}
11041087
@@ -1227,15 +1210,16 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
12271210template <class _Tp , class _Allocator >
12281211_LIBCPP_CONSTEXPR_SINCE_CXX20 void
12291212vector<_Tp, _Allocator>::__move_range (pointer __from_s, pointer __from_e, pointer __to) {
1213+ __annotate_delete ();
1214+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
12301215 pointer __old_last = this ->__end_ ;
12311216 difference_type __n = __old_last - __to;
1232- {
1233- pointer __i = __from_s + __n;
1234- _ConstructTransaction __tx (*this , __from_e - __i);
1235- for (pointer __pos = __tx.__pos_ ; __i < __from_e; ++__i, (void )++__pos, __tx.__pos_ = __pos) {
1236- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__pos), std::move (*__i));
1237- }
1217+
1218+ for (pointer __i = __from_s + __n; __i != __from_e; ++__i) {
1219+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_), std::move (*__i));
1220+ ++__end_;
12381221 }
1222+
12391223 std::move_backward (__from_s, __from_s + __n, __old_last);
12401224}
12411225
@@ -1376,13 +1360,13 @@ vector<_Tp, _Allocator>::__insert_with_size(
13761360 if (__n > __dx) {
13771361#if _LIBCPP_STD_VER >= 23
13781362 if constexpr (!forward_iterator<_Iterator>) {
1379- __construct_at_end (std::move (__first), std::move (__last), __n );
1363+ __construct_at_end (std::move (__first), std::move (__last));
13801364 std::rotate (__p, __old_last, this ->__end_ );
13811365 } else
13821366#endif
13831367 {
13841368 _Iterator __m = std::next (__first, __dx);
1385- __construct_at_end (__m, __last, __n - __dx );
1369+ __construct_at_end (__m, __last);
13861370 if (__dx > 0 ) {
13871371 __move_range (__p, __old_last, __p + __n);
13881372 __insert_assign_n_unchecked (__first, __dx, __p);
0 commit comments