================ @@ -428,50 +653,60 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::shrink_to_fi } } -template <class _Tp, class _Allocator> +template <class _Tp, class _Allocator, template <class, class, class> class _Layout> template <class... _Args> -_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::emplace_front(_Args&&... __args) { - if (__begin_ == __first_) { - if (__end_ < __cap_) { - difference_type __d = __cap_ - __end_; +_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::emplace_front(_Args&&... __args) { + if (__front_spare() == 0) { + pointer __end = end(); + if (__back_spare() > 0) { + // The elements are pressed up against the front of the buffer: we need to move them back a + // little bit to make `emplace_front` have amortised O(1) complexity. + difference_type __d = __back_spare(); __d = (__d + 1) / 2; - __begin_ = std::move_backward(__begin_, __end_, __end_ + __d); - __end_ += __d; + __set_begin(std::move_backward(begin(), __end, __end + __d)); + + // `begin()` was moved further into the buffer, so we need to update the pointer-based + // layout's end with it. We don't need to do anything for the size-based layout here, because + // the number of elements hasn't changed yet. + __set_size_if_pointer_based(__d); } else { - size_type __c = std::max<size_type>(2 * static_cast<size_type>(__cap_ - __first_), 1); - __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc_); - __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_)); - std::swap(__first_, __t.__first_); - std::swap(__begin_, __t.__begin_); - std::swap(__end_, __t.__end_); - std::swap(__cap_, __t.__cap_); + size_type __c = std::max<size_type>(2 * capacity(), 1); + __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, this->__alloc_); + __t.__construct_at_end(move_iterator<pointer>(begin()), move_iterator<pointer>(__end)); + __swap_without_allocator(__t); } } - __alloc_traits::construct(__alloc_, std::__to_address(__begin_ - 1), std::forward<_Args>(__args)...); - --__begin_; + + __alloc_traits::construct(this->__alloc_, std::__to_address(begin() - 1), std::forward<_Args>(__args)...); + __set_begin(begin() - 1); + + // Now that we've added an element to the front of the buffer, we need to update the size-based + // layout's size. We don't need to do anything for the pointer-based layout here, because the end + // pointer was never updated. + __set_end_if_size_based(); ---------------- cjdb wrote:
Done. I agree that combining `__set_begin` and `__set_sentinel` is a good move. https://github.com/llvm/llvm-project/pull/139632 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits