[libcxx-commits] [libcxx] [libcxx] adds a size-based representation for `vector`'s unstable ABI (PR #155330)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Apr 3 09:54:03 PDT 2026


================
@@ -1129,18 +1087,18 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 inline
     void
 #endif
     vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
-  pointer __end = this->__end_;
+  auto __current_boundary = __layout_.__boundary_representation();
   std::__if_likely_else(
-      __end < this->__cap_,
+      __current_boundary < __layout_.__capacity_representation(),
       [&] {
         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
-        ++__end;
+        ++__current_boundary;
       },
-      [&] { __end = __emplace_back_slow_path(std::forward<_Args>(__args)...); });
+      [&] { __current_boundary = __emplace_back_slow_path(std::forward<_Args>(__args)...); });
 
-  this->__end_ = __end;
+  __layout_.__set_boundary(__current_boundary);
----------------
ldionne wrote:

I think this is the last remaining function that is meaningfully different depending on the layout (and that's why it's the last remaining function that uses the `__set_boundary` overload).

In the interest of unblocking this patch, I'd actually prefer doing this than the status quo:

```c++
// TODO: Refactor into the layout type
#if SIZE_BASED_VECTOR
    std::__if_likely_else(
        size() < capacity(),
        [&] {
            __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
            __layout.__set_size(size() + 1);
        },
        [&] { __layout_.__set_end(__emplace_back_slow_path(std::forward<_Args>(__args)...)); }
    );
#else
    // current code
    pointer __end = this->__end_;
    std::__if_likely_else(
      __end < this->__cap_,
      [&] {
        __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
        ++__end;
      },
      [&] { __end = __emplace_back_slow_path(std::forward<_Args>(__args)...); }
    );
    this->__end_ = __end;
#endif
```

This gets rid of what I think is my biggest concern in the patch: the usage of boundary to mean either size of pointer. I've said it many times, but I think that's too subtle and at this point I'd rather temporarily give up on not having any `#ifdef`s in the main vector code (until we find a way to refactor this) than keep all the `boundary` related stuff just for this one usage.

Important note: In `__emplace_back_slow_path`, I'd return a pointer all the time. This does mean the size-based vector is going to be less efficient by one pointer arithmetic, but that's in the slow path where this is going to be completely unnoticeable.

https://github.com/llvm/llvm-project/pull/155330


More information about the libcxx-commits mailing list