diff --git a/libcxx/include/__utility/scope_guard.h b/libcxx/include/__utility/scope_guard.h index 3972102eee891..24f96e5b5fb53 100644 --- a/libcxx/include/__utility/scope_guard.h +++ b/libcxx/include/__utility/scope_guard.h @@ -37,7 +37,10 @@ class __scope_guard { // C++14 doesn't have mandatory RVO, so we have to provide a declaration even though no compiler will ever generate // a call to the move constructor. #if _LIBCPP_STD_VER <= 14 +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wundefined-internal") __scope_guard(__scope_guard&&); +_LIBCPP_DIAGNOSTIC_POP #else __scope_guard(__scope_guard&&) = delete; #endif diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 316d3a9d10eff..7f8f349841a8a 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -64,6 +64,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 @@ -481,9 +482,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 @@ -550,9 +552,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); @@ -601,7 +603,7 @@ class vector { if (__n > 0) { __vallocate(__n); - __construct_at_end(std::move(__first), std::move(__last), __n); + __construct_at_end(std::move(__first), std::move(__last)); } __guard.__complete(); @@ -661,8 +663,7 @@ class vector { __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n); template - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void - __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(_InputIterator __first, _Sentinel __last); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x); @@ -710,9 +711,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 @@ -739,33 +740,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 { @@ -870,6 +849,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() - size(); std::__uninitialized_allocator_relocate( 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 _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(*this)); pointer __ret = __v.begin(); // 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::__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_; } } @@ -956,19 +937,22 @@ _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_; } } 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_); +vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last) { + __annotate_delete(); + 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_ @@ -1085,12 +1069,11 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, if (__new_size > size()) { #if _LIBCPP_STD_VER >= 23 auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in; - __construct_at_end(std::move(__mid), std::move(__last), __new_size - size()); #else _Iterator __mid = std::next(__first, size()); std::copy(__first, __mid, this->__begin_); - __construct_at_end(__mid, __last, __new_size - size()); #endif + __construct_at_end(std::move(__mid), std::move(__last)); } else { pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second; this->__destruct_at_end(__m); @@ -1098,7 +1081,7 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, } else { __vdeallocate(); __vallocate(__recommend(__new_size)); - __construct_at_end(std::move(__first), std::move(__last), __new_size); + __construct_at_end(std::move(__first), std::move(__last)); } } @@ -1227,15 +1210,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); } @@ -1376,13 +1360,13 @@ vector<_Tp, _Allocator>::__insert_with_size( if (__n > __dx) { #if _LIBCPP_STD_VER >= 23 if constexpr (!forward_iterator<_Iterator>) { - __construct_at_end(std::move(__first), std::move(__last), __n); + __construct_at_end(std::move(__first), std::move(__last)); std::rotate(__p, __old_last, this->__end_); } else #endif { _Iterator __m = std::next(__first, __dx); - __construct_at_end(__m, __last, __n - __dx); + __construct_at_end(__m, __last); if (__dx > 0) { __move_range(__p, __old_last, __p + __n); __insert_assign_n_unchecked(__first, __dx, __p);