Commit graph

84 commits

Author SHA1 Message Date
Louis Dionne
17ac8fdd95
[libc++] Don't require complete types in vector<T>::empty() (#210754)
This was previously not required, but the patch to introduce a new
size-based vector layout unintentionally added this new requirement. We
almost certainly not want to promise this guarantee going forward, but
we should actually land this change explicitly and consider the
transition story, not do it as a fallout of another refactoring.

Fixes #210732
2026-07-21 10:21:27 -04:00
halbi2
f5169f2a5c
[libc++] Enable missing allocator constructors in C++11 (#204845)
LWG2210 was a patch to N2554 (C++11) which added missing
allocator-extended constructors to various containers. When LWG2210 was
implemented, the constructors were gated with C++14. However, we
normally apply LWG issue resolutions as DRs.

This patch enables these constructors in C++11 mode too.

Fixes #204843

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
Co-authored-by: A. Jiang <de34@live.cn>
2026-07-10 07:46:26 +08:00
Louis Dionne
48aade5e52
[libc++][NFC] Fix comment about size-based vector (#208463)
The closing #endif comment was using _LIBCPP_ABI_SIZE_BASED_VECTOR,
which was the name of the macro in previous iterations of the size-based
vector patch. We ended up landing on _LIBCPP_ABI_VECTOR_LAYOUT_SIZE_BASED
instead.
2026-07-09 09:37:42 -04:00
Nikolas Klauser
f6b50ceeca
[libc++] Remove some unnecessary functions from __vector_layout (#207152)
This removes functions which produce identical IR after the first
InstCombine pass after inlining compared to their replacements.
2026-07-09 11:16:32 +02:00
Nikolas Klauser
4fad93b912
[libc++] Use _LIBCPP_NO_UNIQUE_ADDRESS for the new vector layout (#207149)
We use `_LIBCPP_NO_UNIQUE_ADDRESS`, since a plain
`[[no_unique_address]]` doesn't work on Windows.
2026-07-03 04:22:45 +02:00
Christopher Di Bella
bd338806e4
[libc++] Add a size-based representation for vector in the unstable ABI (#155330)
This commit adds an alternative representation for `std::vector` in a similar
manner to `__split_buffer` in #139632. This alternative representation was
measured to provide significant performance gains over the classic representation.

To do so, we introduce a layout type that tracks implementation details that
differ between the pointer-based vector and size-based vector representations.
`vector` does not parameterise its layout type, unlike `__split_buffer`.
`__split_buffer` is used by both `vector` and `deque`, and being able to take
an ABI break on `vector` doesn't automatically mean that users can also tolerate
a break on `deque`.

This new vector representation can be opted into by defining the
_LIBCPP_ABI_VECTOR_LAYOUT_SIZE_BASED macro when configuring the
library's ABI.

This change was the target of this RFC: https://discourse.llvm.org/t/adding-a-size-based-vector-to-libc-s-unstable-abi
2026-07-01 15:12:36 -04:00
Nikolas Klauser
e925b357e1
[libc++] Introduce a private version of in_out_result and use it for copy/move algorithms (#198086)
This patch introduces a new `__in_out_result`, which is an internal
back-ported version of `in_out_result`, and is convertible to that when
it exists. This improves the readability of the code, since it replaces
uses of `first` and `second` with `__in_` and `__out_`, making it clear
which iterator is accessed.

Other algorithms will be updated in separate patches.
2026-05-17 10:06:05 +02:00
Christopher Di Bella
8af8a60d54
[libc++] Add __exchange as a C++11 utility (#187953)
`std::exchange` is helpful for simplifying move operations because we
can couple the resetting component with the move operation. This both
halves the number of necessary lines for each move, and also ensures we
haven't forgotten to reset the moved-from object. Since `std::exchange`
is a C++14 feature, we'll need to use `__exchange` for anything that's
from C++11.

This commit also applies `std::__exchange` to a some trivial use-cases
to show its utility. Applying this project-wide requires a census over
all of our types. It's hoped that this will start a community-wide
clean-up that happens over time.
2026-05-05 03:51:00 +08:00
Nico Weber
ac10c55281
[libcxx] Remove NODEBUG, ALWAYS_INLINE from __swap_layouts (#194931)
This addresses reviewer feedback on #180102.

We've seen

```
error: No debug information found in function
_ZNSt4__Cr6vectorIN4bssl3der5InputENS_9allocatorIS3_EEE14__swap_layoutsERNS_14__split_bufferIS3_S5_NS_29__split_buffer_pointer_layoutEEE:
Function profile not used [-Werror,-Wbackend-plugin]
```

on an internal bot due to the _LIBCPP_NODEBUG.
2026-04-29 19:15:02 +00:00
Christopher Di Bella
8c2c816cf7
Reapply "[libcxx] adds __split_buffer::__swap_layouts" (#185120) (#187763)
This reverts commit 01a97050f0.
2026-03-26 17:09:34 +00:00
Nikolas Klauser
e830ee8006
[libc++] Don't double-wrap iterators when bounded iterators are used (#182264)
There is no reason to double-wrap iterators, since we can already
achieve anything we want within `__bounded_iter`itself.

This is technically ABI breaking, but people using bounded iterators
shouldn't require ABI stability currently.

Fixes #178521
2026-03-07 09:12:25 +01:00
Christopher Di Bella
01a97050f0
Revert "[libcxx] adds __split_buffer::__swap_layouts" (#185120)
Reverts llvm/llvm-project#180102
2026-03-06 22:31:42 +00:00
Christopher Di Bella
65f39a16ab
[libcxx] Add __split_buffer::__swap_layouts (#180102)
This commit simplifies the cumbersome process of swapping the respective
layout members for `__split_buffer` and `vector`.
2026-03-06 21:57:03 +00:00
Nikolas Klauser
d6fcf47a89
[libc++] Fix vector::append_range growing before the capacity is reached (#183264)
Currently `vector::append_range` grows even when appending a number of
elements that is exactly equal to its spare capacity, which is
guaranteed by the standard to _not_ happen.

Fixes #183256
2026-02-27 11:12:17 +01:00
Christopher Di Bella
be28e55d2d
[libc++] Memoise size() in vector::__assign_with_size (#180288)
This is an optimisation from the size-based vector project that's
applicable to all vector implementations.
2026-02-16 22:39:11 +00:00
Christopher Di Bella
4d6913e14f
[libcxx] Rename __split_buffer alias template to _SplitBuffer (#180284)
`-Wchanges-meaning` is a GCC warning that catches shadowing in more
contexts. While a bit annoying here, it's a helpful warning. As such, we
need to rename the `__split_buffer` alias template in `std::vector` so
that we don't trip it up.
2026-02-06 23:22:32 +00:00
Christopher Di Bella
f735aa061b
[libc++] Tighten __add_alignment_assumption return type (#180090)
`__add_alignment_assumption` unilaterally returned a `pointer`, even
when passed a `const_pointer`. This was surfaced by some (but not all)
CI jobs when rebasing `std::vector` to have a layout type.
2026-02-06 08:26:37 -05:00
Louis Dionne
a3ebe650d3
[libc++][NFC] Clang-format <vector> and remove unused __self alias (#177021)
These changes were extracted out of the size-based vector patch.

Co-authored-by: Christopher Di Bella <cjdb@google.com>
2026-01-23 09:17:20 -05:00
Nikolas Klauser
b6bfb199cc
[libc++] Fix {deque,vector}::append_range assuming too much about the types (#162438)
Currently, `deque` and `vector`'s `append_range` is implemented in terms
of `insert_range`. The problem with that is that `insert_range` has more
preconditions, resulting in us rejecting valid code.

This also significantly improves performance for `deque` in some cases.
2026-01-09 12:06:43 +01:00
Eduardo Tachotte
e227125e6d
[libc++][NFC] Fix typo in comment (#173741)
Found a typo while reading the `vector` implementation, this PR simply
fixes it.
2025-12-29 01:09:59 +08:00
Nikolas Klauser
b97b1f2f49
[libc++] Optimize vector<bool>::resize() (#172853)
This both simplifies the implementation and improves the performance,
since the compiler is better able to see through what's going on.

```
Benchmark                                                                              old             new    Difference    % Difference
--------------------------------------------------------------------------  --------------  --------------  ------------  --------------
vector<bool>(const_vector<bool>&)                                                    11.99           12.26          0.27           2.25%
vector<bool>(size_type,_const_value_type&)                                            9.24            9.29          0.05           0.54%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(different_allocators)           14.26           14.35          0.09           0.65%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(equal_allocators)                2.67            2.67         -0.01          -0.29%
vector<bool>::reserve()                                                               9.30            9.29         -0.01          -0.12%
vector<bool>::resize()                                                               15.14           13.43         -1.71         -11.28%
Geomean                                                                               9.17            9.03         -0.14          -1.48%
2025-12-20 10:52:48 +01:00
Louis Dionne
2c1decb7f7
[libc++] Don't instantiate __split_buffer with an allocator reference (#171651)
Allocators should be extremely cheap, if not free, to copy. Furthermore,
we have requirements on allocator types that copies must compare equal,
and that move and copy must be the same.

Hence, taking an allocator by reference should not provide benefits
beyond making a copy of it. However, taking the allocator by reference
leads to complexity in __split_buffer, which can be removed if we stop
using that pattern.
2025-12-11 09:31:22 +01:00
Nikolas Klauser
c567e28a9d
[libc++] Optimize vector<bool>::reserve (#170137)
Apple M4:
```
Benchmark                                                                      old        new    Difference    % Difference
--------------------------------------------------------------------------  ------  ----------  ------------  --------------
vector<bool>(const_vector<bool>&)                                            12.73       12.87          0.14           1.07%
vector<bool>(size_type,_const_value_type&)                                    9.39        9.41          0.02           0.22%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(different_allocators)   16.87       15.22         -1.65          -9.80%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(equal_allocators)        2.68        2.73          0.05           1.90%
vector<bool>::reserve()                                                      11.81        9.43         -2.38         -20.14%
Geomean                                                                       9.14        8.62         -0.53          -5.76%
```
2025-12-10 10:18:59 +01:00
Nikolas Klauser
634f6e9ff3
[libc++] Merge the implementations of ranges::copy_n and std::copy_n and fix vector::insert to assign (#157444)
This reduces the amount of code we have to maintain a bit.

This also simplifies `vector` by using the internal API instead of
`#if`s to switch based on language dialect.
2025-11-27 15:50:50 +01:00
Louis Dionne
17ce48f2b6
[libc++] Remove __is_replaceable emulation (#167355)
The Trivial Relocation feature has been removed from the C++26 working
draft. Based on discussions in Kona, it is unlikely that the
"replaceable" type concept will come back in the C++29 time frame.

Since we don't have a use for the type trait in the library at the
moment, remove the code associated to it. If we end up needing something
like it in the future, we can always add it back.
2025-11-11 07:53:56 -05:00
Nikolas Klauser
0d97f43974
[libc++] Inline vector::__append into resize (#162086)
These functions are only used in a single place, so there is not much
reason to keep them around.
2025-11-10 20:02:54 +01:00
Nikolas Klauser
446d950524
[libc++] Use std::__{scope,exception}_guard throughout the code base (#161322)
This simplifies the code quite a bit and seems to improve code size
slightly in some cases.
2025-10-09 09:32:40 +02:00
Nikolas Klauser
a798a10434
[libc++] Optimize vector<bool>(const vector<bool>&) (#161672)
```
Benchmark                   Baseline    Candidate    Difference    % Difference
------------------------  ----------  -----------  ------------  --------------
BM_vector_bool_copy_ctor       56.93        10.93        -46.00          -80.80
BM_vector_bool_size_ctor        7.99         8.01          0.02            0.22
```
2025-10-07 15:07:12 +02:00
Nikolas Klauser
70b7874ab2
[libc++] Make the naming of the iterator_traits aliases consistent (#161661)
This renames all the `iterator_traits` alises to be
`__iterator_<type-name>`. e.g `iterator_traits<T>::value_type` will be
`__iterator_value_type<T>`.
2025-10-07 14:42:11 +02:00
Nikolas Klauser
96a7c9b985
[libc++] Simplify vector<bool> fill constructors (#160521)
#119632 introduced a code size and performance regression. This was
verified by running the included benchmark against trunk and trunk with
#119632 reverted. Instead of actually reverting that patch, we can
inline `__construct_at_end` into the few places it's used instead,
simplifying the implementation further (by not handling special cases we
never actually encounter).

```
Benchmark                   Baseline    Candidate    Difference    % Difference
------------------------  ----------  -----------  ------------  --------------
BM_vector_bool_size_ctor       29.91         8.56        -21.35          -71.37
```
2025-09-25 19:48:14 +02:00
Nikolas Klauser
8cb03a05ff
[libc++][NFC] Refactor __is_allocator to be a variable template (#159584) 2025-09-24 10:41:29 +02:00
Nikolas Klauser
ebcf1bf2ec
[libc++] Remove a few unused includes from <string> and <vector> (#160087) 2025-09-23 09:37:24 +02:00
Nikolas Klauser
76a11c769d
Reapply "[libc++] Mark __{emplace,push}_back_slow_path as noinline (#94379)" (#158606)
This reverts commit 7f2e9b1709.

The LLDB failures have been resolved in trunk.
2025-09-17 11:10:06 +02:00
Aiden Grossman
7f2e9b1709 Revert "[libc++] Mark __{emplace,push}_back_slow_path as noinline (#94379)"
This reverts commit 1bafd020c7.

This breaks the LLDB data formatters which means these failures show up
on every premerge run. Reverting for now until fixing the LLDB
formatters can be coordinated with a relanding.
2025-09-12 21:24:15 +00:00
Christopher Di Bella
e8f61801c6
[libcxx] adds size-based __split_buffer representation to unstable ABI (#139632)
**tl;dr** We can significantly improve the runtime performance of
`std::vector` by changing its representation from three pointers to one
pointer and two integers. This document explains the details of this
change, along with the justifications for making it. See the [RFC] for
more information.

`vector` depends on `__split_buffer` for inserting elements. Changing
`__split_buffer` to match `vector`'s representation simplifies the
model, as it eliminates the need to convert between two different
representations of a contiguous buffer in the same configuration of
libc++.

[RFC]: https://discourse.llvm.org/t/adding-a-size-based-vector-to-libc-s-unstable-abi/86306

---------

Co-authored-by: Jorge Gorbe Moya <jgorbe@google.com>
2025-09-12 06:33:10 -07:00
Nikolas Klauser
1bafd020c7
[libc++] Mark __{emplace,push}_back_slow_path as noinline (#94379)
These are almost certainly intended to not be inlined. This
significantly reduces code size when `push_back` and `emplace_back` are
used heavily.

Fixes #94360
2025-09-12 11:05:14 +02:00
Nikolas Klauser
34d4f0c136
[libc++][NFC] Use llvm.org/PR to link to bug reports (#156288)
We've built up quite a few links directly to github within the code
base. We should instead use `llvm.org/PR<issue-number>` to link to bugs,
since that is resilient to the bug tracker changing in the future. This
is especially relevant for tests linking to bugs, since they will
probably be there for decades to come. A nice side effect is that these
links are significantly shorter than the GH links, making them much less
of an eyesore.

This patch also replaces a few links that linked to the old bugzilla
instance on llvm.org.
2025-09-04 09:20:02 +02:00
Nikolas Klauser
9f00ab411a
[libc++] Add [[nodiscard]] to the vector accessor functions (#150615) 2025-07-29 10:30:37 +02:00
Hui
692c5cdb56
[libc++] Do not call reserve in flat containers if underlying container is user defined (#140379)
This is brought up in the LWG reflector. We currently call `reserve` if
the underlying container has one. But the spec does not specify what
`reserve` should do for Sequence Container. So in theory if the
underlying container is user defined type and it can have a function
called `reserve` which does something completely different.

The fix is to just call `reserve` for STL containers if it has one
2025-06-07 08:47:46 +01:00
A. Jiang
e9ce752769
[libc++] Remove the constexpr hash<vector<bool>> extension (#132617)
libc++ makes the `hash<vector<bool, A>>::operator()` `constexpr` since
C++20, which is a conforming extension, but it was unintended.

This patch removes the extension, with an escape hatch macro for it, and
the escape hatch will be removed in the future. Test cases for
`constexpr` along with the assumption of hash values are moved to the
`libcxx/test/libcxx/` subdirectory.

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-05-14 07:20:27 +08:00
Nikolas Klauser
df78e288c3
[libc++] Use __is_address_in_range in vector (#139032)
This avoids a branch in `vector`s code on whether we're constant
evaluating, which improves our coverage of constant-evaluated code.
2025-05-09 21:45:32 +02:00
Louis Dionne
45d493b680
[libc++] Add the __is_replaceable type trait (#132408)
That type trait represents whether move-assigning an object is
equivalent to destroying it and then move-constructing a new one from
the same argument. This will be useful in a few places where we may want
to destroy + construct instead of doing an assignment, in particular
when implementing some container operations in terms of relocation.

This is effectively adding a library emulation of P2786R12's
is_replaceable trait, similarly to what we do for trivial relocation.
Eventually, we can replace this library emulation by the real
compiler-backed trait.

This is building towards #129328.
2025-05-08 16:35:00 -04:00
Nikolas Klauser
f25f9e480b
[libc++][NFC] Remove a bunch of redundant ASan existence checks (#128504)
There are currently lots of `_LIBCPP_HAS_ASAN` and
`__libcpp_is_constant_evaluated()` checks which aren't needed, since it
is centrally checked inside `__debug_utils/sanitizers.h`.
2025-05-06 22:16:58 +02:00
Nikolas Klauser
8c3aa3e81c
[libc++][NFC] Replace typedefs with using declarations in <vector> (#134083)
This brings the code base a bit closer to using `using` declarations
everywhere.
2025-05-03 08:39:48 +02:00
Nikolas Klauser
af9c04fa68
[libc++] Remove _LIBCPP_TEMPLATE_VIS (#134885)
The need for `_LIBCPP_TEMPLATE_VIS` has been removed in #133233.
2025-04-09 23:47:57 +02:00
Peng Liu
e6c2fdc90f
[libc++] Fix ambiguous call to std::max in vector<bool> (#119801)
Closes #121713.
2025-04-02 11:14:14 -04:00
Louis Dionne
fc5b4d4a9d
[libc++] Rename __construct_one_at_end to __emplace_back_assume_capacity (#132276)
This makes it clear that the end of the vector is updated when calling
the function.
2025-03-25 14:27:54 -04:00
Nikolas Klauser
a8e168e0c1
[libc++][NFC] Replace structs with variable templates in <__memory/allocator_traits.h> (#129237)
Variable templates are a bit easier on the compiler and improve the
readability of the code.
2025-03-25 15:58:24 +01:00
Peng Liu
c5195ae2d0
[libc++] Fix {std, ranges}::equal for vector<bool> with small storage types (#130394)
The current implementation of `{std, ranges}::equal` fails to correctly
compare `vector<bool>`s when the underlying storage type is smaller than
`int` (e.g., `unsigned char`, `unsigned short`, `uint8_t` and
`uint16_t`). See [demo](https://godbolt.org/z/j4s87s6b3)). The problem
arises due to integral promotions on the intermediate bitwise
operations, leading to incorrect final equality comparison results. This
patch fixes the issue by ensuring that `{std, ranges}::equal` operate
properly for both aligned and unaligned bits.
 
Fixes #126369.
2025-03-19 11:51:21 -04:00
Louis Dionne
351bcd9fe2 [libc++][NFC] Add a comment that an include is a workaround 2025-03-18 11:03:42 -04:00