This patch optimizes `bitset::to_string` by replacing the existing bit-by-bit processing with a more efficient
bit traversal strategy. Instead of checking each bit sequentially, we leverage `std::__countr_zero` to efficiently
locate the next set bit, skipping over consecutive zero bits. This greatly accelerates the conversion process,
especially for sparse `bitset`s where zero bits dominate. To ensure similar improvements for dense `bitset`s, we
exploit symmetry by inverting the bit pattern, allowing us to apply the same optimized traversal technique. Even
for uniformly distributed `bitset`s, the proposed approach offers measurable performance gains over the existing
implementation.
Benchmarks demonstrate substantial improvements, achieving up to 13.5x speedup for sparse `bitset`s with
`Pr(true bit) = 0.1`, 16.1x for dense `bitset`s with `Pr(true bit) = 0.9`, and 8.3x for uniformly distributed
`bitset`s with `Pr(true bit) = 0.5)`.
This patch enhances the performance of `std::for_each_n` when used with
segmented iterators, leading to significant performance improvements,
summarized in the tables below. This addresses a subtask of
https://github.com/llvm/llvm-project/issues/102817.
This doesn't show up in the CI, since we don't have abilists for
windows. I'm also not sure whether we want them, so I don't think we can
easily test this change.
This patch introduces `_LIBCPP_{BEGIN,END}_EXPLICIT_ABI_ANNOTATIONS`,
which allow us to have implicit annotations for most functions, and just
where it's not "hide_from_abi everything" we add explicit annotations.
This allows us to drop the `_LIBCPP_HIDE_FROM_ABI` macro from most
functions in libc++.
This has been introduced by #134819, most likely due to a merge conflict
I didn't resolve properly (I thought I did in that patch what I'm now
doing here).
This causes a mismatch between `value_type` and
`allocator_type::value_type` in `__tree`, but I think that's acceptable.
`__tree` primarily gets a `__value_type` wrapper due to potential ABI
breaks and unwraps it to the same as `allocator_type::value_type` in the
end. A cleanup patch will also change `__tree::value_type` to be the
same as `allocator_type::value_type`, making the type mismatch only
visible where `__tree` is instantiated in `map`.
charN_t represent code units of different UTF encodings. Therefore the
values of 2 different charN_t objects do not represent the same
characters.
In order to avoid comparing apples and oranges, we add new warnings to
warn on:
- Implicit conversions
- Comparisons
- Other cases involving arithmetic conversions
We only produce the warning if we cannot establish the comparison would
be safe through constant evaluation.
The new `-Wimplicit-unicode-conversion` warning is enabled by default.
Note that this PR intentionally doesn;t touches char/wchar_t, but it
would be worth considering also warning on extending the new warnings to
these types (in a follow up)
Additionally most arithmetic operations on charN_t don't really make
sense (ie what does it mean to addition code units), so we could add
warnings for that.
Fixes#138526
Before this patch, we were dereferencing pointers to objects which were
never constructed. Now we always assume that nodes store `pair<const
KeyT, ValueT>` for maps instead, as they actually do. This patch also
allows for significant follow-up simplifications, since
`__node_value_type` and `__container_value_type` are the same type now.
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>
GCC 15 has added builtins for various C++ type traits that Clang
already had. Since `__has_builtin(...)` now finds these, the #if
branches previously only used for Clang are now used for GCC 15.
However, GCC 15 requires that these builtins only be used in type
aliases, not in template aliases.
For now, just don't use the `__has_builtin(...)` branches under newer
GCC versions, so both 14 and 15 work during the transition. This
can be cleaned up later to use all the GCC 15 builtins available.
Fixed: #137704Fixed: #117319
Currently, built-in `char`/`wchar_t` arrays are assumed to be
null-terminated sequence with the terminator being the last element in
formatting. This doesn't conform to [format.arg]/6.9.
> otherwise, if `decay_t<TD>` is `char_type*` or `const char_type*`,
> initializes value with `static_cast<const char_type*>(v)`;
The standard wording specifies that character arrays are decayed to
pointers. When the null terminator is not the last element or there's no
null terminator (the latter case is UB), libc++ currently produces
different results.
Also fixes and hardens `formatter<CharT[N], CharT>::format` in
`<__format/formatter_string.h>`. These specializations are rarely used.
Fixes#115935. Also checks the preconditions in this case, which fixes
#116570.
This makes it clearer what the functions actually do. As a nice
side-effect it also avoids a function call. If the C++03 header split is
successful we could drop `__get_pair` entirely.
After 8fc2538f338088bd084d217a7569d72c3b630e8c "Reapply '[libc++]
Optimize num_put integral functions' (#131613) (#133572)", including
<locale> in C++03 mode with Debug hardening enabled fails.
This patch fixes that by applying a workaround used elsewhere to
construct errc in C++03 mode.
`__has_feature(modules)` is always true in C++20 and later. Instead of
using that, just disable extension warnings if they're not ignored
through the system header machinery anyways.
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.
I've recently looked at the assembly for `basic_string::find()` and
realized that there were a few branches I didn't expect. It turns out
that we check for null before calling `__constexpr_memchr` in some
cases, which the compiler doesn't optimize away. This is a really
uncommon case though, so I'm not convinced it makes a ton of sense to
optimize for that.
The second case is where `__pos >= __sz`. There, we can instead check
`__pos > __sz`, which the optimizer is able to remove if `__pos == 0`,
which is also a quite common case (basic_string::find(CharT), without an
explicit size parameter).
This breaks the ABI of `flat_{,multi}map::value_compare`, but this type
has only been introduced in LLVM 20, so it should be very unlikely that
we break anybody if we back-port this now.
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`.
The std::advance function has a clear precondition that it can only be
called with a negative distance when a bidirectional iterator is used.
However, prev() and next() don't have such preconditions explicitly,
they inherit it from calling advance().
This patch removes assertions in prev() and next() that were duplicates
of similar ones in advance(), and removes a copy-pasted comment that was
trying to justify the use of _LIBCPP_ASSERT_PEDANTIC but IMO is creating
confusion with little benefit.
The `_LIBCPP_DISABLE_AVAILABILITY` macro was removed in afae1a5f32bb as an
intended no-op. It turns out that some projects are making use of that
macro to work around a Clang bug with availability annotations that
still exists: https://github.com/llvm/llvm-project/issues/134151.
Since that Clang bug still hasn't been fixed, I feel that we must sill
honor that unfortunate macro until we've figured out how to get rid of
it without breaking code.
We can use the `__is_nothrow_convertible` builtin unconditionally now,
which makes the implementation very simple, so there isn't much of a
need to keep a separate header around.
We're currently adding `bad_function_call::what()` behind an ABI flag,
even though adding it is not an ABI break and can be handled through
availability.
This patch moves the functions common between our two extern template
lists into a common list and avoids some unnecessary _Uglification. This
makes the code a lot nicer to read and makes the differences between the
two lists obvious.
There was a bug in the implementation of `__array_rank` until LLVM 20
which prevented us from using the builtin. Since the bug has been fixed
now we can enable the use and remove the generic implementation in a few
releases.
This improves performance for the copy-assignment operators of associative containers such as `std::map`.
This optimization already exists in other places in the codebase, and seems to have been missed here.
This patch adds `static_assert` using `is_class_v` and `is_union_v` to
reject no-class type template parameters.
Fixes#132133
---------
Co-authored-by: A. Jiang <de34@live.cn>
Previously, the segmented iterator optimization for `std::for_each` was restricted to C++23 and later due to its dependency on `__movable_box`, which is not available in earlier standards. This patch eliminates that restriction, enabling consistent optimizations starting from C++11.
By backporting this enhancement, we improve performance across older standards and create opportunities to extend similar optimizations to other algorithms by forwarding their calls to `std::for_each`.
This patch makes instantiation of `pair` in CTAD a bit lazier to avoid
instantiating invalid `pair` specialization before the decaying explicit
deduction guide works.
`__libcpp_{ctz, clz}` were previously used as fallbacks for `__builtin_{ctzg, clzg}` to ensure compatibility with older compilers (Clang 18 and earlier), as `__builtin_{ctzg, clzg}` became available in Clang 19. Now that support for Clang 18 has been officially dropped in #130142, we can now safely replace all instances of `__libcpp_{ctz, clz}` with `__count{l,r}_zero` (which internally call `__builtin_{ctzg, clzg}` and eliminate the fallback logic.
Closes#131179.
This patch makes the __config_site header modular, which solves various
problems with non-modular headers. This requires going back to
generating the modulemap file, since we only know how to make
__config_site modular when we're not using the per-target runtime dir.
The patch also adds a test that we support
-Wnon-modular-include-in-module, which warns about non-modular includes
from modules.
---------
Co-authored-by: Konstantin Varlamov <varconst@apple.com>