summaryrefslogtreecommitdiff
path: root/contrib/libc++/include/vector
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libc++/include/vector')
-rw-r--r--contrib/libc++/include/vector151
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