diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 4307e78f6ddbc..b9b8c654bc8b4 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -65,6 +65,7 @@ #include <__utility/is_pointer_in_range.h> #include <__utility/move.h> #include <__utility/pair.h> +#include <__utility/scope_guard.h> #include <__utility/swap.h> #include #include @@ -479,9 +480,10 @@ class vector { _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __emplace_back_assume_capacity(_Args&&... __args) { _LIBCPP_ASSERT_INTERNAL( size() < capacity(), "We assume that we have enough space to insert an element at the end of the vector"); - _ConstructTransaction __tx(*this, 1); - __alloc_traits::construct(this->__alloc_, std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...); - ++__tx.__pos_; + __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); + __alloc_traits::construct(this->__alloc_, std::__to_address(__end_), std::forward<_Args>(__args)...); + ++__end_; } #if _LIBCPP_STD_VER >= 23 @@ -548,9 +550,9 @@ class vector { _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { - size_type __old_size = size(); + __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); __base_destruct_at_end(this->__begin_); - __annotate_shrink(__old_size); } _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz); @@ -708,9 +710,9 @@ class vector { _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT { - size_type __old_size = size(); + __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); __base_destruct_at_end(__new_last); - __annotate_shrink(__old_size); } template @@ -737,33 +739,11 @@ class vector { __annotate_contiguous_container(data() + size(), data() + capacity()); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_increase(size_type __n) const _NOEXCEPT { - __annotate_contiguous_container(data() + size(), data() + size() + __n); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __annotate_shrink(size_type __old_size) const _NOEXCEPT { - __annotate_contiguous_container(data() + __old_size, data() + size()); - } - - struct _ConstructTransaction { - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(vector& __v, size_type __n) - : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) { - __v_.__annotate_increase(__n); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { - __v_.__end_ = __pos_; - if (__pos_ != __new_end_) { - __v_.__annotate_shrink(__new_end_ - __v_.__begin_); - } - } - - vector& __v_; - pointer __pos_; - const_pointer const __new_end_; + struct __annotate_new_size { + vector& __vec_; - _ConstructTransaction(_ConstructTransaction const&) = delete; - _ConstructTransaction& operator=(_ConstructTransaction const&) = delete; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __annotate_new_size(vector& __vec) : __vec_(__vec) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()() { __vec_.__annotate_new(__vec_.size()); } }; _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __base_destruct_at_end(pointer __new_last) _NOEXCEPT { @@ -850,6 +830,7 @@ template _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v) { __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); auto __new_begin = __v.__begin_ - (__end_ - __begin_); std::__uninitialized_allocator_relocate( this->__alloc_, std::__to_address(__begin_), std::__to_address(__end_), std::__to_address(__new_begin)); @@ -859,7 +840,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer__end_, __v.__end_); std::swap(this->__cap_, __v.__cap_); __v.__first_ = __v.__begin_; - __annotate_new(size()); } // __swap_out_circular_buffer relocates the objects in [__begin_, __p) into the front of __v, the objects in @@ -870,6 +850,7 @@ template _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::pointer vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer __p) { __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(size())); pointer __ret = __v.__begin_; // Relocate [__p, __end_) first to avoid having a hole in [__begin_, __end_) @@ -889,7 +870,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer__end_, __v.__end_); std::swap(this->__cap_, __v.__cap_); __v.__first_ = __v.__begin_; - __annotate_new(size()); return __ret; } @@ -923,10 +903,12 @@ vector<_Tp, _Allocator>::__recommend(size_type __new_size) const { // Postcondition: size() == size() + __n template _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) { - _ConstructTransaction __tx(*this, __n); - const_pointer __new_end = __tx.__new_end_; - for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) { - __alloc_traits::construct(this->__alloc_, std::__to_address(__pos)); + __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); + + for (size_t __i = 0; __i != __n; ++__i) { + __alloc_traits::construct(this->__alloc_, std::__to_address(__end_)); + ++__end_; } } @@ -939,10 +921,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(s template _LIBCPP_CONSTEXPR_SINCE_CXX20 inline void vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) { - _ConstructTransaction __tx(*this, __n); - const_pointer __new_end = __tx.__new_end_; - for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) { - __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), __x); + __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); + + for (size_t __i = 0; __i != __n; ++__i) { + __alloc_traits::construct(this->__alloc_, std::__to_address(__end_), __x); + ++__end_; } } @@ -950,8 +934,8 @@ template template _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) { - _ConstructTransaction __tx(*this, __n); - __tx.__pos_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __tx.__pos_); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); + __end_ = std::__uninitialized_allocator_copy(this->__alloc_, std::move(__first), std::move(__last), __end_); } // Default constructs __n objects starting at __end_ @@ -1189,15 +1173,16 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) { template _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to) { + __annotate_delete(); + auto __guard = std::__make_scope_guard(__annotate_new_size(*this)); pointer __old_last = this->__end_; difference_type __n = __old_last - __to; - { - pointer __i = __from_s + __n; - _ConstructTransaction __tx(*this, __from_e - __i); - for (pointer __pos = __tx.__pos_; __i < __from_e; ++__i, (void)++__pos, __tx.__pos_ = __pos) { - __alloc_traits::construct(this->__alloc_, std::__to_address(__pos), std::move(*__i)); - } + + for (pointer __i = __from_s + __n; __i != __from_e; ++__i) { + __alloc_traits::construct(this->__alloc_, std::__to_address(__end_), std::move(*__i)); + ++__end_; } + std::move_backward(__from_s, __from_s + __n, __old_last); }