[libcxx-commits] [libcxx] [libcxx] adds size-based `__split_buffer` representation to unstable ABI (PR #139632)
Christopher Di Bella via libcxx-commits
libcxx-commits at lists.llvm.org
Tue May 27 11:09:29 PDT 2025
================
@@ -78,23 +80,260 @@ public:
__split_buffer,
void>;
- pointer __first_;
- pointer __begin_;
- pointer __end_;
- _LIBCPP_COMPRESSED_PAIR(pointer, __cap_, allocator_type, __alloc_);
+ struct __data {
+ pointer __first_ = nullptr;
+ pointer __begin_ = nullptr;
+#ifndef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ pointer __end_ = nullptr;
+ _LIBCPP_COMPRESSED_PAIR(pointer, __cap_ = nullptr, allocator_type, __alloc_);
+#else
+ size_type __size_ = 0;
+ _LIBCPP_COMPRESSED_PAIR(size_type, __cap_ = 0, allocator_type, __alloc_);
+#endif
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __data() = default;
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __data(const allocator_type& __alloc)
+ : __alloc_(__alloc)
+ {}
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer first() _NOEXCEPT {
+ return __first_;
+ }
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer first() const _NOEXCEPT {
+ return __first_;
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer begin() _NOEXCEPT {
+ return __begin_;
+ }
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_pointer begin() const _NOEXCEPT {
+ return __begin_;
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __begin_ + __size_;
+#else
+ return __end_;
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer end() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __begin_ + __size_;
+#else
+ return __end_;
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __size_;
+#else
+ return static_cast<size_type>(__end_ - __begin_);
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __size_ == 0;
+#else
+ return __begin_ == __end_;
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __cap_;
+#else
+ return static_cast<size_type>(__cap_ - __first_);
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __capacity_as_pointer() _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __first_ + __cap_;
+#else
+ return __cap_;
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __capacity_as_pointer() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __first_ + __cap_;
+#else
+ return __cap_;
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __update_begin(pointer __new_begin) _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ __size_ -= __new_begin - __begin_;
+#else
+ // TODO: explain why there isn't a pointer-based analogue
+#endif
+
+ __begin_ = __new_begin;
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const _NOEXCEPT {
+ return static_cast<size_type>(__begin_ - __first_);
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __update_sentinel(pointer __new_end) _NOEXCEPT {
+ _LIBCPP_ASSERT(__first_ <= __new_end, "__new_end cannot precede __first_");
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ __size_ += __new_end - end();
+#else
+ __end_ = __new_end;
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __update_sentinel(size_type __new_size) _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ __size_ = __new_size;
+#else
+ __end_ = __begin_ + __new_size;
+#endif
+ }
- __split_buffer(const __split_buffer&) = delete;
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __update_capacity(size_type __new_capacity) _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ __cap_ = __new_capacity;
+#else
+ __cap_ = __first_ + __new_capacity;
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ // `__cap_ - __end_` tells us the total number of spares when in size-mode. We need to remove
+ // the __front_spare from the count.
+ return __cap_ - __size_ - __front_spare();
+#else
+ return static_cast<size_type>(__cap_ - __end_);
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __begin_[__size_ - 1];
+#else
+ return *(__end_ - 1);
+#endif
+ }
+
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ return __begin_[__size_ - 1];
+#else
+ return *(__end_ - 1);
+#endif
+ }
+
+ template<class _Data2>
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_without_allocator(_Data2& __other) _NOEXCEPT {
+ std::swap(__first_, __other.__first_);
+ std::swap(__begin_, __other.__begin_);
+ std::swap(__cap_, __other.__cap_);
+#ifdef _LIBCPP_ABI_SIZE_BASED_VECTOR
+ std::swap(__size_, __other.__size_);
+#else
+ std::swap(__end_, __other.__end_);
+#endif
+ }
----------------
cjdb wrote:
We swap without the allocator in quite a few places. I'm happy to replace it with a regular `swap`, but this is faithful to those call sites.
https://github.com/llvm/llvm-project/pull/139632
More information about the libcxx-commits
mailing list