================
@@ -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);
----------------
ldionne wrote:

The fact that we special-case on the layout here is a smell. The split buffer's 
layout should be generic and `__split_buffer` should work regardless of the 
layout passed to it (even if we had e.g. a 3rd layout that is somehow different 
from the existing two).

I believe we should always call `__set_sentinel(__end + __d)`. In the 
size-based layout, this will redundantly set `__size_`, but at least it will 
always be correct (if we e.g. had a different layout), and it will remove the 
need for the arguably ad-hoc `__set_size_if_pointer_based` function. I suspect 
that the redundant store will be entirely in the noise compared to all the work 
we're doing in `emplace_front`.

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

Reply via email to