aboutsummaryrefslogtreecommitdiff
path: root/libcxx/test/std
AgeCommit message (Collapse)AuthorFilesLines
2 days[libc++][ranges] Fix `ranges::join_view` segmented iterator trait (#158347)lbonn1-39/+82
The outer iterator needs to move to the next segment when calling __compose. Without this change, `find_segment_if` would never reach the end of the join_view which caused erroneous result when calling `ranges::find` on a join_view of bidirectional ranges. Other specializations using the segmented iterator trait were likely to be affected as well. Fixes #158279 Fixes #93180
4 days[libc++][test] Guard non-guaranteed implicit-lifetime-ness cases with ↵A. Jiang1-0/+11
`_LIBCPP_VERSION` (#160627) And add some guaranteed cases (namely, for `expected`, `optional`, and `variant`) to `is_implicit_lifetime.pass.cpp`. It's somehow unfortunate that `pair` and `tuple` are not guaranteed to propagate triviality of copy/move constructors, and MSVC STL fails to do so due to ABI compatibility. This affects the implicit-lifetime property.
5 days[libc++][C++03] cherry-pick #104773 (#158244)Nikolas Klauser1-2/+0
5 days[libc++] Fold __search_substring into _Traits::find in case the second ↵Nikolas Klauser1-0/+17
string has length 1 (#160076) Apple M4: ``` Benchmark Baseline Candidate Difference % Difference ----------------------------------------------------------- ---------- ----------- ------------ -------------- BM_string_literal/1024 16.99 16.79 -0.21 -1.21 BM_string_literal/128 3.44 3.34 -0.10 -2.88 BM_string_literal/16 1.80 1.69 -0.11 -5.93 BM_string_literal/2048 38.44 38.38 -0.07 -0.17 BM_string_literal/256 5.77 5.65 -0.12 -2.02 BM_string_literal/32 2.03 1.92 -0.11 -5.44 BM_string_literal/4096 73.92 73.74 -0.18 -0.25 BM_string_literal/512 9.49 9.41 -0.08 -0.84 BM_string_literal/64 2.59 2.45 -0.14 -5.38 BM_string_literal/8 1.79 1.69 -0.11 -5.90 BM_string_literal/8192 132.09 131.81 -0.28 -0.21 ```
5 days[libc++][C++03] cherry-pick #106566 (#158250)Nikolas Klauser1-2/+0
5 days[libc++] Refactor some .fail.cpp tests and fix time_point_cast not SFINAEing ↵Nikolas Klauser10-138/+47
away (#159288) All of the `.fail.cpp` tests are actually testing constraints, so we should just test that the overloads SFINAE away correctly.
5 days[libc++][string] P3044R2: sub-`string_view` from `string` (#147095)Hristo Hristov5-0/+324
Implements [P3044R2](https://wg21.link/P3044R2) Note: `substr.pass.cpp` is refactored to accommodate the test of `basic_string_view`'s `subview` which is an alias of `substr` without changing the test cases. Closes #148140 # References - https://github.com/cplusplus/draft/pull/7975 - https://wg21.link/string.substr - https://wg21.link/string.view.ops --------- Co-authored-by: Hristo Hristov <zingam@outlook.com> Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
6 days[libc++][C++03] cherry-pick #119801 (#158247)Nikolas Klauser1-2/+0
6 days[libc++] Implement Resolution of LWG 3886 (#155356)William Tran-Viet5-1/+92
Resolves #118336 - Implement the resolution of [LWG3886](https://cplusplus.github.io/LWG/issue3886) for `optional` and `expected`
6 days[libc++][atomic_ref] Use __atomic_fetch_{add,sub} builtins on ↵Damien L-G2-0/+2
floating-points whenever possible (#135685) Fix #135109 Clang is able to emit an `atomicrmw` instruction from the `__atomic_fetch_add` and `__atomic_fetch_sub` builtins on floating-point types.
10 days[libc++] Remove obsolete locale-specific regex tests (#159590)Louis Dionne17-1023/+360
After a recent macOS update, several of the locale-specific regex tests started failing. These tests were mainly testing two locale specific features of regular expressions: - A character class like `[=x=]` matches any character that is considered equivalent to `x` according to the collation rules of the current locale. - A character class like `[[.ch.]]` matches anything that is equivalent to `ch` (whether as two letters or as a single collation element) in the current locale. However, these tests were relying on platform-specific localization data, specifically they were only working with older macOS localization data. As can be seen from the numerous XFAILs, most mainstream platforms didn't actually pass this test. After the macOS update, macOS itself also doesn't pass these tests anymore. I looked at whether there are locales where these tests would still make sense, and I couldn't find any. I am not a localization expert, but it appears that only legacy locales like the traditional Spanish locale (which isn't commonly shipped on systems anymore) considers `[.ch.]` to be a single collation element. Therefore, it seems that the locale specific part of these tests is not relevant anymore, and this patch removes them. The patch also moves some tests for equivalence classes inside character classes to their non locale-specific tests, since that feature was not covered there. Finally, the lookup_collatename.pass.cpp test was fixed by removing an assertion that `ch` is a collation element in the CZ locale, which seems to not be the case in recent localization data (and appears to be the root cause for about half the failures in these tests).
12 days[libc++] XFAIL regex tests that are currently failing on macOS (#159260)Nikolas Klauser9-0/+9
It seems that an OS update changed the localization on macOS. This XFAILs the tests to make sure the CI is green again until the tests can be updated.
12 daysRevert "[libc++] Optimize __hash_table::erase(iterator, iterator) (#1… ↵Aiden Grossman1-14/+0
(#158769) …52471)" This reverts commit e4eccd6a3c2415c10bb8217c247d7aca76cc9ad5. This was causing ASan failures in some situations involving unordered multimap containers. Details and a reproducer were posted on the original PR (#152471).
2025-09-15[libc++] Specialize __lazy_synth_three_way_comparator for std::greater and ↵Nikolas Klauser4-0/+59
friends (#157624) This specializes `__lazy_synth_three_way_comparator` to forward to `__default_three_way_comparator` if the comparator desugars to `__greater_tag`. This is the same as the desugaring to `__less_tag` except that the sign has to be inverted.
2025-09-12[libc++][C++03] cherry-pick #101889 (#157881)Nikolas Klauser22-44/+0
2025-09-11[libc++] Fix ranges_rotate.pass.cpp complexity checks (#158144)Jonathan Wakely1-0/+2
The complexity is "at most N swaps" _for each invocation of `rotate`_, but the tests currently assert that the total number of swaps for N calls is at most N. The standard allows that to be N squared, so the test is either requiring more than the standard (and the comment in the test) promises, or somebody just forgot to reset the counter on each iteration.
2025-09-11[libc++][C++03] partially cherry-pick #122641 (#157596)Nikolas Klauser1-1/+0
This patch only cherry-picks the parts that actually fix the issue, but not the numerous NFC refactorings around it.
2025-09-09[libc++][NFC] Inline function in string.cons/copy_alloc.pass.cpp that is ↵Nikolas Klauser1-11/+5
used only once (#157429) This makes the test a bit easier to understand.
2025-09-08[libc++][C++03] cherry-pick #126273 (#157095)Nikolas Klauser1-2/+0
2025-09-08[libc++] Optimize most of the __tree search algorithms (#155245)Nikolas Klauser5-0/+5
This patch introduces a new comparator, namely `__lazy_synth_three_way`, which tries to provide an efficient three way comparator for known types and falls back to using the provided comparator if it doesn't know how to do that. Currently, an efficient three way comparison is only provided when using one of the `less` comparions object from the standard library and `std::string`. This will be extended in future patches. ``` ------------------------------------------------------------------------------------------------------------------------------ Benchmark old new ------------------------------------------------------------------------------------------------------------------------------ std::map<std::string, int>::ctor(const&)/0 12.6 ns 12.6 ns std::map<std::string, int>::ctor(const&)/32 858 ns 837 ns std::map<std::string, int>::ctor(const&)/1024 46700 ns 46739 ns std::map<std::string, int>::ctor(const&)/8192 458100 ns 449806 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/0 12.8 ns 12.7 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/32 1286 ns 1266 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/1024 93812 ns 84686 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/8192 1480346 ns 1385924 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/0 12.9 ns 12.8 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/32 1044 ns 1055 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/1024 63071 ns 62861 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/8192 595046 ns 590223 ns std::map<std::string, int>::operator=(const&) (into cleared Container)/0 13.6 ns 13.6 ns std::map<std::string, int>::operator=(const&) (into cleared Container)/32 880 ns 911 ns std::map<std::string, int>::operator=(const&) (into cleared Container)/1024 48627 ns 47808 ns std::map<std::string, int>::operator=(const&) (into cleared Container)/8192 458552 ns 454497 ns std::map<std::string, int>::operator=(const&) (into partially populated Container)/0 13.8 ns 13.6 ns std::map<std::string, int>::operator=(const&) (into partially populated Container)/32 864 ns 851 ns std::map<std::string, int>::operator=(const&) (into partially populated Container)/1024 49483 ns 49555 ns std::map<std::string, int>::operator=(const&) (into partially populated Container)/8192 456977 ns 457894 ns std::map<std::string, int>::operator=(const&) (into populated Container)/0 1.31 ns 1.31 ns std::map<std::string, int>::operator=(const&) (into populated Container)/32 425 ns 415 ns std::map<std::string, int>::operator=(const&) (into populated Container)/1024 14248 ns 14225 ns std::map<std::string, int>::operator=(const&) (into populated Container)/8192 136684 ns 133696 ns std::map<std::string, int>::insert(value) (already present)/0 21.5 ns 16.2 ns std::map<std::string, int>::insert(value) (already present)/32 22.7 ns 25.1 ns std::map<std::string, int>::insert(value) (already present)/1024 54.5 ns 29.1 ns std::map<std::string, int>::insert(value) (already present)/8192 78.4 ns 30.4 ns std::map<std::string, int>::insert(value) (new value)/0 40.9 ns 39.0 ns std::map<std::string, int>::insert(value) (new value)/32 58.3 ns 47.2 ns std::map<std::string, int>::insert(value) (new value)/1024 120 ns 71.3 ns std::map<std::string, int>::insert(value) (new value)/8192 157 ns 129 ns std::map<std::string, int>::insert(hint, value) (good hint)/0 40.3 ns 40.7 ns std::map<std::string, int>::insert(hint, value) (good hint)/32 48.0 ns 30.0 ns std::map<std::string, int>::insert(hint, value) (good hint)/1024 107 ns 63.2 ns std::map<std::string, int>::insert(hint, value) (good hint)/8192 132 ns 107 ns std::map<std::string, int>::insert(hint, value) (bad hint)/0 27.0 ns 40.9 ns std::map<std::string, int>::insert(hint, value) (bad hint)/32 68.3 ns 58.4 ns std::map<std::string, int>::insert(hint, value) (bad hint)/1024 125 ns 82.0 ns std::map<std::string, int>::insert(hint, value) (bad hint)/8192 155 ns 150 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/0 404 ns 405 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/32 2004 ns 1805 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/1024 102820 ns 76102 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/8192 1144590 ns 949266 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/0 408 ns 404 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/32 1592 ns 1377 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/1024 74847 ns 53921 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/8192 828505 ns 698716 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/0 407 ns 407 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/32 1584 ns 1557 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/1024 47157 ns 47443 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/8192 623887 ns 628385 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/0 405 ns 403 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/32 1478 ns 1510 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/1024 47852 ns 47835 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/8192 605311 ns 606951 ns std::map<std::string, int>::erase(key) (existent)/0 129 ns 94.0 ns std::map<std::string, int>::erase(key) (existent)/32 110 ns 106 ns std::map<std::string, int>::erase(key) (existent)/1024 121 ns 128 ns std::map<std::string, int>::erase(key) (existent)/8192 165 ns 66.9 ns std::map<std::string, int>::erase(key) (non-existent)/0 0.269 ns 0.257 ns std::map<std::string, int>::erase(key) (non-existent)/32 21.9 ns 11.3 ns std::map<std::string, int>::erase(key) (non-existent)/1024 53.5 ns 25.4 ns std::map<std::string, int>::erase(key) (non-existent)/8192 67.3 ns 31.9 ns std::map<std::string, int>::erase(iterator)/0 46.3 ns 46.7 ns std::map<std::string, int>::erase(iterator)/32 44.4 ns 41.8 ns std::map<std::string, int>::erase(iterator)/1024 43.7 ns 46.4 ns std::map<std::string, int>::erase(iterator)/8192 45.2 ns 44.1 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/0 407 ns 407 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/32 876 ns 906 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/1024 20880 ns 20444 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/8192 252881 ns 241583 ns std::map<std::string, int>::clear()/0 407 ns 408 ns std::map<std::string, int>::clear()/32 1252 ns 1323 ns std::map<std::string, int>::clear()/1024 38488 ns 38017 ns std::map<std::string, int>::clear()/8192 416492 ns 428534 ns std::map<std::string, int>::find(key) (existent)/0 0.008 ns 0.008 ns std::map<std::string, int>::find(key) (existent)/32 33.9 ns 15.3 ns std::map<std::string, int>::find(key) (existent)/1024 43.0 ns 25.5 ns std::map<std::string, int>::find(key) (existent)/8192 44.6 ns 29.3 ns std::map<std::string, int>::find(key) (non-existent)/0 0.259 ns 0.257 ns std::map<std::string, int>::find(key) (non-existent)/32 22.6 ns 11.4 ns std::map<std::string, int>::find(key) (non-existent)/1024 48.6 ns 25.1 ns std::map<std::string, int>::find(key) (non-existent)/8192 64.1 ns 31.1 ns std::map<std::string, int>::count(key) (existent)/0 0.008 ns 0.008 ns std::map<std::string, int>::count(key) (existent)/32 32.2 ns 17.3 ns std::map<std::string, int>::count(key) (existent)/1024 42.4 ns 25.3 ns std::map<std::string, int>::count(key) (existent)/8192 44.4 ns 31.6 ns std::map<std::string, int>::count(key) (non-existent)/0 0.260 ns 0.259 ns std::map<std::string, int>::count(key) (non-existent)/32 22.9 ns 11.3 ns std::map<std::string, int>::count(key) (non-existent)/1024 49.8 ns 25.5 ns std::map<std::string, int>::count(key) (non-existent)/8192 66.3 ns 31.9 ns std::map<std::string, int>::contains(key) (existent)/0 0.008 ns 0.008 ns std::map<std::string, int>::contains(key) (existent)/32 31.4 ns 18.0 ns std::map<std::string, int>::contains(key) (existent)/1024 44.3 ns 26.5 ns std::map<std::string, int>::contains(key) (existent)/8192 47.4 ns 30.2 ns std::map<std::string, int>::contains(key) (non-existent)/0 0.452 ns 0.441 ns std::map<std::string, int>::contains(key) (non-existent)/32 23.1 ns 11.5 ns std::map<std::string, int>::contains(key) (non-existent)/1024 46.2 ns 26.3 ns std::map<std::string, int>::contains(key) (non-existent)/8192 63.4 ns 31.4 ns std::map<std::string, int>::lower_bound(key) (existent)/0 0.008 ns 0.008 ns std::map<std::string, int>::lower_bound(key) (existent)/32 17.2 ns 19.0 ns std::map<std::string, int>::lower_bound(key) (existent)/1024 27.1 ns 26.2 ns std::map<std::string, int>::lower_bound(key) (existent)/8192 34.0 ns 36.0 ns std::map<std::string, int>::lower_bound(key) (non-existent)/0 0.259 ns 0.257 ns std::map<std::string, int>::lower_bound(key) (non-existent)/32 11.6 ns 11.5 ns std::map<std::string, int>::lower_bound(key) (non-existent)/1024 24.8 ns 25.6 ns std::map<std::string, int>::lower_bound(key) (non-existent)/8192 31.7 ns 31.6 ns std::map<std::string, int>::upper_bound(key) (existent)/0 0.008 ns 0.008 ns std::map<std::string, int>::upper_bound(key) (existent)/32 18.8 ns 19.7 ns std::map<std::string, int>::upper_bound(key) (existent)/1024 25.3 ns 27.7 ns std::map<std::string, int>::upper_bound(key) (existent)/8192 30.2 ns 29.9 ns std::map<std::string, int>::upper_bound(key) (non-existent)/0 0.260 ns 0.259 ns std::map<std::string, int>::upper_bound(key) (non-existent)/32 11.3 ns 12.0 ns std::map<std::string, int>::upper_bound(key) (non-existent)/1024 25.6 ns 25.9 ns std::map<std::string, int>::upper_bound(key) (non-existent)/8192 33.1 ns 34.2 ns std::map<std::string, int>::equal_range(key) (existent)/0 0.008 ns 0.008 ns std::map<std::string, int>::equal_range(key) (existent)/32 33.5 ns 15.8 ns std::map<std::string, int>::equal_range(key) (existent)/1024 43.0 ns 25.1 ns std::map<std::string, int>::equal_range(key) (existent)/8192 54.1 ns 30.7 ns std::map<std::string, int>::equal_range(key) (non-existent)/0 0.265 ns 0.259 ns std::map<std::string, int>::equal_range(key) (non-existent)/32 22.1 ns 12.1 ns std::map<std::string, int>::equal_range(key) (non-existent)/1024 44.8 ns 24.4 ns std::map<std::string, int>::equal_range(key) (non-existent)/8192 62.2 ns 40.1 ns ``` Fixes #66577
2025-09-05[libc++][C++03] cherry-pick #125423 (#156824)Nikolas Klauser2-4/+0
2025-09-05[libc++][C++03] cherry-pick #128054 (#156672)Nikolas Klauser1-2/+0
2025-09-04[libc++] Make it possible to mark a gen-test as UNSUPPORTED (#156737)Louis Dionne3-11/+10
Previously, only the tests that are generated by the gen-test could be marked as UNSUPPORTED. After this patch, the gen-test itself can be marked as UNSUPPORTED, which makes it possible to add RUN lines that would be an error when unsupported to the gen-test itself.
2025-09-04[libc++][NFC] Use llvm.org/PR to link to bug reports (#156288)Nikolas Klauser157-169/+166
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-03[libc++][ranges] LWG4083: `views::as_rvalue` should reject non-input ranges ↵Hristo Hristov1-0/+12
(#155156) Fixes #105351 # References: - https://wg21.link/LWG4083 - https://wg21.link/range.as.rvalue.overview
2025-09-03[libc++][C++03] Backport #111127, #112843 and #121620 (#155571)Nikolas Klauser4-8/+0
2025-09-03[libc++] Optimize {map,set}::insert(InputIterator, InputIterator) (#154703)Nikolas Klauser2-77/+341
``` ---------------------------------------------------------------------------------------------------------------------------- Benchmark old new ---------------------------------------------------------------------------------------------------------------------------- std::map<int, int>::ctor(iterator, iterator) (unsorted sequence)/0 14.2 ns 14.8 ns std::map<int, int>::ctor(iterator, iterator) (unsorted sequence)/32 519 ns 404 ns std::map<int, int>::ctor(iterator, iterator) (unsorted sequence)/1024 52460 ns 36242 ns std::map<int, int>::ctor(iterator, iterator) (unsorted sequence)/8192 724222 ns 706496 ns std::map<int, int>::ctor(iterator, iterator) (sorted sequence)/0 14.2 ns 14.7 ns std::map<int, int>::ctor(iterator, iterator) (sorted sequence)/32 429 ns 349 ns std::map<int, int>::ctor(iterator, iterator) (sorted sequence)/1024 23601 ns 14734 ns std::map<int, int>::ctor(iterator, iterator) (sorted sequence)/8192 267753 ns 112155 ns std::map<int, int>::insert(iterator, iterator) (all new keys)/0 434 ns 448 ns std::map<int, int>::insert(iterator, iterator) (all new keys)/32 950 ns 963 ns std::map<int, int>::insert(iterator, iterator) (all new keys)/1024 27205 ns 25344 ns std::map<int, int>::insert(iterator, iterator) (all new keys)/8192 294248 ns 280713 ns std::map<int, int>::insert(iterator, iterator) (half new keys)/0 435 ns 449 ns std::map<int, int>::insert(iterator, iterator) (half new keys)/32 771 ns 706 ns std::map<int, int>::insert(iterator, iterator) (half new keys)/1024 30841 ns 17495 ns std::map<int, int>::insert(iterator, iterator) (half new keys)/8192 468807 ns 285847 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from same type)/0 449 ns 453 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from same type)/32 1021 ns 932 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from same type)/1024 29796 ns 19518 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from same type)/8192 345688 ns 153966 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from zip_view)/0 449 ns 450 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from zip_view)/32 1026 ns 807 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from zip_view)/1024 31632 ns 15573 ns std::map<int, int>::insert(iterator, iterator) (product_iterator from zip_view)/8192 303024 ns 128946 ns std::map<int, int>::erase(iterator, iterator) (erase half the container)/0 447 ns 452 ns std::map<int, int>::erase(iterator, iterator) (erase half the container)/32 687 ns 710 ns std::map<int, int>::erase(iterator, iterator) (erase half the container)/1024 8604 ns 8581 ns std::map<int, int>::erase(iterator, iterator) (erase half the container)/8192 65693 ns 67406 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/0 15.0 ns 15.0 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/32 2781 ns 1845 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/1024 187999 ns 182103 ns std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/8192 2937242 ns 2934912 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/0 15.0 ns 15.2 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/32 1326 ns 2462 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/1024 81778 ns 72193 ns std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/8192 1177292 ns 669152 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/0 439 ns 454 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/32 2483 ns 2465 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/1024 187614 ns 188072 ns std::map<std::string, int>::insert(iterator, iterator) (all new keys)/8192 1654675 ns 1706603 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/0 437 ns 452 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/32 1836 ns 1820 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/1024 114885 ns 121865 ns std::map<std::string, int>::insert(iterator, iterator) (half new keys)/8192 1151960 ns 1197318 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/0 438 ns 455 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/32 1599 ns 1614 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/1024 95935 ns 82159 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/8192 776480 ns 941043 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/0 435 ns 462 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/32 1723 ns 1550 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/1024 107096 ns 92850 ns std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/8192 893976 ns 775046 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/0 436 ns 453 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/32 775 ns 824 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/1024 20241 ns 20454 ns std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/8192 139038 ns 138032 ns std::set<int>::ctor(iterator, iterator) (unsorted sequence)/0 14.8 ns 14.7 ns std::set<int>::ctor(iterator, iterator) (unsorted sequence)/32 468 ns 426 ns std::set<int>::ctor(iterator, iterator) (unsorted sequence)/1024 54289 ns 39028 ns std::set<int>::ctor(iterator, iterator) (unsorted sequence)/8192 738438 ns 695720 ns std::set<int>::ctor(iterator, iterator) (sorted sequence)/0 14.7 ns 14.6 ns std::set<int>::ctor(iterator, iterator) (sorted sequence)/32 478 ns 391 ns std::set<int>::ctor(iterator, iterator) (sorted sequence)/1024 24017 ns 13905 ns std::set<int>::ctor(iterator, iterator) (sorted sequence)/8192 267862 ns 111378 ns std::set<int>::insert(iterator, iterator) (all new keys)/0 458 ns 450 ns std::set<int>::insert(iterator, iterator) (all new keys)/32 1066 ns 956 ns std::set<int>::insert(iterator, iterator) (all new keys)/1024 29190 ns 25212 ns std::set<int>::insert(iterator, iterator) (all new keys)/8192 320441 ns 279602 ns std::set<int>::insert(iterator, iterator) (half new keys)/0 454 ns 453 ns std::set<int>::insert(iterator, iterator) (half new keys)/32 816 ns 709 ns std::set<int>::insert(iterator, iterator) (half new keys)/1024 32072 ns 17074 ns std::set<int>::insert(iterator, iterator) (half new keys)/8192 403386 ns 286202 ns std::set<int>::erase(iterator, iterator) (erase half the container)/0 451 ns 452 ns std::set<int>::erase(iterator, iterator) (erase half the container)/32 710 ns 703 ns std::set<int>::erase(iterator, iterator) (erase half the container)/1024 8261 ns 8499 ns std::set<int>::erase(iterator, iterator) (erase half the container)/8192 64466 ns 67343 ns std::set<std::string>::ctor(iterator, iterator) (unsorted sequence)/0 15.2 ns 15.0 ns std::set<std::string>::ctor(iterator, iterator) (unsorted sequence)/32 3069 ns 3005 ns std::set<std::string>::ctor(iterator, iterator) (unsorted sequence)/1024 189552 ns 180933 ns std::set<std::string>::ctor(iterator, iterator) (unsorted sequence)/8192 2887579 ns 2691678 ns std::set<std::string>::ctor(iterator, iterator) (sorted sequence)/0 15.1 ns 14.9 ns std::set<std::string>::ctor(iterator, iterator) (sorted sequence)/32 2611 ns 2514 ns std::set<std::string>::ctor(iterator, iterator) (sorted sequence)/1024 91581 ns 78727 ns std::set<std::string>::ctor(iterator, iterator) (sorted sequence)/8192 1192640 ns 1158959 ns std::set<std::string>::insert(iterator, iterator) (all new keys)/0 452 ns 457 ns std::set<std::string>::insert(iterator, iterator) (all new keys)/32 2530 ns 2544 ns std::set<std::string>::insert(iterator, iterator) (all new keys)/1024 195352 ns 179614 ns std::set<std::string>::insert(iterator, iterator) (all new keys)/8192 1737890 ns 1749615 ns std::set<std::string>::insert(iterator, iterator) (half new keys)/0 451 ns 454 ns std::set<std::string>::insert(iterator, iterator) (half new keys)/32 1949 ns 1766 ns std::set<std::string>::insert(iterator, iterator) (half new keys)/1024 128853 ns 109467 ns std::set<std::string>::insert(iterator, iterator) (half new keys)/8192 1233077 ns 1177289 ns std::set<std::string>::erase(iterator, iterator) (erase half the container)/0 450 ns 451 ns std::set<std::string>::erase(iterator, iterator) (erase half the container)/32 809 ns 812 ns std::set<std::string>::erase(iterator, iterator) (erase half the container)/1024 21736 ns 21922 ns std::set<std::string>::erase(iterator, iterator) (erase half the container)/8192 135884 ns 133228 ns ``` Fixes #154650
2025-09-02[libcxx][test] Avoid warnings about unused variables and typedefs if ↵Alex Guteniev5-11/+13
`_LIBCPP_VERSION` is not defined (#155679) Make these tests pass with MSVC STL
2025-09-01[libc++] Remove a few GCC workarounds that aren't needed anymore (#156290)Nikolas Klauser3-10/+1
2025-08-29[libc++] Disable cv-qualified arithmetic hash specializations (#155786)Nikolas Klauser3-0/+30
#140407 accidentally enabled `hash` for cv-qualified types. This patch disables these specializations again.
2025-08-27[libc++] Optimize ofstream::write (#123337)Nikolas Klauser2-1/+149
``` ---------------------------- Benchmark old new ---------------------------- bm_write 1382 ns 521 ns ```
2025-08-27Reapply "[libc++] Refactor key extraction for __hash_table and __tree ↵Nikolas Klauser4-8/+40
(#154512)" (#155565) The original PR has been reverted because of an LLDB test failure. This patch now works around the test failure by simply allowing the new symbols to show up in a stack trace. This reverts commit 72c04bb882ad70230bce309c3013d9cc2c99e9a7. Original commit message: This patch replaces `__can_extract_key` with an overload set to try to extract the key. This simplifies the code, since we don't need to have separate overload sets for the unordered and associative containers. It also allows extending the set of extraction cases more easily, since we have a single place to define how the key is extracted.
2025-08-26Revert "[libc++] Refactor key extraction for __hash_table and __tree (#154512)"Aiden Grossman4-40/+8
This reverts commit af1f06e41b05c267480f1629dc0fcdf18f3b59f6. This is causing some build failures in premerge as some of the LLDB tests fail.
2025-08-26[libc++] Refactor key extraction for __hash_table and __tree (#154512)Nikolas Klauser4-8/+40
This patch replaces `__can_extract_key` with an overload set to try to extract the key. This simplifies the code, since we don't need to have separate overload sets for the unordered and associative containers. It also allows extending the set of extraction cases more easily, since we have a single place to define how the key is extracted.
2025-08-25[libc++] Optimize __hash_table::erase(iterator, iterator) (#152471)Nikolas Klauser1-0/+14
Instead of just calling the single element `erase` on every element of the range, we can combine some of the operations in a custom implementation. Specifically, we don't need to search for the previous node or re-link the list every iteration. Removing this unnecessary work results in some nice performance improvements: ``` ----------------------------------------------------------------------------------------------------------------------- Benchmark old new ----------------------------------------------------------------------------------------------------------------------- std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/0 457 ns 459 ns std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/32 995 ns 626 ns std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/1024 18196 ns 7995 ns std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/8192 124722 ns 70125 ns std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/0 456 ns 461 ns std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/32 1183 ns 769 ns std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/1024 27827 ns 18614 ns std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/8192 266681 ns 226107 ns std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/0 455 ns 462 ns std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/32 996 ns 659 ns std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/1024 15963 ns 8108 ns std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/8192 136493 ns 71848 ns std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/0 454 ns 455 ns std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/32 985 ns 703 ns std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/1024 16277 ns 9085 ns std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/8192 125736 ns 82710 ns std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/0 457 ns 454 ns std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/32 1091 ns 646 ns std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/1024 17784 ns 7664 ns std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/8192 127098 ns 72806 ns ```
2025-08-25[libcxx][test] Fix typos (#155217)Stephan T. Lavavej48-93/+93
I noticed a typo in the directory name `refwrap.comparissons`, then did a quick pass to fix typos elsewhere in the tests. All fixes were manual (some carefully search-and-replaced); I used [cspell](https://www.npmjs.com/package/cspell) to find them.
2025-08-23[libc++] Add tag types to all the __tuple_impl constructors (#154517)Nikolas Klauser1-0/+27
This fixes a bug reported in https://github.com/llvm/llvm-project/pull/151654#issuecomment-3205410955.
2025-08-23[libc++] Fix ABI break introduced by switching to _LIBCPP_COMPRESSED_PAIR ↵Nikolas Klauser3-0/+12
(#154686) LLVM 20 contained an ABI break that can result in the size of `std::unordered_{map,set,multimap,multiset}` and `std::deque` changing when used with an allocator type that is empty and contains a base class that is the same across rebound allocator instantiations (e.g. ``Allocator<int>`` and ``Allocator<char>`` are both empty and contain the same base class). In addition, the layout of a user-defined type that: - contains one of the following containers: `std::unordered_{map,set,multimap,multiset}`, `std::deque`, `std::map`, `std::set`, `std::multimap`, `std::multiset`, `std::list` or `std::vector`, and - passes an empty allocator, comparator or hasher type to that container, and - has a member of that same empty allocator, comparator or hasher type inside the enclosing struct, and - that member is either marked with `[[no_unique_address]]` or optimized out via the EBO (empty base optimization) technique saw its size increase from LLVM 19 to LLVM 20. This was caused by the usage of `[[no_unique_address]]` within some of libc++'s containers in a way that allowed subtle interactions with enclosing objects. This is fixed in LLVM 21 on Clang (returning to the LLVM 19 ABI), however that implies an ABI break from LLVM 20 to LLVM 21. Furthermore, fixing this causes a slight regression to constant evaluation support in `std::unique_ptr`. Specifically, constant evaluation will now fail when the deleter relies on being value-initialized for constant-evaluation admissibility. If a default-initialized deleter can be used during constant evaluation, or if the default constructor is non-trivial, the `unique_ptr` is not affected by this regression. In particular, this regression does not impact any `unique_ptr` using the default deleter. Note that there is currently no way to realistically fix this ABI break on GCC, therefore GCC will remain on the ABI introduced in LLVM 19. That also means that Clang and GCC will have a slightly different ABI for the small subset of types listed above until we are able to apply the same fix we did with Clang on GCC. We fix this regression by surrounding the members of the `_LIBCPP_COMPRESSED_PAIR` with an anonymous struct. This restricts the shifting of empty types to the front of the `_LIBCPP_COMPRESSED_PAIR` instead of throughout the surrounding object. This "frees up" the zero offset to contain another object of the same type, restoring the ability to perform EBO or to elide the storage for a type with `[[no_unique_address]]` in the enclosing (user-defined) struct. Fixes #154146 Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-08-22[libc++] Optimize multi{map,set}::insert(InputIterator, InputIterator) (#152691)Nikolas Klauser2-114/+355
2025-08-21[libcxx][test] Silence nodiscard warnings (#154622)Stephan T. Lavavej3-6/+6
MSVC's STL marks `std::make_shared`, `std::allocate_shared`, `std::bitset::to_ulong`, and `std::bitset::to_ullong` as `[[nodiscard]]`, which causes these libcxx tests to emit righteous warnings. They should use the traditional `(void)` cast technique to ignore the return values.
2025-08-19[libc++][tuple.apply] Implement P2255R2 make_from_tuple part. (#152867)yronglin2-0/+37
Implement P2255R2 tuple.apply part wording for `std::make_from_tuple`. ``` Mandates: If tuple_size_v<remove_reference_t<Tuple>> is 1, then reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))> is false. ``` Fixes #154274 --------- Signed-off-by: yronglin <yronglin777@gmail.com>
2025-08-18[libc++] Implement P3168R2: Give optional range support (#149441)William Tran-Viet5-22/+246
Resolves #105430 - Implement all required pieces of P3168R2 - Leverage existing `wrap_iter` and `bounded_iter` classes to implement the `optional` regular and hardened iterator type, respectively - Update documentation to match
2025-08-18[libc++][ranges] Ensure range access CPOs are provided in `<iterator>` (#151745)A. Jiang2-0/+72
Per [range.access.general]/1, these CPOs are also provided in `<iterator>`. Currently only some of them are provided via transitive inclusion when only `<iterator>` is included. Drive-by: Add an entry for `ranges::reserve_hint` in the general test file for CPOs.
2025-08-16[libc++][jthread] LWG3788: `jthread::operator=(jthread&&)` postconditions ↵Hristo Hristov1-0/+9
are unimplementable under self-assignment (#153758) Already implemented in LLVM18: [695138c](https://github.com/llvm/llvm-project/commit/695138ca8405779c2b7756cc31d887aa54f56bb8) For details see: https://github.com/llvm/llvm-project/issues/105045#issuecomment-3190674947 Closes #105045
2025-08-15[libc++] Optimize __tree::find and __tree::__erase_unique (#152370)Nikolas Klauser1-21/+30
This patch changes `__tree::find` to return when it has found any equal element instead of the lower bound of the equal elements. For `map` and `set` there is no observable difference, since the keys are unique. However for their `multi` versions this can mean a change in behaviour since it's not longer guaranteed that `find` will return the first element. ``` ------------------------------------------------------------------------------------------ Benchmark old new ------------------------------------------------------------------------------------------ std::map<int, int>::erase(key) (existent)/0 24.4 ns 24.9 ns std::map<int, int>::erase(key) (existent)/32 39.8 ns 32.1 ns std::map<int, int>::erase(key) (existent)/1024 83.8 ns 52.5 ns std::map<int, int>::erase(key) (existent)/8192 91.4 ns 66.4 ns std::map<int, int>::erase(key) (non-existent)/0 0.511 ns 0.328 ns std::map<int, int>::erase(key) (non-existent)/32 9.12 ns 5.62 ns std::map<int, int>::erase(key) (non-existent)/1024 26.6 ns 11.3 ns std::map<int, int>::erase(key) (non-existent)/8192 37.0 ns 16.9 ns std::map<int, int>::find(key) (existent)/0 0.007 ns 0.007 ns std::map<int, int>::find(key) (existent)/32 6.02 ns 4.32 ns std::map<int, int>::find(key) (existent)/1024 13.6 ns 8.35 ns std::map<int, int>::find(key) (existent)/8192 30.3 ns 12.8 ns std::map<int, int>::find(key) (non-existent)/0 0.299 ns 0.545 ns std::map<int, int>::find(key) (non-existent)/32 8.78 ns 4.60 ns std::map<int, int>::find(key) (non-existent)/1024 26.1 ns 21.8 ns std::map<int, int>::find(key) (non-existent)/8192 36.2 ns 27.9 ns std::map<std::string, int>::erase(key) (existent)/0 74.1 ns 76.7 ns std::map<std::string, int>::erase(key) (existent)/32 161 ns 114 ns std::map<std::string, int>::erase(key) (existent)/1024 196 ns 126 ns std::map<std::string, int>::erase(key) (existent)/8192 207 ns 160 ns std::map<std::string, int>::erase(key) (non-existent)/0 0.754 ns 0.328 ns std::map<std::string, int>::erase(key) (non-existent)/32 47.3 ns 40.7 ns std::map<std::string, int>::erase(key) (non-existent)/1024 122 ns 96.1 ns std::map<std::string, int>::erase(key) (non-existent)/8192 168 ns 123 ns std::map<std::string, int>::find(key) (existent)/0 0.059 ns 0.058 ns std::map<std::string, int>::find(key) (existent)/32 54.3 ns 34.6 ns std::map<std::string, int>::find(key) (existent)/1024 125 ns 64.5 ns std::map<std::string, int>::find(key) (existent)/8192 159 ns 79.2 ns std::map<std::string, int>::find(key) (non-existent)/0 0.311 ns 0.299 ns std::map<std::string, int>::find(key) (non-existent)/32 44.0 ns 42.7 ns std::map<std::string, int>::find(key) (non-existent)/1024 120 ns 92.6 ns std::map<std::string, int>::find(key) (non-existent)/8192 189 ns 124 ns std::set<int>::erase(key) (existent)/0 25.1 ns 25.1 ns std::set<int>::erase(key) (existent)/32 42.1 ns 33.1 ns std::set<int>::erase(key) (existent)/1024 73.8 ns 55.5 ns std::set<int>::erase(key) (existent)/8192 101 ns 68.8 ns std::set<int>::erase(key) (non-existent)/0 0.511 ns 0.328 ns std::set<int>::erase(key) (non-existent)/32 9.60 ns 4.67 ns std::set<int>::erase(key) (non-existent)/1024 26.5 ns 11.2 ns std::set<int>::erase(key) (non-existent)/8192 46.2 ns 16.8 ns std::set<int>::find(key) (existent)/0 0.008 ns 0.007 ns std::set<int>::find(key) (existent)/32 5.87 ns 4.51 ns std::set<int>::find(key) (existent)/1024 14.3 ns 8.69 ns std::set<int>::find(key) (existent)/8192 30.2 ns 12.8 ns std::set<int>::find(key) (non-existent)/0 0.531 ns 0.530 ns std::set<int>::find(key) (non-existent)/32 8.77 ns 4.64 ns std::set<int>::find(key) (non-existent)/1024 26.1 ns 21.7 ns std::set<int>::find(key) (non-existent)/8192 36.3 ns 27.8 ns std::set<std::string>::erase(key) (existent)/0 93.2 ns 70.2 ns std::set<std::string>::erase(key) (existent)/32 164 ns 116 ns std::set<std::string>::erase(key) (existent)/1024 161 ns 136 ns std::set<std::string>::erase(key) (existent)/8192 231 ns 140 ns std::set<std::string>::erase(key) (non-existent)/0 0.532 ns 0.326 ns std::set<std::string>::erase(key) (non-existent)/32 43.4 ns 40.1 ns std::set<std::string>::erase(key) (non-existent)/1024 122 ns 99.5 ns std::set<std::string>::erase(key) (non-existent)/8192 168 ns 125 ns std::set<std::string>::find(key) (existent)/0 0.059 ns 0.059 ns std::set<std::string>::find(key) (existent)/32 53.1 ns 35.5 ns std::set<std::string>::find(key) (existent)/1024 124 ns 61.2 ns std::set<std::string>::find(key) (existent)/8192 154 ns 73.9 ns std::set<std::string>::find(key) (non-existent)/0 0.532 ns 0.301 ns std::set<std::string>::find(key) (non-existent)/32 44.4 ns 39.5 ns std::set<std::string>::find(key) (non-existent)/1024 120 ns 95.5 ns std::set<std::string>::find(key) (non-existent)/8192 193 ns 119 ns std::multimap<int, int>::erase(key) (existent)/0 26.5 ns 26.6 ns std::multimap<int, int>::erase(key) (existent)/32 33.5 ns 32.9 ns std::multimap<int, int>::erase(key) (existent)/1024 55.5 ns 58.0 ns std::multimap<int, int>::erase(key) (existent)/8192 67.4 ns 70.0 ns std::multimap<int, int>::erase(key) (non-existent)/0 0.523 ns 0.532 ns std::multimap<int, int>::erase(key) (non-existent)/32 5.08 ns 5.09 ns std::multimap<int, int>::erase(key) (non-existent)/1024 13.0 ns 12.9 ns std::multimap<int, int>::erase(key) (non-existent)/8192 19.6 ns 19.8 ns std::multimap<int, int>::find(key) (existent)/0 0.015 ns 0.037 ns std::multimap<int, int>::find(key) (existent)/32 7.07 ns 3.85 ns std::multimap<int, int>::find(key) (existent)/1024 22.0 ns 7.44 ns std::multimap<int, int>::find(key) (existent)/8192 37.6 ns 12.0 ns std::multimap<int, int>::find(key) (non-existent)/0 0.297 ns 0.305 ns std::multimap<int, int>::find(key) (non-existent)/32 8.79 ns 4.59 ns std::multimap<int, int>::find(key) (non-existent)/1024 26.0 ns 11.2 ns std::multimap<int, int>::find(key) (non-existent)/8192 36.4 ns 16.8 ns std::multimap<std::string, int>::erase(key) (existent)/0 93.4 ns 84.5 ns std::multimap<std::string, int>::erase(key) (existent)/32 101 ns 101 ns std::multimap<std::string, int>::erase(key) (existent)/1024 118 ns 126 ns std::multimap<std::string, int>::erase(key) (existent)/8192 108 ns 124 ns std::multimap<std::string, int>::erase(key) (non-existent)/0 2.39 ns 2.43 ns std::multimap<std::string, int>::erase(key) (non-existent)/32 44.4 ns 49.7 ns std::multimap<std::string, int>::erase(key) (non-existent)/1024 108 ns 103 ns std::multimap<std::string, int>::erase(key) (non-existent)/8192 140 ns 125 ns std::multimap<std::string, int>::find(key) (existent)/0 0.059 ns 0.058 ns std::multimap<std::string, int>::find(key) (existent)/32 52.3 ns 32.6 ns std::multimap<std::string, int>::find(key) (existent)/1024 122 ns 58.9 ns std::multimap<std::string, int>::find(key) (existent)/8192 160 ns 72.7 ns std::multimap<std::string, int>::find(key) (non-existent)/0 0.524 ns 0.494 ns std::multimap<std::string, int>::find(key) (non-existent)/32 43.8 ns 38.9 ns std::multimap<std::string, int>::find(key) (non-existent)/1024 123 ns 90.8 ns std::multimap<std::string, int>::find(key) (non-existent)/8192 190 ns 126 ns std::multiset<int>::erase(key) (existent)/0 27.1 ns 26.8 ns std::multiset<int>::erase(key) (existent)/32 33.3 ns 34.1 ns std::multiset<int>::erase(key) (existent)/1024 58.5 ns 58.8 ns std::multiset<int>::erase(key) (existent)/8192 66.7 ns 64.1 ns std::multiset<int>::erase(key) (non-existent)/0 0.318 ns 0.325 ns std::multiset<int>::erase(key) (non-existent)/32 5.15 ns 5.25 ns std::multiset<int>::erase(key) (non-existent)/1024 12.9 ns 12.7 ns std::multiset<int>::erase(key) (non-existent)/8192 20.3 ns 20.3 ns std::multiset<int>::find(key) (existent)/0 0.043 ns 0.015 ns std::multiset<int>::find(key) (existent)/32 6.94 ns 4.22 ns std::multiset<int>::find(key) (existent)/1024 21.4 ns 8.23 ns std::multiset<int>::find(key) (existent)/8192 37.4 ns 12.6 ns std::multiset<int>::find(key) (non-existent)/0 0.515 ns 0.300 ns std::multiset<int>::find(key) (non-existent)/32 8.52 ns 4.62 ns std::multiset<int>::find(key) (non-existent)/1024 25.5 ns 11.3 ns std::multiset<int>::find(key) (non-existent)/8192 36.5 ns 27.0 ns std::multiset<std::string>::erase(key) (existent)/0 81.9 ns 77.5 ns std::multiset<std::string>::erase(key) (existent)/32 113 ns 129 ns std::multiset<std::string>::erase(key) (existent)/1024 132 ns 148 ns std::multiset<std::string>::erase(key) (existent)/8192 114 ns 165 ns std::multiset<std::string>::erase(key) (non-existent)/0 2.33 ns 2.32 ns std::multiset<std::string>::erase(key) (non-existent)/32 44.4 ns 42.0 ns std::multiset<std::string>::erase(key) (non-existent)/1024 97.3 ns 95.1 ns std::multiset<std::string>::erase(key) (non-existent)/8192 132 ns 123 ns std::multiset<std::string>::find(key) (existent)/0 0.058 ns 0.059 ns std::multiset<std::string>::find(key) (existent)/32 48.3 ns 34.4 ns std::multiset<std::string>::find(key) (existent)/1024 121 ns 61.9 ns std::multiset<std::string>::find(key) (existent)/8192 155 ns 77.7 ns std::multiset<std::string>::find(key) (non-existent)/0 0.524 ns 0.306 ns std::multiset<std::string>::find(key) (non-existent)/32 44.1 ns 40.4 ns std::multiset<std::string>::find(key) (non-existent)/1024 121 ns 96.3 ns std::multiset<std::string>::find(key) (non-existent)/8192 193 ns 121 ns ```
2025-08-15[libc++] Optimize __hash_table copy constructors and assignment (#151951)Nikolas Klauser12-1123/+2570
``` ---------------------------------------------------------------------------------------------------------------------- Benchmark old new ---------------------------------------------------------------------------------------------------------------------- std::unordered_set<int>::ctor(const&)/0 15.4 ns 14.6 ns std::unordered_set<int>::ctor(const&)/32 686 ns 322 ns std::unordered_set<int>::ctor(const&)/1024 35839 ns 21490 ns std::unordered_set<int>::ctor(const&)/8192 385790 ns 280270 ns std::unordered_set<int>::operator=(const&) (into cleared Container)/0 15.1 ns 15.9 ns std::unordered_set<int>::operator=(const&) (into cleared Container)/32 1077 ns 333 ns std::unordered_set<int>::operator=(const&) (into cleared Container)/1024 31296 ns 9984 ns std::unordered_set<int>::operator=(const&) (into cleared Container)/8192 266776 ns 109418 ns std::unordered_set<int>::operator=(const&) (into partially populated Container)/0 15.1 ns 16.3 ns std::unordered_set<int>::operator=(const&) (into partially populated Container)/32 962 ns 320 ns std::unordered_set<int>::operator=(const&) (into partially populated Container)/1024 31713 ns 10128 ns std::unordered_set<int>::operator=(const&) (into partially populated Container)/8192 266113 ns 108525 ns std::unordered_set<int>::operator=(const&) (into populated Container)/0 0.990 ns 2.03 ns std::unordered_set<int>::operator=(const&) (into populated Container)/32 963 ns 263 ns std::unordered_set<int>::operator=(const&) (into populated Container)/1024 27600 ns 7793 ns std::unordered_set<int>::operator=(const&) (into populated Container)/8192 235295 ns 66248 ns std::unordered_set<std::string>::ctor(const&)/0 16.0 ns 15.0 ns std::unordered_set<std::string>::ctor(const&)/32 2950 ns 1277 ns std::unordered_set<std::string>::ctor(const&)/1024 246935 ns 73762 ns std::unordered_set<std::string>::ctor(const&)/8192 3310895 ns 2468608 ns std::unordered_set<std::string>::operator=(const&) (into cleared Container)/0 16.1 ns 15.8 ns std::unordered_set<std::string>::operator=(const&) (into cleared Container)/32 5856 ns 1039 ns std::unordered_set<std::string>::operator=(const&) (into cleared Container)/1024 170436 ns 74836 ns std::unordered_set<std::string>::operator=(const&) (into cleared Container)/8192 1574235 ns 1096891 ns std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/0 16.0 ns 16.3 ns std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/32 5571 ns 1064 ns std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/1024 199220 ns 75462 ns std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/8192 1552465 ns 1116094 ns std::unordered_set<std::string>::operator=(const&) (into populated Container)/0 1.70 ns 2.14 ns std::unordered_set<std::string>::operator=(const&) (into populated Container)/32 2562 ns 645 ns std::unordered_set<std::string>::operator=(const&) (into populated Container)/1024 228608 ns 39100 ns std::unordered_set<std::string>::operator=(const&) (into populated Container)/8192 2013723 ns 390401 ns ``` Fixes #77657
2025-08-13[libc++][ranges] LWG4096: `views::iota(views::iota(0))` should be rejected ↵Hristo Hristov1-0/+12
(#152855) Fixes #105352
2025-08-13[libc++] Move some standard tests from test/libcxx (#152982)Nikolas Klauser8-3/+459
This also removes some tests which were redundant, wrong, or never run. Specifically, - `libcxx/utilities/meta/stress_tests/*` were never run and are of questionable usefulness - `libcxx/utilities/template.bitset/includes.pass.cpp` is completely redundant and partially incorrect Also notably, `libcxx/language.support/support.c.headers/support.c.headers.other/math.lerp.verify.cpp` has been refactored to only test the standard mandate.
2025-08-11[libc++] Fix std::variant evaluating template arguments too eagerly (#151028)Nikolas Klauser1-0/+16
This has been reported in https://github.com/llvm/llvm-project/pull/116709#issuecomment-3105095648. Fixes #151328
2025-08-10[libc++] Implement LWG4222 'expected' constructor from a single value ↵yronglin1-0/+11
missing a constraint (#152676) Implement [LWG4222](https://wg21.link/LWG4222). Closes https://github.com/llvm/llvm-project/issues/148208 Signed-off-by: yronglin <yronglin777@gmail.com>