6565#include < __utility/is_pointer_in_range.h>
6666#include < __utility/move.h>
6767#include < __utility/pair.h>
68+ #include < __utility/scope_guard.h>
6869#include < __utility/swap.h>
6970#include < initializer_list>
7071#include < limits>
@@ -479,9 +480,10 @@ class vector {
479480 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __emplace_back_assume_capacity (_Args&&... __args) {
480481 _LIBCPP_ASSERT_INTERNAL (
481482 size () < capacity (), " We assume that we have enough space to insert an element at the end of the vector" );
482- _ConstructTransaction __tx (*this , 1 );
483- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__tx.__pos_ ), std::forward<_Args>(__args)...);
484- ++__tx.__pos_ ;
483+ __annotate_delete ();
484+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
485+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_), std::forward<_Args>(__args)...);
486+ ++__end_;
485487 }
486488
487489#if _LIBCPP_STD_VER >= 23
@@ -548,9 +550,9 @@ class vector {
548550 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase (const_iterator __first, const_iterator __last);
549551
550552 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear () _NOEXCEPT {
551- size_type __old_size = size ();
553+ __annotate_delete ();
554+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
552555 __base_destruct_at_end (this ->__begin_ );
553- __annotate_shrink (__old_size);
554556 }
555557
556558 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize (size_type __sz);
@@ -599,7 +601,7 @@ class vector {
599601
600602 if (__n > 0 ) {
601603 __vallocate (__n);
602- __construct_at_end (std::move (__first), std::move (__last), __n );
604+ __construct_at_end (std::move (__first), std::move (__last));
603605 }
604606
605607 __guard.__complete ();
@@ -659,8 +661,7 @@ class vector {
659661 __insert_with_size (const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n);
660662
661663 template <class _InputIterator , class _Sentinel >
662- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
663- __construct_at_end (_InputIterator __first, _Sentinel __last, size_type __n);
664+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end (_InputIterator __first, _Sentinel __last);
664665
665666 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append (size_type __n);
666667 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append (size_type __n, const_reference __x);
@@ -708,9 +709,9 @@ class vector {
708709 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign (vector& __c, false_type)
709710 _NOEXCEPT_(__alloc_traits::is_always_equal::value);
710711 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end (pointer __new_last) _NOEXCEPT {
711- size_type __old_size = size ();
712+ __annotate_delete ();
713+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
712714 __base_destruct_at_end (__new_last);
713- __annotate_shrink (__old_size);
714715 }
715716
716717 template <class ... _Args>
@@ -737,33 +738,11 @@ class vector {
737738 __annotate_contiguous_container (data () + size (), data () + capacity ());
738739 }
739740
740- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_increase (size_type __n) const _NOEXCEPT {
741- __annotate_contiguous_container (data () + size (), data () + size () + __n);
742- }
743-
744- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_shrink (size_type __old_size) const _NOEXCEPT {
745- __annotate_contiguous_container (data () + __old_size, data () + size ());
746- }
747-
748- struct _ConstructTransaction {
749- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction (vector& __v, size_type __n)
750- : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) {
751- __v_.__annotate_increase (__n);
752- }
753-
754- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction () {
755- __v_.__end_ = __pos_;
756- if (__pos_ != __new_end_) {
757- __v_.__annotate_shrink (__new_end_ - __v_.__begin_ );
758- }
759- }
760-
761- vector& __v_;
762- pointer __pos_;
763- const_pointer const __new_end_;
741+ struct __annotate_new_size {
742+ vector& __vec_;
764743
765- _ConstructTransaction (_ConstructTransaction const &) = delete ;
766- _ConstructTransaction& operator =(_ConstructTransaction const &) = delete ;
744+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __annotate_new_size (vector& __vec) : __vec_(__vec) {}
745+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator ()() { __vec_. __annotate_new (__vec_. size ()); }
767746 };
768747
769748 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end (pointer __new_last) _NOEXCEPT {
@@ -850,6 +829,7 @@ template <class _Tp, class _Allocator>
850829_LIBCPP_CONSTEXPR_SINCE_CXX20 void
851830vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) {
852831 __annotate_delete ();
832+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
853833 auto __new_begin = __v.__begin_ - (__end_ - __begin_);
854834 std::__uninitialized_allocator_relocate (
855835 this ->__alloc_ , std::__to_address (__begin_), std::__to_address (__end_), std::__to_address (__new_begin));
@@ -859,7 +839,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
859839 std::swap (this ->__end_ , __v.__end_ );
860840 std::swap (this ->__cap_ , __v.__cap_ );
861841 __v.__first_ = __v.__begin_ ;
862- __annotate_new (size ());
863842}
864843
865844// __swap_out_circular_buffer relocates the objects in [__begin_, __p) into the front of __v, the objects in
@@ -870,6 +849,7 @@ template <class _Tp, class _Allocator>
870849_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer
871850vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p) {
872851 __annotate_delete ();
852+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
873853 pointer __ret = __v.__begin_ ;
874854
875855 // Relocate [__p, __end_) first to avoid having a hole in [__begin_, __end_)
@@ -889,7 +869,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
889869 std::swap (this ->__end_ , __v.__end_ );
890870 std::swap (this ->__cap_ , __v.__cap_ );
891871 __v.__first_ = __v.__begin_ ;
892- __annotate_new (size ());
893872 return __ret;
894873}
895874
@@ -923,10 +902,12 @@ vector<_Tp, _Allocator>::__recommend(size_type __new_size) const {
923902// Postcondition: size() == size() + __n
924903template <class _Tp , class _Allocator >
925904_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) {
926- _ConstructTransaction __tx (*this , __n);
927- const_pointer __new_end = __tx.__new_end_ ;
928- for (pointer __pos = __tx.__pos_ ; __pos != __new_end; __tx.__pos_ = ++__pos) {
929- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__pos));
905+ __annotate_delete ();
906+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
907+
908+ for (size_t __i = 0 ; __i != __n; ++__i) {
909+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_));
910+ ++__end_;
930911 }
931912}
932913
@@ -939,19 +920,21 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(s
939920template <class _Tp , class _Allocator >
940921_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
941922vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
942- _ConstructTransaction __tx (*this , __n);
943- const_pointer __new_end = __tx.__new_end_ ;
944- for (pointer __pos = __tx.__pos_ ; __pos != __new_end; __tx.__pos_ = ++__pos) {
945- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__pos), __x);
923+ __annotate_delete ();
924+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
925+
926+ for (size_t __i = 0 ; __i != __n; ++__i) {
927+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_), __x);
928+ ++__end_;
946929 }
947930}
948931
949932template <class _Tp , class _Allocator >
950933template <class _InputIterator , class _Sentinel >
951934_LIBCPP_CONSTEXPR_SINCE_CXX20 void
952- vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n ) {
953- _ConstructTransaction __tx ( *this , __n );
954- __tx. __pos_ = std::__uninitialized_allocator_copy (this ->__alloc_ , std::move (__first), std::move (__last), __tx. __pos_ );
935+ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last) {
936+ auto __guard = std::__make_scope_guard ( __annotate_new_size ( *this ) );
937+ __end_ = std::__uninitialized_allocator_copy (this ->__alloc_ , std::move (__first), std::move (__last), __end_ );
955938}
956939
957940// Default constructs __n objects starting at __end_
@@ -1068,20 +1051,19 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
10681051 if (__new_size > size ()) {
10691052#if _LIBCPP_STD_VER >= 23
10701053 auto __mid = ranges::copy_n (std::move (__first), size (), this ->__begin_ ).in ;
1071- __construct_at_end (std::move (__mid), std::move (__last), __new_size - size ());
10721054#else
10731055 _Iterator __mid = std::next (__first, size ());
10741056 std::copy (__first, __mid, this ->__begin_ );
1075- __construct_at_end (__mid, __last, __new_size - size ());
10761057#endif
1058+ __construct_at_end (std::move (__mid), std::move (__last));
10771059 } else {
10781060 pointer __m = std::__copy (std::move (__first), __last, this ->__begin_ ).second ;
10791061 this ->__destruct_at_end (__m);
10801062 }
10811063 } else {
10821064 __vdeallocate ();
10831065 __vallocate (__recommend (__new_size));
1084- __construct_at_end (std::move (__first), std::move (__last), __new_size );
1066+ __construct_at_end (std::move (__first), std::move (__last));
10851067 }
10861068}
10871069
@@ -1189,15 +1171,16 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
11891171template <class _Tp , class _Allocator >
11901172_LIBCPP_CONSTEXPR_SINCE_CXX20 void
11911173vector<_Tp, _Allocator>::__move_range (pointer __from_s, pointer __from_e, pointer __to) {
1174+ __annotate_delete ();
1175+ auto __guard = std::__make_scope_guard (__annotate_new_size (*this ));
11921176 pointer __old_last = this ->__end_ ;
11931177 difference_type __n = __old_last - __to;
1194- {
1195- pointer __i = __from_s + __n;
1196- _ConstructTransaction __tx (*this , __from_e - __i);
1197- for (pointer __pos = __tx.__pos_ ; __i < __from_e; ++__i, (void )++__pos, __tx.__pos_ = __pos) {
1198- __alloc_traits::construct (this ->__alloc_ , std::__to_address (__pos), std::move (*__i));
1199- }
1178+
1179+ for (pointer __i = __from_s + __n; __i != __from_e; ++__i) {
1180+ __alloc_traits::construct (this ->__alloc_ , std::__to_address (__end_), std::move (*__i));
1181+ ++__end_;
12001182 }
1183+
12011184 std::move_backward (__from_s, __from_s + __n, __old_last);
12021185}
12031186
@@ -1338,13 +1321,13 @@ vector<_Tp, _Allocator>::__insert_with_size(
13381321 if (__n > __dx) {
13391322#if _LIBCPP_STD_VER >= 23
13401323 if constexpr (!forward_iterator<_Iterator>) {
1341- __construct_at_end (std::move (__first), std::move (__last), __n );
1324+ __construct_at_end (std::move (__first), std::move (__last));
13421325 std::rotate (__p, __old_last, this ->__end_ );
13431326 } else
13441327#endif
13451328 {
13461329 _Iterator __m = std::next (__first, __dx);
1347- __construct_at_end (__m, __last, __n - __dx );
1330+ __construct_at_end (__m, __last);
13481331 if (__dx > 0 ) {
13491332 __move_range (__p, __old_last, __p + __n);
13501333 __insert_assign_n_unchecked (__first, __dx, __p);
0 commit comments