#else
_LIBCPP_INLINE_VISIBILITY
void __annotate_contiguous_container(const void*, const void*, const void*,
- const void*) const {}
+ const void*) const _NOEXCEPT {}
#endif
_LIBCPP_INLINE_VISIBILITY
- void __annotate_new(size_type __current_size) const {
+ void __annotate_new(size_type __current_size) const _NOEXCEPT {
__annotate_contiguous_container(data(), data() + capacity(),
data() + capacity(), data() + __current_size);
}
_LIBCPP_INLINE_VISIBILITY
- void __annotate_delete() const {
+ void __annotate_delete() const _NOEXCEPT {
__annotate_contiguous_container(data(), data() + capacity(),
data() + size(), data() + capacity());
}
_LIBCPP_INLINE_VISIBILITY
- void __annotate_increase(size_type __n) const
+ void __annotate_increase(size_type __n) const _NOEXCEPT
{
__annotate_contiguous_container(data(), data() + capacity(),
data() + size(), data() + size() + __n);
}
_LIBCPP_INLINE_VISIBILITY
- void __annotate_shrink(size_type __old_size) const
+ void __annotate_shrink(size_type __old_size) const _NOEXCEPT
{
__annotate_contiguous_container(data(), data() + capacity(),
data() + __old_size, data() + size());
}
+
+ struct _ConstructTransaction {
+ explicit _ConstructTransaction(vector &__v, size_type __n)
+ : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) {
#ifndef _LIBCPP_HAS_NO_ASAN
- // The annotation for size increase should happen before the actual increase,
- // but if an exception is thrown after that the annotation has to be undone.
- struct __RAII_IncreaseAnnotator {
- __RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1)
- : __commit(false), __v(__v), __old_size(__v.size() + __n) {
- __v.__annotate_increase(__n);
- }
- void __done() { __commit = true; }
- ~__RAII_IncreaseAnnotator() {
- if (__commit) return;
- __v.__annotate_shrink(__old_size);
+ __v_.__annotate_increase(__n);
+#endif
+ }
+ ~_ConstructTransaction() {
+ __v_.__end_ = __pos_;
+#ifndef _LIBCPP_HAS_NO_ASAN
+ if (__pos_ != __new_end_) {
+ __v_.__annotate_shrink(__new_end_ - __v_.__begin_);
}
- bool __commit;
- const vector &__v;
- size_type __old_size;
- };
-#else
- struct __RAII_IncreaseAnnotator {
- _LIBCPP_INLINE_VISIBILITY
- __RAII_IncreaseAnnotator(const vector &, size_type = 1) {}
- _LIBCPP_INLINE_VISIBILITY void __done() {}
- };
#endif
+ }
+
+ vector &__v_;
+ pointer __pos_;
+ const_pointer const __new_end_;
+
+ private:
+ _ConstructTransaction(_ConstructTransaction const&) = delete;
+ _ConstructTransaction& operator=(_ConstructTransaction const&) = delete;
+ };
+ template <class ..._Args>
+ _LIBCPP_INLINE_VISIBILITY
+ void __construct_one_at_end(_Args&& ...__args) {
+ _ConstructTransaction __tx(*this, 1);
+ __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(__tx.__pos_),
+ _VSTD::forward<_Args>(__args)...);
+ ++__tx.__pos_;
+ }
};
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
void
vector<_Tp, _Allocator>::__construct_at_end(size_type __n)
{
- allocator_type& __a = this->__alloc();
- do
- {
- __RAII_IncreaseAnnotator __annotator(*this);
- __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
- ++this->__end_;
- --__n;
- __annotator.__done();
- } while (__n > 0);
+ _ConstructTransaction __tx(*this, __n);
+ for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) {
+ __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(__tx.__pos_));
+ }
}
// Copy constructs __n objects starting at __end_ from __x
void
vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
{
- allocator_type& __a = this->__alloc();
- do
- {
- __RAII_IncreaseAnnotator __annotator(*this);
- __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
- ++this->__end_;
- --__n;
- __annotator.__done();
- } while (__n > 0);
+ _ConstructTransaction __tx(*this, __n);
+ for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) {
+ __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(__tx.__pos_), __x);
+ }
}
template <class _Tp, class _Allocator>
>::type
vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n)
{
- allocator_type& __a = this->__alloc();
- __RAII_IncreaseAnnotator __annotator(*this, __n);
- __alloc_traits::__construct_range_forward(__a, __first, __last, this->__end_);
- __annotator.__done();
+ _ConstructTransaction __tx(*this, __n);
+ __alloc_traits::__construct_range_forward(this->__alloc(), __first, __last, __tx.__pos_);
}
// Default constructs __n objects starting at __end_
{
if (this->__end_ != this->__end_cap())
{
- __RAII_IncreaseAnnotator __annotator(*this);
- __alloc_traits::construct(this->__alloc(),
- _VSTD::__to_raw_pointer(this->__end_), __x);
- __annotator.__done();
- ++this->__end_;
+ __construct_one_at_end(__x);
}
else
__push_back_slow_path(__x);
{
if (this->__end_ < this->__end_cap())
{
- __RAII_IncreaseAnnotator __annotator(*this);
- __alloc_traits::construct(this->__alloc(),
- _VSTD::__to_raw_pointer(this->__end_),
- _VSTD::move(__x));
- __annotator.__done();
- ++this->__end_;
+ __construct_one_at_end(_VSTD::move(__x));
}
else
__push_back_slow_path(_VSTD::move(__x));
{
if (this->__end_ < this->__end_cap())
{
- __RAII_IncreaseAnnotator __annotator(*this);
- __alloc_traits::construct(this->__alloc(),
- _VSTD::__to_raw_pointer(this->__end_),
- _VSTD::forward<_Args>(__args)...);
- __annotator.__done();
- ++this->__end_;
+ __construct_one_at_end(_VSTD::forward<_Args>(__args)...);
}
else
__emplace_back_slow_path(_VSTD::forward<_Args>(__args)...);
{
pointer __old_last = this->__end_;
difference_type __n = __old_last - __to;
- for (pointer __i = __from_s + __n; __i < __from_e; ++__i, ++this->__end_)
- __alloc_traits::construct(this->__alloc(),
- _VSTD::__to_raw_pointer(this->__end_),
- _VSTD::move(*__i));
+ {
+ pointer __i = __from_s + __n;
+ _ConstructTransaction __tx(*this, __from_e - __i);
+ for (; __i < __from_e; ++__i, ++__tx.__pos_) {
+ __alloc_traits::construct(this->__alloc(),
+ _VSTD::__to_raw_pointer(__tx.__pos_),
+ _VSTD::move(*__i));
+ }
+ }
_VSTD::move_backward(__from_s, __from_s + __n, __old_last);
}
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
- __RAII_IncreaseAnnotator __annotator(*this);
if (__p == this->__end_)
{
- __alloc_traits::construct(this->__alloc(),
- _VSTD::__to_raw_pointer(this->__end_), __x);
- ++this->__end_;
+ __construct_one_at_end(__x);
}
else
{
++__xr;
*__p = *__xr;
}
- __annotator.__done();
}
else
{
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
- __RAII_IncreaseAnnotator __annotator(*this);
if (__p == this->__end_)
{
- __alloc_traits::construct(this->__alloc(),
- _VSTD::__to_raw_pointer(this->__end_),
- _VSTD::move(__x));
- ++this->__end_;
+ __construct_one_at_end(_VSTD::move(__x));
}
else
{
__move_range(__p, this->__end_, __p + 1);
*__p = _VSTD::move(__x);
}
- __annotator.__done();
}
else
{
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
- __RAII_IncreaseAnnotator __annotator(*this);
if (__p == this->__end_)
{
- __alloc_traits::construct(this->__alloc(),
- _VSTD::__to_raw_pointer(this->__end_),
- _VSTD::forward<_Args>(__args)...);
- ++this->__end_;
+ __construct_one_at_end(_VSTD::forward<_Args>(__args)...);
}
else
{
__move_range(__p, this->__end_, __p + 1);
*__p = _VSTD::move(__tmp.get());
}
- __annotator.__done();
}
else
{
}
if (__n > 0)
{
- __RAII_IncreaseAnnotator __annotator(*this, __n);
__move_range(__p, __old_last, __p + __old_n);
- __annotator.__done();
const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
if (__p <= __xr && __xr < this->__end_)
__xr += __old_n;
pointer __old_last = this->__end_;
for (; this->__end_ != this->__end_cap() && __first != __last; ++__first)
{
- __RAII_IncreaseAnnotator __annotator(*this);
- __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
- *__first);
- ++this->__end_;
- __annotator.__done();
+ __construct_one_at_end(*__first);
}
__split_buffer<value_type, allocator_type&> __v(__a);
if (__first != __last)
}
if (__n > 0)
{
- __RAII_IncreaseAnnotator __annotator(*this, __n);
__move_range(__p, __old_last, __p + __old_n);
- __annotator.__done();
_VSTD::copy(__first, __m, __p);
}
}