src/cxx_supportlib/vendor-modified/boost/container/vector.hpp in passenger-6.0.2 vs src/cxx_supportlib/vendor-modified/boost/container/vector.hpp in passenger-6.0.3
- old
+ new
@@ -120,46 +120,46 @@
: m_ptr(other.get_ptr())
{}
//Pointer like operators
BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
- { return *m_ptr; }
+ { BOOST_ASSERT(!!m_ptr); return *m_ptr; }
BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
- { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
+ { return m_ptr; }
BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
- { return m_ptr[off]; }
+ { BOOST_ASSERT(!!m_ptr); return m_ptr[off]; }
//Increment / Decrement
BOOST_CONTAINER_FORCEINLINE vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
- { ++m_ptr; return *this; }
+ { BOOST_ASSERT(!!m_ptr); ++m_ptr; return *this; }
BOOST_CONTAINER_FORCEINLINE vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
- { return vec_iterator(m_ptr++); }
+ { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr++); }
BOOST_CONTAINER_FORCEINLINE vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
- { --m_ptr; return *this; }
+ { BOOST_ASSERT(!!m_ptr); --m_ptr; return *this; }
BOOST_CONTAINER_FORCEINLINE vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
- { return vec_iterator(m_ptr--); }
+ { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr--); }
//Arithmetic
BOOST_CONTAINER_FORCEINLINE vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
- { m_ptr += off; return *this; }
+ { BOOST_ASSERT(m_ptr || !off); m_ptr += off; return *this; }
BOOST_CONTAINER_FORCEINLINE vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
- { m_ptr -= off; return *this; }
+ { BOOST_ASSERT(m_ptr || !off); m_ptr -= off; return *this; }
BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
- { return vec_iterator(x.m_ptr+off); }
+ { BOOST_ASSERT(x.m_ptr || !off); return vec_iterator(x.m_ptr+off); }
BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW
- { right.m_ptr += off; return right; }
+ { BOOST_ASSERT(right.m_ptr || !off); right.m_ptr += off; return right; }
BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
- { left.m_ptr -= off; return left; }
+ { BOOST_ASSERT(left.m_ptr || !off); left.m_ptr -= off; return left; }
BOOST_CONTAINER_FORCEINLINE friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
{ return left.m_ptr - right.m_ptr; }
//Comparison operators
@@ -929,10 +929,16 @@
//!
//! <b>Throws</b>: If allocator_type's allocation
//! throws or T's constructor taking a dereferenced InIt throws.
//!
//! <b>Complexity</b>: Linear to the range [first, last).
+// template <class InIt>
+// vector(InIt first, InIt last
+// BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+// < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+// BOOST_MOVE_I dtl::nat >::type * = 0)
+// ) -> vector<typename iterator_traits<InIt>::value_type, new_allocator<typename iterator_traits<InIt>::value_type>>;
template <class InIt>
vector(InIt first, InIt last
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
< dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
BOOST_MOVE_I dtl::nat >::type * = 0)
@@ -945,10 +951,16 @@
//!
//! <b>Throws</b>: If allocator_type's allocation
//! throws or T's constructor taking a dereferenced InIt throws.
//!
//! <b>Complexity</b>: Linear to the range [first, last).
+// template <class InIt>
+// vector(InIt first, InIt last, const allocator_type& a
+// BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
+// < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
+// BOOST_MOVE_I dtl::nat >::type * = 0)
+// ) -> vector<typename iterator_traits<InIt>::value_type, new_allocator<typename iterator_traits<InIt>::value_type>>;
template <class InIt>
vector(InIt first, InIt last, const allocator_type& a
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
< dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
BOOST_MOVE_I dtl::nat >::type * = 0)
@@ -1117,11 +1129,10 @@
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_RV_REF(vector) x)
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
|| allocator_traits_type::is_always_equal::value)
{
- BOOST_ASSERT(&x != this);
this->priv_move_assign(boost::move(x));
return *this;
}
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1178,10 +1189,11 @@
//! T's constructor/assignment from dereferencing InpIt throws.
//!
//! <b>Complexity</b>: Linear to n.
template <class InIt>
void assign(InIt first, InIt last
+ //Input iterators or version 0 allocator
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
< void
BOOST_MOVE_I dtl::is_convertible<InIt BOOST_MOVE_I size_type>
BOOST_MOVE_I dtl::and_
< dtl::is_different<alloc_version BOOST_MOVE_I version_0>
@@ -1227,10 +1239,11 @@
//! T's constructor/assignment from dereferencing InpIt throws.
//!
//! <b>Complexity</b>: Linear to n.
template <class FwdIt>
void assign(FwdIt first, FwdIt last
+ //Forward iterators and version > 0 allocator
BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
< void
BOOST_MOVE_I dtl::is_same<alloc_version BOOST_MOVE_I version_0>
BOOST_MOVE_I dtl::is_convertible<FwdIt BOOST_MOVE_I size_type>
BOOST_MOVE_I dtl::is_input_iterator<FwdIt>
@@ -1266,25 +1279,13 @@
#endif
this->m_holder.capacity(real_cap);
//Forward expansion, use assignment + back deletion/construction that comes later
}
}
- //Overwrite all elements we can from [first, last)
- iterator cur = this->begin();
- const iterator end_it = this->end();
- for ( ; first != last && cur != end_it; ++cur, ++first){
- *cur = *first;
- }
- if (first == last){
- //There are no more elements in the sequence, erase remaining
- this->priv_destroy_last_n(this->size() - input_sz);
- }
- else{
- //Uninitialized construct at end the remaining range
- this->priv_uninitialized_construct_at_end(first, last);
- }
+ boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), first, input_sz, this->priv_raw_begin(), this->size());
+ this->m_holder.m_size = input_sz;
}
//! <b>Effects</b>: Assigns the n copies of val to *this.
//!
//! <b>Throws</b>: If memory allocation throws or
@@ -1348,11 +1349,15 @@
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
- { return iterator(this->m_holder.start() + this->m_holder.m_size); }
+ {
+ pointer const bg = this->m_holder.start();
+ size_type const sz = this->m_holder.m_size;
+ return iterator(BOOST_LIKELY(sz) ? bg + sz : bg); //Avoid UB on null-pointer arithmetic
+ }
//! <b>Effects</b>: Returns a const_iterator to the end of the vector.
//!
//! <b>Throws</b>: Nothing.
//!
@@ -1408,11 +1413,16 @@
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
- { return const_iterator(this->m_holder.start() + this->m_holder.m_size); }
+ {
+ pointer const bg = this->m_holder.start();
+ size_type const sz = this->m_holder.m_size;
+ return const_iterator(BOOST_LIKELY(sz) ? bg + sz : bg); //Avoid UB on null-pointer arithmetic
+ }
+ //{ return const_iterator(this->m_holder.start() + this->m_holder.m_size); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed vector.
//!
//! <b>Throws</b>: Nothing.
@@ -2033,13 +2043,14 @@
//!
//! <b>Complexity</b>: Linear to the distance between first and last
//! plus linear to the elements between pos and the last element.
iterator erase(const_iterator first, const_iterator last)
{
- BOOST_ASSERT(first == last ||
- (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
if (first != last){
+ BOOST_ASSERT(this->priv_in_range(first));
+ BOOST_ASSERT(this->priv_in_range_or_end(last));
+ BOOST_ASSERT(first < last);
T* const old_end_ptr = this->priv_raw_end();
T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first));
T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last));
T* const ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
this->priv_destroy_last_n(old_end_ptr - ptr);
@@ -2178,11 +2189,11 @@
if(!dtl::is_input_iterator<InputIt>::value &&
free_cap < (n = static_cast<size_type>(boost::container::iterator_distance(first, last)))){
this->priv_merge_in_new_buffer(first, n, comp, alloc_version());
}
else{
- iterator pos(this->insert(this->cend(), first, last));
+ this->insert(this->cend(), first, last);
T *const raw_beg = this->priv_raw_begin();
T *const raw_end = this->priv_raw_end();
T *const raw_pos = raw_beg + s;
boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_cap - n);
}
@@ -2193,15 +2204,15 @@
{ this->merge_unique(first, last, value_less_t()); }
template<class InputIt, class Compare>
BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last, Compare comp)
{
- size_type const s = this->size();
+ size_type const old_size = this->size();
this->priv_set_difference_back(first, last, comp);
T *const raw_beg = this->priv_raw_begin();
T *const raw_end = this->priv_raw_end();
- T *raw_pos = raw_beg + s;
+ T *raw_pos = raw_beg + old_size;
boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size());
}
private:
template<class PositionValue>
@@ -2274,18 +2285,18 @@
return;
}
if (comp(*first1, *first2)) {
this->emplace_back(*first1);
- //Reallocation happened, update range
T * const raw_begin = this->priv_raw_begin();
- if(old_first2 != raw_begin){
+ if(old_first2 != raw_begin)
+ {
+ //Reallocation happened, update range
first2 = raw_begin + (first2 - old_first2);
- last2 = first2 + (last2 - old_first2);
+ last2 = raw_begin + (last2 - old_first2);
old_first2 = raw_begin;
}
-
++first1;
}
else {
if (!comp(*first2, *first1)) {
++first1;
@@ -2392,30 +2403,25 @@
< void
, dtl::is_version<OtherAllocator, 0>
, dtl::is_different<OtherAllocator, allocator_type>
>::type * = 0)
{
- //for move assignment, no aliasing (&x != this) is assummed.
- BOOST_ASSERT(this != &x);
+ //for move assignment, no aliasing (&x != this) is assumed.
+ //x.size() == 0 is allowed for buggy std libraries.
+ BOOST_ASSERT(this != &x || x.size() == 0);
allocator_type &this_alloc = this->m_holder.alloc();
allocator_type &x_alloc = x.m_holder.alloc();
const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc);
- const bool is_propagable_from_t = is_propagable_from(this_alloc, m_holder.start(), x_alloc, propagate_alloc);
- const bool are_both_propagable = is_propagable_from_x && is_propagable_from_t;
//Resources can be transferred if both allocators are
//going to be equal after this function (either propagated or already equal)
- if(are_both_propagable){
- //Destroy objects but retain memory in case x reuses it in the future
+ if(is_propagable_from_x){
this->clear();
- this->m_holder.swap_resources(x.m_holder);
- }
- else if(is_propagable_from_x){
- this->clear();
- this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity);
+ if(BOOST_LIKELY(!!this->m_holder.m_start))
+ this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity);
this->m_holder.steal_resources(x.m_holder);
}
//Else do a one by one move
else{
this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
@@ -2475,10 +2481,13 @@
, x.get_stored_allocator(), x.m_holder.start(), propagate_alloc)){
//Just swap internals
this->m_holder.swap_resources(x.m_holder);
}
else{
+ if (BOOST_UNLIKELY(&x == this))
+ return;
+
//Else swap element by element...
bool const t_smaller = this->size() < x.size();
vector &sml = t_smaller ? *this : x;
vector &big = t_smaller ? x : *this;
@@ -2650,11 +2659,12 @@
{
const size_type cp = this->m_holder.capacity();
if(cp){
const size_type sz = this->size();
if(!sz){
- this->m_holder.deallocate(this->m_holder.m_start, cp);
+ if(BOOST_LIKELY(!!this->m_holder.m_start))
+ this->m_holder.deallocate(this->m_holder.m_start, cp);
this->m_holder.m_start = pointer();
this->m_holder.m_capacity = 0;
}
else if(sz < cp){
//Allocate a new buffer.
@@ -2676,11 +2686,12 @@
{
const size_type cp = this->m_holder.capacity();
if(cp){
const size_type sz = this->size();
if(!sz){
- this->m_holder.deallocate(this->m_holder.m_start, cp);
+ if(BOOST_LIKELY(!!this->m_holder.m_start))
+ this->m_holder.deallocate(this->m_holder.m_start, cp);
this->m_holder.m_start = pointer();
this->m_holder.m_capacity = 0;
}
else{
size_type received_size = sz;
@@ -3349,9 +3360,22 @@
void reset_alloc_stats()
{ num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; }
#endif
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
+
+#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
+
+template <typename InputIterator>
+vector(InputIterator, InputIterator) ->
+ vector<typename iterator_traits<InputIterator>::value_type>;
+
+template <typename InputIterator, typename Allocator>
+vector(InputIterator, InputIterator, Allocator const&) ->
+ vector<typename iterator_traits<InputIterator>::value_type, Allocator>;
+
+#endif
+
}} //namespace boost::container
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED