diff options
Diffstat (limited to 'contrib/libc++/include/vector')
-rw-r--r-- | contrib/libc++/include/vector | 151 |
1 files changed, 90 insertions, 61 deletions
diff --git a/contrib/libc++/include/vector b/contrib/libc++/include/vector index 021bbfb6643e1..4dd0e527ff578 100644 --- a/contrib/libc++/include/vector +++ b/contrib/libc++/include/vector @@ -99,7 +99,7 @@ public: void push_back(const value_type& x); void push_back(value_type&& x); template <class... Args> - void emplace_back(Args&&... args); + reference emplace_back(Args&&... args); void pop_back(); template <class... Args> iterator emplace(const_iterator position, Args&&... args); @@ -218,7 +218,7 @@ public: const_reference back() const; void push_back(const value_type& x); - template <class... Args> void emplace_back(Args&&... args); // C++14 + template <class... Args> reference emplace_back(Args&&... args); // C++14 void pop_back(); template <class... Args> iterator emplace(const_iterator position, Args&&... args); // C++14 @@ -290,37 +290,29 @@ class __vector_base_common { protected: _LIBCPP_ALWAYS_INLINE __vector_base_common() {} - void __throw_length_error() const; - void __throw_out_of_range() const; + _LIBCPP_NORETURN void __throw_length_error() const; + _LIBCPP_NORETURN void __throw_out_of_range() const; }; template <bool __b> void __vector_base_common<__b>::__throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw length_error("vector"); -#else - assert(!"vector length_error"); -#endif + _VSTD::__throw_length_error("vector"); } template <bool __b> void __vector_base_common<__b>::__throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("vector"); -#else - assert(!"vector out_of_range"); -#endif + _VSTD::__throw_out_of_range("vector"); } #ifdef _LIBCPP_MSVC #pragma warning( push ) #pragma warning( disable: 4231 ) #endif // _LIBCPP_MSVC -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __vector_base_common<true>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __vector_base_common<true>) #ifdef _LIBCPP_MSVC #pragma warning( pop ) #endif // _LIBCPP_MSVC @@ -455,7 +447,7 @@ __vector_base<_Tp, _Allocator>::~__vector_base() } template <class _Tp, class _Allocator /* = allocator<_Tp> */> -class _LIBCPP_TYPE_VIS_ONLY vector +class _LIBCPP_TEMPLATE_VIS vector : private __vector_base<_Tp, _Allocator> { private: @@ -687,7 +679,7 @@ public: #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args> _LIBCPP_INLINE_VISIBILITY - void emplace_back(_Args&&... __args); + reference emplace_back(_Args&&... __args); #endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -746,9 +738,9 @@ public: void swap(vector&) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; + _NOEXCEPT_DEBUG; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif @@ -765,6 +757,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); + _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last); void allocate(size_type __n); void deallocate() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const; @@ -794,21 +787,7 @@ private: _LIBCPP_INLINE_VISIBILITY void __destruct_at_end(pointer __new_last) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) - { - --__p; - const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); - if (__i->base() > __new_last) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif + __invalidate_iterators_past(__new_last); size_type __old_size = size(); __base::__destruct_at_end(__new_last); __annotate_shrink(__old_size); @@ -829,30 +808,40 @@ private: // We call annotatations only for the default Allocator because other allocators // may not meet the AddressSanitizer alignment constraints. // See the documentation for __sanitizer_annotate_contiguous_container for more details. - void __annotate_contiguous_container - (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid) const - { #ifndef _LIBCPP_HAS_NO_ASAN + void __annotate_contiguous_container(const void *__beg, const void *__end, + const void *__old_mid, + const void *__new_mid) const + { + if (__beg && is_same<allocator_type, __default_allocator_type>::value) __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid); -#endif } - - void __annotate_new(size_type __current_size) const - { +#else + _LIBCPP_INLINE_VISIBILITY + void __annotate_contiguous_container(const void*, const void*, const void*, + const void*) const {} +#endif + _LIBCPP_INLINE_VISIBILITY + void __annotate_new(size_type __current_size) const { __annotate_contiguous_container(data(), data() + capacity(), data() + capacity(), data() + __current_size); } - void __annotate_delete() const - { + + _LIBCPP_INLINE_VISIBILITY + void __annotate_delete() const { __annotate_contiguous_container(data(), data() + capacity(), data() + size(), data() + capacity()); } + + _LIBCPP_INLINE_VISIBILITY void __annotate_increase(size_type __n) const { __annotate_contiguous_container(data(), data() + capacity(), data() + size(), data() + size() + __n); } + + _LIBCPP_INLINE_VISIBILITY void __annotate_shrink(size_type __old_size) const { __annotate_contiguous_container(data(), data() + capacity(), @@ -877,8 +866,9 @@ private: }; #else struct __RAII_IncreaseAnnotator { - inline __RAII_IncreaseAnnotator(const vector &, size_type __n = 1) {} - inline void __done() {} + _LIBCPP_INLINE_VISIBILITY + __RAII_IncreaseAnnotator(const vector &, size_type = 1) {} + _LIBCPP_INLINE_VISIBILITY void __done() {} }; #endif @@ -949,7 +939,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::size_type vector<_Tp, _Allocator>::max_size() const _NOEXCEPT { - return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), numeric_limits<size_type>::max() / 2); // end() >= begin(), always + return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), + numeric_limits<difference_type>::max()); } // Precondition: __new_size > capacity() @@ -1411,6 +1402,7 @@ vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __las allocate(__recommend(__new_size)); __construct_at_end(__first, __last, __new_size); } + __invalidate_all_iterators(); } template <class _Tp, class _Allocator> @@ -1432,6 +1424,7 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) allocate(__recommend(static_cast<size_type>(__n))); __construct_at_end(__n, __u); } + __invalidate_all_iterators(); } template <class _Tp, class _Allocator> @@ -1632,7 +1625,7 @@ vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) template <class _Tp, class _Allocator> template <class... _Args> inline -void +typename vector<_Tp, _Allocator>::reference vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) { if (this->__end_ < this->__end_cap()) @@ -1646,6 +1639,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) } else __emplace_back_slow_path(_VSTD::forward<_Args>(__args)...); + return this->back(); } #endif // _LIBCPP_HAS_NO_VARIADICS @@ -1674,8 +1668,9 @@ vector<_Tp, _Allocator>::erase(const_iterator __position) "vector::erase(iterator) called with a non-dereferenceable iterator"); difference_type __ps = __position - cbegin(); pointer __p = this->__begin_ + __ps; - iterator __r = __make_iter(__p); this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p)); + this->__invalidate_iterators_past(__p-1); + iterator __r = __make_iter(__p); return __r; } @@ -1687,12 +1682,17 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, "vector::erase(iterator, iterator) called with an iterator not" " referring to this vector"); + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, + "vector::erase(iterator, iterator) called with an iterator not" + " referring to this vector"); #endif _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); - iterator __r = __make_iter(__p); - if (__first != __last) + if (__first != __last) { this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p)); + this->__invalidate_iterators_past(__p - 1); + } + iterator __r = __make_iter(__p); return __r; } @@ -2013,9 +2013,9 @@ template <class _Tp, class _Allocator> void vector<_Tp, _Allocator>::swap(vector& __x) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT + _NOEXCEPT_DEBUG #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -2098,6 +2098,28 @@ vector<_Tp, _Allocator>::__invalidate_all_iterators() #endif // _LIBCPP_DEBUG_LEVEL >= 2 } + +template <class _Tp, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +void +vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) { + --__p; + const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); + if (__i->base() > __new_last) { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#else + ((void)__new_last); +#endif +} + // vector<bool> template <class _Allocator> class vector<bool, _Allocator>; @@ -2111,7 +2133,7 @@ struct __has_storage_type<vector<bool, _Allocator> > }; template <class _Allocator> -class _LIBCPP_TYPE_VIS_ONLY vector<bool, _Allocator> +class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator> : private __vector_base_common<true> { public: @@ -2314,8 +2336,10 @@ public: void push_back(const value_type& __x); #if _LIBCPP_STD_VER > 11 template <class... _Args> - _LIBCPP_INLINE_VISIBILITY void emplace_back(_Args&&... __args) - { push_back ( value_type ( _VSTD::forward<_Args>(__args)... )); } + _LIBCPP_INLINE_VISIBILITY reference emplace_back(_Args&&... __args) { + push_back ( value_type ( _VSTD::forward<_Args>(__args)... )); + return this->back(); + } #endif _LIBCPP_INLINE_VISIBILITY void pop_back() {--__size_;} @@ -2360,7 +2384,7 @@ public: #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif static void swap(reference __x, reference __y) _NOEXCEPT { _VSTD::swap(__x, __y); } @@ -2448,7 +2472,7 @@ private: friend class __bit_iterator<vector, false>; friend class __bit_iterator<vector, true>; friend struct __bit_array<vector>; - friend struct _LIBCPP_TYPE_VIS_ONLY hash<vector>; + friend struct _LIBCPP_TEMPLATE_VIS hash<vector>; }; template <class _Allocator> @@ -2891,6 +2915,7 @@ vector<bool, _Allocator>::assign(size_type __n, const value_type& __x) } _VSTD::fill_n(begin(), __n, __x); } + __invalidate_all_iterators(); } template <class _Allocator> @@ -2918,7 +2943,9 @@ typename enable_if vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) { clear(); - difference_type __n = _VSTD::distance(__first, __last); + difference_type __ns = _VSTD::distance(__first, __last); + _LIBCPP_ASSERT(__ns >= 0, "invalid range specified"); + const size_t __n = static_cast<size_type>(__ns); if (__n) { if (__n > capacity()) @@ -3097,7 +3124,9 @@ typename enable_if >::type vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { - difference_type __n = _VSTD::distance(__first, __last); + const difference_type __n_signed = _VSTD::distance(__first, __last); + _LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified"); + const size_type __n = static_cast<size_type>(__n_signed); iterator __r; size_type __c = capacity(); if (__n <= __c && size() <= __c - __n) @@ -3148,7 +3177,7 @@ vector<bool, _Allocator>::swap(vector& __x) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -3246,7 +3275,7 @@ vector<bool, _Allocator>::__hash_code() const _NOEXCEPT } template <class _Allocator> -struct _LIBCPP_TYPE_VIS_ONLY hash<vector<bool, _Allocator> > +struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> > : public unary_function<vector<bool, _Allocator>, size_t> { _LIBCPP_INLINE_VISIBILITY |