For certain time_points there are specializations of __convert_to_tm.
This means the non-specialized version is never called. This means some
of the `if constexpr` will never be true. These are removed.
Since there is a `static_assert` accidental removal of the
specialization will make the code ill-formed.
Drive-by changes:
- Consistently mark `std::__inplace_merge::__inplace_merge_impl`
`_LIBCPP_CONSTEXPR_SINCE_CXX26`.
- This function template is only called by other functions that becomes
constexpr since C++26, and it itself calls `std::__inplace_merge` that
is constexpr since C++26.
- Unblock related test coverage in constant evaluation for
`stable_partition`, `ranges::stable_sort`, `std::stable_sort`,
`std::stable_partition`, and `std::inplace_merge`.
When an allocator-aware container already defines a member type alias
`__alloc_traits` for `std::allocator_traits<allocator_type>`, we should
consistently use `__alloc_traits`. Mixing the usage of both
`__alloc_traits` and `std::allocator_traits` can lead to inconsistencies
and confusion.
This patch fixes an issue in libc++ where `std::copy_backward` and
`ranges::copy_backward` incorrectly copy `std::vector<bool>` with small
storage types (e.g., `uint8_t`, `uint16_t`). The problem arises from
flawed bit mask computations involving integral promotions and sign-bit
extension, leading to unintended zeroing of bits. This patch corrects
the bitwise operations to ensure correct bit-level copying.
Fixes#131718.
The current implementation of `{std, ranges}::copy` fails to copy
`vector<bool>` correctly when the underlying storage type
(`__storage_type`) is smaller than `int`, such as `unsigned char`,
`unsigned short`, `uint8_t` and `uint16_t`. The root cause is that the
unsigned small storage type undergoes integer promotion to (signed)
`int`, which is then left and right shifted, leading to UB (before
C++20) and sign-bit extension (since C++20) respectively. As a result,
the underlying bit mask evaluations become incorrect, causing erroneous
copying behavior.
This patch resolves the issue by correcting the internal bitwise
operations, ensuring that `{std, ranges}::copy` operates correctly for
`vector<bool>` with any custom (unsigned) storage types.
Fixes#131692.
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.
This PR fixes an ambiguous call encountered while using the
`std::ranges::count` and `std::count` algorithms with `vector<bool>`
with small `size_type`s.
The ambiguity arises from integral promotions during the internal
bitwise arithmetic of the `count` algorithms for small integral types.
This results in multiple viable candidates:
`__libcpp_popcount(unsigned)`,` __libcpp_popcount(unsigned long)`, and
`__libcpp_popcount(unsigned long long)`, leading to an ambiguous call
error. To resolve this ambiguity, we introduce a dispatcher function,
`__popcount`, which directs calls to the appropriate overloads of
`__libcpp_popcount`. This closes#122528.
Recent Clang-21 builds improved the deprecated diagnotics. This
uncovered missing guards in libc++ internally.
Note: This patch should be a separate commit and not merged.
For testing purposes they are combined.
Reviewed as part of #130497.
The following three string-like constructors for `std::bitset`
- `bitset(const CharT* str, std::size_t n, CharT zero, CharT one)`;
- `bitset(const std::basic_string<CharT, Traits, Alloc>& str, typename
std::basic_string<CharT, Traits, Alloc>::size_type pos, CharT zero,
CharT one)`;
- `bitset(std::basic_string_view<CharT, Traits> str, std::size_t pos,
std::size_t n, CharT zero, CharT one)`
already initialize the underlying storage array to all zeroes via
default-constructor of the base class `__bitset`. Therefore,
re-assigning the storage array to zeroes via `std::fill_n` in the
string-like constructors is truly redundant.
This PR refactors `basic_string` a bit to simplify its implementation in
the following ways:
- Instead of manually checking whether a string is short or long,
followed by calling the specific functions (e.g., `__get_short_size()`,
`__get_long_size()`), we call the general functions (`size()`) to hide
the conditional checks and make the code more concise.
- Once a string is determined to be short or long, we directly call the
specific functions instead of the general versions to get rid of
unnecessary internal conditional checks. For example, for a long string,
we would directly call `{__set, __get}_long_pointer` instead of `{__set,
__get}_pointer()`.
- Variables that are defined in both the `if` and `else` branches are
now declared in a common scope to reduce redundancy.
- When the string size is calculated multiple times using
`traits_type::length(__s)`, a variable is introduced to store its
length. While modern compilers can optimize this with constant folding,
explicitly storing the length improves code readability and makes the
logic clearer.
- Fixed synopsis with missing default arguments.
This PR fixes an ambiguous call encountered when using the `std::ranges::find` or `std::find`
algorithms with `vector<bool>` with small `allocator_traits::size_type`s, an issue reported
in #122528. The ambiguity arises from integral promotions during the internal bitwise
arithmetic of the `find` algorithms when applied to `vector<bool>` with small integral
`size_type`s. This leads to multiple viable candidates for small integral types:
__libcpp_ctz(unsigned), __libcpp_ctz(unsigned long), and __libcpp_ctz(unsigned long long),
none of which represent a single best viable match, resulting in an ambiguous call error.
To resolve this, we propose invoking an internal function __countr_zero as a dispatcher
that directs the call to the appropriate overload of __libcpp_ctz. Necessary amendments
have also been made to __countr_zero.
This PR optimizes the performance of `std::ranges::rotate` for
`vector<bool>::iterator`. The optimization yields a performance
improvement of up to 2096x.
Closes#64038.
`\_ `is a valid identity escape in regular expressions, but previously
libc++ incorrectly treated it as invalid. So I deleted this judgment
fixes#129062
- Aligns all version comments to line 65.
- Consistently uses `// since C++` instead of `// C++`, in lowercase as
used in most version comments.
- Consistently uses `class` to introduce type template parameters.
- Consistently uses `inline constexpr` for variable templates.
- Corrects the comment for `bool_constant` to `// since C++17` as it's a
C++17 feature.
- Changes the class-key of `result_of` to `struct`, which follows N4659
[depr.meta.types] and the actual usage in libc++.
- Adds missed `// since C++17` for `is_(nothrow_)invocable(_r)`.
- Moves the comments for `is_nothrow_convertible_v` to the part for
variable templates.
- Removes duplicated comments for `true_type` and `false_type`.
Previously, commit 042f07eed8c1acba19ea04310137bee12b18045a claimed that
P0767R1 was implemented in LLVM 7.0, but no deprecation warning was
implemented. This patch adds the missing warnings.
Drive-by: Enables test coverage for `ranges::stable_sort` with proxy
iterators, and changes "constexpr in" to "constexpr since" in comments
in `<algorithm>`.
`std::erase(_if)` for `basic_string` were made `constexpr` in C++20 by
cplusplus/draft@2c1ab9775c as follow-up
changes of P0980R1.
This patch implements the missed changes that were not tracked in a
specific paper.
This PR optimizes the performance of `std::ranges::swap_ranges` for
`vector<bool>::iterator`, addressing a subtask outlined in issue #64038.
The optimizations yield performance improvements of up to **611x** for
aligned range swap and **78x** for unaligned range swap comparison.
Additionally, comprehensive tests covering up to 4 storage words (256
bytes) with odd and even bit sizes are provided, which validate the
proposed optimizations in this patch.
Drive-by changes:
- Enables no-memory case for Clang.
- Enables `robust_re_difference_type.compile.pass.cpp` and
`robust_against_proxy_iterators_lifetime_bugs.pass.cpp` test coverage
for `std::stable_sort` in constant evaluation since C++26. The changes
were missing in the PR making `std::stable_sort` `constexpr`.
`money_get::do_get` needs to be fixed to handle extremely huge input
(e.g. more than 100 digits).
1. `__double_or_nothing` needs to copy the contents of the stack buffer
on the initial allocation.
2. The `sscanf` call in `do_get` needs to scan the dynamic buffer if
dynamic allocation happens.
This relies on Clang's no_specializations attribute which is not
supported by GCC.
Implements:
- LWG2129: User specializations of std::initializer_list
Fixes: #126270
The codecvt class is defined in <locale> and the contents of the
<codecvt> header don't work when localization is disabled. Without this
guard, builds with localization disabled that happen to include
<codecvt> could be broken because they would try to include <__locale>,
which ends up trying to include the locale base API and eventually
platform headers like <xlocale.h> that may not exist.
Previously the wrong detection macro has been used to check whether arm
NEON is available. This fixes it, and removes a few unnecessary includes
from `__algorithm/simd_utils.h` as a drive-by.
Since `363bfd6090b0 ([libc++] Use the new locale base API on Linux
(#128007), 2025-02-24)`, musl targets will fail to build with errors
due to missing strtoll_l functions.
Co-authored-by: Pirama Arumuga Nainar <pirama@google.com>
This set usage of operator& instead of std::addressof seems not be easy
to "abuse". Some seem easy to misuse, like basic_ostream::operator<<,
trying to do that results in compilation errors since the `widen`
function is not specialized for the hijacking character type. Hence
there are no tests.