In #155245, we implemented an optimization to std::map and std::set search operations. That optimization took advantage of something that is guaranteed by the Standard, namely that the comparator provided to the associative container is a valid strict weak ordering. Sadly, some code in the wild did not satisfy this requirement, such as Boost.ICL: boostorg/icl#51 Since this can have extremely tricky runtime consequences, this patch introduces a temporary escape hatch for the LLVM 22 release that allows reverting to the previous behavior. It also explicitly calls out the change in the release notes, adds some regression tests and adds debug mode support for catching some of these invalid predicates. Fixes #183189
159 lines
8.2 KiB
ReStructuredText
159 lines
8.2 KiB
ReStructuredText
===========================================
|
|
Libc++ 22.0.0 (In-Progress) Release Notes
|
|
===========================================
|
|
|
|
.. contents::
|
|
:local:
|
|
:depth: 2
|
|
|
|
Written by the `Libc++ Team <https://libcxx.llvm.org>`_
|
|
|
|
.. warning::
|
|
|
|
These are in-progress notes for the upcoming libc++ 22.0.0 release.
|
|
Release notes for previous releases can be found on
|
|
`the Download Page <https://releases.llvm.org/download.html>`_.
|
|
|
|
Introduction
|
|
============
|
|
|
|
This document contains the release notes for the libc++ C++ Standard Library,
|
|
part of the LLVM Compiler Infrastructure, release 22.0.0. Here we describe the
|
|
status of libc++ in some detail, including major improvements from the previous
|
|
release and new feature work. For the general LLVM release notes, see `the LLVM
|
|
documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
|
|
be downloaded from the `LLVM releases web site <https://llvm.org/releases/>`_.
|
|
|
|
For more information about libc++, please see the `Libc++ Web Site
|
|
<https://libcxx.llvm.org>`_ or the `LLVM Web Site <https://llvm.org>`_.
|
|
|
|
Note that if you are reading this file from a Git checkout or the
|
|
main Libc++ web page, this document applies to the *next* release, not
|
|
the current one. To see the release notes for a specific release, please
|
|
see the `releases page <https://llvm.org/releases/>`_.
|
|
|
|
What's New in Libc++ 22.0.0?
|
|
==============================
|
|
|
|
Implemented Papers
|
|
------------------
|
|
|
|
- P2592R3: Hashing support for ``std::chrono`` value classes (`Github <https://llvm.org/PR105358>`__)
|
|
- P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__)
|
|
- P2988R12: ``std::optional<T&>`` (`Github <https://llvm.org/PR148131>`__)
|
|
- P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
|
|
- P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__)
|
|
- P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__)
|
|
- P2404R3: Move-only types for ``equality_comparable_with``, ``totally_ordered_with``, and ``three_way_comparable_with``
|
|
(`Github <https://llvm.org/PR105210>`__)
|
|
- P2641R4: Checking if a ``union`` alternative is active (``std::is_within_lifetime``)
|
|
(`Github <https://llvm.org/PR105381>`__)
|
|
- P2835R7: Expose ``std::atomic_ref``'s object address (`Github <https://llvm.org/PR118377>`__)
|
|
- P2944R3: Comparisons for ``reference_wrapper`` (`Github <https://llvm.org/PR105424>`__)
|
|
- P3168R2: Give ``std::optional`` Range Support
|
|
(guarded by ``-fexperimental-library``, `Github <https://llvm.org/PR105430>`__)
|
|
- P3567R2: ``flat_meow`` Fixes (`Github <https://llvm.org/PR162022>`__)
|
|
- P3836R2: Make ``optional<T&>`` trivially copyable (`Github <https://llvm.org/PR171275>`__)
|
|
- P1789R3: Library Support for Expansion Statements (`Github <https://llvm.org/PR167184>`__)
|
|
|
|
Improvements and New Features
|
|
-----------------------------
|
|
|
|
- The performance of associative and unordered containers has been significantly improved. This is an overview of the
|
|
different functions and by up to how much they have been improved:
|
|
|
|
- ``map::map(const map&)``: 2.3x
|
|
- ``map::operator=(const map&)``: 11x
|
|
- ``unordered_set::unordered_set(const unordered_set&)``: 3.3x
|
|
- ``unordered_set::operator=(const unordered_set&)``: 5x
|
|
- ``erase`` of ``map`` and ``set``: 2x
|
|
- ``find(key)`` of ``map``, ``set``, ``multimap`` and ``multiset``: 2.3x
|
|
- ``(iterator, iterator)`` constructors of ``map``, ``set``, ``multimap`` and ``multiset``: 3x
|
|
- ``insert(iterator, iterator)`` of ``map``, ``set``, ``multimap`` and ``multiset``: 2.5x
|
|
- ``erase(iterator, iterator)`` of the unordered containers: 1.9x
|
|
- ``map::insert_or_assign``: 2x
|
|
|
|
- The performance of many algorithms has been improved. This is an overview of the different functions and by up to how
|
|
much they have been improved:
|
|
|
|
- ``std::find`` for integral types: 2x
|
|
- ``std::for_each`` and ``ranges::for_each`` over the associative containers: 2x
|
|
- ``std::rotate``: 3x
|
|
- Some have been specifically optimized for segmented iterators:
|
|
|
|
- ``std::distance`` and ``std::ranges::distance`` on non-random-access iterators: 1600x
|
|
- ``{std,ranges}::{fill, fill_n}``: 10x
|
|
- ``std::{generate, generate_n}`` and ``std::ranges::generate_n``: 1.8x
|
|
|
|
- ``std::search_n`` for random access iterators now tries to skip elements.
|
|
In contrived cases improvements of 70,000x have been observed.
|
|
|
|
- There have also been performance improvements in other library facilities:
|
|
|
|
- ``vector<bool>::reserve()``: 2x
|
|
- ``deque::append_range``: 3.4x
|
|
- ``num_get::do_get`` integral overloads: 2.8x
|
|
- Some reallocations are now avoided in ``std::filesystem::path::lexically_relative``: 1.7x
|
|
- ``ofstream::write`` passes large strings to system calls directly instead of copying them in chunks into a buffer
|
|
- ``std::align`` is now an inline function, which allows the compiler to better optimize calls to it
|
|
|
|
- ``std::atomic::wait`` has been refactored to accept more types to use platform native wait functions directly.
|
|
This is guarded behind the ABI Macro ``_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE``.
|
|
|
|
- Multiple internal types have been refactored to use ``[[no_unique_address]]``, resulting in faster compile times and
|
|
reduced debug information.
|
|
|
|
Deprecations and Removals
|
|
-------------------------
|
|
|
|
- The minimally supported deployment target on macOS has been increased to 11.0.
|
|
|
|
Potentially breaking changes
|
|
----------------------------
|
|
|
|
- The algorithm for ``multi{map,set}::find`` has been modified such that it doesn't necessarily return an iterator to
|
|
the first equal element in the container. This was never guaranteed by the Standard, but libc++ previously happened to
|
|
always return the first equal element, like other implementations do. Starting with this release, code relying on the
|
|
first element being returned from ``find`` will be broken, and ``lower_bound`` or ``equal_range`` should be used
|
|
instead.
|
|
|
|
- The algorithms for ``std::{map,set}`` ``lower_bound`` and ``upper_bound`` operations were modified such that their
|
|
result changed for comparators that are not a strict weak order. Being a strict weak order was always a requirement
|
|
of the Standard and still is, however in this release libc++ changed the behavior of ``std::{map,set}`` for such
|
|
comparators. Since this may be tricky to work around in some cases, an escape hatch is provided in this release:
|
|
defining ``_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND`` will revert to the historical implementation of
|
|
these operations. That escape hatch will be removed in LLVM 23.
|
|
|
|
- The ABI flag ``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` has been split off from
|
|
``_LIBCPP_ABI_NO_ITERATOR_BASES``. If you are using this flag and care about ABI stability, you should set
|
|
``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` as well.
|
|
|
|
Announcements About Future Releases
|
|
-----------------------------------
|
|
|
|
ABI Affecting Changes
|
|
---------------------
|
|
|
|
- The ABI flag ``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` has been split off from
|
|
``_LIBCPP_ABI_NO_ITERATOR_BASES``. If you are using this flag and care about ABI stability, you should set
|
|
``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER`` as well.
|
|
|
|
- The internal types ``__map_value_compare``, ``__unordered_map_hasher``, ``__unordered_map_equal``,
|
|
``__hash_map_hasher`` and ``__hash_map_equal`` have been refactored to use ``_LIBCPP_COMPRESSED_ELEMENT`` instead of
|
|
potentially inheriting from the types they wrap. At this point in time we are not aware of any ABI changes caused by
|
|
this.
|
|
|
|
- ``ranges::iota_view`` is now aware of ``__int128``. This causes ``iota_view::difference_type`` to change from
|
|
``long long`` to ``__int128`` in some cases.
|
|
|
|
- ``std::allocator`` is now trivially default constructible. The behaviour can be reverted by defining
|
|
``_LIBCPP_DEPRECATED_ABI_NON_TRIVIAL_ALLOCATOR``. Please inform the libc++ team if you need this flag, since it will
|
|
be removed in LLVM 24 if there is no evidence that it's required.
|
|
|
|
- ``bitset::operator[]`` now returns ``bool``, making libc++ conforming. The behaviour can be reverted by defining
|
|
``_LIBCPP_DEPRECATED_ABI_BITSET_CONST_SUBSCRIPT_RETURN_REF``. Please inform the libc++ team if you need this flag,
|
|
since it will be removed in LLVM 24 if there is no evidence that it's required.
|
|
|
|
Build System Changes
|
|
--------------------
|