diff --git a/libcxx/include/vector b/libcxx/include/vector index 80819080a9fbe4..f19aaa1cbd7b6f 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -315,167 +315,37 @@ template class __vector_base : protected __vector_base_common // This base class is historical, but it needs to remain for ABI compatibility { -public: - typedef _Allocator allocator_type; - typedef allocator_traits __alloc_traits; - typedef typename __alloc_traits::size_type size_type; -protected: - typedef _Tp value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename __alloc_traits::difference_type difference_type; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; - typedef pointer iterator; - typedef const_pointer const_iterator; + typedef _Allocator allocator_type; + typedef typename allocator_traits::pointer pointer; - pointer __begin_; - pointer __end_; - __compressed_pair __end_cap_; - - _LIBCPP_INLINE_VISIBILITY - allocator_type& __alloc() _NOEXCEPT - {return __end_cap_.second();} - _LIBCPP_INLINE_VISIBILITY - const allocator_type& __alloc() const _NOEXCEPT - {return __end_cap_.second();} - _LIBCPP_INLINE_VISIBILITY - pointer& __end_cap() _NOEXCEPT - {return __end_cap_.first();} - _LIBCPP_INLINE_VISIBILITY - const pointer& __end_cap() const _NOEXCEPT - {return __end_cap_.first();} +protected: + pointer __begin_; + pointer __end_; + __compressed_pair __end_cap_; _LIBCPP_INLINE_VISIBILITY __vector_base() - _NOEXCEPT_(is_nothrow_default_constructible::value); - _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT; -#endif - ~__vector_base(); - - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__destruct_at_end(__begin_);} - _LIBCPP_INLINE_VISIBILITY - size_type capacity() const _NOEXCEPT - {return static_cast(__end_cap() - __begin_);} - - _LIBCPP_INLINE_VISIBILITY - void __destruct_at_end(pointer __new_last) _NOEXCEPT; - - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __vector_base& __c) - {__copy_assign_alloc(__c, integral_constant());} - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__vector_base& __c) - _NOEXCEPT_( - !__alloc_traits::propagate_on_container_move_assignment::value || - is_nothrow_move_assignable::value) - {__move_assign_alloc(__c, integral_constant());} - - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI - void __throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __vector_base_common::__throw_length_error(); -#else - _VSTD::abort(); -#endif - } - - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI - void __throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - __vector_base_common::__throw_out_of_range(); -#else - _VSTD::abort(); -#endif - } - -private: - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __vector_base& __c, true_type) - { - if (__alloc() != __c.__alloc()) - { - clear(); - __alloc_traits::deallocate(__alloc(), __begin_, capacity()); - __begin_ = __end_ = __end_cap() = nullptr; - } - __alloc() = __c.__alloc(); - } - - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __vector_base&, false_type) - {} - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__vector_base& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable::value) - { - __alloc() = _VSTD::move(__c.__alloc()); - } - - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__vector_base&, false_type) - _NOEXCEPT - {} -}; - -template -inline _LIBCPP_INLINE_VISIBILITY -void -__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT -{ - pointer __soon_to_be_end = __end_; - while (__new_last != __soon_to_be_end) - __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__soon_to_be_end)); - __end_ = __new_last; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -__vector_base<_Tp, _Allocator>::__vector_base() _NOEXCEPT_(is_nothrow_default_constructible::value) - : __begin_(nullptr), - __end_(nullptr), - __end_cap_(nullptr, __default_init_tag()) -{ -} + : __begin_(nullptr), + __end_(nullptr), + __end_cap_(nullptr, __default_init_tag()) {} -template -inline _LIBCPP_INLINE_VISIBILITY -__vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a) - : __begin_(nullptr), - __end_(nullptr), - __end_cap_(nullptr, __a) -{ -} + _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a) + : __begin_(nullptr), + __end_(nullptr), + __end_cap_(nullptr, __a) {} #ifndef _LIBCPP_CXX03_LANG -template -inline _LIBCPP_INLINE_VISIBILITY -__vector_base<_Tp, _Allocator>::__vector_base(allocator_type&& __a) _NOEXCEPT - : __begin_(nullptr), - __end_(nullptr), - __end_cap_(nullptr, _VSTD::move(__a)) {} + _LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT + : __begin_(nullptr), + __end_(nullptr), + __end_cap_(nullptr, _VSTD::move(__a)) {} #endif - -template -__vector_base<_Tp, _Allocator>::~__vector_base() -{ - if (__begin_ != nullptr) - { - clear(); - __alloc_traits::deallocate(__alloc(), __begin_, capacity()); - } -} +}; template */> class _LIBCPP_TEMPLATE_VIS vector + // This base class is historical, but it needs to remain for ABI compatibility. : private __vector_base<_Tp, _Allocator> { private: @@ -485,17 +355,17 @@ public: typedef vector __self; typedef _Tp value_type; typedef _Allocator allocator_type; - typedef typename __base::__alloc_traits __alloc_traits; - typedef typename __base::reference reference; - typedef typename __base::const_reference const_reference; - typedef typename __base::size_type size_type; - typedef typename __base::difference_type difference_type; - typedef typename __base::pointer pointer; - typedef typename __base::const_pointer const_pointer; + typedef allocator_traits __alloc_traits; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::difference_type difference_type; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; typedef __wrap_iter iterator; typedef __wrap_iter const_iterator; - typedef _VSTD::reverse_iterator reverse_iterator; - typedef _VSTD::reverse_iterator const_reverse_iterator; + typedef _VSTD::reverse_iterator reverse_iterator; + typedef _VSTD::reverse_iterator const_reverse_iterator; static_assert((is_same::value), "Allocator::value_type must be same type as value_type"); @@ -557,10 +427,16 @@ public: _LIBCPP_INLINE_VISIBILITY ~vector() { - __annotate_delete(); + __annotate_delete(); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->__erase_c(this); + __get_db()->__erase_c(this); #endif + + if (this->__begin_ != nullptr) + { + __clear(); + __alloc_traits::deallocate(__alloc(), this->__begin_, capacity()); + } } vector(const vector& __x); @@ -665,7 +541,7 @@ public: {return static_cast(this->__end_ - this->__begin_);} _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT - {return __base::capacity();} + {return static_cast(__end_cap() - this->__begin_);} _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return this->__begin_ == this->__end_;} @@ -778,7 +654,7 @@ public: void clear() _NOEXCEPT { size_type __old_size = size(); - __base::clear(); + __clear(); __annotate_shrink(__old_size); __invalidate_all_iterators(); } @@ -839,7 +715,7 @@ private: { __invalidate_iterators_past(__new_last); size_type __old_size = size(); - __base::__destruct_at_end(__new_last); + __base_destruct_at_end(__new_last); __annotate_shrink(__old_size); } @@ -934,6 +810,89 @@ private: _VSTD::forward<_Args>(__args)...); ++__tx.__pos_; } + + _LIBCPP_INLINE_VISIBILITY + allocator_type& __alloc() _NOEXCEPT + {return this->__end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY + const allocator_type& __alloc() const _NOEXCEPT + {return this->__end_cap_.second();} + _LIBCPP_INLINE_VISIBILITY + pointer& __end_cap() _NOEXCEPT + {return this->__end_cap_.first();} + _LIBCPP_INLINE_VISIBILITY + const pointer& __end_cap() const _NOEXCEPT + {return this->__end_cap_.first();} + + _LIBCPP_INLINE_VISIBILITY + void __clear() _NOEXCEPT {__base_destruct_at_end(this->__begin_);} + + _LIBCPP_INLINE_VISIBILITY + void __base_destruct_at_end(pointer __new_last) _NOEXCEPT { + pointer __soon_to_be_end = this->__end_; + while (__new_last != __soon_to_be_end) + __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__soon_to_be_end)); + this->__end_ = __new_last; + } + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const vector& __c) + {__copy_assign_alloc(__c, integral_constant());} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(vector& __c) + _NOEXCEPT_( + !__alloc_traits::propagate_on_container_move_assignment::value || + is_nothrow_move_assignable::value) + {__move_assign_alloc(__c, integral_constant());} + + _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI + void __throw_length_error() const { +#ifndef _LIBCPP_NO_EXCEPTIONS + __vector_base_common::__throw_length_error(); +#else + _VSTD::abort(); +#endif + } + + _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI + void __throw_out_of_range() const { +#ifndef _LIBCPP_NO_EXCEPTIONS + __vector_base_common::__throw_out_of_range(); +#else + _VSTD::abort(); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const vector& __c, true_type) + { + if (__alloc() != __c.__alloc()) + { + __clear(); + __alloc_traits::deallocate(__alloc(), this->__begin_, capacity()); + this->__begin_ = this->__end_ = __end_cap() = nullptr; + } + __alloc() = __c.__alloc(); + } + + _LIBCPP_INLINE_VISIBILITY + void __copy_assign_alloc(const vector&, false_type) + {} + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(vector& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) + { + __alloc() = _VSTD::move(__c.__alloc()); + } + + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(vector&, false_type) + _NOEXCEPT + {} }; #if _LIBCPP_STD_VER >= 17 @@ -1374,7 +1333,7 @@ void vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value) { - if (__base::__alloc() != __c.__alloc()) + if (__alloc() != __c.__alloc()) { typedef move_iterator _Ip; assign(_Ip(__c.begin()), _Ip(__c.end())); @@ -1389,7 +1348,7 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable::value) { __vdeallocate(); - __base::__move_assign_alloc(__c); // this can throw + __move_assign_alloc(__c); // this can throw this->__begin_ = __c.__begin_; this->__end_ = __c.__end_; this->__end_cap() = __c.__end_cap(); @@ -1408,7 +1367,7 @@ vector<_Tp, _Allocator>::operator=(const vector& __x) { if (this != _VSTD::addressof(__x)) { - __base::__copy_assign_alloc(__x); + __copy_assign_alloc(__x); assign(__x.__begin_, __x.__end_); } return *this;