[libcxx-commits] [libcxx] [libcxxabi] [llvm] Adding Support for Offloading C++ standard algorithms (PR #116869)

Vedant Tewari via libcxx-commits libcxx-commits at lists.llvm.org
Sun Nov 24 09:41:19 PST 2024


https://github.com/xevor11 updated https://github.com/llvm/llvm-project/pull/116869

>From 5c8fefbefff498ebf215a2d51ba66d6841909b38 Mon Sep 17 00:00:00 2001
From: AntonRydahl <rydahl2610 at gmail.com>
Date: Wed, 20 Sep 2023 17:06:10 -0700
Subject: [PATCH 1/3] Adding OpenMP Offloading Backend for C++ Parallel
 Algorithms Rebased

---
 .github/workflows/libcxx-build-and-test.yaml  |    1 +
 libcxx/CMakeLists.txt                         |   12 +-
 libcxx/cmake/caches/Generic-pstl-openmp.cmake |    1 +
 libcxx/docs/UserDocumentation.rst             |  339 +-
 libcxx/docs/VendorDocumentation.rst           |  407 +-
 libcxx/include/CMakeLists.txt                 |    1 +
 libcxx/include/__config_site.in               |    1 +
 libcxx/include/__pstl/backend.h               |   28 +-
 libcxx/include/__pstl/backend_fwd.h           |   20 +-
 libcxx/include/__pstl/backends/openmp.h       |  511 ++
 libcxx/include/__pstl/dispatch.h              |   15 +
 libcxx/include/module.modulemap               | 4300 ++++++++---------
 .../alg.pstl.openmp/fill_offload.pass.cpp     |   52 +
 .../alg.pstl.openmp/find_if.pass.cpp          |   67 +
 .../alg.pstl.openmp/find_if_funptr.pass.cpp   |   36 +
 .../alg.pstl.openmp/find_if_offload.pass.cpp  |   39 +
 .../alg.pstl.openmp/for_each_funptr.pass.cpp  |   36 +
 .../alg.pstl.openmp/for_each_lambda.pass.cpp  |   49 +
 .../alg.pstl.openmp/for_each_offload.pass.cpp |   39 +
 .../for_each_overwrite_input.pass.cpp         |   63 +
 .../gpu_environment_variables.pass.cpp        |   49 +
 .../openmp_version_40.verify.cpp              |   21 +
 .../openmp_version_45.verify.cpp              |   21 +
 .../openmp_version_51.verify.cpp              |   21 +
 .../transform_offload.pass.cpp                |   55 +
 .../transform_reduce_offload.pass.cpp         |   41 +
 ...educe_supported_binary_operations.pass.cpp |  199 +
 libcxx/utils/ci/run-buildbot                  |  342 +-
 libcxx/utils/libcxx/test/features.py          |  282 +-
 libcxx/utils/run.py                           |   15 +
 libcxxabi/CMakeLists.txt                      |    8 +
 31 files changed, 4143 insertions(+), 2928 deletions(-)
 create mode 100644 libcxx/cmake/caches/Generic-pstl-openmp.cmake
 create mode 100644 libcxx/include/__pstl/backends/openmp.h
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/fill_offload.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_funptr.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_offload.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_funptr.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_lambda.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_offload.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_overwrite_input.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/gpu_environment_variables.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_40.verify.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_45.verify.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_51.verify.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_offload.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_offload.pass.cpp
 create mode 100644 libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_supported_binary_operations.pass.cpp

diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml
index 2184ddd49537b5..9e483612bc9943 100644
--- a/.github/workflows/libcxx-build-and-test.yaml
+++ b/.github/workflows/libcxx-build-and-test.yaml
@@ -158,6 +158,7 @@ jobs:
           'generic-no-wide-characters',
           'generic-no-rtti',
           'generic-optimized-speed',
+          'generic-pstl-openmp',
           'generic-static',
           'bootstrapping-build'
         ]
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index abe12c2805a7cf..dee2a75f74d89f 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -300,10 +300,11 @@ option(LIBCXX_HAS_EXTERNAL_THREAD_API
    This option may only be set to ON when LIBCXX_ENABLE_THREADS=ON." OFF)
 
 if (LIBCXX_ENABLE_THREADS)
-  set(LIBCXX_PSTL_BACKEND "std_thread" CACHE STRING "Which PSTL backend to use")
+  set(LIBCXX_PSTL_BACKEND_DEFAULT "std_thread")
 else()
-  set(LIBCXX_PSTL_BACKEND "serial" CACHE STRING "Which PSTL backend to use")
+  set(LIBCXX_PSTL_BACKEND_DEFAULT "serial")
 endif()
+set(LIBCXX_PSTL_BACKEND "${LIBCXX_PSTL_BACKEND_DEFAULT}" CACHE STRING "Select the PSTL backend to use. Valid values are serial, std-thread, libdispatch, openmp. Default: ${LIBCXX_PSTL_BACKEND_DEFAULT}")
 
 # Misc options ----------------------------------------------------------------
 # FIXME: Turn -pedantic back ON. It is currently off because it warns
@@ -552,6 +553,11 @@ function(cxx_add_basic_build_flags target)
     endif()
   endif()
   target_compile_options(${target} PUBLIC "${LIBCXX_ADDITIONAL_COMPILE_FLAGS}")
+
+  # If the PSTL backend depends on OpenMP, we must enable the OpenMP tool chain
+  if (LIBCXX_PSTL_BACKEND STREQUAL "openmp")
+    target_add_compile_flags_if_supported(${target} PUBLIC -fopenmp)
+  endif()
 endfunction()
 
 # Exception flags =============================================================
@@ -784,6 +790,8 @@ elseif(LIBCXX_PSTL_BACKEND STREQUAL "std_thread")
   config_define(1 _LIBCPP_PSTL_BACKEND_STD_THREAD)
 elseif(LIBCXX_PSTL_BACKEND STREQUAL "libdispatch")
   config_define(1 _LIBCPP_PSTL_BACKEND_LIBDISPATCH)
+elseif (LIBCXX_PSTL_BACKEND STREQUAL "openmp")
+  config_define(1 _LIBCPP_PSTL_BACKEND_OPENMP)
 else()
   message(FATAL_ERROR "LIBCXX_PSTL_BACKEND is set to ${LIBCXX_PSTL_BACKEND}, which is not a valid backend.
                        Valid backends are: serial, std_thread and libdispatch")
diff --git a/libcxx/cmake/caches/Generic-pstl-openmp.cmake b/libcxx/cmake/caches/Generic-pstl-openmp.cmake
new file mode 100644
index 00000000000000..f3ff4f3b57fd21
--- /dev/null
+++ b/libcxx/cmake/caches/Generic-pstl-openmp.cmake
@@ -0,0 +1 @@
+set(LIBCXX_PSTL_BACKEND openmp CACHE STRING "")
diff --git a/libcxx/docs/UserDocumentation.rst b/libcxx/docs/UserDocumentation.rst
index 2c1bc1373659c3..f1e7b19ead5798 100644
--- a/libcxx/docs/UserDocumentation.rst
+++ b/libcxx/docs/UserDocumentation.rst
@@ -1,17 +1,19 @@
-.. _user-documentation:
+.. _using-libcxx:
 
-==================
-User documentation
-==================
+============
+Using libc++
+============
 
 .. contents::
   :local:
 
+Usually, libc++ is packaged and shipped by a vendor through some delivery vehicle
+(operating system distribution, SDK, toolchain, etc) and users don't need to do
+anything special in order to use the library.
+
 This page contains information about configuration knobs that can be used by
 users when they know libc++ is used by their toolchain, and how to use libc++
-when it is not the default library used by their toolchain. It is aimed at
-users of libc++: a separate page contains documentation aimed at vendors who
-build and ship libc++ as part of their toolchain.
+when it is not the default library used by their toolchain.
 
 
 Using a different version of the C++ Standard
@@ -26,29 +28,10 @@ matches that Standard in the library.
 
   $ clang++ -std=c++17 test.cpp
 
-Note that using ``-std=c++XY`` with a version of the Standard that has not been ratified
-yet is considered unstable. While we strive to maintain stability, libc++ may be forced to
-make breaking changes to features shipped in a Standard that hasn't been ratified yet. Use
-these versions of the Standard at your own risk.
-
-
-Using libc++ when it is not the system default
-==============================================
-
-Usually, libc++ is packaged and shipped by a vendor through some delivery vehicle
-(operating system distribution, SDK, toolchain, etc) and users don't need to do
-anything special in order to use the library.
-
-On systems where libc++ is provided but is not the default, Clang provides a flag
-called ``-stdlib=`` that can be used to decide which standard library is used.
-Using ``-stdlib=libc++`` will select libc++:
-
-.. code-block:: bash
-
-  $ clang++ -stdlib=libc++ test.cpp
-
-On systems where libc++ is the library in use by default such as macOS and FreeBSD,
-this flag is not required.
+.. warning::
+  Using ``-std=c++XY`` with a version of the Standard that has not been ratified yet
+  is considered unstable. Libc++ reserves the right to make breaking changes to the
+  library until the standard has been ratified.
 
 
 Enabling experimental C++ Library features
@@ -60,19 +43,15 @@ the Standard but whose implementation is not complete or stable yet in libc++. T
 are disabled by default because they are neither API nor ABI stable. However, the
 ``-fexperimental-library`` compiler flag can be defined to turn those features on.
 
-On compilers that do not support the ``-fexperimental-library`` flag (such as GCC),
-users can define the ``_LIBCPP_ENABLE_EXPERIMENTAL`` macro and manually link against
-the appropriate static library (usually shipped as ``libc++experimental.a``) to get
-access to experimental library features.
-
 The following features are currently considered experimental and are only provided
 when ``-fexperimental-library`` is passed:
 
 * The parallel algorithms library (``<execution>`` and the associated algorithms)
+* ``std::stop_token``, ``std::stop_source`` and ``std::stop_callback``
+* ``std::jthread``
 * ``std::chrono::tzdb`` and related time zone functionality
-* ``<syncstream>``
 
-.. note::
+.. warning::
   Experimental libraries are experimental.
     * The contents of the ``<experimental/...>`` headers and the associated static
       library will not remain compatible between versions.
@@ -81,18 +60,98 @@ when ``-fexperimental-library`` is passed:
       the experimental feature is removed two releases after the non-experimental
       version has shipped. The full policy is explained :ref:`here <experimental features>`.
 
+.. note::
+  On compilers that do not support the ``-fexperimental-library`` flag, users can
+  define the ``_LIBCPP_ENABLE_EXPERIMENTAL`` macro and manually link against the
+  appropriate static library (usually shipped as ``libc++experimental.a``) to get
+  access to experimental library features.
 
-Libc++ Configuration Macros
+
+Using libc++ when it is not the system default
+==============================================
+
+On systems where libc++ is provided but is not the default, Clang provides a flag
+called ``-stdlib=`` that can be used to decide which standard library is used.
+Using ``-stdlib=libc++`` will select libc++:
+
+.. code-block:: bash
+
+  $ clang++ -stdlib=libc++ test.cpp
+
+On systems where libc++ is the library in use by default such as macOS and FreeBSD,
+this flag is not required.
+
+
+.. _alternate libcxx:
+
+Using a custom built libc++
 ===========================
 
-Libc++ provides a number of configuration macros that can be used by developers to
-enable or disable extended libc++ behavior.
+Most compilers provide a way to disable the default behavior for finding the
+standard library and to override it with custom paths. With Clang, this can
+be done with:
 
-.. warning::
-  Configuration macros that are not documented here are not intended to be customized
-  by developers and should not be used. In particular, some configuration macros are
-  only intended to be used by vendors and changing their value from the one provided
-  in your toolchain can lead to unexpected behavior.
+.. code-block:: bash
+
+  $ clang++ -nostdinc++ -nostdlib++           \
+            -isystem <install>/include/c++/v1 \
+            -L <install>/lib                  \
+            -Wl,-rpath,<install>/lib          \
+            -lc++                             \
+            test.cpp
+
+The option ``-Wl,-rpath,<install>/lib`` adds a runtime library search path,
+which causes the system's dynamic linker to look for libc++ in ``<install>/lib``
+whenever the program is loaded.
+
+GCC does not support the ``-nostdlib++`` flag, so one must use ``-nodefaultlibs``
+instead. Since that removes all the standard system libraries and not just libc++,
+the system libraries must be re-added manually. For example:
+
+.. code-block:: bash
+
+  $ g++ -nostdinc++ -nodefaultlibs           \
+        -isystem <install>/include/c++/v1    \
+        -L <install>/lib                     \
+        -Wl,-rpath,<install>/lib             \
+        -lc++ -lc++abi -lm -lc -lgcc_s -lgcc \
+        test.cpp
+
+
+GDB Pretty printers for libc++
+==============================
+
+GDB does not support pretty-printing of libc++ symbols by default. However, libc++ does
+provide pretty-printers itself. Those can be used as:
+
+.. code-block:: bash
+
+  $ gdb -ex "source <libcxx>/utils/gdb/libcxx/printers.py" \
+        -ex "python register_libcxx_printer_loader()" \
+        <args>
+
+.. _include-what-you-use:
+
+include-what-you-use (IWYU)
+===========================
+
+libc++ provides an IWYU `mapping file <https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUMappings.md>`_,
+which drastically improves the accuracy of the tool when using libc++. To use the mapping file with
+IWYU, you should run the tool like so:
+
+.. code-block:: bash
+
+  $ include-what-you-use -Xiwyu --mapping_file=/path/to/libcxx/include/libcxx.imp file.cpp
+
+If you would prefer to not use that flag, then you can replace ``/path/to/include-what-you-use/share/libcxx.imp``
+file with the libc++-provided ``libcxx.imp`` file.
+
+Libc++ Configuration Macros
+===========================
+
+Libc++ provides a number of configuration macros which can be used to enable
+or disable extended libc++ behavior, including enabling hardening or thread
+safety annotations.
 
 **_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS**:
   This macro is used to enable -Wthread-safety annotations on libc++'s
@@ -134,12 +193,6 @@ enable or disable extended libc++ behavior.
   warning saying that `std::auto_ptr` is deprecated. If the macro is defined,
   no warning will be emitted. By default, this macro is not defined.
 
-**_LIBCPP_ENABLE_EXPERIMENTAL**:
-  This macro enables experimental features. This can be used on compilers that do
-  not support the ``-fexperimental-library`` flag. When used, users also need to
-  ensure that the appropriate experimental library (usually ``libc++experimental.a``)
-  is linked into their program.
-
 C++17 Specific Configuration Macros
 -----------------------------------
 **_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR**:
@@ -156,18 +209,12 @@ C++17 Specific Configuration Macros
 **_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE**:
   This macro is used to re-enable the `random_shuffle` algorithm.
 
-**_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION**:
-  This macro is used to re-enable `unary_function` and `binary_function`.
-
 **_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS**:
   This macro is used to re-enable `set_unexpected`, `get_unexpected`, and
   `unexpected`.
 
 C++20 Specific Configuration Macros
 -----------------------------------
-**_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION**:
-  This macro is used to re-enable `uncaught_exception`.
-
 **_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE**:
   This macro is used to re-enable the function
   ``std::shared_ptr<...>::unique()``.
@@ -184,9 +231,6 @@ C++20 Specific Configuration Macros
 **_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR**:
   This macro is used to re-enable `raw_storage_iterator`.
 
-**_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER**:
-  This macro is used to re-enable `get_temporary_buffer` and `return_temporary_buffer`.
-
 **_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS**:
   This macro is used to re-enable `is_literal_type`, `is_literal_type_v`,
   `result_of` and `result_of_t`.
@@ -263,7 +307,7 @@ Extensions to the C++23 modules ``std`` and ``std.compat``
 ----------------------------------------------------------
 
 Like other major implementations, libc++ provides C++23 modules ``std`` and
-``std.compat`` in C++20 as an extension.
+``std.compat`` in C++20 as an extension"
 
 Constant-initialized std::string
 --------------------------------
@@ -320,14 +364,109 @@ Unpoisoning may not be an option, if (for example) you are not maintaining the a
 * You are using allocator, which does not call destructor during deallocation.
 * You are aware that memory allocated with an allocator may be accessed, even when unused by container.
 
-Support for compiler extensions
--------------------------------
+Offloading C++ Parallel Algorithms to GPUs
+------------------------------------------
+
+Experimental support for GPU offloading has been added to ``libc++``. The
+implementation uses OpenMP target offloading to leverage GPU compute resources.
+The OpenMP PSTL backend can target both NVIDIA and AMD GPUs.
+However, the implementation only supports contiguous iterators, such as
+iterators for ``std::vector`` or ``std::array``.
+To enable the OpenMP offloading backend it must be selected with
+``LIBCXX_PSTL_BACKEND=openmp`` when installing ``libc++``. Further, when
+compiling a program, the user must specify the command line options
+``-fopenmp -fexperimental-library``. To install LLVM with OpenMP offloading
+enabled, please read
+`the LLVM OpenMP FAQ. <https://openmp.llvm.org/SupportAndFAQ.html>`_
+You may also want to to visit
+`the OpenMP offloading command-line argument reference. <https://openmp.llvm.org/CommandLineArgumentReference.html#offload-command-line-arguments>`_
+
+Example
+~~~~~~~
+
+The following is an example of offloading vector addition to a GPU using our
+standard library extension. It implements the classical vector addition from
+BLAS that overwrites the vector ``y`` with ``y=a*x+y``. Thus ``y.begin()`` is
+both used as an input and an output iterator in this example.
+
+.. code-block:: cpp
+
+  #include <algorithm>
+  #include <execution>
+
+  template <typename T1, typename T2, typename T3>
+  void axpy(const T1 a, const std::vector<T2> &x, std::vector<T3> &y) {
+    std::transform(std::execution::par_unseq, x.begin(), x.end(), y.begin(),
+                  y.begin(), [=](T2 xi, T3 yi) { return a * xi + yi; });
+  }
 
-Clang, GCC and other compilers all provide their own set of language extensions. These extensions
-have often been developed without particular consideration for their interaction with the library,
-and as such, libc++ does not go out of its way to support them. The library may support specific
-compiler extensions which would then be documented explicitly, but the basic expectation should be
-that no special support is provided for arbitrary compiler extensions.
+The execution policy ``std::execution::par_unseq`` states that the algorithm's
+execution may be parallelized, vectorized, and migrated across threads. This is
+the only execution mode that is safe to offload to GPUs, and for all other
+execution modes the algorithms will execute on the CPU.
+Special attention must be paid to the lambda captures when enabling GPU
+offloading. If the lambda captures by reference, the user must manually map the
+variables to the device. If capturing by reference, the above example could
+be implemented in the following way.
+
+.. code-block:: cpp
+
+  template <typename T1, typename T2, typename T3>
+  void axpy(const T1 a, const std::vector<T2> &x, std::vector<T3> &y) {
+  #pragma omp target data map(to : a)
+    std::transform(std::execution::par_unseq, x.begin(), x.end(), y.begin(),
+                  y.begin(), [&](T2 xi, T3 yi) { return a * xi + yi; });
+  }
+
+However, if unified shared memory, USM, is enabled, no additional data mapping
+is necessary when capturing y reference.
+
+Compiling functions for GPUs with OpenMP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The C++ standard defines that all accesses to memory are inside a single address
+space. However, discrete GPU systems have distinct address spaces. A single
+address space can be emulated if your system supports unified shared memory.
+However, many discrete GPU systems do not, and in those cases it is important to
+pass device function pointers to the parallel algorithms. Below is an example of
+how the OpenMP ``declare target`` directive with the ``indirect`` clause can be
+used to mark that a function should be compiled for both host and device.
+
+.. code-block:: cpp
+
+  // This function computes the squared difference of two floating points
+  float squared(float a, float b) { return a * a - 2.0f * a * b + b * b; };
+
+  // Declare that the function must be compiled for both host and device
+  #pragma omp declare target indirect to(squared)
+
+  int main() {
+    std::vector<float> a(100, 1.0);
+    std::vector<float> b(100, 1.25);
+
+    // Pass the host function pointer to the parallel algorithm and let OpenMP
+    // translate it to the device function pointer internally
+    float sum =
+        std::transform_reduce(std::execution::par_unseq, a.begin(), a.end(),
+                              b.begin(), 0.0f, std::plus{}, squared);
+
+    // Validate that the result is approximately 6.25
+    assert(std::abs(sum - 6.25f) < 1e-10);
+    return 0;
+  }
+
+Without unified shared memory, the above example will not work if the host
+function pointer ``squared`` is passed to the parallel algorithm.
+
+Important notes about exception handling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+GPU architectures do not support exception handling. If compiling a program
+containing parallel algorithms with current versions of Clang, a program with
+exceptions in offloaded code regions will compile, but the program will
+terminate if an exception is thrown on the device. This does not conform with
+the C++ standard and exception handling on GPUs will hopefully be better
+supported in future releases of LLVM.
 
 Platform specific behavior
 ==========================
@@ -351,67 +490,3 @@ specific locale is imbued, the IO with the underlying stream happens with
 regular ``char`` elements, which are converted to/from wide characters
 according to the locale. Note that this doesn't behave as expected if the
 stream has been set in Unicode mode.
-
-
-Third-party Integrations
-========================
-
-Libc++ provides integration with a few third-party tools.
-
-Debugging libc++ internals in LLDB
-----------------------------------
-
-LLDB hides the implementation details of libc++ by default.
-
-E.g., when setting a breakpoint in a comparator passed to ``std::sort``, the
-backtrace will read as
-
-.. code-block::
-
-  (lldb) thread backtrace
-  * thread #1, name = 'a.out', stop reason = breakpoint 3.1
-    * frame #0: 0x000055555555520e a.out`my_comparator(a=1, b=8) at test-std-sort.cpp:6:3
-      frame #7: 0x0000555555555615 a.out`void std::__1::sort[abi:ne200000]<std::__1::__wrap_iter<int*>, bool (*)(int, int)>(__first=(item = 8), __last=(item = 0), __comp=(a.out`my_less(int, int) at test-std-sort.cpp:5)) at sort.h:1003:3
-      frame #8: 0x000055555555531a a.out`main at test-std-sort.cpp:24:3
-
-Note how the caller of ``my_comparator`` is shown as ``std::sort``. Looking at
-the frame numbers, we can see that frames #1 until #6 were hidden. Those frames
-represent internal implementation details such as ``__sort4`` and similar
-utility functions.
-
-To also show those implementation details, use ``thread backtrace -u``.
-Alternatively, to disable those compact backtraces, use ``frame recognizer list``
-and ``frame recognizer disable`` on the "libc++ frame recognizer".
-
-Futhermore, stepping into libc++ functions is disabled by default. This is controlled via the
-setting ``target.process.thread.step-avoid-regexp`` which defaults to ``^std::`` and can be
-disabled using ``settings set target.process.thread.step-avoid-regexp ""``.
-
-GDB Pretty printers for libc++
-------------------------------
-
-GDB does not support pretty-printing of libc++ symbols by default. However, libc++ does
-provide pretty-printers itself. Those can be used as:
-
-.. code-block:: bash
-
-  $ gdb -ex "source <libcxx>/utils/gdb/libcxx/printers.py" \
-        -ex "python register_libcxx_printer_loader()" \
-        <args>
-
-
-.. _include-what-you-use:
-
-include-what-you-use (IWYU)
----------------------------
-
-libc++ provides an IWYU `mapping file <https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUMappings.md>`_,
-which drastically improves the accuracy of the tool when using libc++. To use the mapping file with
-IWYU, you should run the tool like so:
-
-.. code-block:: bash
-
-  $ include-what-you-use -Xiwyu --mapping_file=/path/to/libcxx/include/libcxx.imp file.cpp
-
-If you would prefer to not use that flag, then you can replace ``/path/to/include-what-you-use/share/libcxx.imp``
-file with the libc++-provided ``libcxx.imp`` file.
diff --git a/libcxx/docs/VendorDocumentation.rst b/libcxx/docs/VendorDocumentation.rst
index 959a28607d75dd..5727005e24fbde 100644
--- a/libcxx/docs/VendorDocumentation.rst
+++ b/libcxx/docs/VendorDocumentation.rst
@@ -1,17 +1,19 @@
-.. _VendorDocumentation:
+.. _BuildingLibcxx:
 
-====================
-Vendor Documentation
-====================
+===============
+Building libc++
+===============
 
 .. contents::
   :local:
 
+.. _build instructions:
+
 The instructions on this page are aimed at vendors who ship libc++ as part of an
 operating system distribution, a toolchain or similar shipping vehicles. If you
 are a user merely trying to use libc++ in your program, you most likely want to
-refer to your vendor's documentation, or to the general user documentation
-:ref:`here <user-documentation>`.
+refer to your vendor's documentation, or to the general documentation for using
+libc++ :ref:`here <using-libcxx>`.
 
 .. warning::
   If your operating system already provides libc++, it is important to be careful
@@ -40,37 +42,21 @@ with the following CMake invocation:
   $ ninja -C build install-cxx install-cxxabi install-unwind                                # Install
 
 .. note::
-  See :ref:`Vendor Configuration Options` below for more configuration options.
+  See :ref:`CMake Options` below for more configuration options.
 
 After building the various ``install-XXX`` targets, shared libraries for libc++, libc++abi and
 libunwind should now be present in ``<CMAKE_INSTALL_PREFIX>/lib``, and headers in
-``<CMAKE_INSTALL_PREFIX>/include/c++/v1``. See the instructions below for information on how
-to use this libc++ over the default one.
+``<CMAKE_INSTALL_PREFIX>/include/c++/v1``. See :ref:`using an alternate libc++ installation
+<alternate libcxx>` for information on how to use this libc++ over the default one.
 
 In the default configuration, the runtimes will be built using the compiler available by default
 on your system. Of course, you can change what compiler is being used with the usual CMake
 variables. If you wish to build the runtimes from a just-built Clang, the bootstrapping build
 explained below makes this task easy.
 
-Using the just-built libc++
----------------------------
-
-Most compilers provide a way to disable the default behavior for finding the standard library and
-to override it with custom paths. With Clang, this can be done with:
-
-.. code-block:: bash
-
-  $ clang++ -nostdinc++ -isystem <install>/include/c++/v1 \
-            -nostdlib++ -L <install>/lib -lc++            \
-            -Wl,-rpath,<install>/lib                      \
-            test.cpp
 
-The option ``-Wl,-rpath,<install>/lib`` adds a runtime library search path, which causes the system's
-dynamic linker to look for libc++ in ``<install>/lib`` whenever the program is loaded.
-
-
-The Bootstrapping build
-=======================
+Bootstrapping build
+===================
 
 It is possible to build Clang and then build the runtimes using that just-built compiler in a
 single CMake invocation. This is usually the correct way to build the runtimes when putting together
@@ -89,29 +75,123 @@ CMake invocation at ``<monorepo>/llvm``:
   $ ninja -C build install-runtimes                                                        # Install
 
 .. note::
-  - This type of build is also commonly called a "Runtimes build", but we would like to move
-    away from that terminology, which is too confusing.
+  This type of build is also commonly called a "Runtimes build", but we would like to move
+  away from that terminology, which is too confusing.
 
-  - Adding the `--fresh` flag to the top-level cmake invocation in a bootstrapping build *will not*
-    freshen the cmake cache of any of the enabled runtimes.
+.. warning::
+  Adding the `--fresh` flag to the top-level cmake invocation in a bootstrapping build *will not*
+  freshen the cmake cache of any of the enabled runtimes.
 
+Support for Windows
+===================
 
-.. _Vendor Configuration Options:
+libcxx supports being built with clang-cl, but not with MSVC's cl.exe, as
+cl doesn't support the ``#include_next`` extension. Furthermore, VS 2017 or
+newer (19.14) is required.
 
-Vendor Configuration Options
-============================
+libcxx also supports being built with clang targeting MinGW environments.
 
-This section documents configuration options that can be used by vendors when building the library.
-These options provide a great deal of flexibility to customize libc++, such as selecting the ABI in
-use, whether some features are provided, etc.
+CMake + Visual Studio
+---------------------
 
-.. warning::
-  Many of these CMake options are tied to configuration macros with a corresponding name in the source
-  code. However, these configuration macros are not intended to be customized by users directly, since
-  many of them require the library to be built with a matching configuration. If you don't build libc++
-  yourself, you should not use the options documented here.
+Building with Visual Studio currently does not permit running tests. However,
+it is the simplest way to build.
+
+.. code-block:: batch
+
+  > cmake -G "Visual Studio 16 2019" -S runtimes -B build ^
+          -T "ClangCL"                                    ^
+          -DLLVM_ENABLE_RUNTIMES=libcxx                   ^
+          -DLIBCXX_ENABLE_SHARED=YES                      ^
+          -DLIBCXX_ENABLE_STATIC=NO
+  > cmake --build build
+
+CMake + ninja (MSVC)
+--------------------
+
+Building with ninja is required for development to enable tests.
+A couple of tests require Bash to be available, and a couple dozens
+of tests require other posix tools (cp, grep and similar - LLVM's tests
+require the same). Without those tools the vast majority of tests
+can still be ran successfully.
+
+If Git for Windows is available, that can be used to provide the bash
+shell by adding the right bin directory to the path, e.g.
+``set PATH=%PATH%;C:\Program Files\Git\usr\bin``.
+
+Alternatively, one can also choose to run the whole build in a MSYS2
+shell. That can be set up e.g. by starting a Visual Studio Tools Command
+Prompt (for getting the environment variables pointing to the headers and
+import libraries), and making sure that clang-cl is available in the
+path. From there, launch an MSYS2 shell via e.g.
+``C:\msys64\msys2_shell.cmd -full-path -mingw64`` (preserving the earlier
+environment, allowing the MSVC headers/libraries and clang-cl to be found).
+
+In either case, then run:
+
+.. code-block:: batch
+
+  > cmake -G Ninja -S runtimes -B build                                               ^
+          -DCMAKE_C_COMPILER=clang-cl                                                 ^
+          -DCMAKE_CXX_COMPILER=clang-cl                                               ^
+          -DLLVM_ENABLE_RUNTIMES=libcxx
+  > ninja -C build cxx
+  > ninja -C build check-cxx
+
+If you are running in an MSYS2 shell and you have installed the
+MSYS2-provided clang package (which defaults to a non-MSVC target), you
+should add e.g. ``-DCMAKE_CXX_COMPILER_TARGET=x86_64-windows-msvc`` (replacing
+``x86_64`` with the architecture you're targeting) to the ``cmake`` command
+line above. This will instruct ``check-cxx`` to use the right target triple
+when invoking ``clang++``.
+
+CMake + ninja (MinGW)
+---------------------
+
+libcxx can also be built in MinGW environments, e.g. with the MinGW
+compilers in MSYS2. This requires clang to be available (installed with
+e.g. the ``mingw-w64-x86_64-clang`` package), together with CMake and ninja.
+
+.. code-block:: bash
+
+  > cmake -G Ninja -S runtimes -B build                                               \
+          -DCMAKE_C_COMPILER=clang                                                    \
+          -DCMAKE_CXX_COMPILER=clang++                                                \
+          -DLLVM_ENABLE_LLD=ON                                                        \
+          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"                                   \
+          -DLIBCXXABI_ENABLE_SHARED=OFF                                               \
+          -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON
+  > ninja -C build cxx
+  > ninja -C build check-cxx
+
+.. _`libc++abi`: http://libcxxabi.llvm.org/
+
+
+.. _CMake Options:
+
+CMake Options
+=============
 
-General purpose options
+Here are some of the CMake variables that are used often, along with a
+brief explanation and LLVM-specific notes. For full documentation, check the
+CMake docs or execute ``cmake --help-variable VARIABLE_NAME``.
+
+**CMAKE_BUILD_TYPE**:STRING
+  Sets the build type for ``make`` based generators. Possible values are
+  Release, Debug, RelWithDebInfo and MinSizeRel. On systems like Visual Studio
+  the user sets the build type with the IDE settings.
+
+**CMAKE_INSTALL_PREFIX**:PATH
+  Path where LLVM will be installed if "make install" is invoked or the
+  "INSTALL" target is built.
+
+**CMAKE_CXX_COMPILER**:STRING
+  The C++ compiler to use when building and testing libc++.
+
+
+.. _libcxx-specific options:
+
+libc++ specific options
 -----------------------
 
 .. option:: LIBCXX_INSTALL_LIBRARY:BOOL
@@ -213,13 +293,11 @@ General purpose options
 
   Output name for the shared libc++ runtime library.
 
-.. option:: {LIBCXX,LIBCXXABI,LIBUNWIND}_ADDITIONAL_COMPILE_FLAGS:STRING
+.. option:: LIBCXX_ADDITIONAL_COMPILE_FLAGS:STRING
 
   **Default**: ``""``
 
-  Additional compile flags to use when building the runtimes. This should be a CMake ``;``-delimited list of individual
-  compiler options to use. For options that must be passed as-is to the compiler without deduplication (e.g.
-  ``-Xclang -foo`` option groups), consider using ``SHELL:`` as `documented here <https://cmake.org/cmake/help/latest/command/add_compile_options.html#option-de-duplication>`_.
+  Additional Compile only flags which can be provided in cache.
 
 .. option:: LIBCXX_ADDITIONAL_LIBRARIES:STRING
 
@@ -227,6 +305,65 @@ General purpose options
 
   Additional libraries libc++ is linked to which can be provided in cache.
 
+
+.. _ABI Library Specific Options:
+
+ABI Library Specific Options
+----------------------------
+
+.. option:: LIBCXX_CXX_ABI:STRING
+
+  **Values**: ``none``, ``libcxxabi``, ``system-libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``, ``vcruntime``.
+
+  Select the ABI library to build libc++ against.
+
+.. option:: LIBCXX_CXX_ABI_INCLUDE_PATHS:PATHS
+
+  Provide additional search paths for the ABI library headers.
+
+.. option:: LIBCXX_CXX_ABI_LIBRARY_PATH:PATH
+
+  Provide the path to the ABI library that libc++ should link against. This is only
+  useful when linking against an out-of-tree ABI library.
+
+.. option:: LIBCXX_ENABLE_STATIC_ABI_LIBRARY:BOOL
+
+  **Default**: ``OFF``
+
+  If this option is enabled, libc++ will try and link the selected ABI library
+  statically.
+
+.. option:: LIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL
+
+  **Default**: ``ON`` by default on UNIX platforms other than Apple unless
+  'LIBCXX_ENABLE_STATIC_ABI_LIBRARY' is ON. Otherwise the default value is ``OFF``.
+
+  This option generate and installs a linker script as ``libc++.so`` which
+  links the correct ABI library.
+
+.. option:: LIBCXXABI_USE_LLVM_UNWINDER:BOOL
+
+  **Default**: ``ON``
+
+  Build and use the LLVM unwinder. Note: This option can only be used when
+  libc++abi is the C++ ABI library used.
+
+.. option:: LIBCXXABI_ADDITIONAL_COMPILE_FLAGS:STRING
+
+  **Default**: ``""``
+
+  Additional Compile only flags which can be provided in cache.
+
+.. option:: LIBCXXABI_ADDITIONAL_LIBRARIES:STRING
+
+  **Default**: ``""``
+
+  Additional libraries libc++abi is linked to which can be provided in cache.
+
+
+libc++ Feature Options
+----------------------
+
 .. option:: LIBCXX_ENABLE_EXCEPTIONS:BOOL
 
   **Default**: ``ON``
@@ -244,8 +381,7 @@ General purpose options
 
   **Default**: ``ON`` (or value of ``LLVM_INCLUDE_TESTS``)
 
-  Build the libc++ test suite, which includes various types of tests like conformance
-  tests, vendor-specific tests and benchmarks.
+  Build the libc++ tests.
 
 .. option:: LIBCXX_INCLUDE_BENCHMARKS:BOOL
 
@@ -254,6 +390,31 @@ General purpose options
   Build the libc++ benchmark tests and the Google Benchmark library needed
   to support them.
 
+.. option:: LIBCXX_BENCHMARK_TEST_ARGS:STRING
+
+  **Default**: ``--benchmark_min_time=0.01``
+
+  A semicolon list of arguments to pass when running the libc++ benchmarks using the
+  ``check-cxx-benchmarks`` rule. By default we run the benchmarks for a very short amount of time,
+  since the primary use of ``check-cxx-benchmarks`` is to get test and sanitizer coverage, not to
+  get accurate measurements.
+
+.. option:: LIBCXX_BENCHMARK_NATIVE_STDLIB:STRING
+
+  **Default**:: ``""``
+
+  **Values**:: ``libc++``, ``libstdc++``
+
+  Build the libc++ benchmark tests and Google Benchmark library against the
+  specified standard library on the platform. On Linux this can be used to
+  compare libc++ to libstdc++ by building the benchmark tests against both
+  standard libraries.
+
+.. option:: LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN:STRING
+
+  Use the specified GCC toolchain and standard library when building the native
+  stdlib benchmark tests.
+
 .. option:: LIBCXX_ASSERTION_HANDLER_FILE:PATH
 
   **Default**:: ``"${CMAKE_CURRENT_SOURCE_DIR}/vendor/llvm/default_assertion_handler.in"``
@@ -261,11 +422,22 @@ General purpose options
   Specify the path to a header that contains a custom implementation of the
   assertion handler that gets invoked when a hardening assertion fails. If
   provided, this header will be included by the library, replacing the
-  default assertion handler. If this is specified as a relative path, it
-  is assumed to be relative to ``<monorepo>/libcxx``.
+  default assertion handler.
+
+.. option:: LIBCXX_PSTL_BACKEND:STRING
+
+  **Default**:: ``"serial"``
+
+  **Values**:: ``serial``, ``std-thread``, ``libdispatch``, ``openmp``
+
+  Select the desired backend for C++ parallel algorithms. All four options can
+  target multi-core CPU architectures, and ``openmp`` can additionally target
+  GPU architectures. The ``openmp`` backend requires OpenMP version 4.5 or
+  later.
 
-ABI Specific Options
---------------------
+
+libc++ ABI Feature Options
+--------------------------
 
 The following options allow building libc++ for a different ABI version.
 
@@ -291,7 +463,7 @@ The following options allow building libc++ for a different ABI version.
   with other libc++ versions.
 
   .. warning::
-    When providing a custom namespace, it's the vendor's responsibility to ensure the name won't cause
+    When providing a custom namespace, it's the user's responsibility to ensure the name won't cause
     conflicts with other names defined by libc++, both now and in the future. In particular, inline
     namespaces of the form ``__[0-9]+`` could cause conflicts with future versions of the library,
     and so should be avoided.
@@ -303,48 +475,8 @@ The following options allow building libc++ for a different ABI version.
   A semicolon-separated list of ABI macros to persist in the site config header.
   See ``include/__config`` for the list of ABI macros.
 
-.. option:: LIBCXX_CXX_ABI:STRING
-
-  **Values**: ``none``, ``libcxxabi``, ``system-libcxxabi``, ``libcxxrt``, ``libstdc++``, ``libsupc++``, ``vcruntime``.
-
-  Select the ABI library to build libc++ against.
-
-.. option:: LIBCXX_CXX_ABI_INCLUDE_PATHS:PATHS
-
-  Provide additional search paths for the ABI library headers.
-
-.. option:: LIBCXX_CXX_ABI_LIBRARY_PATH:PATH
-
-  Provide the path to the ABI library that libc++ should link against. This is only
-  useful when linking against an out-of-tree ABI library.
-
-.. option:: LIBCXX_ENABLE_STATIC_ABI_LIBRARY:BOOL
-
-  **Default**: ``OFF``
-
-  If this option is enabled, libc++ will try and link the selected ABI library
-  statically.
-
-.. option:: LIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL
-
-  **Default**: ``ON`` by default on UNIX platforms other than Apple unless
-  'LIBCXX_ENABLE_STATIC_ABI_LIBRARY' is ON. Otherwise the default value is ``OFF``.
-
-  This option generate and installs a linker script as ``libc++.so`` which
-  links the correct ABI library.
-
-.. option:: LIBCXXABI_USE_LLVM_UNWINDER:BOOL
-
-  **Default**: ``ON``
-
-  Build and use the LLVM unwinder. Note: This option can only be used when
-  libc++abi is the C++ ABI library used.
 
-.. option:: LIBCXXABI_ADDITIONAL_LIBRARIES:STRING
-
-  **Default**: ``""``
-
-  Additional libraries libc++abi is linked to which can be provided in cache.
+.. _LLVM-specific variables:
 
 LLVM-specific options
 ---------------------
@@ -367,91 +499,6 @@ LLVM-specific options
   others.
 
 
-Support for Windows
-===================
-
-Libc++ supports being built with clang-cl, but not with MSVC's cl.exe, as
-cl doesn't support the ``#include_next`` extension. Furthermore, VS 2017 or
-newer (19.14) is required.
-
-Libc++ also supports being built with clang targeting MinGW environments.
-
-CMake + Visual Studio
----------------------
-
-Building with Visual Studio currently does not permit running tests. However,
-it is the simplest way to build.
-
-.. code-block:: batch
-
-  > cmake -G "Visual Studio 16 2019" -S runtimes -B build ^
-          -T "ClangCL"                                    ^
-          -DLLVM_ENABLE_RUNTIMES=libcxx                   ^
-          -DLIBCXX_ENABLE_SHARED=YES                      ^
-          -DLIBCXX_ENABLE_STATIC=NO
-  > cmake --build build
-
-CMake + ninja (MSVC)
---------------------
-
-Building with ninja is required for development to enable tests.
-A couple of tests require Bash to be available, and a couple dozens
-of tests require other posix tools (cp, grep and similar - LLVM's tests
-require the same). Without those tools the vast majority of tests
-can still be ran successfully.
-
-If Git for Windows is available, that can be used to provide the bash
-shell by adding the right bin directory to the path, e.g.
-``set PATH=%PATH%;C:\Program Files\Git\usr\bin``.
-
-Alternatively, one can also choose to run the whole build in a MSYS2
-shell. That can be set up e.g. by starting a Visual Studio Tools Command
-Prompt (for getting the environment variables pointing to the headers and
-import libraries), and making sure that clang-cl is available in the
-path. From there, launch an MSYS2 shell via e.g.
-``C:\msys64\msys2_shell.cmd -full-path -mingw64`` (preserving the earlier
-environment, allowing the MSVC headers/libraries and clang-cl to be found).
-
-In either case, then run:
-
-.. code-block:: batch
-
-  > cmake -G Ninja -S runtimes -B build                                               ^
-          -DCMAKE_C_COMPILER=clang-cl                                                 ^
-          -DCMAKE_CXX_COMPILER=clang-cl                                               ^
-          -DLLVM_ENABLE_RUNTIMES=libcxx
-  > ninja -C build cxx
-  > ninja -C build check-cxx
-
-If you are running in an MSYS2 shell and you have installed the
-MSYS2-provided clang package (which defaults to a non-MSVC target), you
-should add e.g. ``-DCMAKE_CXX_COMPILER_TARGET=x86_64-windows-msvc`` (replacing
-``x86_64`` with the architecture you're targeting) to the ``cmake`` command
-line above. This will instruct ``check-cxx`` to use the right target triple
-when invoking ``clang++``.
-
-CMake + ninja (MinGW)
----------------------
-
-libcxx can also be built in MinGW environments, e.g. with the MinGW
-compilers in MSYS2. This requires clang to be available (installed with
-e.g. the ``mingw-w64-x86_64-clang`` package), together with CMake and ninja.
-
-.. code-block:: bash
-
-  > cmake -G Ninja -S runtimes -B build                                               \
-          -DCMAKE_C_COMPILER=clang                                                    \
-          -DCMAKE_CXX_COMPILER=clang++                                                \
-          -DLLVM_ENABLE_LLD=ON                                                        \
-          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"                                   \
-          -DLIBCXXABI_ENABLE_SHARED=OFF                                               \
-          -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON
-  > ninja -C build cxx
-  > ninja -C build check-cxx
-
-.. _`libc++abi`: http://libcxxabi.llvm.org/
-
-
 .. _assertion-handler:
 
 Overriding the default assertion handler
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 1610d1ee848a5f..9bf39b2a255395 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -600,6 +600,7 @@ set(files
   __pstl/backend_fwd.h
   __pstl/backends/default.h
   __pstl/backends/libdispatch.h
+  __pstl/backends/openmp.h
   __pstl/backends/serial.h
   __pstl/backends/std_thread.h
   __pstl/cpu_algos/any_of.h
diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index fc01aaf2d8746e..fa1c99264514c0 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -38,6 +38,7 @@
 #cmakedefine _LIBCPP_PSTL_BACKEND_SERIAL
 #cmakedefine _LIBCPP_PSTL_BACKEND_STD_THREAD
 #cmakedefine _LIBCPP_PSTL_BACKEND_LIBDISPATCH
+#cmakedefine _LIBCPP_PSTL_BACKEND_OPENMP
 
 // Hardening.
 #cmakedefine _LIBCPP_HARDENING_MODE_DEFAULT @_LIBCPP_HARDENING_MODE_DEFAULT@
diff --git a/libcxx/include/__pstl/backend.h b/libcxx/include/__pstl/backend.h
index 5980b0708cd340..cb47501c19fc88 100644
--- a/libcxx/include/__pstl/backend.h
+++ b/libcxx/include/__pstl/backend.h
@@ -19,20 +19,20 @@
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
-#if _LIBCPP_STD_VER >= 17
-
-#  if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
-#    include <__pstl/backends/default.h>
-#    include <__pstl/backends/serial.h>
-#  elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
-#    include <__pstl/backends/default.h>
-#    include <__pstl/backends/std_thread.h>
-#  elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
-#    include <__pstl/backends/default.h>
-#    include <__pstl/backends/libdispatch.h>
-#  endif
-
-#endif // _LIBCPP_STD_VER >= 17
+#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
+#  include <__pstl/backends/default.h>
+#  include <__pstl/backends/serial.h>
+#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
+#  include <__pstl/backends/default.h>
+#  include <__pstl/backends/std_thread.h>
+#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
+#  include <__pstl/backends/default.h>
+#  include <__pstl/backends/libdispatch.h>
+#elif defined(_LIBCPP_PSTL_BACKEND_OPENMP)
+#  include <__pstl/backends/default.h>
+#  include <__pstl/backends/openmp.h>
+#  include <__pstl/backends/std_thread.h>
+#endif
 
 _LIBCPP_POP_MACROS
 
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index 2132e8dbceb3ad..ed08d45206a8b8 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -39,8 +39,6 @@ _LIBCPP_PUSH_MACROS
 // the user.
 //
 
-#if _LIBCPP_STD_VER >= 17
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __pstl {
 
@@ -49,21 +47,25 @@ struct __backend_configuration;
 
 struct __default_backend_tag;
 struct __libdispatch_backend_tag;
+struct __openmp_backend_tag;
 struct __serial_backend_tag;
 struct __std_thread_backend_tag;
 
-#  if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
+#if defined(_LIBCPP_PSTL_BACKEND_SERIAL)
 using __current_configuration = __backend_configuration<__serial_backend_tag, __default_backend_tag>;
-#  elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
+#elif defined(_LIBCPP_PSTL_BACKEND_STD_THREAD)
 using __current_configuration = __backend_configuration<__std_thread_backend_tag, __default_backend_tag>;
-#  elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
+#elif defined(_LIBCPP_PSTL_BACKEND_LIBDISPATCH)
 using __current_configuration = __backend_configuration<__libdispatch_backend_tag, __default_backend_tag>;
-#  else
+#elif defined(_LIBCPP_PSTL_BACKEND_OPENMP)
+using __current_configuration =
+    __backend_configuration<__openmp_backend_tag, __std_thread_backend_tag, __default_backend_tag>;
+#else
 
 // ...New vendors can add parallel backends here...
 
-#    error "Invalid PSTL backend configuration"
-#  endif
+#  error "Invalid PSTL backend configuration"
+#endif
 
 template <class _Backend, class _ExecutionPolicy>
 struct __find_if;
@@ -298,8 +300,6 @@ struct __reduce;
 } // namespace __pstl
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP_STD_VER >= 17
-
 _LIBCPP_POP_MACROS
 
 #endif // _LIBCPP___PSTL_BACKEND_FWD_H
diff --git a/libcxx/include/__pstl/backends/openmp.h b/libcxx/include/__pstl/backends/openmp.h
new file mode 100644
index 00000000000000..158be91fb9ca99
--- /dev/null
+++ b/libcxx/include/__pstl/backends/openmp.h
@@ -0,0 +1,511 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_BACKENDS_OPENMP_H
+#define _LIBCPP___PSTL_BACKENDS_OPENMP_H
+
+// Combined OpenMP CPU and GPU Backend
+// ===================================
+// Contrary to the CPU backends found in ./cpu_backends/, the OpenMP backend can
+// target both CPUs and GPUs. The OpenMP standard defines that when offloading
+// code to an accelerator, the compiler must generate a fallback code for
+// execution on the host. Thereby, the backend works as a CPU backend if no
+// targeted accelerator is available at execution time. The target regions can
+// also be compiled directly for a CPU architecture, for instance by adding the
+// command-line option `-fopenmp-targets=x86_64-pc-linux-gnu` in Clang.
+//
+// When is an Algorithm Offloaded?
+// -------------------------------
+// Only parallel algorithms with the parallel unsequenced execution policy are
+// offloaded to the device. We cannot offload parallel algorithms with a
+// parallel execution policy to GPUs because invocations executing in the same
+// thread "are indeterminately sequenced with respect to each other" which we
+// cannot guarantee on a GPU.
+//
+// The standard draft states that "the semantics [...] allow the implementation
+// to fall back to sequential execution if the system cannot parallelize an
+// algorithm invocation". If it is not deemed safe to offload the parallel
+// algorithm to the device, we first fall back to a parallel unsequenced
+// implementation from ./cpu_backends. The CPU implementation may then fall back
+// to sequential execution. In that way we strive to achieve the best possible
+// performance.
+//
+// Further, "it is the caller's responsibility to ensure that the invocation
+// does not introduce data races or deadlocks."
+//
+// Implicit Assumptions
+// --------------------
+// If the user provides a function pointer as an argument to a parallel
+// algorithm, it is assumed that it is the device pointer as there is currently
+// no way to check whether a host or device pointer was passed.
+//
+// Mapping Clauses
+// ---------------
+// In some of the parallel algorithms, the user is allowed to provide the same
+// iterator as input and output. The order of the maps matters because OpenMP
+// keeps a reference counter of which variables have been mapped to the device.
+// Thereby, a varible is only copied to the device if its reference counter is
+// incremented from zero, and it is only copied back to the host when the
+// reference counter is decremented to zero again.
+// This allows nesting mapped regions, for instance in recursive functions,
+// without enforcing a lot of unnecessary data movement.
+// Therefore, `pragma omp target data map(to:...)` must be used before
+// `pragma omp target data map(alloc:...)`. Conversely, the maps with map
+// modifier `release` must be placed before the maps with map modifier `from`
+// when transferring the result from the device to the host.
+//
+// Example: Assume `a` and `b` are pointers to the same array.
+// ``` C++
+// #pragma omp target enter data map(alloc:a[0:n])
+// // The reference counter is incremented from 0 to 1. a is not copied to the
+// // device because of the `alloc` map modifier.
+// #pragma omp target enter data map(to:b[0:n])
+// // The reference counter is incremented from 1 to 2. b is not copied because
+// // the reference counter is positive. Therefore b, and a, are uninitialized
+// // on the device.
+// ```
+//
+// Exceptions
+// ----------
+// Currently, GPU architectures do not handle exceptions. OpenMP target regions
+// are allowed to contain try/catch statements and throw expressions in Clang,
+// but if a throw expression is reached, it will terminate the program. That
+// does not conform to the C++ standard.
+//
+// [This document](https://eel.is/c++draft/algorithms.parallel) has been used as
+// reference for these considerations.
+
+#include <__algorithm/unwrap_iter.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/wrap_iter.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/dispatch.h>
+#include <__type_traits/desugars_to.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/is_trivially_copyable.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/empty.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <execution>
+#include <optional>
+
+#if !defined(_OPENMP)
+#  error "Trying to use the OpenMP PSTL backend, but OpenMP is not enabled. Did you compile with -fopenmp?"
+#elif (defined(_OPENMP) && _OPENMP < 201511)
+#  error                                                                                                               \
+      "OpenMP target offloading has been supported since OpenMP version 4.5 (201511). Please use a more recent version of OpenMP."
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+// The following functions can be used to map contiguous array sections to and from the device.
+// For now, they are simple overlays of the OpenMP pragmas, but they should be updated when adding
+// support for other iterator types.
+template <class _Iterator, class _DifferenceType>
+_LIBCPP_HIDE_FROM_ABI void
+__omp_map_to([[maybe_unused]] const _Iterator __p, [[maybe_unused]] const _DifferenceType __len) noexcept {
+  static_assert(__libcpp_is_contiguous_iterator<_Iterator>::value);
+#pragma omp target enter data map(to : __p[0 : __len])
+}
+
+template <class _Iterator, class _DifferenceType>
+_LIBCPP_HIDE_FROM_ABI void
+__omp_map_from([[maybe_unused]] const _Iterator __p, [[maybe_unused]] const _DifferenceType __len) noexcept {
+  static_assert(__libcpp_is_contiguous_iterator<_Iterator>::value);
+#pragma omp target exit data map(from : __p[0 : __len])
+}
+
+template <class _Iterator, class _DifferenceType>
+_LIBCPP_HIDE_FROM_ABI void
+__omp_map_alloc([[maybe_unused]] const _Iterator __p, [[maybe_unused]] const _DifferenceType __len) noexcept {
+  static_assert(__libcpp_is_contiguous_iterator<_Iterator>::value);
+#pragma omp target enter data map(alloc : __p[0 : __len])
+}
+
+template <class _Iterator, class _DifferenceType>
+_LIBCPP_HIDE_FROM_ABI void
+__omp_map_release([[maybe_unused]] const _Iterator __p, [[maybe_unused]] const _DifferenceType __len) noexcept {
+  static_assert(__libcpp_is_contiguous_iterator<_Iterator>::value);
+#pragma omp target exit data map(release : __p[0 : __len])
+}
+
+//
+// fill
+//
+template <class _Tp, class _DifferenceType, class _Up>
+_LIBCPP_HIDE_FROM_ABI _Tp* __omp_fill(_Tp* __out1, _DifferenceType __n, const _Up& __value) noexcept {
+  __pstl::__omp_map_alloc(__out1, __n);
+#pragma omp target teams distribute parallel for
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    *(__out1 + __i) = __value;
+  __pstl::__omp_map_from(__out1, __n);
+  return __out1 + __n;
+}
+
+template <>
+struct __fill<__openmp_backend_tag, execution::parallel_unsequenced_policy> {
+  template <class _Policy, class _ForwardIterator, class _Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
+  operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
+    using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
+    if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator>::value && is_trivially_copyable_v<_ValueType> &&
+                  is_trivially_copyable_v<_Tp>) {
+      __pstl::__omp_fill(std::__unwrap_iter(__first), __last - __first, __value);
+      return __empty{};
+    } else {
+      using _Backends = __backends_after<__current_configuration, __openmp_backend_tag>;
+      using _Fallback = __dispatch<__pstl::__fill, _Backends, __remove_cvref_t<_Policy>>;
+      return _Fallback{}(std::forward<_Policy>(__policy), std::move(__first), std::move(__last), __value);
+    }
+  }
+};
+
+//
+// find_if
+//
+template <class _Tp, class _DifferenceType, class _Predicate>
+_LIBCPP_HIDE_FROM_ABI _Tp* __omp_find_if(_Tp* __first, _DifferenceType __n, _Predicate __pred) noexcept {
+  __pstl::__omp_map_to(__first, __n);
+  _DifferenceType __idx = __n;
+#pragma omp target teams distribute parallel for reduction(min : __idx)
+  for (_DifferenceType __i = 0; __i < __n; ++__i) {
+    if (__pred(*(__first + __i))) {
+      __idx = (__i < __idx) ? __i : __idx;
+    }
+  }
+  __pstl::__omp_map_release(__first, __n);
+  return __first + __idx;
+}
+
+template <>
+struct __find_if<__openmp_backend_tag, execution::parallel_unsequenced_policy> {
+  template <class _Policy, class _ForwardIterator, class _Predicate>
+  _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+  operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) const noexcept {
+    using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
+    if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator>::value && is_trivially_copyable_v<_ValueType>) {
+      return std::__rewrap_iter(__first, __pstl::__omp_find_if(std::__unwrap_iter(__first), __last - __first, __pred));
+    } else {
+      using _Backends = __backends_after<__current_configuration, __openmp_backend_tag>;
+      using _Fallback = __dispatch<__pstl::__find_if, _Backends, __remove_cvref_t<_Policy>>;
+      return _Fallback{}(std::forward<_Policy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
+    }
+  }
+};
+
+//
+// for_each
+//
+template <class _Tp, class _DifferenceType, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Tp* __omp_for_each(_Tp* __inout1, _DifferenceType __n, _Function __f) noexcept {
+  __pstl::__omp_map_to(__inout1, __n);
+#pragma omp target teams distribute parallel for
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    __f(*(__inout1 + __i));
+  __pstl::__omp_map_from(__inout1, __n);
+  return __inout1 + __n;
+}
+
+template <>
+struct __for_each<__openmp_backend_tag, execution::parallel_unsequenced_policy> {
+  template <class _Policy, class _ForwardIterator, class _Functor>
+  _LIBCPP_HIDE_FROM_ABI optional<__empty>
+  operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) const noexcept {
+    using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
+    if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator>::value &&
+                  __libcpp_is_contiguous_iterator<_ForwardIterator>::value && is_trivially_copyable_v<_ValueType>) {
+      __pstl::__omp_for_each(std::__unwrap_iter(__first), __last - __first, std::move(__func));
+      return __empty{};
+    } else {
+      using _Backends = __backends_after<__current_configuration, __openmp_backend_tag>;
+      using _Fallback = __dispatch<__pstl::__for_each, _Backends, __remove_cvref_t<_Policy>>;
+      return _Fallback{}(std::forward<_Policy>(__policy), std::move(__first), std::move(__last), std::move(__func));
+    }
+  }
+};
+
+//
+// transform
+//
+template <class _Tp, class _DifferenceType, class _Up, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Tp* __omp_transform(_Tp* __in1, _DifferenceType __n, _Up* __out1, _Function __f) noexcept {
+  // The order of the following maps matter, as we wish to move the data. If
+  // they were placed in the reverse order, and __in equals __out, then we would
+  // allocate the buffer on the device without copying the data.
+  __pstl::__omp_map_to(__in1, __n);
+  __pstl::__omp_map_alloc(__out1, __n);
+#pragma omp target teams distribute parallel for
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    *(__out1 + __i) = __f(*(__in1 + __i));
+  // The order of the following two maps matters, since the user could legally
+  // overwrite __in The "release" map modifier decreases the reference counter
+  // by one, and "from" only moves the data to the host, when the reference
+  // count is decremented to zero.
+  __pstl::__omp_map_release(__in1, __n);
+  __pstl::__omp_map_from(__out1, __n);
+  return __out1 + __n;
+}
+
+template <>
+struct __transform<__openmp_backend_tag, execution::parallel_unsequenced_policy> {
+  template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation>
+  _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+  operator()(_Policy&& __policy,
+             _ForwardIterator __first,
+             _ForwardIterator __last,
+             _ForwardOutIterator __outit,
+             _UnaryOperation __op) const noexcept {
+    using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
+    if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator>::value &&
+                  __libcpp_is_contiguous_iterator<_ForwardOutIterator>::value && is_trivially_copyable_v<_ValueType>) {
+      return std::__rewrap_iter(
+          __outit,
+          __omp_transform(
+              std::__unwrap_iter(__first), __last - __first, std::__unwrap_iter(__outit), std::move(__op)));
+    } else {
+      using _Backends = __backends_after<__current_configuration, __openmp_backend_tag>;
+      using _Fallback = __dispatch<__pstl::__transform, _Backends, __remove_cvref_t<_Policy>>;
+      return _Fallback{}(
+          std::forward<_Policy>(__policy), std::move(__first), std::move(__last), std::move(__outit), std::move(__op));
+    }
+  }
+};
+
+//
+// transform_binary
+//
+template <class _Tp, class _DifferenceType, class _Up, class _Vp, class _Function>
+_LIBCPP_HIDE_FROM_ABI _Tp*
+__omp_transform(_Tp* __in1, _DifferenceType __n, _Up* __in2, _Vp* __out1, _Function __f) noexcept {
+  // The order of the following maps matter, as we wish to move the data. If
+  // they were placed in the reverse order, and __out equals __in1 or __in2,
+  // then we would allocate one of the buffer on the device without copying the
+  // data.
+  __pstl::__omp_map_to(__in1, __n);
+  __pstl::__omp_map_to(__in2, __n);
+  __pstl::__omp_map_alloc(__out1, __n);
+#pragma omp target teams distribute parallel for
+  for (_DifferenceType __i = 0; __i < __n; ++__i)
+    *(__out1 + __i) = __f(*(__in1 + __i), *(__in2 + __i));
+  // The order of the following three maps matters, since the user could legally
+  // overwrite either of the inputs if __out equals __in1 or __in2. The
+  // "release" map modifier decreases the reference counter by one, and "from"
+  // only moves the data from the device, when the reference count is
+  // decremented to zero.
+  __pstl::__omp_map_release(__in1, __n);
+  __pstl::__omp_map_release(__in2, __n);
+  __pstl::__omp_map_from(__out1, __n);
+  return __out1 + __n;
+}
+
+template <>
+struct __transform_binary<__openmp_backend_tag, execution::parallel_unsequenced_policy> {
+  template <class _Policy,
+            class _ForwardIterator1,
+            class _ForwardIterator2,
+            class _ForwardOutIterator,
+            class _BinaryOperation>
+  _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
+  operator()(_Policy&& __policy,
+             _ForwardIterator1 __first1,
+             _ForwardIterator1 __last1,
+             _ForwardIterator2 __first2,
+             _ForwardOutIterator __outit,
+             _BinaryOperation __op) const noexcept {
+    using _ValueType1 = typename iterator_traits<_ForwardIterator1>::value_type;
+    using _ValueType2 = typename iterator_traits<_ForwardIterator2>::value_type;
+    if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator1>::value &&
+                  __libcpp_is_contiguous_iterator<_ForwardIterator2>::value &&
+                  __libcpp_is_contiguous_iterator<_ForwardOutIterator>::value && is_trivially_copyable_v<_ValueType1> &&
+                  is_trivially_copyable_v<_ValueType2>) {
+      return std::__rewrap_iter(
+          __outit,
+          __pstl::__omp_transform(
+              std::__unwrap_iter(__first1),
+              __last1 - __first1,
+              std::__unwrap_iter(__first2),
+              std::__unwrap_iter(__outit),
+              std::move(__op)));
+    } else {
+      using _Backends = __backends_after<__current_configuration, __openmp_backend_tag>;
+      using _Fallback = __dispatch<__pstl::__transform_binary, _Backends, __remove_cvref_t<_Policy>>;
+      return _Fallback{}(
+          std::forward<_Policy>(__policy),
+          std::move(__first1),
+          std::move(__last1),
+          std::move(__first2),
+          std::move(__outit),
+          std::move(__op));
+    }
+  }
+};
+
+//
+// transform_reduce
+//
+#define _LIBCPP_PSTL_OMP_SIMD_1_REDUCTION(omp_op, std_op)                                                              \
+  template <class _Iterator,                                                                                           \
+            class _DifferenceType,                                                                                     \
+            typename _Tp,                                                                                              \
+            typename _BinaryOperationType,                                                                             \
+            typename _UnaryOperation>                                                                                  \
+  _LIBCPP_HIDE_FROM_ABI _Tp __omp_transform_reduce(                                                                    \
+      _Iterator __first,                                                                                               \
+      _DifferenceType __n,                                                                                             \
+      _Tp __init,                                                                                                      \
+      std_op<_BinaryOperationType> __reduce,                                                                           \
+      _UnaryOperation __transform) noexcept {                                                                          \
+    __pstl::__omp_map_to(__first, __n);                                                                                \
+_PSTL_PRAGMA(omp target teams distribute parallel for reduction(omp_op:__init))                                        \
+    for (_DifferenceType __i = 0; __i < __n; ++__i)                                                                    \
+      __init = __reduce(__init, __transform(*(__first + __i)));                                                        \
+    __pstl::__omp_map_release(__first, __n);                                                                           \
+    return __init;                                                                                                     \
+  }
+
+#define _LIBCPP_PSTL_OMP_SIMD_2_REDUCTION(omp_op, std_op)                                                              \
+  template <class _Iterator1,                                                                                          \
+            class _Iterator2,                                                                                          \
+            class _DifferenceType,                                                                                     \
+            typename _Tp,                                                                                              \
+            typename _BinaryOperationType,                                                                             \
+            typename _UnaryOperation >                                                                                 \
+  _LIBCPP_HIDE_FROM_ABI _Tp __omp_transform_reduce(                                                                    \
+      _Iterator1 __first1,                                                                                             \
+      _Iterator2 __first2,                                                                                             \
+      _DifferenceType __n,                                                                                             \
+      _Tp __init,                                                                                                      \
+      std_op<_BinaryOperationType> __reduce,                                                                           \
+      _UnaryOperation __transform) noexcept {                                                                          \
+    __pstl::__omp_map_to(__first1, __n);                                                                               \
+    __pstl::__omp_map_to(__first2, __n);                                                                               \
+_PSTL_PRAGMA(omp target teams distribute parallel for reduction(omp_op:__init))                                        \
+    for (_DifferenceType __i = 0; __i < __n; ++__i)                                                                    \
+      __init = __reduce(__init, __transform(*(__first1 + __i), *(__first2 + __i)));                                    \
+    __pstl::__omp_map_release(__first1, __n);                                                                          \
+    __pstl::__omp_map_release(__first2, __n);                                                                          \
+    return __init;                                                                                                     \
+  }
+
+#define _LIBCPP_PSTL_OMP_SIMD_REDUCTION(omp_op, std_op)                                                                \
+  _LIBCPP_PSTL_OMP_SIMD_1_REDUCTION(omp_op, std_op)                                                                    \
+  _LIBCPP_PSTL_OMP_SIMD_2_REDUCTION(omp_op, std_op)
+
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(+, std::plus)
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(-, std::minus)
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(*, std::multiplies)
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(&&, std::logical_and)
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(||, std::logical_or)
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(&, std::bit_and)
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(|, std::bit_or)
+_LIBCPP_PSTL_OMP_SIMD_REDUCTION(^, std::bit_xor)
+
+// Determine whether a reduction is supported by the OpenMP backend
+template <class _T1, class _T2, class _T3>
+struct __is_supported_reduction : std::false_type {};
+
+#define _LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(func)                                                                      \
+  template <class _Tp>                                                                                                 \
+  struct __is_supported_reduction<func<_Tp>, _Tp, _Tp> : true_type {};                                                 \
+  template <class _Tp, class _Up>                                                                                      \
+  struct __is_supported_reduction<func<>, _Tp, _Up> : true_type {};
+
+// __is_trivial_plus_operation already exists
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::plus)
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::minus)
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::multiplies)
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::logical_and)
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::logical_or)
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::bit_and)
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::bit_or)
+_LIBCPP_PSTL_IS_SUPPORTED_REDUCTION(std::bit_xor)
+
+template <>
+struct __transform_reduce<__openmp_backend_tag, execution::parallel_unsequenced_policy> {
+  template <class _Policy, class _ForwardIterator, class _Tp, class _Reduction, class _Transform>
+  _LIBCPP_HIDE_FROM_ABI optional<_Tp>
+  operator()(_Policy&& __policy,
+             _ForwardIterator __first,
+             _ForwardIterator __last,
+             _Tp __init,
+             _Reduction __reduce,
+             _Transform __transform) const noexcept {
+    using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;
+    if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator>::value && is_arithmetic_v<_Tp> &&
+                  __is_supported_reduction<_Reduction, _Tp, _Tp>::value && is_trivially_copyable_v<_ValueType>) {
+      return __pstl::__omp_transform_reduce(
+          std::__unwrap_iter(__first), __last - __first, __init, std::move(__reduce), std::move(__transform));
+    } else {
+      using _Backends = __backends_after<__current_configuration, __openmp_backend_tag>;
+      using _Fallback = __dispatch<__pstl::__transform_reduce, _Backends, __remove_cvref_t<_Policy>>;
+      return _Fallback{}(
+          std::forward<_Policy>(__policy),
+          std::move(__first),
+          std::move(__last),
+          std::move(__init),
+          std::move(__reduce),
+          std::move(__transform));
+    }
+  }
+};
+
+//
+// transform_reduce_binary
+//
+template <>
+struct __transform_reduce_binary<__openmp_backend_tag, execution::parallel_unsequenced_policy> {
+  template <class _Policy,
+            class _ForwardIterator1,
+            class _ForwardIterator2,
+            class _Tp,
+            class _Reduction,
+            class _Transform>
+  _LIBCPP_HIDE_FROM_ABI optional<_Tp> operator()(
+      _Policy&& __policy,
+      _ForwardIterator1 __first1,
+      _ForwardIterator1 __last1,
+      _ForwardIterator2 __first2,
+      _Tp __init,
+      _Reduction __reduce,
+      _Transform __transform) const noexcept {
+    using _ValueType1 = typename iterator_traits<_ForwardIterator1>::value_type;
+    using _ValueType2 = typename iterator_traits<_ForwardIterator2>::value_type;
+    if constexpr (__libcpp_is_contiguous_iterator<_ForwardIterator1>::value &&
+                  __libcpp_is_contiguous_iterator<_ForwardIterator2>::value && is_arithmetic_v<_Tp> &&
+                  __is_supported_reduction<_Reduction, _Tp, _Tp>::value && is_trivially_copyable_v<_ValueType1> &&
+                  is_trivially_copyable_v<_ValueType2>) {
+      return __pstl::__omp_transform_reduce(
+          std::__unwrap_iter(__first1),
+          std::__unwrap_iter(__first2),
+          __last1 - __first1,
+          std::move(__init),
+          std::move(__reduce),
+          std::move(__transform));
+    } else {
+      using _Backends = __backends_after<__current_configuration, __openmp_backend_tag>;
+      using _Fallback = __dispatch<__pstl::__transform_reduce_binary, _Backends, __remove_cvref_t<_Policy>>;
+      return _Fallback{}(
+          std::forward<_Policy>(__policy),
+          std::move(__first1),
+          std::move(__last1),
+          std::move(__first2),
+          std::move(__init),
+          std::move(__reduce),
+          std::move(__transform));
+    }
+  }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___PSTL_BACKENDS_OPENMP_H
diff --git a/libcxx/include/__pstl/dispatch.h b/libcxx/include/__pstl/dispatch.h
index ea40fa79eb9496..13f51c26a6e22c 100644
--- a/libcxx/include/__pstl/dispatch.h
+++ b/libcxx/include/__pstl/dispatch.h
@@ -60,6 +60,21 @@ struct __find_first_implemented<_Algorithm, __backend_configuration<_B1, _Bn...>
 template <template <class, class> class _Algorithm, class _BackendConfiguration, class _ExecutionPolicy>
 using __dispatch = typename __find_first_implemented<_Algorithm, _BackendConfiguration, _ExecutionPolicy>::type;
 
+template <class _BackendConfiguration, class _Backend>
+struct __backends_after_impl;
+
+template <class _Backend, class... _RemainingBackends>
+struct __backends_after_impl<__backend_configuration<_Backend, _RemainingBackends...>, _Backend> {
+  using type = __backend_configuration<_RemainingBackends...>;
+};
+
+template <class _B1, class... _Bn, class _Backend>
+struct __backends_after_impl<__backend_configuration<_B1, _Bn...>, _Backend>
+    : __backends_after_impl<__backend_configuration<_Bn...>, _Backend> {};
+
+template <class _BackendConfiguration, class _Backend>
+using __backends_after = typename __backends_after_impl<_BackendConfiguration, _Backend>::type;
+
 } // namespace __pstl
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index cd08b2810e437b..5276a14f20cb70 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1,2300 +1,2128 @@
-// This module contains headers related to the configuration of the library. These headers
-// are free of any dependency on the rest of libc++.
-module std_config [system] {
-  textual header "__config"
-  textual header "__configuration/abi.h"
-  textual header "__configuration/availability.h"
-  textual header "__configuration/compiler.h"
-  textual header "__configuration/language.h"
-  textual header "__configuration/platform.h"
-  textual header "version"
+// Main C++ standard library interfaces
+module std_algorithm [system] {
+  header "algorithm"
+  export *
+}
+module std_any [system] {
+  header "any"
+  export *
+}
+module std_array [system] {
+  header "array"
+  export *
+}
+module std_atomic [system] {
+  header "atomic"
+  export *
+}
+module std_barrier [system] {
+  header "barrier"
+  export *
+}
+module std_bit [system] {
+  header "bit"
+  export *
+}
+module std_bitset [system] {
+  header "bitset"
+  export *
+}
+module std_charconv [system] {
+  header "charconv"
+  export *
+}
+module std_chrono [system] {
+  header "chrono"
+  export *
+}
+module std_codecvt [system] {
+  header "codecvt"
+  export *
+}
+module std_compare [system] {
+  header "compare"
+  export *
+}
+module std_complex [system] {
+  header "complex"
+  export *
+}
+module std_concepts [system] {
+  header "concepts"
+  export *
+}
+module std_condition_variable [system] {
+  header "condition_variable"
+  export *
+}
+module std_coroutine [system] {
+  header "coroutine"
+  export *
+}
+module std_deque [system] {
+  header "deque"
+  export *
+}
+module std_exception [system] {
+  header "exception"
+  export *
+}
+module std_execution [system] {
+  header "execution"
+  export *
+}
+module std_expected [system] {
+  header "expected"
+  export *
+}
+module std_filesystem [system] {
+  header "filesystem"
+  export *
+}
+module std_format [system] {
+  header "format"
+  export *
+}
+module std_forward_list [system] {
+  header "forward_list"
+  export *
+}
+module std_fstream [system] {
+  header "fstream"
+  export *
+}
+module std_functional [system] {
+  header "functional"
+  export *
+}
+module std_future [system] {
+  header "future"
+  export *
+}
+module std_initializer_list [system] {
+  header "initializer_list"
+  export *
+}
+module std_iomanip [system] {
+  header "iomanip"
+  export *
+}
+module std_ios [system] {
+  header "ios"
+  export *
+}
+module std_iosfwd [system] {
+  header "iosfwd"
+  export *
+}
+module std_iostream [system] {
+  header "iostream"
+  export *
+}
+module std_istream [system] {
+  header "istream"
+  export *
+}
+module std_iterator [system] {
+  header "iterator"
+  export *
+}
+module std_latch [system] {
+  header "latch"
+  export *
+}
+module std_limits [system] {
+  header "limits"
+  export *
+}
+module std_list [system] {
+  header "list"
+  export *
+}
+module std_locale [system] {
+  header "locale"
+  export *
+}
+module std_map [system] {
+  header "map"
+  export *
+}
+module std_mdspan [system] {
+  header "mdspan"
+  export *
+}
+module std_memory [system] {
+  header "memory"
+  export *
+}
+module std_memory_resource [system] {
+  header "memory_resource"
+  export *
+}
+module std_mutex [system] {
+  header "mutex"
+  export *
+}
+module std_new [system] {
+  header "new"
+  export *
+}
+module std_numbers [system] {
+  header "numbers"
+  export *
+}
+module std_numeric [system] {
+  header "numeric"
+  export *
+}
+module std_optional [system] {
+  header "optional"
+  export *
+}
+module std_ostream [system] {
+  header "ostream"
+  export *
+}
+module std_print [system] {
+  header "print"
+  export *
+}
+module std_queue [system] {
+  header "queue"
+  export *
+}
+module std_random [system] {
+  header "random"
+  export *
+}
+module std_ranges [system] {
+  header "ranges"
+  export *
+}
+module std_ratio [system] {
+  header "ratio"
+  export *
+}
+module std_regex [system] {
+  header "regex"
+  export *
+}
+module std_scoped_allocator [system] {
+  header "scoped_allocator"
+  export *
+}
+module std_semaphore [system] {
+  header "semaphore"
+  export *
+}
+module std_set [system] {
+  header "set"
+  export *
+}
+module std_shared_mutex [system] {
+  header "shared_mutex"
+  export std_version
+}
+module std_source_location [system] {
+  header "source_location"
+  export *
+}
+module std_span [system] {
+  header "span"
+  export std_private_ranges_enable_borrowed_range
+  export std_version
+  export std_private_span_span_fwd
+}
+module std_sstream [system] {
+  header "sstream"
+  export *
+}
+module std_stack [system] {
+  header "stack"
+  export *
+}
+module std_stdexcept [system] {
+  header "stdexcept"
+  export *
+}
+module std_stop_token {
+  header "stop_token"
+  export *
+}
+module std_streambuf [system] {
+  header "streambuf"
+  export *
+}
+module std_string [system] {
+  header "string"
+  export *
+}
+module std_string_view [system] {
+  header "string_view"
+  export *
+}
+module std_strstream [system] {
+  header "strstream"
+  export *
+}
+module std_syncstream [system] {
+  header "syncstream"
+  export *
+}
+module std_system_error [system] {
+  header "system_error"
+  export *
+}
+module std_thread [system] {
+  header "thread"
+  export *
+}
+module std_tuple [system] {
+  header "tuple"
+  export *
+}
+module std_type_traits [system] {
+  header "type_traits"
+  export *
+}
+module std_typeindex [system] {
+  header "typeindex"
+  export *
+}
+module std_typeinfo [system] {
+  header "typeinfo"
+  export *
+}
+module std_unordered_map [system] {
+  header "unordered_map"
+  export *
+}
+module std_unordered_set [system] {
+  header "unordered_set"
+  export *
+}
+module std_utility [system] {
+  header "utility"
+  export *
+}
+module std_valarray [system] {
+  header "valarray"
+  export *
+}
+module std_variant [system] {
+  header "variant"
+  export *
+}
+module std_vector [system] {
+  header "vector"
+  export *
+}
+module std_version [system] {
+  header "version"
+  export *
 }
 
-module std_core [system] {
-  module cstddef {
-    module byte         { header "__cstddef/byte.h" }
-    module max_align_t  {
-      header "__cstddef/max_align_t.h"
-      export *
-    }
-    module nullptr_t    { header "__cstddef/nullptr_t.h" }
-    module ptrdiff_t    { header "__cstddef/ptrdiff_t.h" }
-    module size_t       { header "__cstddef/size_t.h" }
-  }
-
-  module cstdint {
-    header "cstdint"
-    export *
-  }
-
-  module fwd {
-    module byte         { header "__fwd/byte.h" }
-    module functional   { header "__fwd/functional.h" }
-    module pair         { header "__fwd/pair.h" }
-    module tuple        { header "__fwd/tuple.h" }
-  }
-
-  module limits {
-    header "limits"
-    export *
-  }
-
-  module math {
-    module abs                              { header "__math/abs.h" }
-    module copysign                         { header "__math/copysign.h" }
-    module error_functions                  { header "__math/error_functions.h" }
-    module exponential_functions            { header "__math/exponential_functions.h" }
-    module fdim                             { header "__math/fdim.h" }
-    module fma                              { header "__math/fma.h" }
-    module gamma                            { header "__math/gamma.h" }
-    module hyperbolic_functions             { header "__math/hyperbolic_functions.h" }
-    module hypot                            { header "__math/hypot.h" }
-    module inverse_hyperbolic_functions     { header "__math/inverse_hyperbolic_functions.h" }
-    module inverse_trigonometric_functions  { header "__math/inverse_trigonometric_functions.h" }
-    module logarithms                       { header "__math/logarithms.h" }
-    module min_max                          { header "__math/min_max.h" }
-    module modulo                           { header "__math/modulo.h" }
-    module remainder                        { header "__math/remainder.h" }
-    module roots                            { header "__math/roots.h" }
-    module rounding_functions               { header "__math/rounding_functions.h" }
-    module special_functions                { header "__math/special_functions.h" }
-    module traits                           { header "__math/traits.h" }
-    module trigonometric_functions          { header "__math/trigonometric_functions.h" }
-  }
-
-  module type_traits {
-    module add_cv_quals                               { header "__type_traits/add_cv_quals.h" }
-    module add_lvalue_reference                       { header "__type_traits/add_lvalue_reference.h" }
-    module add_pointer                                { header "__type_traits/add_pointer.h" }
-    module add_rvalue_reference                       { header "__type_traits/add_rvalue_reference.h" }
-    module aligned_storage                            { header "__type_traits/aligned_storage.h" }
-    module aligned_union                              { header "__type_traits/aligned_union.h" }
-    module alignment_of                               { header "__type_traits/alignment_of.h" }
-    module can_extract_key                            { header "__type_traits/can_extract_key.h" }
-    module common_reference                           { header "__type_traits/common_reference.h" }
-    module common_type {
-      header "__type_traits/common_type.h"
-      // We need to export those because common_type inherits from either of those based on __builtin_common_type.
-      export std_core.type_traits.type_identity
-      export std_core.utility_core.empty
-    }
-    module conditional                                { header "__type_traits/conditional.h" }
-    module conjunction                                { header "__type_traits/conjunction.h" }
-    module container_traits                           { header "__type_traits/container_traits.h" }
-    module copy_cv                                    { header "__type_traits/copy_cv.h" }
-    module copy_cvref                                 { header "__type_traits/copy_cvref.h" }
-    module datasizeof                                 { header "__type_traits/datasizeof.h" }
-    module decay                                      { header "__type_traits/decay.h" }
-    module dependent_type                             { header "__type_traits/dependent_type.h" }
-    module desugars_to                                { header "__type_traits/desugars_to.h" }
-    module disjunction                                { header "__type_traits/disjunction.h" }
-    module enable_if                                  { header "__type_traits/enable_if.h" }
-    module extent                                     { header "__type_traits/extent.h" }
-    module has_unique_object_representation           { header "__type_traits/has_unique_object_representation.h" }
-    module has_virtual_destructor                     { header "__type_traits/has_virtual_destructor.h" }
-    module integral_constant                          { header "__type_traits/integral_constant.h" }
-    module invoke                                     { header "__type_traits/invoke.h" }
-    module is_abstract {
-      header "__type_traits/is_abstract.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_aggregate {
-      header "__type_traits/is_aggregate.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_allocator {
-      header "__type_traits/is_allocator.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_always_bitcastable {
-      header "__type_traits/is_always_bitcastable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_arithmetic {
-      header "__type_traits/is_arithmetic.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_array {
-      header "__type_traits/is_array.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_assignable {
-      header "__type_traits/is_assignable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_base_of {
-      header "__type_traits/is_base_of.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_bounded_array {
-      header "__type_traits/is_bounded_array.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_callable {
-      header "__type_traits/is_callable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_char_like_type {
-      header "__type_traits/is_char_like_type.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_class {
-      header "__type_traits/is_class.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_compound {
-      header "__type_traits/is_compound.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_const {
-      header "__type_traits/is_const.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_constant_evaluated {
-      header "__type_traits/is_constant_evaluated.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_constructible {
-      header "__type_traits/is_constructible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_convertible {
-      header "__type_traits/is_convertible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_core_convertible {
-      header "__type_traits/is_core_convertible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_destructible {
-      header "__type_traits/is_destructible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_empty {
-      header "__type_traits/is_empty.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_enum {
-      header "__type_traits/is_enum.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_equality_comparable {
-      header "__type_traits/is_equality_comparable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_execution_policy {
-      header "__type_traits/is_execution_policy.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_final {
-      header "__type_traits/is_final.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_floating_point {
-      header "__type_traits/is_floating_point.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_function {
-      header "__type_traits/is_function.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_fundamental {
-      header "__type_traits/is_fundamental.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_implicit_lifetime {
-      header "__type_traits/is_implicit_lifetime.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_implicitly_default_constructible {
-      header "__type_traits/is_implicitly_default_constructible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_integral {
-      header "__type_traits/is_integral.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_literal_type {
-      header "__type_traits/is_literal_type.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_member_pointer {
-      header "__type_traits/is_member_pointer.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_nothrow_assignable {
-      header "__type_traits/is_nothrow_assignable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_nothrow_constructible {
-      header "__type_traits/is_nothrow_constructible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_nothrow_convertible {
-      header "__type_traits/is_nothrow_convertible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_nothrow_destructible {
-      header "__type_traits/is_nothrow_destructible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_null_pointer {
-      header "__type_traits/is_null_pointer.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_object {
-      header "__type_traits/is_object.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_pod {
-      header "__type_traits/is_pod.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_pointer {
-      header "__type_traits/is_pointer.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_polymorphic {
-      header "__type_traits/is_polymorphic.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_primary_template {
-      header "__type_traits/is_primary_template.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_reference_wrapper {
-      header "__type_traits/is_reference_wrapper.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_reference {
-      header "__type_traits/is_reference.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_referenceable {
-      header "__type_traits/is_referenceable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_same {
-      header "__type_traits/is_same.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_scalar {
-      header "__type_traits/is_scalar.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_signed_integer {
-      header "__type_traits/is_signed_integer.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_signed {
-      header "__type_traits/is_signed.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_specialization {
-      header "__type_traits/is_specialization.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_standard_layout {
-      header "__type_traits/is_standard_layout.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_swappable {
-      header "__type_traits/is_swappable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_trivial {
-      header "__type_traits/is_trivial.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_trivially_assignable {
-      header "__type_traits/is_trivially_assignable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_trivially_constructible {
-      header "__type_traits/is_trivially_constructible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_trivially_copyable {
-      header "__type_traits/is_trivially_copyable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_trivially_destructible {
-      header "__type_traits/is_trivially_destructible.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_trivially_lexicographically_comparable {
-      header "__type_traits/is_trivially_lexicographically_comparable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_trivially_relocatable {
-      header "__type_traits/is_trivially_relocatable.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_unbounded_array {
-      header "__type_traits/is_unbounded_array.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_union {
-      header "__type_traits/is_union.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_unsigned_integer {
-      header "__type_traits/is_unsigned_integer.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_unsigned {
-      header "__type_traits/is_unsigned.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_valid_expansion {
-      header "__type_traits/is_valid_expansion.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_void {
-      header "__type_traits/is_void.h"
-      export std_core.type_traits.integral_constant
-    }
-    module is_volatile {
-      header "__type_traits/is_volatile.h"
-      export std_core.type_traits.integral_constant
-    }
-    module lazy                                       { header "__type_traits/lazy.h" }
-    module make_32_64_or_128_bit                      { header "__type_traits/make_32_64_or_128_bit.h" }
-    module make_const_lvalue_ref                      { header "__type_traits/make_const_lvalue_ref.h" }
-    module make_signed                                { header "__type_traits/make_signed.h" }
-    module make_unsigned                              { header "__type_traits/make_unsigned.h" }
-    module maybe_const                                { header "__type_traits/maybe_const.h" }
-    module nat                                        { header "__type_traits/nat.h" }
-    module negation                                   { header "__type_traits/negation.h" }
-    module promote                                    { header "__type_traits/promote.h" }
-    module rank                                       { header "__type_traits/rank.h" }
-    module remove_all_extents                         { header "__type_traits/remove_all_extents.h" }
-    module remove_const_ref                           { header "__type_traits/remove_const_ref.h" }
-    module remove_const                               { header "__type_traits/remove_const.h" }
-    module remove_cv                                  { header "__type_traits/remove_cv.h" }
-    module remove_cvref                               { header "__type_traits/remove_cvref.h" }
-    module remove_extent                              { header "__type_traits/remove_extent.h" }
-    module remove_pointer                             { header "__type_traits/remove_pointer.h" }
-    module remove_reference                           { header "__type_traits/remove_reference.h" }
-    module remove_volatile                            { header "__type_traits/remove_volatile.h" }
-    module result_of                                  { header "__type_traits/result_of.h" }
-    module strip_signature                            { header "__type_traits/strip_signature.h" }
-    module type_identity                              { header "__type_traits/type_identity.h" }
-    module type_list                                  { header "__type_traits/type_list.h" }
-    module underlying_type                            { header "__type_traits/underlying_type.h" }
-    module unwrap_ref                                 { header "__type_traits/unwrap_ref.h" }
-    module void_t                                     { header "__type_traits/void_t.h" }
-
-    header "type_traits"
-    export *
-  } // module type_traits
-
-  // Only the truly dependency-free parts of __utility are here
-  module utility_core {
-    module declval  { header "__utility/declval.h" }
-    module empty    { header "__utility/empty.h" }
-    module forward  { header "__utility/forward.h" }
-  }
-} // module std_core
-
-module std [system] {
-  module algorithm {
-    module adjacent_find                          { header "__algorithm/adjacent_find.h" }
-    module all_of                                 { header "__algorithm/all_of.h" }
-    module any_of                                 { header "__algorithm/any_of.h" }
-    module binary_search                          { header "__algorithm/binary_search.h" }
-    module clamp                                  { header "__algorithm/clamp.h" }
-    module comp_ref_type                          { header "__algorithm/comp_ref_type.h" }
-    module comp                                   { header "__algorithm/comp.h" }
-    module copy_backward                          { header "__algorithm/copy_backward.h" }
-    module copy_if                                { header "__algorithm/copy_if.h" }
-    module copy_move_common                       { header "__algorithm/copy_move_common.h" }
-    module copy_n                                 { header "__algorithm/copy_n.h" }
-    module copy                                   { header "__algorithm/copy.h" }
-    module count_if                               { header "__algorithm/count_if.h" }
-    module count                                  { header "__algorithm/count.h" }
-    module equal_range                            { header "__algorithm/equal_range.h" }
-    module equal                                  { header "__algorithm/equal.h" }
-    module fill_n                                 { header "__algorithm/fill_n.h" }
-    module fill                                   { header "__algorithm/fill.h" }
-    module find_end                               { header "__algorithm/find_end.h" }
-    module find_first_of                          { header "__algorithm/find_first_of.h" }
-    module find_if_not                            { header "__algorithm/find_if_not.h" }
-    module find_if                                { header "__algorithm/find_if.h" }
-    module find_segment_if                        { header "__algorithm/find_segment_if.h" }
-    module find                                   { header "__algorithm/find.h" }
-    module for_each_n                             { header "__algorithm/for_each_n.h" }
-    module for_each_segment                       { header "__algorithm/for_each_segment.h" }
-    module for_each                               { header "__algorithm/for_each.h" }
-    module generate_n                             { header "__algorithm/generate_n.h" }
-    module generate                               { header "__algorithm/generate.h" }
-    module half_positive                          { header "__algorithm/half_positive.h" }
-    module in_found_result                        { header "__algorithm/in_found_result.h" }
-    module in_fun_result                          { header "__algorithm/in_fun_result.h" }
-    module in_in_out_result                       { header "__algorithm/in_in_out_result.h" }
-    module in_in_result                           { header "__algorithm/in_in_result.h" }
-    module in_out_out_result                      { header "__algorithm/in_out_out_result.h" }
-    module in_out_result                          { header "__algorithm/in_out_result.h" }
-    module includes                               { header "__algorithm/includes.h" }
-    module inplace_merge                          { header "__algorithm/inplace_merge.h" }
-    module is_heap_until                          { header "__algorithm/is_heap_until.h" }
-    module is_heap                                { header "__algorithm/is_heap.h" }
-    module is_partitioned                         { header "__algorithm/is_partitioned.h" }
-    module is_permutation                         { header "__algorithm/is_permutation.h" }
-    module is_sorted_until                        { header "__algorithm/is_sorted_until.h" }
-    module is_sorted                              { header "__algorithm/is_sorted.h" }
-    module iter_swap                              { header "__algorithm/iter_swap.h" }
-    module iterator_operations {
-      header "__algorithm/iterator_operations.h"
-      export std.iterator.advance
-      export std.iterator.distance
-      export std.iterator.iter_move
-      export std.iterator.iter_swap
-      export std.iterator.next
-      export std.iterator.prev
-    }
-    module lexicographical_compare_three_way      { header "__algorithm/lexicographical_compare_three_way.h" }
-    module lexicographical_compare                { header "__algorithm/lexicographical_compare.h" }
-    module lower_bound                            { header "__algorithm/lower_bound.h" }
-    module make_heap                              { header "__algorithm/make_heap.h" }
-    module make_projected                         { header "__algorithm/make_projected.h" }
-    module max_element                            { header "__algorithm/max_element.h" }
-    module max                                    { header "__algorithm/max.h" }
-    module merge                                  { header "__algorithm/merge.h" }
-    module min_element                            { header "__algorithm/min_element.h" }
-    module min_max_result                         { header "__algorithm/min_max_result.h" }
-    module min                                    { header "__algorithm/min.h" }
-    module minmax_element                         { header "__algorithm/minmax_element.h" }
-    module minmax {
-      header "__algorithm/minmax.h"
-      export std.utility.pair // return type
-    }
-    module mismatch {
-      header "__algorithm/mismatch.h"
-      export std.utility.pair // return type
-    }
-    module move_backward                          { header "__algorithm/move_backward.h" }
-    module move                                   { header "__algorithm/move.h" }
-    module next_permutation                       { header "__algorithm/next_permutation.h" }
-    module none_of                                { header "__algorithm/none_of.h" }
-    module nth_element                            { header "__algorithm/nth_element.h" }
-    module partial_sort_copy                      { header "__algorithm/partial_sort_copy.h" }
-    module partial_sort                           { header "__algorithm/partial_sort.h" }
-    module partition_copy                         { header "__algorithm/partition_copy.h" }
-    module partition_point                        { header "__algorithm/partition_point.h" }
-    module partition                              { header "__algorithm/partition.h" }
-    module pop_heap                               { header "__algorithm/pop_heap.h" }
-    module prev_permutation                       { header "__algorithm/prev_permutation.h" }
-    module pstl                                   { header "__algorithm/pstl.h" }
-    module push_heap                              { header "__algorithm/push_heap.h" }
-    module ranges_adjacent_find                   { header "__algorithm/ranges_adjacent_find.h" }
-    module ranges_all_of                          { header "__algorithm/ranges_all_of.h" }
-    module ranges_any_of                          { header "__algorithm/ranges_any_of.h" }
-    module ranges_binary_search {
-      header "__algorithm/ranges_binary_search.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_clamp {
-      header "__algorithm/ranges_clamp.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_contains_subrange {
-      header "__algorithm/ranges_contains_subrange.h"
-    }
-    module ranges_contains {
-      header "__algorithm/ranges_contains.h"
-    }
-    module ranges_copy_backward {
-      header "__algorithm/ranges_copy_backward.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_copy_if {
-      header "__algorithm/ranges_copy_if.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_copy_n {
-      header "__algorithm/ranges_copy_n.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_copy {
-      header "__algorithm/ranges_copy.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_count_if                        { header "__algorithm/ranges_count_if.h" }
-    module ranges_count                           { header "__algorithm/ranges_count.h" }
-    module ranges_ends_with                       { header "__algorithm/ranges_ends_with.h" }
-    module ranges_equal_range {
-      header "__algorithm/ranges_equal_range.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_equal {
-      header "__algorithm/ranges_equal.h"
-      export std.functional.identity
-    }
-    module ranges_fill_n                          { header "__algorithm/ranges_fill_n.h" }
-    module ranges_fill                            { header "__algorithm/ranges_fill.h" }
-    module ranges_find_end                        { header "__algorithm/ranges_find_end.h" }
-    module ranges_find_first_of                   { header "__algorithm/ranges_find_first_of.h" }
-    module ranges_find_if_not                     { header "__algorithm/ranges_find_if_not.h" }
-    module ranges_find_if                         { header "__algorithm/ranges_find_if.h" }
-    module ranges_find_last                       { header "__algorithm/ranges_find_last.h" }
-    module ranges_find                            { header "__algorithm/ranges_find.h" }
-    module ranges_fold                            { header "__algorithm/ranges_fold.h" }
-    module ranges_for_each_n {
-      header "__algorithm/ranges_for_each_n.h"
-      export std.algorithm.in_fun_result
-    }
-    module ranges_for_each {
-      header "__algorithm/ranges_for_each.h"
-      export std.algorithm.in_fun_result
-    }
-    module ranges_generate_n {
-      header "__algorithm/ranges_generate_n.h"
-    }
-    module ranges_generate {
-      header "__algorithm/ranges_generate.h"
-    }
-    module ranges_includes {
-      header "__algorithm/ranges_includes.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_inplace_merge {
-      header "__algorithm/ranges_inplace_merge.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_is_heap_until {
-      header "__algorithm/ranges_is_heap_until.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_is_heap {
-      header "__algorithm/ranges_is_heap.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_is_partitioned {
-      header "__algorithm/ranges_is_partitioned.h"
-    }
-    module ranges_is_permutation {
-      header "__algorithm/ranges_is_permutation.h"
-    }
-    module ranges_is_sorted_until {
-      header "__algorithm/ranges_is_sorted_until.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_is_sorted {
-      header "__algorithm/ranges_is_sorted.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_iterator_concept {
-      header "__algorithm/ranges_iterator_concept.h"
-    }
-    module ranges_lexicographical_compare {
-      header "__algorithm/ranges_lexicographical_compare.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_lower_bound {
-      header "__algorithm/ranges_lower_bound.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_make_heap {
-      header "__algorithm/ranges_make_heap.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_max_element {
-      header "__algorithm/ranges_max_element.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_max {
-      header "__algorithm/ranges_max.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_merge {
-      header "__algorithm/ranges_merge.h"
-      export std.functional.ranges_operations
-      export std.algorithm.in_in_out_result
-    }
-    module ranges_min_element {
-      header "__algorithm/ranges_min_element.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_min {
-      header "__algorithm/ranges_min.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_minmax_element {
-      header "__algorithm/ranges_minmax_element.h"
-      export std.functional.ranges_operations
-      export std.algorithm.min_max_result
-    }
-    module ranges_minmax {
-      header "__algorithm/ranges_minmax.h"
-      export std.functional.ranges_operations
-      export std.algorithm.min_max_result
-    }
-    module ranges_mismatch {
-      header "__algorithm/ranges_mismatch.h"
-      export std.algorithm.in_in_result
-    }
-    module ranges_move_backward {
-      header "__algorithm/ranges_move_backward.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_move {
-      header "__algorithm/ranges_move.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_next_permutation {
-      header "__algorithm/ranges_next_permutation.h"
-      export std.functional.ranges_operations
-      export std.algorithm.in_found_result
-    }
-    module ranges_none_of {
-      header "__algorithm/ranges_none_of.h"
-    }
-    module ranges_nth_element {
-      header "__algorithm/ranges_nth_element.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_partial_sort_copy {
-      header "__algorithm/ranges_partial_sort_copy.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_partial_sort {
-      header "__algorithm/ranges_partial_sort.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_partition_copy {
-      header "__algorithm/ranges_partition_copy.h"
-      export std.algorithm.in_out_out_result
-    }
-    module ranges_partition_point {
-      header "__algorithm/ranges_partition_point.h"
-    }
-    module ranges_partition {
-      header "__algorithm/ranges_partition.h"
-    }
-    module ranges_pop_heap {
-      header "__algorithm/ranges_pop_heap.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_prev_permutation {
-      header "__algorithm/ranges_prev_permutation.h"
-      export std.functional.ranges_operations
-      export std.algorithm.in_found_result
-    }
-    module ranges_push_heap {
-      header "__algorithm/ranges_push_heap.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_remove_copy_if {
-      header "__algorithm/ranges_remove_copy_if.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_remove_copy {
-      header "__algorithm/ranges_remove_copy.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_remove_if {
-      header "__algorithm/ranges_remove_if.h"
-    }
-    module ranges_remove {
-      header "__algorithm/ranges_remove.h"
-    }
-    module ranges_replace_copy_if {
-      header "__algorithm/ranges_replace_copy_if.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_replace_copy {
-      header "__algorithm/ranges_replace_copy.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_replace_if {
-      header "__algorithm/ranges_replace_if.h"
-    }
-    module ranges_replace {
-      header "__algorithm/ranges_replace.h"
-    }
-    module ranges_reverse_copy {
-      header "__algorithm/ranges_reverse_copy.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_reverse {
-      header "__algorithm/ranges_reverse.h"
-    }
-    module ranges_rotate_copy {
-      header "__algorithm/ranges_rotate_copy.h"
-      export std.algorithm.in_out_result
-    }
-    module ranges_rotate                          { header "__algorithm/ranges_rotate.h" }
-    module ranges_sample                          { header "__algorithm/ranges_sample.h" }
-    module ranges_search_n                        { header "__algorithm/ranges_search_n.h" }
-    module ranges_search                          { header "__algorithm/ranges_search.h" }
-    module ranges_set_difference {
-      header "__algorithm/ranges_set_difference.h"
-      export std.functional.ranges_operations
-      export std.algorithm.in_out_result
-    }
-    module ranges_set_intersection {
-      header "__algorithm/ranges_set_intersection.h"
-      export std.functional.ranges_operations
-      export std.algorithm.in_in_out_result
-    }
-    module ranges_set_symmetric_difference {
-      header "__algorithm/ranges_set_symmetric_difference.h"
-      export std.functional.ranges_operations
-      export std.algorithm.in_in_out_result
-    }
-    module ranges_set_union {
-      header "__algorithm/ranges_set_union.h"
-      export std.functional.ranges_operations
-      export std.algorithm.in_in_out_result
-    }
-    module ranges_shuffle {
-      header "__algorithm/ranges_shuffle.h"
-    }
-    module ranges_sort_heap {
-      header "__algorithm/ranges_sort_heap.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_sort {
-      header "__algorithm/ranges_sort.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_stable_partition {
-      header "__algorithm/ranges_stable_partition.h"
-    }
-    module ranges_stable_sort {
-      header "__algorithm/ranges_stable_sort.h"
-      export std.functional.ranges_operations
-    }
-    module ranges_starts_with {
-      header "__algorithm/ranges_starts_with.h"
-    }
-    module ranges_swap_ranges {
-      header "__algorithm/ranges_swap_ranges.h"
-      export std.algorithm.in_in_result
-    }
-    module ranges_transform {
-      header "__algorithm/ranges_transform.h"
-      export std.algorithm.in_out_result
-      export std.algorithm.in_in_out_result
-    }
-    module ranges_unique_copy {
-      header "__algorithm/ranges_unique_copy.h"
-    }
-    module ranges_unique {
-      header "__algorithm/ranges_unique.h"
-    }
-    module ranges_upper_bound {
-      header "__algorithm/ranges_upper_bound.h"
-      export std.functional.ranges_operations
-    }
-    module remove_copy_if                         { header "__algorithm/remove_copy_if.h" }
-    module remove_copy                            { header "__algorithm/remove_copy.h" }
-    module remove_if                              { header "__algorithm/remove_if.h" }
-    module remove                                 { header "__algorithm/remove.h" }
-    module replace_copy_if                        { header "__algorithm/replace_copy_if.h" }
-    module replace_copy                           { header "__algorithm/replace_copy.h" }
-    module replace_if                             { header "__algorithm/replace_if.h" }
-    module replace                                { header "__algorithm/replace.h" }
-    module reverse_copy                           { header "__algorithm/reverse_copy.h" }
-    module reverse                                { header "__algorithm/reverse.h" }
-    module rotate_copy                            { header "__algorithm/rotate_copy.h" }
-    module rotate                                 { header "__algorithm/rotate.h" }
-    module sample                                 { header "__algorithm/sample.h" }
-    module search_n                               { header "__algorithm/search_n.h" }
-    module search                                 { header "__algorithm/search.h" }
-    module set_difference                         { header "__algorithm/set_difference.h" }
-    module set_intersection                       { header "__algorithm/set_intersection.h" }
-    module set_symmetric_difference               { header "__algorithm/set_symmetric_difference.h" }
-    module set_union                              { header "__algorithm/set_union.h" }
-    module shift_left                             { header "__algorithm/shift_left.h" }
-    module shift_right                            { header "__algorithm/shift_right.h" }
-    module shuffle                                { header "__algorithm/shuffle.h" }
-    module sift_down                              { header "__algorithm/sift_down.h" }
-    module simd_utils                             { header "__algorithm/simd_utils.h" }
-    module sort_heap                              { header "__algorithm/sort_heap.h" }
-    module sort                                   { header "__algorithm/sort.h" }
-    module stable_partition                       { header "__algorithm/stable_partition.h" }
-    module stable_sort                            { header "__algorithm/stable_sort.h" }
-    module swap_ranges                            { header "__algorithm/swap_ranges.h" }
-    module three_way_comp_ref_type                { header "__algorithm/three_way_comp_ref_type.h" }
-    module transform                              { header "__algorithm/transform.h" }
-    module uniform_random_bit_generator_adaptor   { header "__algorithm/uniform_random_bit_generator_adaptor.h" }
-    module unique_copy                            { header "__algorithm/unique_copy.h" }
-    module unique                                 { header "__algorithm/unique.h" }
-    module unwrap_iter                            { header "__algorithm/unwrap_iter.h" }
-    module unwrap_range                           { header "__algorithm/unwrap_range.h" }
-    module upper_bound                            { header "__algorithm/upper_bound.h" }
-
-    header "algorithm"
-    export *
-  } // module algorithm
-
-  module any {
-    header "any"
-    export *
-  }
-
-  module array {
-    module fwd { header "__fwd/array.h" }
-
-    header "array"
-    export *
-  }
-
-  module atomic {
-    module aliases                { header "__atomic/aliases.h" }
-    module atomic_base            { header "__atomic/atomic_base.h" }
-    module atomic_flag            { header "__atomic/atomic_flag.h" }
-    module atomic_init            { header "__atomic/atomic_init.h" }
-    module atomic_lock_free       { header "__atomic/atomic_lock_free.h" }
-    module atomic_ref             { header "__atomic/atomic_ref.h" }
-    module atomic_sync            { header "__atomic/atomic_sync.h" }
-    module atomic {
-      header "__atomic/atomic.h"
-      export std.atomic.atomic_base // most of std::atomic methods are defined there
-    }
-    module check_memory_order     { header "__atomic/check_memory_order.h" }
-    module contention_t           { header "__atomic/contention_t.h" }
-    module cxx_atomic_impl        { header "__atomic/cxx_atomic_impl.h" }
-    module fence                  { header "__atomic/fence.h" }
-    module is_always_lock_free    { header "__atomic/is_always_lock_free.h" }
-    module kill_dependency        { header "__atomic/kill_dependency.h" }
-    module memory_order           { header "__atomic/memory_order.h" }
-    module to_gcc_order           { header "__atomic/to_gcc_order.h" }
-
-    header "atomic"
-    export *
-  }
-
-  module barrier {
-    header "barrier"
-    export *
-  }
-
-  module bit {
-    module bit_cast         { header "__bit/bit_cast.h" }
-    module bit_ceil         { header "__bit/bit_ceil.h" }
-    module bit_floor        { header "__bit/bit_floor.h" }
-    module bit_log2         { header "__bit/bit_log2.h" }
-    module bit_width        { header "__bit/bit_width.h" }
-    module blsr             { header "__bit/blsr.h" }
-    module byteswap         { header "__bit/byteswap.h" }
-    module countl           { header "__bit/countl.h" }
-    module countr           { header "__bit/countr.h" }
-    module endian           { header "__bit/endian.h" }
-    module has_single_bit   { header "__bit/has_single_bit.h" }
-    module invert_if        { header "__bit/invert_if.h" }
-    module popcount         { header "__bit/popcount.h" }
-    module rotate           { header "__bit/rotate.h" }
-
-    header "bit"
-    export *
-  }
-
-  module bitset {
-    header "bitset"
-    export *
-  }
-
-  module charconv {
-    module chars_format               { header "__charconv/chars_format.h" }
-    module from_chars_floating_point  { header "__charconv/from_chars_floating_point.h" }
-    module from_chars_integral        { header "__charconv/from_chars_integral.h" }
-    module from_chars_result          { header "__charconv/from_chars_result.h" }
-    module tables                     { header "__charconv/tables.h" }
-    module to_chars                   { header "__charconv/to_chars.h" }
-    module to_chars_base_10           { header "__charconv/to_chars_base_10.h" }
-    module to_chars_floating_point    { header "__charconv/to_chars_floating_point.h" }
-    module to_chars_integral          { header "__charconv/to_chars_integral.h" }
-    module to_chars_result            { header "__charconv/to_chars_result.h" }
-    module traits                     { header "__charconv/traits.h" }
-
-    header "charconv"
-    export *
-  }
-
-  module chrono {
-    module calendar                   { header "__chrono/calendar.h" }
-    module concepts                   { header "__chrono/concepts.h" }
-    module convert_to_timespec        { header "__chrono/convert_to_timespec.h" }
-    module convert_to_tm              { header "__chrono/convert_to_tm.h" }
-    module day                        { header "__chrono/day.h" }
-    module duration                   { header "__chrono/duration.h" }
-    module exception                  { header "__chrono/exception.h" }
-    module file_clock                 { header "__chrono/file_clock.h" }
-    module formatter                  { header "__chrono/formatter.h" }
-    module hh_mm_ss                   { header "__chrono/hh_mm_ss.h" }
-    module high_resolution_clock {
-      header "__chrono/high_resolution_clock.h"
-      export *
-    }
-    module leap_second {
-      header "__chrono/leap_second.h"
-    }
-    module literals {
-      header "__chrono/literals.h"
-    }
-    module local_info {
-      header "__chrono/local_info.h"
-      export std.chrono.sys_info
-    }
-    module month_weekday              { header "__chrono/month_weekday.h" }
-    module month                      { header "__chrono/month.h" }
-    module monthday                   { header "__chrono/monthday.h" }
-    module ostream                    { header "__chrono/ostream.h" }
-    module parser_std_format_spec     { header "__chrono/parser_std_format_spec.h" }
-    module statically_widen           { header "__chrono/statically_widen.h" }
-    module steady_clock {
-      header "__chrono/steady_clock.h"
-      export std.chrono.time_point
-    }
-    module sys_info {
-      header "__chrono/sys_info.h"
-    }
-    module system_clock {
-      header "__chrono/system_clock.h"
-      export std.chrono.time_point
-    }
-    module time_point                 { header "__chrono/time_point.h" }
-    module time_zone_link             { header "__chrono/time_zone_link.h" }
-    module time_zone                  { header "__chrono/time_zone.h" }
-    module tzdb_list {
-      header "__chrono/tzdb_list.h"
-      export std.forward_list // forward_list iterators are used to implement this API
-      export std.string_view // by-value argument of type std::string_view
-    }
-    module tzdb {
-      header "__chrono/tzdb.h"
-      export std.string // public data member of type std::string
-      export std.vector // public data members of type std::vector
-    }
-    module weekday                    { header "__chrono/weekday.h" }
-    module year_month_day             { header "__chrono/year_month_day.h" }
-    module year_month_weekday         { header "__chrono/year_month_weekday.h" }
-    module year_month                 { header "__chrono/year_month.h" }
-    module year                       { header "__chrono/year.h" }
-    module zoned_time                 { header "__chrono/zoned_time.h" }
-
-    header "chrono"
-    export *
-  } // module chrono
-
-  module codecvt {
-    header "codecvt"
-    export *
-  }
-
-  module compare {
-    module common_comparison_category       { header "__compare/common_comparison_category.h" }
-    module compare_partial_order_fallback   { header "__compare/compare_partial_order_fallback.h" }
-    module compare_strong_order_fallback    { header "__compare/compare_strong_order_fallback.h" }
-    module compare_three_way                { header "__compare/compare_three_way.h" }
-    module compare_three_way_result         { header "__compare/compare_three_way_result.h" }
-    module compare_weak_order_fallback      { header "__compare/compare_weak_order_fallback.h" }
-    module is_eq                            { header "__compare/is_eq.h" }
-    module ordering                         { header "__compare/ordering.h" }
-    module partial_order                    { header "__compare/partial_order.h" }
-    module strong_order                     { header "__compare/strong_order.h" }
-    module synth_three_way                  { header "__compare/synth_three_way.h" }
-    module three_way_comparable             { header "__compare/three_way_comparable.h" }
-    module weak_order                       { header "__compare/weak_order.h" }
-
-    header "compare"
-    export *
-  }
-
-  module complex {
-    module fwd { header "__fwd/complex.h" }
-
-    header "complex"
-    export *
-  }
-
-  module concepts {
-    module arithmetic               { header "__concepts/arithmetic.h" }
-    module assignable               { header "__concepts/assignable.h" }
-    module boolean_testable         { header "__concepts/boolean_testable.h" }
-    module class_or_enum            { header "__concepts/class_or_enum.h" }
-    module common_reference_with    { header "__concepts/common_reference_with.h" }
-    module common_with              { header "__concepts/common_with.h" }
-    module constructible            { header "__concepts/constructible.h" }
-    module convertible_to           { header "__concepts/convertible_to.h" }
-    module copyable                 { header "__concepts/copyable.h" }
-    module derived_from             { header "__concepts/derived_from.h" }
-    module destructible             { header "__concepts/destructible.h" }
-    module different_from           { header "__concepts/different_from.h" }
-    module equality_comparable      { header "__concepts/equality_comparable.h" }
-    module invocable                { header "__concepts/invocable.h" }
-    module movable                  { header "__concepts/movable.h" }
-    module predicate                { header "__concepts/predicate.h" }
-    module regular                  { header "__concepts/regular.h" }
-    module relation                 { header "__concepts/relation.h" }
-    module same_as                  { header "__concepts/same_as.h" }
-    module semiregular              { header "__concepts/semiregular.h" }
-    module swappable                { header "__concepts/swappable.h" }
-    module totally_ordered          { header "__concepts/totally_ordered.h" }
-
-    header "concepts"
-    export *
-  }
-
-  module condition_variable {
-    module condition_variable   { header "__condition_variable/condition_variable.h" }
-
-    header "condition_variable"
-    export *
-  }
-
-  module cassert {
-    textual header "cassert" // NDEBUG requires textual inclusion
-  }
-
-  module ccomplex {
-    header "ccomplex"
-    export *
-  }
-
-  module cctype {
-    header "cctype"
-    export *
-  }
-
-  module cerrno {
-    header "cerrno"
-    export *
-  }
-
-  module cfenv {
-    header "cfenv"
-    export *
-  }
-
-  module cfloat {
-    header "cfloat"
-    export *
-  }
-
-  module cinttypes {
-    header "cinttypes"
-    export *
-  }
-
-  module ciso646 {
-    header "ciso646"
-    export *
-  }
-
-  module climits {
-    header "climits"
-    export *
-  }
-
-  module clocale {
-    header "clocale"
-    export *
-  }
-
-  module cmath {
-    header "cmath"
-    export *
-  }
-
-  // TODO: Make non-textual. This seems to cause problems when compiling against Glibc.
-  module csetjmp {
-    textual header "csetjmp"
-  }
-
-  module csignal {
-    header "csignal"
-    export *
-  }
-
-  module cstdalign {
-    header "cstdalign"
-    export *
-  }
-
-  module cstdarg {
-    header "cstdarg"
-    export *
-  }
-
-  module cstdbool {
-    header "cstdbool"
-    export *
-  }
-
-  module cstddef {
-    header "cstddef"
-    export *
-  }
-
-  module cstdio {
-    header "cstdio"
-    export *
-  }
-
-  module cstdlib {
-    header "cstdlib"
-    export *
-  }
-
-  module cstring {
-    header "cstring"
-    export *
-  }
-
-  module ctgmath {
-    header "ctgmath"
-    export *
-  }
-
-  module ctime {
-    header "ctime"
-    export *
-  }
-
-  module cuchar {
-    header "cuchar"
-    export *
-  }
-
-  module cwchar {
-    header "cwchar"
-    export *
-  }
-
-  module cwctype {
-    header "cwctype"
-    export *
-  }
-
-  module deque {
-    module fwd { header "__fwd/deque.h" }
-
-    header "deque"
-    export *
-  }
-
-  module exception {
-    module exception          { header "__exception/exception.h" }
-    module exception_ptr      { header "__exception/exception_ptr.h" }
-    module nested_exception   { header "__exception/nested_exception.h" }
-    module operations         { header "__exception/operations.h" }
-    module terminate          { header "__exception/terminate.h" }
-
-    header "exception"
-    export *
-  }
-
-  module execution {
-    header "execution"
-    export *
-  }
-
-  module expected {
-    module bad_expected_access    { header "__expected/bad_expected_access.h" }
-    module expected               { header "__expected/expected.h" }
-    module unexpect               { header "__expected/unexpect.h" }
-    module unexpected             { header "__expected/unexpected.h" }
-
-    header "expected"
-    export *
-  }
-
-  module filesystem {
-    module copy_options                   { header "__filesystem/copy_options.h" }
-    module directory_entry                { header "__filesystem/directory_entry.h" }
-    module directory_iterator             { header "__filesystem/directory_iterator.h" }
-    module directory_options              { header "__filesystem/directory_options.h" }
-    module file_status                    { header "__filesystem/file_status.h" }
-    module file_time_type                 { header "__filesystem/file_time_type.h" }
-    module file_type                      { header "__filesystem/file_type.h" }
-    module filesystem_error               { header "__filesystem/filesystem_error.h" }
-    module operations                     { header "__filesystem/operations.h" }
-    module path_iterator                  { header "__filesystem/path_iterator.h" }
-    module path                           {
-      header "__filesystem/path.h"
-      export std.string // returned by various methods of filesystem::path
-    }
-    module perm_options                   { header "__filesystem/perm_options.h" }
-    module perms                          { header "__filesystem/perms.h" }
-    module recursive_directory_iterator   { header "__filesystem/recursive_directory_iterator.h" }
-    module space_info                     { header "__filesystem/space_info.h" }
-    module u8path                         { header "__filesystem/u8path.h" }
-
-    header "filesystem"
-    export *
-  }
-
-  module flat_map {
-    module flat_map                       { header "__flat_map/flat_map.h" }
-    module sorted_unique                  { header "__flat_map/sorted_unique.h" }
-
-    header "flat_map"
-    export *
-  }
-
-  module format {
-    module buffer                             { header "__format/buffer.h" }
-    module concepts                           { header "__format/concepts.h" }
-    module container_adaptor                  { header "__format/container_adaptor.h" }
-    module enable_insertable                  { header "__format/enable_insertable.h" }
-    module escaped_output_table               { header "__format/escaped_output_table.h" }
-    module extended_grapheme_cluster_table    { header "__format/extended_grapheme_cluster_table.h" }
-    module format_arg                         { header "__format/format_arg.h" }
-    module format_arg_store                   { header "__format/format_arg_store.h" }
-    module format_args                        { header "__format/format_args.h" }
-    module format_context {
-      header "__format/format_context.h"
-      export std.optional // default argument for __format_context_create
-    }
-    module format_error {
-      header "__format/format_error.h"
-    }
-    module format_functions {
-      header "__format/format_functions.h"
-      export std.string // returned by the functions in that header
-    }
-    module format_parse_context               { header "__format/format_parse_context.h" }
-    module format_string                      { header "__format/format_string.h" }
-    module format_to_n_result                 { header "__format/format_to_n_result.h" }
-    module formatter                          { header "__format/formatter.h" }
-    module formatter_bool                     { header "__format/formatter_bool.h" }
-    module formatter_char                     { header "__format/formatter_char.h" }
-    module formatter_floating_point           { header "__format/formatter_floating_point.h" }
-    module formatter_integer                  { header "__format/formatter_integer.h" }
-    module formatter_integral                 { header "__format/formatter_integral.h" }
-    module formatter_output                   { header "__format/formatter_output.h" }
-    module formatter_pointer                  { header "__format/formatter_pointer.h" }
-    module formatter_string                   { header "__format/formatter_string.h" }
-    module formatter_tuple                    { header "__format/formatter_tuple.h" }
-    module fwd                                { header "__fwd/format.h" }
-    module indic_conjunct_break_table         { header "__format/indic_conjunct_break_table.h" }
-    module parser_std_format_spec             { header "__format/parser_std_format_spec.h" }
-    module range_default_formatter            { header "__format/range_default_formatter.h" }
-    module range_formatter                    { header "__format/range_formatter.h" }
-    module unicode                            { header "__format/unicode.h" }
-    module width_estimation_table             { header "__format/width_estimation_table.h" }
-    module write_escaped                      { header "__format/write_escaped.h" }
-
-    header "format"
-    export *
-  } // module format
-
-  module forward_list {
-    header "forward_list"
-    export *
-  }
-
-  module fstream {
-    module fwd { header "__fwd/fstream.h" }
-
-    header "fstream"
-    export *
-  }
-
-  module functional {
-    module binary_function              { header "__functional/binary_function.h" }
-    module binary_negate                { header "__functional/binary_negate.h" }
-    module bind_back {
-      header "__functional/bind_back.h"
-      export std.functional.perfect_forward // inherited from and using its operators
-    }
-    module bind_front {
-      header "__functional/bind_front.h"
-      export std.functional.perfect_forward // inherited from and using its operators
-    }
-    module bind                         { header "__functional/bind.h" }
-    module binder1st                    { header "__functional/binder1st.h" }
-    module binder2nd                    { header "__functional/binder2nd.h" }
-    module boyer_moore_searcher {
-      header "__functional/boyer_moore_searcher.h"
-      export std.memory.shared_ptr
-    }
-    module compose {
-      header "__functional/compose.h"
-      export std.functional.perfect_forward // inherited from and using its operators
-    }
-    module default_searcher             { header "__functional/default_searcher.h" }
-    module function                     { header "__functional/function.h" }
-    module hash                         { header "__functional/hash.h" }
-    module identity                     { header "__functional/identity.h" }
-    module invoke                       { header "__functional/invoke.h" }
-    module is_transparent               { header "__functional/is_transparent.h" }
-    module mem_fn                       { header "__functional/mem_fn.h" }
-    module mem_fun_ref                  { header "__functional/mem_fun_ref.h" }
-    module not_fn {
-      header "__functional/not_fn.h"
-      export std.functional.perfect_forward // inherited from and using its operators
-    }
-    module operations                   { header "__functional/operations.h" }
-    module perfect_forward {
-      header "__functional/perfect_forward.h"
-      export std.tuple
-    }
-    module pointer_to_binary_function   { header "__functional/pointer_to_binary_function.h" }
-    module pointer_to_unary_function    { header "__functional/pointer_to_unary_function.h" }
-    module ranges_operations            { header "__functional/ranges_operations.h" }
-    module reference_wrapper            { header "__functional/reference_wrapper.h" }
-    module unary_function               { header "__functional/unary_function.h" }
-    module unary_negate                 { header "__functional/unary_negate.h" }
-    module weak_result_type             { header "__functional/weak_result_type.h" }
-
-    header "functional"
-    export *
-  } // module functional
-
-  module future {
-    header "future"
-    export *
-  }
-
-  module initializer_list {
-    header "initializer_list"
-    export *
-  }
-
-  module iomanip {
-    header "iomanip"
-    export *
-  }
-
-  module ios {
-    module fwd  { header "__fwd/ios.h" }
-    module fpos { header "__ios/fpos.h" }
-
-    header "ios"
-    export *
-  }
-
-  module iosfwd {
-    header "iosfwd"
-    export *
-  }
-
-  module iostream {
-    header "iostream"
-    export *
-  }
-
-  module istream {
-    module fwd { header "__fwd/istream.h" }
-
-    header "istream"
-    export std.ios // base class
-  }
-
-  module iterator {
-    module access                     { header "__iterator/access.h" }
-    module advance                    { header "__iterator/advance.h" }
-    module aliasing_iterator          { header "__iterator/aliasing_iterator.h" }
-    module back_insert_iterator       { header "__iterator/back_insert_iterator.h" }
-    module bounded_iter               { header "__iterator/bounded_iter.h" }
-    module common_iterator            { header "__iterator/common_iterator.h" }
-    module concepts {
-      header "__iterator/concepts.h"
-      export std_core.type_traits.common_reference
-    }
-    module counted_iterator           { header "__iterator/counted_iterator.h" }
-    module cpp17_iterator_concepts    { header "__iterator/cpp17_iterator_concepts.h" }
-    module data                       { header "__iterator/data.h" }
-    module default_sentinel           { header "__iterator/default_sentinel.h" }
-    module distance                   { header "__iterator/distance.h" }
-    module empty                      { header "__iterator/empty.h" }
-    module erase_if_container         { header "__iterator/erase_if_container.h" }
-    module front_insert_iterator      { header "__iterator/front_insert_iterator.h" }
-    module incrementable_traits       { header "__iterator/incrementable_traits.h" }
-    module indirectly_comparable      { header "__iterator/indirectly_comparable.h" }
-    module insert_iterator            { header "__iterator/insert_iterator.h" }
-    module istream_iterator           { header "__iterator/istream_iterator.h" }
-    module istreambuf_iterator        {
-      header "__iterator/istreambuf_iterator.h"
-      export std.string.char_traits
-    }
-    module iter_move                  { header "__iterator/iter_move.h" }
-    module iter_swap                  { header "__iterator/iter_swap.h" }
-    module iterator_traits {
-      header "__iterator/iterator_traits.h"
-      export std_core.type_traits.integral_constant
-    }
-    module iterator_with_data         { header "__iterator/iterator_with_data.h" }
-    module iterator                   { header "__iterator/iterator.h" }
-    module mergeable                  { header "__iterator/mergeable.h" }
-    module move_iterator              { header "__iterator/move_iterator.h" }
-    module move_sentinel              { header "__iterator/move_sentinel.h" }
-    module next                       { header "__iterator/next.h" }
-    module ostream_iterator           { header "__iterator/ostream_iterator.h" }
-    module ostreambuf_iterator {
-      header "__iterator/ostreambuf_iterator.h"
-      export iosfwd // for default template argument of ostreambuf_iterator
-    }
-    module permutable                 { header "__iterator/permutable.h" }
-    module prev                       { header "__iterator/prev.h" }
-    module projected                  { header "__iterator/projected.h" }
-    module ranges_iterator_traits     { header "__iterator/ranges_iterator_traits.h" }
-    module readable_traits            { header "__iterator/readable_traits.h" }
-    module reverse_access             { header "__iterator/reverse_access.h" }
-    module reverse_iterator           { header "__iterator/reverse_iterator.h" }
-    module segmented_iterator         { header "__iterator/segmented_iterator.h" }
-    module size                       { header "__iterator/size.h" }
-    module sortable                   { header "__iterator/sortable.h" }
-    module static_bounded_iter        { header "__iterator/static_bounded_iter.h" }
-    module unreachable_sentinel       { header "__iterator/unreachable_sentinel.h" }
-    module wrap_iter                  { header "__iterator/wrap_iter.h" }
-
-    header "iterator"
-    export *
-  }
-
-  module latch {
-    header "latch"
-    export *
-  }
-
-  module list {
-    header "list"
-    export *
-  }
-
-  module locale {
-    header "locale"
-    header "__locale_dir/locale_guard.h"
-
-    module support {
-      header "__locale_dir/locale_base_api.h"
-      export *
-    }
-
-    module support_impl {
-      textual header "__locale_dir/support/apple.h"
-      textual header "__locale_dir/support/bsd_like.h"
-      textual header "__locale_dir/support/freebsd.h"
-    }
-
-    module locale_base_api {
-      textual header "__locale_dir/locale_base_api/android.h"
-      textual header "__locale_dir/locale_base_api/bsd_locale_defaults.h"
-      textual header "__locale_dir/locale_base_api/bsd_locale_fallbacks.h"
-      textual header "__locale_dir/locale_base_api/fuchsia.h"
-      textual header "__locale_dir/locale_base_api/ibm.h"
-      textual header "__locale_dir/locale_base_api/musl.h"
-      textual header "__locale_dir/locale_base_api/openbsd.h"
-      textual header "__locale_dir/locale_base_api/win32.h"
-    }
-    export *
-  }
-
-  // TODO: Understand why this needs to live in its own module
-  module locale_base [system] {
-    header "__locale"
-    export *
-  }
-
-  module map {
-    header "map"
-    export *
-  }
-
-  module mdspan {
-    module default_accessor   { header "__mdspan/default_accessor.h" }
-    module extents            { header "__mdspan/extents.h" }
-    module fwd                { header "__fwd/mdspan.h" }
-    module layout_left        { header "__mdspan/layout_left.h" }
-    module layout_right       { header "__mdspan/layout_right.h" }
-    module layout_stride      { header "__mdspan/layout_stride.h" }
-    module mdspan {
-      header "__mdspan/mdspan.h"
-      export std.array // returned by some methods
-    }
-
-    header "mdspan"
-    export *
-  }
-
-  module memory {
-    module addressof                          { header "__memory/addressof.h" }
-    module align                              { header "__memory/align.h" }
-    module aligned_alloc                      { header "__memory/aligned_alloc.h" }
-    module allocate_at_least                  { header "__memory/allocate_at_least.h" }
-    module allocation_guard                   { header "__memory/allocation_guard.h" }
-    module allocator                          { header "__memory/allocator.h" }
-    module allocator_arg_t                    { header "__memory/allocator_arg_t.h" }
-    module allocator_destructor               { header "__memory/allocator_destructor.h" }
-    module allocator_traits                   { header "__memory/allocator_traits.h" }
-    module array_cookie                       { header "__memory/array_cookie.h" }
-    module assume_aligned                     { header "__memory/assume_aligned.h" }
-    module auto_ptr                           { header "__memory/auto_ptr.h" }
-    module builtin_new_allocator              { header "__memory/builtin_new_allocator.h" }
-    module compressed_pair                    { header "__memory/compressed_pair.h" }
-    module concepts                           { header "__memory/concepts.h" }
-    module construct_at                       { header "__memory/construct_at.h" }
-    module destruct_n                         { header "__memory/destruct_n.h" }
-    module fwd                                { header "__fwd/memory.h" }
-    module inout_ptr                          { header "__memory/inout_ptr.h" }
-    module noexcept_move_assign_container     { header "__memory/noexcept_move_assign_container.h" }
-    module out_ptr                            { header "__memory/out_ptr.h" }
-    module pointer_traits                     { header "__memory/pointer_traits.h" }
-    module ranges_construct_at                { header "__memory/ranges_construct_at.h" }
-    module ranges_uninitialized_algorithms {
-      header "__memory/ranges_uninitialized_algorithms.h"
-      export std.algorithm.in_out_result
-    }
-    module raw_storage_iterator               { header "__memory/raw_storage_iterator.h" }
-    module shared_count                       { header "__memory/shared_count.h" }
-    module shared_ptr                         { header "__memory/shared_ptr.h" }
-    module swap_allocator                     { header "__memory/swap_allocator.h" }
-    module temp_value                         { header "__memory/temp_value.h" }
-    module temporary_buffer                   {
-      header "__memory/temporary_buffer.h"
-      export std.utility.pair // return type of std::get_temporary_buffer()
-    }
-    module uninitialized_algorithms {
-      header "__memory/uninitialized_algorithms.h"
-      export std.utility.pair
-    }
-    module unique_ptr {
-      header "__memory/unique_ptr.h"
-    }
-    module unique_temporary_buffer {
-      header "__memory/unique_temporary_buffer.h"
-      export std.memory.unique_ptr
-      export std_core.type_traits.is_constant_evaluated
-    }
-    module uses_allocator                     { header "__memory/uses_allocator.h" }
-    module uses_allocator_construction        { header "__memory/uses_allocator_construction.h" }
-
-    header "memory"
-    export *
-  }
-
-  module memory_resource {
-    module fwd                            { header "__fwd/memory_resource.h" }
-    module memory_resource                { header "__memory_resource/memory_resource.h" }
-    module monotonic_buffer_resource      { header "__memory_resource/monotonic_buffer_resource.h" }
-    module polymorphic_allocator          { header "__memory_resource/polymorphic_allocator.h" }
-    module pool_options                   { header "__memory_resource/pool_options.h" }
-    module synchronized_pool_resource     { header "__memory_resource/synchronized_pool_resource.h" }
-    module unsynchronized_pool_resource   { header "__memory_resource/unsynchronized_pool_resource.h" }
-
-    header "memory_resource"
-    export *
-  }
-
-  module mutex {
-    module lock_guard     { header "__mutex/lock_guard.h" }
-    module mutex          { header "__mutex/mutex.h" }
-    module once_flag      { header "__mutex/once_flag.h" }
-    module tag_types      { header "__mutex/tag_types.h" }
-    module unique_lock    { header "__mutex/unique_lock.h" }
-
-    header "mutex"
-    export *
-  }
-
-  module new {
-    header "new"
-    export *
-  }
-
-  module numbers {
-    header "numbers"
-    export *
-  }
-
-  module numeric {
-    module accumulate                 { header "__numeric/accumulate.h" }
-    module adjacent_difference        { header "__numeric/adjacent_difference.h" }
-    module exclusive_scan             { header "__numeric/exclusive_scan.h" }
-    module gcd_lcm                    { header "__numeric/gcd_lcm.h" }
-    module inclusive_scan             { header "__numeric/inclusive_scan.h" }
-    module inner_product              { header "__numeric/inner_product.h" }
-    module iota                       { header "__numeric/iota.h" }
-    module midpoint                   { header "__numeric/midpoint.h" }
-    module partial_sum                { header "__numeric/partial_sum.h" }
-    module pstl                       { header "__numeric/pstl.h" }
-    module reduce                     { header "__numeric/reduce.h" }
-    module saturation_arithmetic      { header "__numeric/saturation_arithmetic.h" }
-    module transform_exclusive_scan   { header "__numeric/transform_exclusive_scan.h" }
-    module transform_inclusive_scan   { header "__numeric/transform_inclusive_scan.h" }
-    module transform_reduce           { header "__numeric/transform_reduce.h" }
-
-    header "numeric"
-    export *
-  }
-
-  module optional {
-    header "optional"
-    export *
-  }
-
-  module ostream {
-    module basic_ostream {
-      header "__ostream/basic_ostream.h"
-      export std.ios // base class
-    }
-    module fwd {
-      header "__fwd/ostream.h"
-    }
-    module print {
-      header "__ostream/print.h"
-      export *
-    }
-
-    header "ostream"
-    export *
-  }
-
-  module print {
-    header "print"
-    export *
-  }
-
-  module queue {
-    module fwd { header "__fwd/queue.h" }
-
-    header "queue"
-    export *
-  }
-
-  module random {
-    module bernoulli_distribution             { header "__random/bernoulli_distribution.h" }
-    module binomial_distribution              { header "__random/binomial_distribution.h" }
-    module cauchy_distribution                { header "__random/cauchy_distribution.h" }
-    module chi_squared_distribution           { header "__random/chi_squared_distribution.h" }
-    module clamp_to_integral                  { header "__random/clamp_to_integral.h" }
-    module default_random_engine              { header "__random/default_random_engine.h" }
-    module discard_block_engine               { header "__random/discard_block_engine.h" }
-    module discrete_distribution              { header "__random/discrete_distribution.h" }
-    module exponential_distribution           { header "__random/exponential_distribution.h" }
-    module extreme_value_distribution         { header "__random/extreme_value_distribution.h" }
-    module fisher_f_distribution              { header "__random/fisher_f_distribution.h" }
-    module gamma_distribution                 { header "__random/gamma_distribution.h" }
-    module generate_canonical                 { header "__random/generate_canonical.h" }
-    module geometric_distribution             { header "__random/geometric_distribution.h" }
-    module independent_bits_engine            { header "__random/independent_bits_engine.h" }
-    module is_seed_sequence                   { header "__random/is_seed_sequence.h" }
-    module is_valid {
-      header "__random/is_valid.h"
-      export std_core.type_traits.integral_constant
-    }
-    module knuth_b                            { header "__random/knuth_b.h" }
-    module linear_congruential_engine         { header "__random/linear_congruential_engine.h" }
-    module log2                               { header "__random/log2.h" }
-    module lognormal_distribution             { header "__random/lognormal_distribution.h" }
-    module mersenne_twister_engine            { header "__random/mersenne_twister_engine.h" }
-    module negative_binomial_distribution     { header "__random/negative_binomial_distribution.h" }
-    module normal_distribution                { header "__random/normal_distribution.h" }
-    module piecewise_constant_distribution    { header "__random/piecewise_constant_distribution.h" }
-    module piecewise_linear_distribution      { header "__random/piecewise_linear_distribution.h" }
-    module poisson_distribution               { header "__random/poisson_distribution.h" }
-    module random_device                      { header "__random/random_device.h" }
-    module ranlux                             { header "__random/ranlux.h" }
-    module seed_seq                           { header "__random/seed_seq.h" }
-    module shuffle_order_engine               { header "__random/shuffle_order_engine.h" }
-    module student_t_distribution             { header "__random/student_t_distribution.h" }
-    module subtract_with_carry_engine         { header "__random/subtract_with_carry_engine.h" }
-    module uniform_int_distribution           { header "__random/uniform_int_distribution.h" }
-    module uniform_random_bit_generator       { header "__random/uniform_random_bit_generator.h" }
-    module uniform_real_distribution          { header "__random/uniform_real_distribution.h" }
-    module weibull_distribution               { header "__random/weibull_distribution.h" }
-
-    header "random"
-    export *
-  }
-
-  module ranges {
-    module access                         { header "__ranges/access.h" }
-    module all                            { header "__ranges/all.h" }
-    module as_rvalue_view                 { header "__ranges/as_rvalue_view.h" }
-    module chunk_by_view {
-      header "__ranges/chunk_by_view.h"
-      export std.functional.bind_back
-    }
-    module common_view                    { header "__ranges/common_view.h" }
-    module concepts                       { header "__ranges/concepts.h" }
-    module container_compatible_range     { header "__ranges/container_compatible_range.h" }
-    module counted {
-      header "__ranges/counted.h"
-      export std.span            // return type of views::counted
-      export std.ranges.subrange // return type of views::counted
-    }
-    module dangling {
-      header "__ranges/dangling.h"
-    }
-    module data {
-      header "__ranges/data.h"
-    }
-    module drop_view {
-      header "__ranges/drop_view.h"
-      export std.functional.bind_back
-    }
-    module drop_while_view {
-      header "__ranges/drop_while_view.h"
-      export std.functional.bind_back
-    }
-    module elements_view                  { header "__ranges/elements_view.h" }
-    module empty                          { header "__ranges/empty.h" }
-    module empty_view                     { header "__ranges/empty_view.h" }
-    module enable_borrowed_range          { header "__ranges/enable_borrowed_range.h" }
-    module enable_view                    { header "__ranges/enable_view.h" }
-    module filter_view {
-      header "__ranges/filter_view.h"
-      export std.functional.bind_back
-    }
-    module from_range                     { header "__ranges/from_range.h" }
-    module iota_view                      { header "__ranges/iota_view.h" }
-    module istream_view                   { header "__ranges/istream_view.h" }
-    module join_view                      { header "__ranges/join_view.h" }
-    module lazy_split_view {
-      header "__ranges/lazy_split_view.h"
-      export std.functional.bind_back
-    }
-    module movable_box                    { header "__ranges/movable_box.h" }
-    module non_propagating_cache          { header "__ranges/non_propagating_cache.h" }
-    module owning_view                    { header "__ranges/owning_view.h" }
-    module range_adaptor                  { header "__ranges/range_adaptor.h" }
-    module rbegin                         { header "__ranges/rbegin.h" }
-    module ref_view                       { header "__ranges/ref_view.h" }
-    module rend                           { header "__ranges/rend.h" }
-    module repeat_view                    { header "__ranges/repeat_view.h" }
-    module reverse_view                   { header "__ranges/reverse_view.h" }
-    module single_view                    { header "__ranges/single_view.h" }
-    module size                           { header "__ranges/size.h" }
-    module split_view {
-      header "__ranges/split_view.h"
-      export std.functional.bind_back
-    }
-    module subrange {
-      header "__ranges/subrange.h"
-      export std.ranges.subrange_fwd
-    }
-    module subrange_fwd {
-      header "__fwd/subrange.h"
-    }
-    module take_view {
-      header "__ranges/take_view.h"
-      export std.functional.bind_back
-    }
-    module take_while_view {
-      header "__ranges/take_while_view.h"
-      export std.functional.bind_back
-    }
-    module to {
-      header "__ranges/to.h"
-      export std.functional.bind_back
-    }
-    module transform_view {
-      header "__ranges/transform_view.h"
-      export std.functional.bind_back
-    }
-    module view_interface {
-      header "__ranges/view_interface.h"
-    }
-    module views {
-      header "__ranges/views.h"
-    }
-    module zip_view {
-      header "__ranges/zip_view.h"
-      export std.utility.pair
-    }
-
-    header "ranges"
-    export *
-  } // module ranges
-
-  module ratio {
-    header "ratio"
-    export *
-  }
-
-  module regex {
-    header "regex"
-    export *
-  }
-
-  module scoped_allocator {
-    header "scoped_allocator"
-    export *
-  }
-
-  module semaphore {
-    header "semaphore"
-    export *
-  }
-
-  module set {
-    header "set"
-    export *
-  }
-
-  module shared_mutex {
-    header "shared_mutex"
-    export *
-  }
-
-  module source_location {
-    header "source_location"
-    export *
-  }
-
-  module span {
-    module fwd { header "__fwd/span.h" }
-
-    header "span"
-    export *
-  }
-
-  module sstream {
-    module fwd { header "__fwd/sstream.h" }
-
-    header "sstream"
-    export *
-  }
-
-  module stack {
-    module fwd { header "__fwd/stack.h" }
-
-    header "stack"
-    export *
-  }
-
-  module stdexcept {
-    header "stdexcept"
-    export *
-  }
-
-  module stop_token {
-    module atomic_unique_lock     { header "__stop_token/atomic_unique_lock.h" }
-    module intrusive_list_view    { header "__stop_token/intrusive_list_view.h" }
-    module intrusive_shared_ptr   { header "__stop_token/intrusive_shared_ptr.h" }
-    module stop_callback          { header "__stop_token/stop_callback.h" }
-    module stop_source            { header "__stop_token/stop_source.h" }
-    module stop_state             { header "__stop_token/stop_state.h" }
-    module stop_token             { header "__stop_token/stop_token.h" }
-
-    header "stop_token"
-    export *
-  }
-
-  module streambuf {
-    module fwd { header "__fwd/streambuf.h" }
-
-    header "streambuf"
-    export *
-  }
-
-  module string {
-    module char_traits              { header "__string/char_traits.h" }
-    module constexpr_c_functions    { header "__string/constexpr_c_functions.h" }
-    module extern_template_lists    { header "__string/extern_template_lists.h" }
-    module fwd                      {  header "__fwd/string.h" }
-
-    header "string"
-    export *
-  }
-
-  module string_view {
-    module fwd { header "__fwd/string_view.h" }
-
-    header "string_view"
-    export *
-  }
-
-  module strstream {
-    header "strstream"
-    export *
-  }
-
-  module syncstream {
-    header "syncstream"
-    export *
-  }
-
-  module system_error {
-    module errc               { header "__system_error/errc.h" }
-    module error_category     { header "__system_error/error_category.h" }
-    module error_code {
-      header "__system_error/error_code.h"
-      export std.system_error.error_category // methods of error_code return that type
-    }
-    module error_condition    { header "__system_error/error_condition.h" }
-    module system_error       { header "__system_error/system_error.h" }
-
-    header "system_error"
-    export *
-  }
-
-  module thread {
-    module formatter              { header "__thread/formatter.h" }
-    module id                     { header "__thread/id.h" }
-    module jthread                { header "__thread/jthread.h" }
-    module poll_with_backoff      { header "__thread/poll_with_backoff.h" }
-    module this_thread            { header "__thread/this_thread.h" }
-    module thread                 { header "__thread/thread.h" }
-    module timed_backoff_policy   { header "__thread/timed_backoff_policy.h" }
-
-    module support {
-      header "__thread/support.h"
-      export *
-    }
-    module support_impl {
-      textual header "__thread/support/c11.h"
-      textual header "__thread/support/external.h"
-      textual header "__thread/support/pthread.h"
-      textual header "__thread/support/windows.h"
-    }
-
-    header "thread"
-    export *
-  }
+// C standard library interface wrappers
+module std_cassert [system] {
+  // <cassert>'s use of NDEBUG requires textual inclusion.
+  textual header "cassert"
+}
+module std_ccomplex [system] {
+  header "ccomplex"
+  export *
+}
+module std_cctype [system] {
+  header "cctype"
+  export *
+}
+module std_cerrno [system] {
+  header "cerrno"
+  export *
+}
+module std_cfenv [system] {
+  header "cfenv"
+  export *
+}
+module std_cfloat [system] {
+  header "cfloat"
+  export *
+}
+module std_cinttypes [system] {
+  header "cinttypes"
+  export *
+}
+module std_ciso646 [system] {
+  header "ciso646"
+  export *
+}
+module std_climits [system] {
+  header "climits"
+  export *
+}
+module std_clocale [system] {
+  header "clocale"
+  export *
+}
+module std_cmath [system] {
+  header "cmath"
+  export *
+}
+module std_csetjmp [system] {
+  header "csetjmp"
+  export *
+}
+module std_csignal [system] {
+  header "csignal"
+  export *
+}
+// FIXME: <cstdalign> is missing.
+module std_cstdarg [system] {
+  header "cstdarg"
+  export *
+}
+module std_cstdbool [system] {
+  header "cstdbool"
+  export *
+}
+module std_cstddef [system] {
+  header "cstddef"
+  export *
+}
+module std_cstdint [system] {
+  header "cstdint"
+  export *
+}
+module std_cstdio [system] {
+  header "cstdio"
+  export *
+}
+module std_cstdlib [system] {
+  header "cstdlib"
+  export *
+}
+module std_cstring [system] {
+  header "cstring"
+  export *
+}
+module std_ctgmath [system] {
+  header "ctgmath"
+  export *
+}
+module std_ctime [system] {
+  header "ctime"
+  export *
+}
+module std_cuchar [system] {
+  header "cuchar"
+  export *
+}
+module std_cwchar [system] {
+  header "cwchar"
+  export *
+}
+module std_cwctype [system] {
+  header "cwctype"
+  export *
+}
 
-  module tuple {
-    module find_index               { header "__tuple/find_index.h" }
-    module ignore                   { header "__tuple/ignore.h" }
-    module make_tuple_types         { header "__tuple/make_tuple_types.h" }
-    module sfinae_helpers           { header "__tuple/sfinae_helpers.h" }
-    module tuple_element            { header "__tuple/tuple_element.h" }
-    module tuple_indices            { header "__tuple/tuple_indices.h" }
-    module tuple_like_ext           { header "__tuple/tuple_like_ext.h" }
-    module tuple_like_no_subrange   { header "__tuple/tuple_like_no_subrange.h" }
-    module tuple_like               { header "__tuple/tuple_like.h" }
-    module tuple_size               { header "__tuple/tuple_size.h" }
-    module tuple_types              { header "__tuple/tuple_types.h" }
+// C standard library interfaces augmented/replaced in C++
+// <assert.h> provided by C library.
+module std_complex_h [system] {
+  header "complex.h"
+  export *
+}
+module std_ctype_h [system] {
+  header "ctype.h"
+  export *
+}
+module std_errno_h [system] {
+  header "errno.h"
+  export *
+}
+module std_fenv_h [system] {
+  header "fenv.h"
+  export *
+}
+module std_float_h [system] {
+  header "float.h"
+  export *
+}
+module std_inttypes_h [system] {
+  header "inttypes.h"
+  export *
+}
+// <iso646.h> provided by compiler.
+module std_locale_h [system] {
+  header "locale.h"
+  export *
+}
+module std_math_h [system] {
+  header "math.h"
+  export *
+}
+// <setjmp.h> provided by C library.
+// <signal.h> provided by C library.
+// FIXME: <stdalign.h> is missing.
+// <stdarg.h> provided by compiler.
+module std_stdatomic_h [system] {
+  header "stdatomic.h"
+  export *
+}
+module std_stdbool_h [system] {
+  // <stdbool.h>'s __bool_true_false_are_defined macro requires textual inclusion.
+  textual header "stdbool.h"
+  export *
+}
+module std_stddef_h [system] {
+  // <stddef.h>'s __need_* macros require textual inclusion.
+  textual header "stddef.h"
+  export *
+}
+module std_stdint_h [system] {
+  header "stdint.h"
+  export *
+}
+module std_stdio_h [system] {
+  // <stdio.h>'s __need_* macros require textual inclusion.
+  textual header "stdio.h"
+  export *
+}
+module std_stdlib_h [system] {
+  // <stdlib.h>'s __need_* macros require textual inclusion.
+  textual header "stdlib.h"
+  export *
+}
+module std_string_h [system] {
+  header "string.h"
+  export *
+}
+module std_tgmath_h [system] {
+  header "tgmath.h"
+  export *
+}
+module std_uchar_h [system] {
+  header "uchar.h"
+  export *
+}
+// <time.h> provided by C library.
+module std_wchar_h [system] {
+  // <wchar.h>'s __need_* macros require textual inclusion.
+  textual header "wchar.h"
+  export *
+}
+module std_wctype_h [system] {
+  header "wctype.h"
+  export *
+}
 
-    header "tuple"
+// Experimental C++ standard library interfaces
+module std_experimental [system] {
+  module iterator {
+    header "experimental/iterator"
     export *
   }
-
-  module typeindex {
-    header "typeindex"
+  module memory {
+    header "experimental/memory"
     export *
   }
-
-  module typeinfo {
-    header "typeinfo"
+  module propagate_const {
+    header "experimental/propagate_const"
     export *
   }
+  module simd {
+    module aligned_tag          { private header "experimental/__simd/aligned_tag.h" }
+    module declaration          { private header "experimental/__simd/declaration.h" }
+    module reference            { private header "experimental/__simd/reference.h" }
+    module scalar               { private header "experimental/__simd/scalar.h" }
+    module simd                 { private header "experimental/__simd/simd.h" }
+    module simd_mask            { private header "experimental/__simd/simd_mask.h" }
+    module traits               { private header "experimental/__simd/traits.h" }
+    module utility              { private header "experimental/__simd/utility.h" }
+    module vec_ext              { private header "experimental/__simd/vec_ext.h" }
 
-  module unordered_map {
-    header "unordered_map"
+    header "experimental/simd"
     export *
   }
-
-  module unordered_set {
-    header "unordered_set"
+  module type_traits {
+    header "experimental/type_traits"
     export *
   }
-
   module utility {
-    module as_const                   { header "__utility/as_const.h" }
-    module as_lvalue                  { header "__utility/as_lvalue.h" }
-    module auto_cast                  {
-      header "__utility/auto_cast.h"
-      export std_core.type_traits.decay // the macro expansion uses that trait
-    }
-    module cmp                        { header "__utility/cmp.h" }
-    module convert_to_integral        { header "__utility/convert_to_integral.h" }
-    module exception_guard            { header "__utility/exception_guard.h" }
-    module exchange                   { header "__utility/exchange.h" }
-    module forward_like               { header "__utility/forward_like.h" }
-    module in_place {
-      header "__utility/in_place.h"
-      export std_core.type_traits.integral_constant
-    }
-    module integer_sequence           { header "__utility/integer_sequence.h" }
-    module is_pointer_in_range        { header "__utility/is_pointer_in_range.h" }
-    module is_valid_range             { header "__utility/is_valid_range.h" }
-    module move                       { header "__utility/move.h" }
-    module no_destroy                 { header "__utility/no_destroy.h" }
-    module pair                       { header "__utility/pair.h" }
-    module piecewise_construct        { header "__utility/piecewise_construct.h" }
-    module priority_tag               { header "__utility/priority_tag.h" }
-    module private_constructor_tag    { header "__utility/private_constructor_tag.h" }
-    module rel_ops                    { header "__utility/rel_ops.h" }
-    module scope_guard                { header "__utility/scope_guard.h" }
-    module small_buffer               { header "__utility/small_buffer.h" }
-    module swap                       { header "__utility/swap.h" }
-    module to_underlying              { header "__utility/to_underlying.h" }
-    module unreachable                { header "__utility/unreachable.h" }
-
-    header "utility"
-    export *
-  }
-
-  module valarray {
-    header "valarray"
+    header "experimental/utility"
     export *
   }
-
-  module variant {
-    module fwd       { header "__fwd/variant.h" }
-    module monostate { header "__variant/monostate.h" }
-
-    header "variant"
+  module __config {
+    textual header "experimental/__config"
     export *
   }
+}
 
-  module vector {
-    module fwd                   { header "__fwd/vector.h" }
-
-    module comparison            { header "__vector/comparison.h" }
-    module container_traits      { header "__vector/container_traits.h" }
-    module erase                 { header "__vector/erase.h" }
-    module vector_bool_formatter {
-      header "__vector/vector_bool_formatter.h"
-
-      export std.format.formatter
-    }
-    module pmr                   {
-      header "__vector/pmr.h"
+// Convenience method to get all of the above modules in a single import statement.
+// Importing only the needed modules is likely to be more performant.
+module std [system] {
+  header "__std_clang_module"
+  export *
+}
 
-      export std.memory_resource.polymorphic_allocator
-    }
-    module swap                  { header "__vector/swap.h" }
-    module vector_bool           {
-      header "__vector/vector_bool.h"
-      export std.bit_reference
-      export std.memory.allocator
-      export std.vector.comparison
-      export std.vector.fwd
-      export std.vector.swap
-    }
-    module vector                {
-      header "__vector/vector.h"
-      export std.iterator.bounded_iter
-      export std.iterator.wrap_iter
-      export std.memory.allocator
-      export std.vector.comparison
-      export std.vector.fwd
-      export std.vector.swap
-    }
+// Implementation detail headers that are private to libc++. These modules
+// must not be directly imported.
+module std_private_assert            [system] {
+  header "__assert"
+  export *
+}
+module std_private_bit_reference     [system] {
+  header "__bit_reference"
+  export *
+}
+module std_private_fwd_bit_reference [system] {
+  header "__fwd/bit_reference.h"
+}
+module std_private_config            [system] {
+  textual header "__config"
+  textual header "__configuration/abi.h"
+  textual header "__configuration/availability.h"
+  textual header "__configuration/compiler.h"
+  textual header "__configuration/language.h"
+  textual header "__configuration/platform.h"
+  export *
+}
+module std_private_hash_table        [system] {
+  header "__hash_table"
+  export *
+}
+module std_private_locale            [system] {
+  header "__locale"
+  export *
+}
+module std_private_mbstate_t         [system] {
+  header "__mbstate_t.h"
+  export *
+}
+module std_private_node_handle       [system] {
+  header "__node_handle"
+  export *
+}
+module std_private_split_buffer      [system] {
+  header "__split_buffer"
+  export *
+}
+module std_private_std_mbstate_t     [system] {
+  header "__std_mbstate_t.h"
+  export *
+}
+module std_private_tree              [system] {
+  header "__tree"
+  export *
+}
+module std_private_undef_macros      [system] {
+  textual header "__undef_macros"
+  export *
+}
+module std_private_verbose_abort     [system] {
+  header "__verbose_abort"
+  export *
+}
 
-    header "vector"
-    export *
-  }
+module std_private_algorithm_adjacent_find                               [system] { header "__algorithm/adjacent_find.h" }
+module std_private_algorithm_all_of                                      [system] { header "__algorithm/all_of.h" }
+module std_private_algorithm_any_of                                      [system] { header "__algorithm/any_of.h" }
+module std_private_algorithm_binary_search                               [system] { header "__algorithm/binary_search.h" }
+module std_private_algorithm_clamp                                       [system] { header "__algorithm/clamp.h" }
+module std_private_algorithm_comp                                        [system] { header "__algorithm/comp.h" }
+module std_private_algorithm_comp_ref_type                               [system] { header "__algorithm/comp_ref_type.h" }
+module std_private_algorithm_copy                                        [system] {
+  header "__algorithm/copy.h"
+  export std_private_algorithm_copy_move_common
+}
+module std_private_algorithm_copy_backward                               [system] { header "__algorithm/copy_backward.h" }
+module std_private_algorithm_copy_if                                     [system] { header "__algorithm/copy_if.h" }
+module std_private_algorithm_copy_move_common                            [system] {
+  header "__algorithm/copy_move_common.h"
+  export std_private_type_traits_is_trivially_copyable
+}
+module std_private_algorithm_copy_n                                      [system] { header "__algorithm/copy_n.h" }
+module std_private_algorithm_count                                       [system] { header "__algorithm/count.h" }
+module std_private_algorithm_count_if                                    [system] { header "__algorithm/count_if.h" }
+module std_private_algorithm_equal                                       [system] { header "__algorithm/equal.h" }
+module std_private_algorithm_equal_range                                 [system] { header "__algorithm/equal_range.h" }
+module std_private_algorithm_fill                                        [system] { header "__algorithm/fill.h" }
+module std_private_algorithm_fill_n                                      [system] { header "__algorithm/fill_n.h" }
+module std_private_algorithm_find                                        [system] {
+  header "__algorithm/find.h"
+  export std_private_algorithm_unwrap_iter
+}
+module std_private_algorithm_find_end                                    [system] { header "__algorithm/find_end.h" }
+module std_private_algorithm_find_first_of                               [system] { header "__algorithm/find_first_of.h" }
+module std_private_algorithm_find_if                                     [system] { header "__algorithm/find_if.h" }
+module std_private_algorithm_find_if_not                                 [system] { header "__algorithm/find_if_not.h" }
+module std_private_algorithm_find_segment_if                             [system] { header "__algorithm/find_segment_if.h" }
+module std_private_algorithm_fold                                        [system] { header "__algorithm/fold.h" }
+module std_private_algorithm_for_each                                    [system] { header "__algorithm/for_each.h" }
+module std_private_algorithm_for_each_n                                  [system] { header "__algorithm/for_each_n.h" }
+module std_private_algorithm_for_each_segment                            [system] { header "__algorithm/for_each_segment.h" }
+module std_private_algorithm_generate                                    [system] { header "__algorithm/generate.h" }
+module std_private_algorithm_generate_n                                  [system] { header "__algorithm/generate_n.h" }
+module std_private_algorithm_half_positive                               [system] { header "__algorithm/half_positive.h" }
+module std_private_algorithm_in_found_result                             [system] { header "__algorithm/in_found_result.h" }
+module std_private_algorithm_in_fun_result                               [system] { header "__algorithm/in_fun_result.h" }
+module std_private_algorithm_in_in_out_result                            [system] { header "__algorithm/in_in_out_result.h" }
+module std_private_algorithm_in_in_result                                [system] { header "__algorithm/in_in_result.h" }
+module std_private_algorithm_in_out_out_result                           [system] { header "__algorithm/in_out_out_result.h" }
+module std_private_algorithm_in_out_result                               [system] { header "__algorithm/in_out_result.h" }
+module std_private_algorithm_includes                                    [system] { header "__algorithm/includes.h" }
+module std_private_algorithm_inplace_merge                               [system] { header "__algorithm/inplace_merge.h" }
+module std_private_algorithm_is_heap                                     [system] { header "__algorithm/is_heap.h" }
+module std_private_algorithm_is_heap_until                               [system] { header "__algorithm/is_heap_until.h" }
+module std_private_algorithm_is_partitioned                              [system] { header "__algorithm/is_partitioned.h" }
+module std_private_algorithm_is_permutation                              [system] { header "__algorithm/is_permutation.h" }
+module std_private_algorithm_is_sorted                                   [system] { header "__algorithm/is_sorted.h" }
+module std_private_algorithm_is_sorted_until                             [system] { header "__algorithm/is_sorted_until.h" }
+module std_private_algorithm_iter_swap                                   [system] { header "__algorithm/iter_swap.h" }
+module std_private_algorithm_iterator_operations                         [system] {
+  header "__algorithm/iterator_operations.h"
+  export *
+}
+module std_private_algorithm_lexicographical_compare                     [system] { header "__algorithm/lexicographical_compare.h" }
+module std_private_algorithm_lexicographical_compare_three_way           [system] { header "__algorithm/lexicographical_compare_three_way.h" }
+module std_private_algorithm_lower_bound                                 [system] { header "__algorithm/lower_bound.h" }
+module std_private_algorithm_make_heap                                   [system] { header "__algorithm/make_heap.h" }
+module std_private_algorithm_make_projected                              [system] { header "__algorithm/make_projected.h" }
+module std_private_algorithm_max                                         [system] { header "__algorithm/max.h" }
+module std_private_algorithm_max_element                                 [system] { header "__algorithm/max_element.h" }
+module std_private_algorithm_merge                                       [system] { header "__algorithm/merge.h" }
+module std_private_algorithm_min                                         [system] { header "__algorithm/min.h" }
+module std_private_algorithm_min_element                                 [system] { header "__algorithm/min_element.h" }
+module std_private_algorithm_min_max_result                              [system] { header "__algorithm/min_max_result.h" }
+module std_private_algorithm_minmax                                      [system] {
+  header "__algorithm/minmax.h"
+  export *
+}
+module std_private_algorithm_minmax_element                              [system] { header "__algorithm/minmax_element.h" }
+module std_private_algorithm_mismatch                                    [system] {
+  header "__algorithm/mismatch.h"
+  export std_private_algorithm_simd_utils
+  export std_private_iterator_aliasing_iterator
+}
+module std_private_algorithm_move                                        [system] { header "__algorithm/move.h" }
+module std_private_algorithm_move_backward                               [system] { header "__algorithm/move_backward.h" }
+module std_private_algorithm_next_permutation                            [system] { header "__algorithm/next_permutation.h" }
+module std_private_algorithm_none_of                                     [system] { header "__algorithm/none_of.h" }
+module std_private_algorithm_nth_element                                 [system] { header "__algorithm/nth_element.h" }
+module std_private_algorithm_partial_sort                                [system] { header "__algorithm/partial_sort.h" }
+module std_private_algorithm_partial_sort_copy                           [system] { header "__algorithm/partial_sort_copy.h" }
+module std_private_algorithm_partition                                   [system] { header "__algorithm/partition.h" }
+module std_private_algorithm_partition_copy                              [system] { header "__algorithm/partition_copy.h" }
+module std_private_algorithm_partition_point                             [system] { header "__algorithm/partition_point.h" }
+module std_private_algorithm_pop_heap                                    [system] { header "__algorithm/pop_heap.h" }
+module std_private_algorithm_prev_permutation                            [system] { header "__algorithm/prev_permutation.h" }
+module std_private_algorithm_pstl                                        [system] {
+  header "__algorithm/pstl.h"
+  export *
+}
+module std_private_algorithm_push_heap                                   [system] { header "__algorithm/push_heap.h" }
+module std_private_algorithm_ranges_adjacent_find                        [system] { header "__algorithm/ranges_adjacent_find.h" }
+module std_private_algorithm_ranges_all_of                               [system] { header "__algorithm/ranges_all_of.h" }
+module std_private_algorithm_ranges_any_of                               [system] { header "__algorithm/ranges_any_of.h" }
+module std_private_algorithm_ranges_binary_search                        [system] {
+  header "__algorithm/ranges_binary_search.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_clamp                                [system] {
+  header "__algorithm/ranges_clamp.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_contains                             [system] { header "__algorithm/ranges_contains.h" }
+module std_private_algorithm_ranges_contains_subrange                    [system] { header "__algorithm/ranges_contains_subrange.h" }
+module std_private_algorithm_ranges_copy                                 [system] {
+  header "__algorithm/ranges_copy.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_copy_backward                        [system] {
+  header "__algorithm/ranges_copy_backward.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_copy_if                              [system] {
+  header "__algorithm/ranges_copy_if.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_copy_n                               [system] {
+  header "__algorithm/ranges_copy_n.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_count                                [system] { header "__algorithm/ranges_count.h" }
+module std_private_algorithm_ranges_count_if                             [system] { header "__algorithm/ranges_count_if.h" }
+module std_private_algorithm_ranges_ends_with                            [system] { header "__algorithm/ranges_ends_with.h" }
+module std_private_algorithm_ranges_equal                                [system] { header "__algorithm/ranges_equal.h" }
+module std_private_algorithm_ranges_equal_range                          [system] {
+  header "__algorithm/ranges_equal_range.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_fill                                 [system] { header "__algorithm/ranges_fill.h" }
+module std_private_algorithm_ranges_fill_n                               [system] { header "__algorithm/ranges_fill_n.h" }
+module std_private_algorithm_ranges_find                                 [system] { header "__algorithm/ranges_find.h" }
+module std_private_algorithm_ranges_find_end                             [system] { header "__algorithm/ranges_find_end.h" }
+module std_private_algorithm_ranges_find_first_of                        [system] { header "__algorithm/ranges_find_first_of.h" }
+module std_private_algorithm_ranges_find_if                              [system] { header "__algorithm/ranges_find_if.h" }
+module std_private_algorithm_ranges_find_if_not                          [system] { header "__algorithm/ranges_find_if_not.h" }
+module std_private_algorithm_ranges_for_each                             [system] {
+  header "__algorithm/ranges_for_each.h"
+  export std_private_algorithm_in_fun_result
+}
+module std_private_algorithm_ranges_for_each_n                           [system] {
+  header "__algorithm/ranges_for_each_n.h"
+  export std_private_algorithm_in_fun_result
+}
+module std_private_algorithm_ranges_generate                             [system] { header "__algorithm/ranges_generate.h" }
+module std_private_algorithm_ranges_generate_n                           [system] { header "__algorithm/ranges_generate_n.h" }
+module std_private_algorithm_ranges_includes                             [system] {
+  header "__algorithm/ranges_includes.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_inplace_merge                        [system] {
+  header "__algorithm/ranges_inplace_merge.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_is_heap                              [system] {
+  header "__algorithm/ranges_is_heap.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_is_heap_until                        [system] {
+  header "__algorithm/ranges_is_heap_until.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_is_partitioned                       [system] { header "__algorithm/ranges_is_partitioned.h" }
+module std_private_algorithm_ranges_is_permutation                       [system] { header "__algorithm/ranges_is_permutation.h" }
+module std_private_algorithm_ranges_is_sorted                            [system] {
+  header "__algorithm/ranges_is_sorted.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_is_sorted_until                      [system] {
+  header "__algorithm/ranges_is_sorted_until.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_iterator_concept                     [system] { header "__algorithm/ranges_iterator_concept.h" }
+module std_private_algorithm_ranges_lexicographical_compare              [system] {
+  header "__algorithm/ranges_lexicographical_compare.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_lower_bound                          [system] {
+  header "__algorithm/ranges_lower_bound.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_make_heap                            [system] {
+  header "__algorithm/ranges_make_heap.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_max                                  [system] {
+  header "__algorithm/ranges_max.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_max_element                          [system] {
+  header "__algorithm/ranges_max_element.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_merge                                [system] {
+  header "__algorithm/ranges_merge.h"
+  export std_private_algorithm_in_in_out_result
+}
+module std_private_algorithm_ranges_min                                  [system] {
+  header "__algorithm/ranges_min.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_min_element                          [system] {
+  header "__algorithm/ranges_min_element.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_minmax                               [system] {
+  header "__algorithm/ranges_minmax.h"
+  export std_private_functional_ranges_operations
+  export std_private_algorithm_min_max_result
+}
+module std_private_algorithm_ranges_minmax_element                       [system] {
+  header "__algorithm/ranges_minmax_element.h"
+  export std_private_functional_ranges_operations
+  export std_private_algorithm_min_max_result
+}
+module std_private_algorithm_ranges_mismatch                             [system] {
+  header "__algorithm/ranges_mismatch.h"
+  export std_private_algorithm_in_in_result
+}
+module std_private_algorithm_ranges_move                                 [system] {
+  header "__algorithm/ranges_move.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_move_backward                        [system] {
+  header "__algorithm/ranges_move_backward.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_next_permutation                     [system] {
+  header "__algorithm/ranges_next_permutation.h"
+  export std_private_algorithm_in_found_result
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_none_of                              [system] { header "__algorithm/ranges_none_of.h" }
+module std_private_algorithm_ranges_nth_element                          [system] {
+  header "__algorithm/ranges_nth_element.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_partial_sort                         [system] {
+  header "__algorithm/ranges_partial_sort.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_partial_sort_copy                    [system] {
+  header "__algorithm/ranges_partial_sort_copy.h"
+  export std_private_algorithm_in_out_result
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_partition                            [system] { header "__algorithm/ranges_partition.h" }
+module std_private_algorithm_ranges_partition_copy                       [system] { header "__algorithm/ranges_partition_copy.h" }
+module std_private_algorithm_ranges_partition_point                      [system] { header "__algorithm/ranges_partition_point.h" }
+module std_private_algorithm_ranges_pop_heap                             [system] {
+  header "__algorithm/ranges_pop_heap.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_prev_permutation                     [system] {
+  header "__algorithm/ranges_prev_permutation.h"
+  export std_private_algorithm_in_found_result
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_push_heap                            [system] {
+  header "__algorithm/ranges_push_heap.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_remove                               [system] { header "__algorithm/ranges_remove.h" }
+module std_private_algorithm_ranges_remove_copy                          [system] {
+  header "__algorithm/ranges_remove_copy.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_remove_copy_if                       [system] {
+  header "__algorithm/ranges_remove_copy_if.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_remove_if                            [system] { header "__algorithm/ranges_remove_if.h" }
+module std_private_algorithm_ranges_replace                              [system] { header "__algorithm/ranges_replace.h" }
+module std_private_algorithm_ranges_replace_copy                         [system] {
+  header "__algorithm/ranges_replace_copy.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_replace_copy_if                      [system] {
+  header "__algorithm/ranges_replace_copy_if.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_replace_if                           [system] { header "__algorithm/ranges_replace_if.h" }
+module std_private_algorithm_ranges_reverse                              [system] { header "__algorithm/ranges_reverse.h" }
+module std_private_algorithm_ranges_reverse_copy                         [system] {
+  header "__algorithm/ranges_reverse_copy.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_rotate                               [system] { header "__algorithm/ranges_rotate.h" }
+module std_private_algorithm_ranges_rotate_copy                          [system] {
+  header "__algorithm/ranges_rotate_copy.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_sample                               [system] { header "__algorithm/ranges_sample.h" }
+module std_private_algorithm_ranges_search                               [system] { header "__algorithm/ranges_search.h" }
+module std_private_algorithm_ranges_search_n                             [system] { header "__algorithm/ranges_search_n.h" }
+module std_private_algorithm_ranges_set_difference                       [system] {
+  header "__algorithm/ranges_set_difference.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_set_intersection                     [system] {
+  header "__algorithm/ranges_set_intersection.h"
+  export std_private_algorithm_in_in_out_result
+}
+module std_private_algorithm_ranges_set_symmetric_difference             [system] {
+  header "__algorithm/ranges_set_symmetric_difference.h"
+  export std_private_algorithm_in_in_out_result
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_set_union                            [system] {
+  header "__algorithm/ranges_set_union.h"
+  export std_private_algorithm_in_in_out_result
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_shuffle                              [system] { header "__algorithm/ranges_shuffle.h" }
+module std_private_algorithm_ranges_sort                                 [system] {
+  header "__algorithm/ranges_sort.h"
+  export std_private_algorithm_make_projected
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_sort_heap                            [system] {
+  header "__algorithm/ranges_sort_heap.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_stable_partition                     [system] { header "__algorithm/ranges_stable_partition.h" }
+module std_private_algorithm_ranges_stable_sort                          [system] {
+  header "__algorithm/ranges_stable_sort.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_ranges_starts_with                          [system] { header "__algorithm/ranges_starts_with.h" }
+module std_private_algorithm_ranges_swap_ranges                          [system] {
+  header "__algorithm/ranges_swap_ranges.h"
+  export std_private_algorithm_in_in_result
+}
+module std_private_algorithm_ranges_transform                            [system] {
+  header "__algorithm/ranges_transform.h"
+  export std_private_algorithm_in_in_out_result
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_unique                               [system] { header "__algorithm/ranges_unique.h" }
+module std_private_algorithm_ranges_unique_copy                          [system] {
+  header "__algorithm/ranges_unique_copy.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_algorithm_ranges_upper_bound                          [system] {
+  header "__algorithm/ranges_upper_bound.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_algorithm_remove                                      [system] { header "__algorithm/remove.h" }
+module std_private_algorithm_remove_copy                                 [system] { header "__algorithm/remove_copy.h" }
+module std_private_algorithm_remove_copy_if                              [system] { header "__algorithm/remove_copy_if.h" }
+module std_private_algorithm_remove_if                                   [system] { header "__algorithm/remove_if.h" }
+module std_private_algorithm_replace                                     [system] { header "__algorithm/replace.h" }
+module std_private_algorithm_replace_copy                                [system] { header "__algorithm/replace_copy.h" }
+module std_private_algorithm_replace_copy_if                             [system] { header "__algorithm/replace_copy_if.h" }
+module std_private_algorithm_replace_if                                  [system] { header "__algorithm/replace_if.h" }
+module std_private_algorithm_reverse                                     [system] { header "__algorithm/reverse.h" }
+module std_private_algorithm_reverse_copy                                [system] { header "__algorithm/reverse_copy.h" }
+module std_private_algorithm_rotate                                      [system] { header "__algorithm/rotate.h" }
+module std_private_algorithm_rotate_copy                                 [system] { header "__algorithm/rotate_copy.h" }
+module std_private_algorithm_sample                                      [system] { header "__algorithm/sample.h" }
+module std_private_algorithm_search                                      [system] { header "__algorithm/search.h" }
+module std_private_algorithm_search_n                                    [system] { header "__algorithm/search_n.h" }
+module std_private_algorithm_set_difference                              [system] { header "__algorithm/set_difference.h" }
+module std_private_algorithm_set_intersection                            [system] { header "__algorithm/set_intersection.h" }
+module std_private_algorithm_set_symmetric_difference                    [system] { header "__algorithm/set_symmetric_difference.h" }
+module std_private_algorithm_set_union                                   [system] { header "__algorithm/set_union.h" }
+module std_private_algorithm_shift_left                                  [system] { header "__algorithm/shift_left.h" }
+module std_private_algorithm_shift_right                                 [system] { header "__algorithm/shift_right.h" }
+module std_private_algorithm_shuffle                                     [system] { header "__algorithm/shuffle.h" }
+module std_private_algorithm_sift_down                                   [system] { header "__algorithm/sift_down.h" }
+module std_private_algorithm_sort                                        [system] {
+  header "__algorithm/sort.h"
+  export std_private_debug_utils_strict_weak_ordering_check
+}
+module std_private_algorithm_simd_utils                                  [system] { header "__algorithm/simd_utils.h" }
+module std_private_algorithm_sort_heap                                   [system] { header "__algorithm/sort_heap.h" }
+module std_private_algorithm_stable_partition                            [system] { header "__algorithm/stable_partition.h" }
+module std_private_algorithm_stable_sort                                 [system] { header "__algorithm/stable_sort.h" }
+module std_private_algorithm_swap_ranges                                 [system] {
+  header "__algorithm/swap_ranges.h"
+  export std_private_algorithm_iterator_operations
+}
+module std_private_algorithm_three_way_comp_ref_type                     [system] { header "__algorithm/three_way_comp_ref_type.h" }
+module std_private_algorithm_transform                                   [system] { header "__algorithm/transform.h" }
+module std_private_algorithm_uniform_random_bit_generator_adaptor        [system] { header "__algorithm/uniform_random_bit_generator_adaptor.h" }
+module std_private_algorithm_unique                                      [system] { header "__algorithm/unique.h" }
+module std_private_algorithm_unique_copy                                 [system] { header "__algorithm/unique_copy.h" }
+module std_private_algorithm_unwrap_iter                                 [system] {
+  header "__algorithm/unwrap_iter.h"
+  export std_private_iterator_iterator_traits
+}
+module std_private_algorithm_unwrap_range                                [system] {
+  header "__algorithm/unwrap_range.h"
+  export std_private_utility_pair
+}
+module std_private_algorithm_upper_bound                                 [system] { header "__algorithm/upper_bound.h" }
 
-  // Experimental C++ Standard Library interfaces
-  module experimental {
-    module iterator           { header "experimental/iterator" }
-    module memory             { header "experimental/memory" }
-    module propagate_const    { header "experimental/propagate_const" }
-    module type_traits        { header "experimental/type_traits" }
-    module utility            { header "experimental/utility" }
-    module simd {
-      private header "experimental/__simd/aligned_tag.h"
-      private header "experimental/__simd/declaration.h"
-      private header "experimental/__simd/reference.h"
-      private header "experimental/__simd/scalar.h"
-      private header "experimental/__simd/simd_mask.h"
-      private header "experimental/__simd/simd.h"
-      private header "experimental/__simd/traits.h"
-      private header "experimental/__simd/utility.h"
-      private header "experimental/__simd/vec_ext.h"
-      header "experimental/simd"
-      export *
-    }
-  }
+module std_private_array_array_fwd [system] { header "__fwd/array.h" }
 
-  // Implementation detail headers that are private to libc++. These modules
-  // must not be directly imported.
-  module debug_utils {
-    module randomize_range              { header "__debug_utils/randomize_range.h" }
-    module sanitizers                   { header "__debug_utils/sanitizers.h" }
-    module strict_weak_ordering_check   { header "__debug_utils/strict_weak_ordering_check.h" }
-  }
+module std_private_atomic_aliases             [system] {
+  header "__atomic/aliases.h"
+  export std_private_atomic_atomic
+}
+module std_private_atomic_atomic              [system] {
+  header "__atomic/atomic.h"
+  export std_private_atomic_atomic_base
+}
+module std_private_atomic_atomic_base         [system] { header "__atomic/atomic_base.h" }
+module std_private_atomic_atomic_flag         [system] {
+  header "__atomic/atomic_flag.h"
+  export *
+}
+module std_private_atomic_atomic_init         [system] { header "__atomic/atomic_init.h" }
+module std_private_atomic_atomic_lock_free    [system] { header "__atomic/atomic_lock_free.h" }
+module std_private_atomic_atomic_ref          [system] { header "__atomic/atomic_ref.h" }
+module std_private_atomic_atomic_sync         [system] {
+  header "__atomic/atomic_sync.h"
+  export std_private_atomic_to_gcc_order
+}
+module std_private_atomic_check_memory_order  [system] { header "__atomic/check_memory_order.h" }
+module std_private_atomic_contention_t        [system] { header "__atomic/contention_t.h" }
+module std_private_atomic_cxx_atomic_impl     [system] { header "__atomic/cxx_atomic_impl.h" }
+module std_private_atomic_fence               [system] { header "__atomic/fence.h" }
+module std_private_atomic_is_always_lock_free [system] { header "__atomic/is_always_lock_free.h" }
+module std_private_atomic_kill_dependency     [system] { header "__atomic/kill_dependency.h" }
+module std_private_atomic_memory_order        [system] { header "__atomic/memory_order.h" }
+module std_private_atomic_to_gcc_order        [system] {
+  header "__atomic/to_gcc_order.h"
+  export std_private_atomic_memory_order
+}
 
-  module get_fwd {
-    header "__fwd/get.h"
-    export std_core.fwd.pair
-    export std_core.fwd.tuple
-    export std.array.fwd
-    export std.complex.fwd
-    export std.ranges.subrange_fwd
-    export std.variant.fwd
-  }
+module std_private_bit_bit_cast       [system] { header "__bit/bit_cast.h" }
+module std_private_bit_bit_ceil       [system] { header "__bit/bit_ceil.h" }
+module std_private_bit_bit_floor      [system] { header "__bit/bit_floor.h" }
+module std_private_bit_bit_log2       [system] { header "__bit/bit_log2.h" }
+module std_private_bit_bit_width      [system] { header "__bit/bit_width.h" }
+module std_private_bit_blsr           [system] { header "__bit/blsr.h" }
+module std_private_bit_byteswap       [system] { header "__bit/byteswap.h" }
+module std_private_bit_countl         [system] { header "__bit/countl.h" }
+module std_private_bit_countr         [system] { header "__bit/countr.h" }
+module std_private_bit_endian         [system] { header "__bit/endian.h" }
+module std_private_bit_has_single_bit [system] { header "__bit/has_single_bit.h" }
+module std_private_bit_invert_if      [system] { header "__bit/invert_if.h" }
+module std_private_bit_popcount       [system] { header "__bit/popcount.h" }
+module std_private_bit_rotate         [system] { header "__bit/rotate.h" }
+
+module std_private_charconv_chars_format            [system] { header "__charconv/chars_format.h" }
+module std_private_charconv_from_chars_integral     [system] { header "__charconv/from_chars_integral.h" }
+module std_private_charconv_from_chars_result       [system] { header "__charconv/from_chars_result.h" }
+module std_private_charconv_tables                  [system] { header "__charconv/tables.h" }
+module std_private_charconv_to_chars                [system] { header "__charconv/to_chars.h" }
+module std_private_charconv_to_chars_base_10        [system] { header "__charconv/to_chars_base_10.h" }
+module std_private_charconv_to_chars_floating_point [system] { header "__charconv/to_chars_floating_point.h" }
+module std_private_charconv_to_chars_integral       [system] { header "__charconv/to_chars_integral.h" }
+module std_private_charconv_to_chars_result         [system] {
+  header "__charconv/to_chars_result.h"
+  export *
+}
+module std_private_charconv_traits                  [system] { header "__charconv/traits.h" }
+
+module std_private_chrono_calendar               [system] { header "__chrono/calendar.h" }
+module std_private_chrono_concepts               [system] { header "__chrono/concepts.h" }
+module std_private_chrono_convert_to_timespec    [system] { header "__chrono/convert_to_timespec.h" }
+module std_private_chrono_convert_to_tm          [system] { header "__chrono/convert_to_tm.h" }
+module std_private_chrono_day                    [system] { header "__chrono/day.h" }
+module std_private_chrono_duration               [system] {
+  header "__chrono/duration.h"
+  export std_private_type_traits_is_convertible
+}
+module std_private_chrono_exception              [system] { header "__chrono/exception.h" }
+module std_private_chrono_file_clock             [system] { header "__chrono/file_clock.h" }
+module std_private_chrono_formatter              [system] {
+  header "__chrono/formatter.h"
+}
+module std_private_chrono_hh_mm_ss               [system] { header "__chrono/hh_mm_ss.h" }
+module std_private_chrono_high_resolution_clock  [system] {
+  header "__chrono/high_resolution_clock.h"
+  export std_private_chrono_steady_clock
+  export std_private_chrono_system_clock
+}
+module std_private_chrono_leap_second            [system] { header "__chrono/leap_second.h" }
+module std_private_chrono_literals               [system] { header "__chrono/literals.h" }
+module std_private_chrono_local_info             [system] {
+  header "__chrono/local_info.h"
+  export std_private_chrono_sys_info
+}
+module std_private_chrono_month                  [system] { header "__chrono/month.h" }
+module std_private_chrono_month_weekday          [system] { header "__chrono/month_weekday.h" }
+module std_private_chrono_monthday               [system] { header "__chrono/monthday.h" }
+module std_private_chrono_ostream                [system] {
+  header "__chrono/ostream.h"
+}
+module std_private_chrono_parser_std_format_spec [system] {
+  header "__chrono/parser_std_format_spec.h"
+}
+module std_private_chrono_statically_widen       [system] { header "__chrono/statically_widen.h" }
+module std_private_chrono_steady_clock           [system] {
+  header "__chrono/steady_clock.h"
+  export std_private_chrono_time_point
+}
+module std_private_chrono_time_zone              [system] {
+  header "__chrono/time_zone.h"
+}
+module std_private_chrono_time_zone_link         [system] {
+  header "__chrono/time_zone_link.h"
+}
+module std_private_chrono_sys_info               [system] {
+  header "__chrono/sys_info.h"
+}
+module std_private_chrono_system_clock           [system] {
+  header "__chrono/system_clock.h"
+  export std_private_chrono_time_point
+}
+module std_private_chrono_tzdb                   [system] {
+  header "__chrono/tzdb.h"
+  export *
+}
+module std_private_chrono_tzdb_list              [system] {
+  header "__chrono/tzdb_list.h"
+  export *
+}
+module std_private_chrono_time_point             [system] { header "__chrono/time_point.h" }
+module std_private_chrono_weekday                [system] { header "__chrono/weekday.h" }
+module std_private_chrono_year                   [system] { header "__chrono/year.h" }
+module std_private_chrono_year_month             [system] { header "__chrono/year_month.h" }
+module std_private_chrono_year_month_day         [system] { header "__chrono/year_month_day.h" }
+module std_private_chrono_year_month_weekday     [system] { header "__chrono/year_month_weekday.h" }
+module std_private_chrono_zoned_time             [system] { header "__chrono/zoned_time.h" }
+
+module std_private_compare_common_comparison_category     [system] { header "__compare/common_comparison_category.h" }
+module std_private_compare_compare_partial_order_fallback [system] { header "__compare/compare_partial_order_fallback.h" }
+module std_private_compare_compare_strong_order_fallback  [system] { header "__compare/compare_strong_order_fallback.h" }
+module std_private_compare_compare_three_way              [system] { header "__compare/compare_three_way.h" }
+module std_private_compare_compare_three_way_result       [system] { header "__compare/compare_three_way_result.h" }
+module std_private_compare_compare_weak_order_fallback    [system] { header "__compare/compare_weak_order_fallback.h" }
+module std_private_compare_is_eq                          [system] { header "__compare/is_eq.h" }
+module std_private_compare_ordering                       [system] { header "__compare/ordering.h" }
+module std_private_compare_partial_order                  [system] { header "__compare/partial_order.h" }
+module std_private_compare_strong_order                   [system] { header "__compare/strong_order.h" }
+module std_private_compare_synth_three_way                [system] { header "__compare/synth_three_way.h" }
+module std_private_compare_three_way_comparable           [system] { header "__compare/three_way_comparable.h" }
+module std_private_compare_weak_order                     [system] { header "__compare/weak_order.h" }
+
+module std_private_complex_complex_fwd            [system] { header "__fwd/complex.h" }
+
+module std_private_concepts_arithmetic            [system] { header "__concepts/arithmetic.h" }
+module std_private_concepts_assignable            [system] { header "__concepts/assignable.h" }
+module std_private_concepts_boolean_testable      [system] { header "__concepts/boolean_testable.h" }
+module std_private_concepts_class_or_enum         [system] { header "__concepts/class_or_enum.h" }
+module std_private_concepts_common_reference_with [system] { header "__concepts/common_reference_with.h" }
+module std_private_concepts_common_with           [system] { header "__concepts/common_with.h" }
+module std_private_concepts_constructible         [system] {
+  header "__concepts/constructible.h"
+  export std_private_concepts_destructible
+}
+module std_private_concepts_convertible_to        [system] { header "__concepts/convertible_to.h" }
+module std_private_concepts_copyable              [system] { header "__concepts/copyable.h" }
+module std_private_concepts_derived_from          [system] { header "__concepts/derived_from.h" }
+module std_private_concepts_destructible          [system] {
+  header "__concepts/destructible.h"
+  export std_private_type_traits_is_nothrow_destructible
+}
+module std_private_concepts_different_from        [system] { header "__concepts/different_from.h" }
+module std_private_concepts_equality_comparable   [system] {
+  header "__concepts/equality_comparable.h"
+  export std_private_type_traits_common_reference
+}
+module std_private_concepts_invocable             [system] { header "__concepts/invocable.h" }
+module std_private_concepts_movable               [system] {
+  header "__concepts/movable.h"
+  export std_private_type_traits_is_object
+}
+module std_private_concepts_predicate             [system] { header "__concepts/predicate.h" }
+module std_private_concepts_regular               [system] { header "__concepts/regular.h" }
+module std_private_concepts_relation              [system] { header "__concepts/relation.h" }
+module std_private_concepts_same_as               [system] {
+  header "__concepts/same_as.h"
+  export std_private_type_traits_is_same
+}
+module std_private_concepts_semiregular           [system] { header "__concepts/semiregular.h" }
+module std_private_concepts_swappable             [system] { header "__concepts/swappable.h" }
+module std_private_concepts_totally_ordered       [system] { header "__concepts/totally_ordered.h" }
 
-  module pstl {
-    module backend_fwd {
-      header "__pstl/backend_fwd.h"
-    }
-    module backend {
-      header "__pstl/backend.h"
-      export * // need to export everything from whatever backend is currently configured
-    }
-    module backends {
-      module default {
-        header "__pstl/backends/default.h"
-        export std_core.utility_core.empty
-      }
-      module libdispatch {
-        header "__pstl/backends/libdispatch.h"
-        export std.pstl.cpu_algos
-        export std_core.utility_core.empty
-      }
-      module serial {
-        header "__pstl/backends/serial.h"
-        export std_core.utility_core.empty
-      }
-      module std_thread {
-        header "__pstl/backends/std_thread.h"
-        export std.pstl.cpu_algos
-        export std_core.utility_core.empty
-      }
-    }
-    module cpu_algos {
-      module any_of {
-        header "__pstl/cpu_algos/any_of.h"
-      }
-      module cpu_traits {
-        header "__pstl/cpu_algos/cpu_traits.h"
-      }
-      module fill {
-        header "__pstl/cpu_algos/fill.h"
-        export std_core.utility_core.empty
-      }
-      module find_if {
-        header "__pstl/cpu_algos/find_if.h"
-      }
-      module for_each {
-        header "__pstl/cpu_algos/for_each.h"
-        export std_core.utility_core.empty
-      }
-      module merge {
-        header "__pstl/cpu_algos/merge.h"
-      }
-      module stable_sort {
-        header "__pstl/cpu_algos/stable_sort.h"
-        export std_core.utility_core.empty
-      }
-      module transform {
-        header "__pstl/cpu_algos/transform.h"
-      }
-      module transform_reduce {
-        header "__pstl/cpu_algos/transform_reduce.h"
-      }
-    }
-    module dispatch           { header "__pstl/dispatch.h" }
-    module handle_exception   { header "__pstl/handle_exception.h" }
-  }
+module std_private_condition_variable_condition_variable [system] {
+  header "__condition_variable/condition_variable.h"
+  export *
+}
 
-  // Miscellaneous modules for top-level headers
-  module bit_reference_fwd {
-    header "__fwd/bit_reference.h"
-  }
-  module bit_reference {
-    header "__bit_reference"
-    export std.bit_reference_fwd
-  }
-  module hash_table           { header "__hash_table" }
-  module node_handle          { header "__node_handle" }
-  module split_buffer         { header "__split_buffer" }
-  module tree                 { header "__tree" }
-  module std_mbstate_t {
-    header "__std_mbstate_t.h"
-    export *
-  }
-  module verbose_abort {
-    header "__verbose_abort"
-  }
-  module internal_assert {
-    header "__assert"
-    export *
-  }
+module std_private_coroutine_coroutine_handle      [system] { header "__coroutine/coroutine_handle.h" }
+module std_private_coroutine_coroutine_traits      [system] { header "__coroutine/coroutine_traits.h" }
+module std_private_coroutine_noop_coroutine_handle [system] { header "__coroutine/noop_coroutine_handle.h" }
+module std_private_coroutine_trivial_awaitables    [system] { header "__coroutine/trivial_awaitables.h" }
 
-  module undef_macros {
-    textual header "__undef_macros"
-  }
+module std_private_debug_utils_randomize_range            [system] { header "__debug_utils/randomize_range.h" }
+module std_private_debug_utils_sanitizers                 [system] { header "__debug_utils/sanitizers.h" }
+module std_private_debug_utils_strict_weak_ordering_check [system] {
+  header "__debug_utils/strict_weak_ordering_check.h"
+  export std_private_type_traits_is_constant_evaluated
+}
 
-  // This module needs to appear after __tree to work around issues with modules in Objective-C++ mode.
-  module coroutine {
-    module coroutine_handle         { header "__coroutine/coroutine_handle.h" }
-    module coroutine_traits         { header "__coroutine/coroutine_traits.h" }
-    module noop_coroutine_handle    { header "__coroutine/noop_coroutine_handle.h" }
-    module trivial_awaitables       { header "__coroutine/trivial_awaitables.h" }
+module std_private_deque_fwd [system] { header "__fwd/deque.h" }
 
-    header "coroutine"
-    export *
-  }
-} // module std
+module std_private_exception_exception        [system] { header "__exception/exception.h" }
+module std_private_exception_exception_ptr    [system] {
+  header "__exception/exception_ptr.h"
+  export std_private_exception_operations
+}
+module std_private_exception_nested_exception [system] { header "__exception/nested_exception.h" }
+module std_private_exception_operations       [system] { header "__exception/operations.h" }
+module std_private_exception_terminate        [system] { header "__exception/terminate.h" }
+
+module std_private_expected_bad_expected_access [system] { header "__expected/bad_expected_access.h" }
+module std_private_expected_expected            [system] { header "__expected/expected.h" }
+module std_private_expected_unexpect            [system] { header "__expected/unexpect.h" }
+module std_private_expected_unexpected          [system] { header "__expected/unexpected.h" }
+
+module std_private_filesystem_copy_options                 [system] { header "__filesystem/copy_options.h" }
+module std_private_filesystem_directory_entry              [system] {
+  header "__filesystem/directory_entry.h"
+  export *
+}
+module std_private_filesystem_directory_iterator           [system] {
+  header "__filesystem/directory_iterator.h"
+  export *
+}
+module std_private_filesystem_directory_options            [system] { header "__filesystem/directory_options.h" }
+module std_private_filesystem_file_status                  [system] { header "__filesystem/file_status.h" }
+module std_private_filesystem_file_time_type               [system] { header "__filesystem/file_time_type.h" }
+module std_private_filesystem_file_type                    [system] { header "__filesystem/file_type.h" }
+module std_private_filesystem_filesystem_error             [system] {
+  header "__filesystem/filesystem_error.h"
+  export *
+}
+module std_private_filesystem_operations                   [system] { header "__filesystem/operations.h" }
+module std_private_filesystem_path                         [system] {
+  header "__filesystem/path.h"
+  export *
+}
+module std_private_filesystem_path_iterator                [system] { header "__filesystem/path_iterator.h" }
+module std_private_filesystem_perm_options                 [system] { header "__filesystem/perm_options.h" }
+module std_private_filesystem_perms                        [system] { header "__filesystem/perms.h" }
+module std_private_filesystem_recursive_directory_iterator [system] {
+  header "__filesystem/recursive_directory_iterator.h"
+  export *
+}
+module std_private_filesystem_space_info                   [system] { header "__filesystem/space_info.h" }
+module std_private_filesystem_u8path                       [system] { header "__filesystem/u8path.h" }
+
+module std_private_format_buffer                          [system] { header "__format/buffer.h" }
+module std_private_format_concepts                        [system] { header "__format/concepts.h" }
+module std_private_format_container_adaptor               [system] { header "__format/container_adaptor.h" }
+module std_private_format_enable_insertable               [system] { header "__format/enable_insertable.h" }
+module std_private_format_escaped_output_table            [system] { header "__format/escaped_output_table.h" }
+module std_private_format_extended_grapheme_cluster_table [system] { header "__format/extended_grapheme_cluster_table.h" }
+module std_private_format_format_arg                      [system] { header "__format/format_arg.h" }
+module std_private_format_format_arg_store                [system] { header "__format/format_arg_store.h" }
+module std_private_format_format_args                     [system] { header "__format/format_args.h" }
+module std_private_format_format_context                  [system] {
+  header "__format/format_context.h"
+  export *
+}
+module std_private_format_format_error                    [system] { header "__format/format_error.h" }
+module std_private_format_format_functions                [system] {
+  header "__format/format_functions.h"
+  export std_string
+}
+module std_private_format_fwd                             [system] { header "__fwd/format.h" }
+module std_private_format_format_parse_context            [system] { header "__format/format_parse_context.h" }
+module std_private_format_format_string                   [system] { header "__format/format_string.h" }
+module std_private_format_format_to_n_result              [system] {
+  header "__format/format_to_n_result.h"
+  export std_private_iterator_incrementable_traits
+}
+module std_private_format_formatter                       [system] { header "__format/formatter.h" }
+module std_private_format_formatter_bool                  [system] { header "__format/formatter_bool.h" }
+module std_private_format_formatter_char                  [system] { header "__format/formatter_char.h" }
+module std_private_format_formatter_floating_point        [system] { header "__format/formatter_floating_point.h" }
+module std_private_format_formatter_integer               [system] { header "__format/formatter_integer.h" }
+module std_private_format_formatter_integral              [system] { header "__format/formatter_integral.h" }
+module std_private_format_formatter_output                [system] { header "__format/formatter_output.h" }
+module std_private_format_formatter_pointer               [system] { header "__format/formatter_pointer.h" }
+module std_private_format_formatter_string                [system] { header "__format/formatter_string.h" }
+module std_private_format_formatter_tuple                 [system] { header "__format/formatter_tuple.h" }
+module std_private_format_indic_conjunct_break_table      [system] { header "__format/indic_conjunct_break_table.h" }
+module std_private_format_parser_std_format_spec          [system] { header "__format/parser_std_format_spec.h" }
+module std_private_format_range_default_formatter         [system] { header "__format/range_default_formatter.h" }
+module std_private_format_range_formatter                 [system] { header "__format/range_formatter.h" }
+module std_private_format_unicode                         [system] {
+  header "__format/unicode.h"
+  export std_private_format_extended_grapheme_cluster_table
+  export std_private_format_indic_conjunct_break_table
+}
+module std_private_format_width_estimation_table          [system] { header "__format/width_estimation_table.h" }
+module std_private_format_write_escaped                   [system] { header "__format/write_escaped.h" }
+
+module std_private_functional_binary_function            [system] { header "__functional/binary_function.h" }
+module std_private_functional_binary_negate              [system] { header "__functional/binary_negate.h" }
+module std_private_functional_bind                       [system] { header "__functional/bind.h" }
+module std_private_functional_bind_back                  [system] { header "__functional/bind_back.h" }
+module std_private_functional_bind_front                 [system] { header "__functional/bind_front.h" }
+module std_private_functional_binder1st                  [system] { header "__functional/binder1st.h" }
+module std_private_functional_binder2nd                  [system] { header "__functional/binder2nd.h" }
+module std_private_functional_boyer_moore_searcher       [system] {
+  header "__functional/boyer_moore_searcher.h"
+  export std_private_memory_shared_ptr
+}
+module std_private_functional_compose                    [system] {
+  header "__functional/compose.h"
+  export std_private_functional_perfect_forward
+}
+module std_private_functional_default_searcher           [system] { header "__functional/default_searcher.h" }
+module std_private_functional_function                   [system] { header "__functional/function.h" }
+module std_private_functional_hash                       [system] {
+  header "__functional/hash.h"
+  export std_cstdint
+  export std_private_type_traits_underlying_type
+  export std_private_utility_pair
+}
+module std_private_functional_fwd                        [system] { header "__fwd/functional.h" }
+module std_private_functional_identity                   [system] { header "__functional/identity.h" }
+module std_private_functional_invoke                     [system] {
+  header "__functional/invoke.h"
+  export *
+}
+module std_private_functional_is_transparent             [system] { header "__functional/is_transparent.h" }
+module std_private_functional_mem_fn                     [system] { header "__functional/mem_fn.h" }
+module std_private_functional_mem_fun_ref                [system] { header "__functional/mem_fun_ref.h" }
+module std_private_functional_not_fn                     [system] {
+  header "__functional/not_fn.h"
+  export std_private_functional_perfect_forward
+}
+module std_private_functional_operations                 [system] { header "__functional/operations.h" }
+module std_private_functional_perfect_forward            [system] {
+  header "__functional/perfect_forward.h"
+  export *
+}
+module std_private_functional_pointer_to_binary_function [system] { header "__functional/pointer_to_binary_function.h" }
+module std_private_functional_pointer_to_unary_function  [system] { header "__functional/pointer_to_unary_function.h" }
+module std_private_functional_ranges_operations          [system] { header "__functional/ranges_operations.h" }
+module std_private_functional_reference_wrapper          [system] { header "__functional/reference_wrapper.h" }
+module std_private_functional_unary_function             [system] { header "__functional/unary_function.h" }
+module std_private_functional_unary_negate               [system] { header "__functional/unary_negate.h" }
+module std_private_functional_weak_result_type           [system] { header "__functional/weak_result_type.h" }
+
+module std_private_ios_fpos [system] { header "__ios/fpos.h" }
+
+module std_private_iosfwd_fstream_fwd   [system] { header "__fwd/fstream.h" }
+module std_private_iosfwd_ios_fwd       [system] { header "__fwd/ios.h" }
+module std_private_iosfwd_istream_fwd   [system] { header "__fwd/istream.h" }
+module std_private_iosfwd_ostream_fwd   [system] { header "__fwd/ostream.h" }
+module std_private_iosfwd_sstream_fwd   [system] { header "__fwd/sstream.h" }
+module std_private_iosfwd_streambuf_fwd [system] { header "__fwd/streambuf.h" }
+
+module std_private_iterator_access                  [system] { header "__iterator/access.h" }
+module std_private_iterator_advance                 [system] { header "__iterator/advance.h" }
+module std_private_iterator_aliasing_iterator       [system] { header "__iterator/aliasing_iterator.h" }
+module std_private_iterator_back_insert_iterator    [system] { header "__iterator/back_insert_iterator.h" }
+module std_private_iterator_bounded_iter            [system] { header "__iterator/bounded_iter.h" }
+module std_private_iterator_common_iterator         [system] { header "__iterator/common_iterator.h" }
+module std_private_iterator_concepts                [system] {
+  header "__iterator/concepts.h"
+  export std_private_concepts_constructible
+  export std_private_concepts_equality_comparable
+  export std_private_concepts_movable
+  export std_private_type_traits_common_reference
+  export std_private_type_traits_is_reference
+  export std_private_type_traits_remove_cvref
+}
+module std_private_iterator_counted_iterator        [system] { header "__iterator/counted_iterator.h" }
+module std_private_iterator_cpp17_iterator_concepts [system] { header "__iterator/cpp17_iterator_concepts.h" }
+module std_private_iterator_data                    [system] { header "__iterator/data.h" }
+module std_private_iterator_default_sentinel        [system] { header "__iterator/default_sentinel.h" }
+module std_private_iterator_distance                [system] {
+  header "__iterator/distance.h"
+  export std_private_ranges_size
+}
+module std_private_iterator_empty                   [system] { header "__iterator/empty.h" }
+module std_private_iterator_erase_if_container      [system] { header "__iterator/erase_if_container.h" }
+module std_private_iterator_front_insert_iterator   [system] { header "__iterator/front_insert_iterator.h" }
+module std_private_iterator_incrementable_traits    [system] { header "__iterator/incrementable_traits.h" }
+module std_private_iterator_indirectly_comparable   [system] { header "__iterator/indirectly_comparable.h" }
+module std_private_iterator_insert_iterator         [system] { header "__iterator/insert_iterator.h" }
+module std_private_iterator_istream_iterator        [system] { header "__iterator/istream_iterator.h" }
+module std_private_iterator_istreambuf_iterator     [system] { header "__iterator/istreambuf_iterator.h" }
+module std_private_iterator_iter_move               [system] { header "__iterator/iter_move.h" }
+module std_private_iterator_iter_swap               [system] { header "__iterator/iter_swap.h" }
+module std_private_iterator_iterator                [system] { header "__iterator/iterator.h" }
+module std_private_iterator_iterator_traits         [system] {
+  header "__iterator/iterator_traits.h"
+  export std_private_type_traits_is_primary_template
+}
+module std_private_iterator_iterator_with_data      [system] { header "__iterator/iterator_with_data.h" }
+module std_private_iterator_mergeable               [system] {
+  header "__iterator/mergeable.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_iterator_move_iterator           [system] { header "__iterator/move_iterator.h" }
+module std_private_iterator_move_sentinel           [system] { header "__iterator/move_sentinel.h" }
+module std_private_iterator_next                    [system] { header "__iterator/next.h" }
+module std_private_iterator_ostream_iterator        [system] { header "__iterator/ostream_iterator.h" }
+module std_private_iterator_ostreambuf_iterator     [system] {
+  header "__iterator/ostreambuf_iterator.h"
+  export *
+}
+module std_private_iterator_permutable              [system] { header "__iterator/permutable.h" }
+module std_private_iterator_prev                    [system] { header "__iterator/prev.h" }
+module std_private_iterator_projected               [system] { header "__iterator/projected.h" }
+module std_private_iterator_ranges_iterator_traits  [system] { header "__iterator/ranges_iterator_traits.h" }
+module std_private_iterator_readable_traits         [system] { header "__iterator/readable_traits.h" }
+module std_private_iterator_reverse_access          [system] { header "__iterator/reverse_access.h" }
+module std_private_iterator_reverse_iterator        [system] { header "__iterator/reverse_iterator.h" }
+module std_private_iterator_segmented_iterator      [system] { header "__iterator/segmented_iterator.h" }
+module std_private_iterator_size                    [system] { header "__iterator/size.h" }
+module std_private_iterator_sortable                [system] {
+  header "__iterator/sortable.h"
+  export std_private_functional_ranges_operations
+}
+module std_private_iterator_unreachable_sentinel    [system] { header "__iterator/unreachable_sentinel.h" }
+module std_private_iterator_wrap_iter               [system] { header "__iterator/wrap_iter.h" }
+
+module std_private_locale_locale_base_api_android              [system] { textual header "__locale_dir/locale_base_api/android.h" }
+module std_private_locale_locale_base_api_bsd_locale_defaults  [system] { textual header "__locale_dir/locale_base_api/bsd_locale_defaults.h" }
+module std_private_locale_locale_base_api_bsd_locale_fallbacks [system] { textual header "__locale_dir/locale_base_api/bsd_locale_fallbacks.h" }
+module std_private_locale_locale_base_api_fuchsia              [system] { textual header "__locale_dir/locale_base_api/fuchsia.h" }
+module std_private_locale_locale_base_api_ibm                  [system] { textual header "__locale_dir/locale_base_api/ibm.h" }
+module std_private_locale_locale_base_api_locale_guard         [system] { header "__locale_dir/locale_base_api/locale_guard.h" }
+module std_private_locale_locale_base_api_musl                 [system] { textual header "__locale_dir/locale_base_api/musl.h" }
+module std_private_locale_locale_base_api_newlib               [system] { textual header "__locale_dir/locale_base_api/newlib.h" }
+module std_private_locale_locale_base_api_openbsd              [system] { textual header "__locale_dir/locale_base_api/openbsd.h" }
+module std_private_locale_locale_base_api_win32                [system] { textual header "__locale_dir/locale_base_api/win32.h" }
+module std_private_locale_locale_base_api                      [system] {
+  header "__locale_dir/locale_base_api.h"
+  export *
+}
 
-// C compatibility headers
-//
-// These modules need to be their own top-level modules because they depend on the system-provided
-// headers (via include_next), which are then free to include other C headers provided by libc++.
-// If we group these headers in a single module, we would end up with circular dependencies.
-module std_complex_h [system] {
-  header "complex.h"
+module std_private_math_abs                             [system] { header "__math/abs.h" }
+module std_private_math_copysign                        [system] { header "__math/copysign.h" }
+module std_private_math_error_functions                 [system] { header "__math/error_functions.h" }
+module std_private_math_exponential_functions           [system] { header "__math/exponential_functions.h" }
+module std_private_math_fdim                            [system] { header "__math/fdim.h" }
+module std_private_math_fma                             [system] { header "__math/fma.h" }
+module std_private_math_gamma                           [system] { header "__math/gamma.h" }
+module std_private_math_hyperbolic_functions            [system] { header "__math/hyperbolic_functions.h" }
+module std_private_math_hypot                           [system] { header "__math/hypot.h" }
+module std_private_math_inverse_hyperbolic_functions    [system] { header "__math/inverse_hyperbolic_functions.h" }
+module std_private_math_inverse_trigonometric_functions [system] { header "__math/inverse_trigonometric_functions.h" }
+module std_private_math_logarithms                      [system] { header "__math/logarithms.h" }
+module std_private_math_min_max                         [system] { header "__math/min_max.h" }
+module std_private_math_modulo                          [system] { header "__math/modulo.h" }
+module std_private_math_remainder                       [system] { header "__math/remainder.h" }
+module std_private_math_roots                           [system] { header "__math/roots.h" }
+module std_private_math_rounding_functions              [system] { header "__math/rounding_functions.h" }
+module std_private_math_traits                          [system] { header "__math/traits.h" }
+module std_private_math_trigonometric_functions         [system] { header "__math/trigonometric_functions.h" }
+
+module std_private_mdspan_default_accessor [system] { header "__mdspan/default_accessor.h" }
+module std_private_mdspan_extents          [system] {
+  header "__mdspan/extents.h"
   export *
 }
-module std_ctype_h [system] {
-  header "ctype.h"
+module std_private_mdspan_layout_left      [system] { header "__mdspan/layout_left.h" }
+module std_private_mdspan_layout_right     [system] { header "__mdspan/layout_right.h" }
+module std_private_mdspan_layout_stride    [system] { header "__mdspan/layout_stride.h" }
+module std_private_mdspan_mdspan           [system] { header "__mdspan/mdspan.h" }
+module std_private_mdspan_mdspan_fwd       [system] { header "__fwd/mdspan.h" }
+
+module std_private_memory_addressof                       [system] { header "__memory/addressof.h" }
+module std_private_memory_align                           [system] { header "__memory/align.h" }
+module std_private_memory_aligned_alloc                   [system] { header "__memory/aligned_alloc.h" }
+module std_private_memory_allocate_at_least               [system] { header "__memory/allocate_at_least.h" }
+module std_private_memory_allocation_guard                [system] { header "__memory/allocation_guard.h" }
+module std_private_memory_allocator                       [system] { header "__memory/allocator.h" }
+module std_private_memory_allocator_arg_t                 [system] { header "__memory/allocator_arg_t.h" }
+module std_private_memory_allocator_destructor            [system] { header "__memory/allocator_destructor.h" }
+module std_private_memory_allocator_traits                [system] { header "__memory/allocator_traits.h" }
+module std_private_memory_assume_aligned                  [system] { header "__memory/assume_aligned.h" }
+module std_private_memory_auto_ptr                        [system] { header "__memory/auto_ptr.h" }
+module std_private_memory_builtin_new_allocator           [system] {
+  header "__memory/builtin_new_allocator.h"
   export *
 }
-module std_errno_h [system] {
-  header "errno.h"
+module std_private_memory_compressed_pair                 [system] { header "__memory/compressed_pair.h" }
+module std_private_memory_concepts                        [system] {
+  header "__memory/concepts.h"
+  export std_private_type_traits_remove_reference
+}
+module std_private_memory_construct_at                    [system] { header "__memory/construct_at.h" }
+module std_private_memory_destruct_n                      [system] { header "__memory/destruct_n.h" }
+module std_private_memory_fwd                             [system] { header "__fwd/memory.h" }
+module std_private_memory_pointer_traits                  [system] { header "__memory/pointer_traits.h" }
+module std_private_memory_ranges_construct_at             [system] { header "__memory/ranges_construct_at.h" }
+module std_private_memory_ranges_uninitialized_algorithms [system] {
+  header "__memory/ranges_uninitialized_algorithms.h"
+  export std_private_algorithm_in_out_result
+}
+module std_private_memory_raw_storage_iterator            [system] { header "__memory/raw_storage_iterator.h" }
+module std_private_memory_shared_ptr                      [system] {
+  header "__memory/shared_ptr.h"
+  export std_private_memory_uninitialized_algorithms
+}
+module std_private_memory_swap_allocator                  [system] { header "__memory/swap_allocator.h" }
+module std_private_memory_temp_value                      [system] { header "__memory/temp_value.h" }
+module std_private_memory_temporary_buffer                [system] {
+  header "__memory/temporary_buffer.h"
+  export std_private_utility_pair
+}
+module std_private_memory_uninitialized_algorithms        [system] {
+  header "__memory/uninitialized_algorithms.h"
+  export std_private_algorithm_copy
+}
+module std_private_memory_unique_ptr                      [system] {
+  header "__memory/unique_ptr.h"
+  export std_private_type_traits_add_lvalue_reference
+  export std_private_type_traits_is_pointer
+  export std_private_type_traits_type_identity
+}
+module std_private_memory_uses_allocator                  [system] { header "__memory/uses_allocator.h" }
+module std_private_memory_uses_allocator_construction     [system] { header "__memory/uses_allocator_construction.h" }
+module std_private_memory_voidify                         [system] { header "__memory/voidify.h" }
+
+module std_private_memory_resource_memory_resource              [system] { header "__memory_resource/memory_resource.h" }
+module std_private_memory_resource_memory_resource_fwd          [system] { header "__fwd/memory_resource.h" }
+module std_private_memory_resource_monotonic_buffer_resource    [system] { header "__memory_resource/monotonic_buffer_resource.h" }
+module std_private_memory_resource_polymorphic_allocator        [system] { header "__memory_resource/polymorphic_allocator.h" }
+module std_private_memory_resource_pool_options                 [system] { header "__memory_resource/pool_options.h" }
+module std_private_memory_resource_synchronized_pool_resource   [system] {
+  header "__memory_resource/synchronized_pool_resource.h"
   export *
 }
-module std_fenv_h [system] {
-  header "fenv.h"
+module std_private_memory_resource_unsynchronized_pool_resource [system] { header "__memory_resource/unsynchronized_pool_resource.h" }
+
+module std_private_mutex_lock_guard  [system] { header "__mutex/lock_guard.h" }
+module std_private_mutex_mutex       [system] { header "__mutex/mutex.h" }
+module std_private_mutex_once_flag  [system]  { header "__mutex/once_flag.h" }
+module std_private_mutex_tag_types   [system] { header "__mutex/tag_types.h" }
+module std_private_mutex_unique_lock [system] { header "__mutex/unique_lock.h" }
+
+module std_private_numeric_accumulate               [system] { header "__numeric/accumulate.h" }
+module std_private_numeric_adjacent_difference      [system] { header "__numeric/adjacent_difference.h" }
+module std_private_numeric_exclusive_scan           [system] { header "__numeric/exclusive_scan.h" }
+module std_private_numeric_gcd_lcm                  [system] { header "__numeric/gcd_lcm.h" }
+module std_private_numeric_inclusive_scan           [system] { header "__numeric/inclusive_scan.h" }
+module std_private_numeric_inner_product            [system] { header "__numeric/inner_product.h" }
+module std_private_numeric_iota                     [system] { header "__numeric/iota.h" }
+module std_private_numeric_midpoint                 [system] { header "__numeric/midpoint.h" }
+module std_private_numeric_partial_sum              [system] { header "__numeric/partial_sum.h" }
+module std_private_numeric_pstl                     [system] {
+  header "__numeric/pstl.h"
   export *
 }
-module std_float_h [system] {
-  header "float.h"
+module std_private_numeric_reduce                   [system] { header "__numeric/reduce.h" }
+module std_private_numeric_saturation_arithmetic    [system] { header "__numeric/saturation_arithmetic.h" }
+module std_private_numeric_transform_exclusive_scan [system] { header "__numeric/transform_exclusive_scan.h" }
+module std_private_numeric_transform_inclusive_scan [system] { header "__numeric/transform_inclusive_scan.h" }
+module std_private_numeric_transform_reduce         [system] { header "__numeric/transform_reduce.h" }
+
+module std_private_pstl_backend                    [system] {
+  header "__pstl/backend.h"
   export *
 }
-module std_inttypes_h [system] {
-  header "inttypes.h"
+module std_private_pstl_backend_fwd                [system] {
+  header "__pstl/backend_fwd.h"
   export *
 }
-module std_math_h [system] {
-  header "math.h"
+module std_private_pstl_backends_default           [system] {
+  header "__pstl/backends/default.h"
   export *
 }
-module std_stdatomic_h [system] {
-  header "stdatomic.h"
+module std_private_pstl_backends_libdispatch       [system] {
+  header "__pstl/backends/libdispatch.h"
   export *
 }
-module std_stdbool_h [system] {
-  // <stdbool.h>'s __bool_true_false_are_defined macro requires textual inclusion.
-  textual header "stdbool.h"
+module std_private_pstl_backends_openmp            [system] {
+  header "__pstl/backends/openmp.h"
+  export *
 }
-module std_stddef_h [system] {
-  // <stddef.h>'s __need_* macros require textual inclusion.
-  textual header "stddef.h"
+module std_private_pstl_backends_serial            [system] {
+  header "__pstl/backends/serial.h"
+  export *
 }
-module std_stdio_h [system] {
-  // <stdio.h>'s __need_* macros require textual inclusion.
-  textual header "stdio.h"
+module std_private_pstl_backends_std_thread        [system] {
+  header "__pstl/backends/std_thread.h"
+  export *
 }
-module std_stdlib_h [system] {
-  // <stdlib.h>'s __need_* macros require textual inclusion.
-  textual header "stdlib.h"
+module std_private_pstl_cpu_algos_any_of           [system] { header "__pstl/cpu_algos/any_of.h" }
+module std_private_pstl_cpu_algos_cpu_traits       [system] { header "__pstl/cpu_algos/cpu_traits.h" }
+module std_private_pstl_cpu_algos_fill             [system] { header "__pstl/cpu_algos/fill.h" }
+module std_private_pstl_cpu_algos_find_if          [system] { header "__pstl/cpu_algos/find_if.h" }
+module std_private_pstl_cpu_algos_for_each         [system] { header "__pstl/cpu_algos/for_each.h" }
+module std_private_pstl_cpu_algos_merge            [system] { header "__pstl/cpu_algos/merge.h" }
+module std_private_pstl_cpu_algos_stable_sort      [system] { header "__pstl/cpu_algos/stable_sort.h" }
+module std_private_pstl_cpu_algos_transform        [system] { header "__pstl/cpu_algos/transform.h" }
+module std_private_pstl_cpu_algos_transform_reduce [system] { header "__pstl/cpu_algos/transform_reduce.h" }
+module std_private_pstl_dispatch                   [system] { header "__pstl/dispatch.h" }
+module std_private_pstl_handle_exception           [system] { header "__pstl/handle_exception.h" }
+
+module std_private_queue_fwd [system] { header "__fwd/queue.h" }
+
+module std_private_ostream_basic_ostream [system] {
+  header "__ostream/basic_ostream.h"
+  export std_streambuf
 }
-module std_string_h [system] {
-  header "string.h"
+module std_private_ostream_print         [system] {
+  header "__ostream/print.h"
+  export std_print
+}
+
+module std_private_random_bernoulli_distribution          [system] { header "__random/bernoulli_distribution.h" }
+module std_private_random_binomial_distribution           [system] { header "__random/binomial_distribution.h" }
+module std_private_random_cauchy_distribution             [system] { header "__random/cauchy_distribution.h" }
+module std_private_random_chi_squared_distribution        [system] { header "__random/chi_squared_distribution.h" }
+module std_private_random_clamp_to_integral               [system] { header "__random/clamp_to_integral.h" }
+module std_private_random_default_random_engine           [system] { header "__random/default_random_engine.h" }
+module std_private_random_discard_block_engine            [system] { header "__random/discard_block_engine.h" }
+module std_private_random_discrete_distribution           [system] {
+  header "__random/discrete_distribution.h"
   export *
 }
-module std_tgmath_h [system] {
-  header "tgmath.h"
+module std_private_random_exponential_distribution        [system] { header "__random/exponential_distribution.h" }
+module std_private_random_extreme_value_distribution      [system] { header "__random/extreme_value_distribution.h" }
+module std_private_random_fisher_f_distribution           [system] { header "__random/fisher_f_distribution.h" }
+module std_private_random_gamma_distribution              [system] { header "__random/gamma_distribution.h" }
+module std_private_random_generate_canonical              [system] { header "__random/generate_canonical.h" }
+module std_private_random_geometric_distribution          [system] { header "__random/geometric_distribution.h" }
+module std_private_random_independent_bits_engine         [system] { header "__random/independent_bits_engine.h" }
+module std_private_random_is_seed_sequence                [system] { header "__random/is_seed_sequence.h" }
+module std_private_random_is_valid                        [system] { header "__random/is_valid.h" }
+module std_private_random_knuth_b                         [system] { header "__random/knuth_b.h" }
+module std_private_random_linear_congruential_engine      [system] { header "__random/linear_congruential_engine.h" }
+module std_private_random_log2                            [system] { header "__random/log2.h" }
+module std_private_random_lognormal_distribution          [system] { header "__random/lognormal_distribution.h" }
+module std_private_random_mersenne_twister_engine         [system] { header "__random/mersenne_twister_engine.h" }
+module std_private_random_negative_binomial_distribution  [system] { header "__random/negative_binomial_distribution.h" }
+module std_private_random_normal_distribution             [system] { header "__random/normal_distribution.h" }
+module std_private_random_piecewise_constant_distribution [system] {
+  header "__random/piecewise_constant_distribution.h"
   export *
 }
-module std_uchar_h [system] {
-  header "uchar.h"
+module std_private_random_piecewise_linear_distribution   [system] {
+  header "__random/piecewise_linear_distribution.h"
   export *
 }
-module std_wchar_h [system] {
-  // <wchar.h>'s __need_* macros require textual inclusion.
-  textual header "wchar.h"
+module std_private_random_poisson_distribution            [system] { header "__random/poisson_distribution.h" }
+module std_private_random_random_device                   [system] {
+  header "__random/random_device.h"
+  export *
 }
-module std_wctype_h [system] {
-  header "wctype.h"
+module std_private_random_ranlux                          [system] { header "__random/ranlux.h" }
+module std_private_random_seed_seq                        [system] {
+  header "__random/seed_seq.h"
+  export *
+}
+module std_private_random_shuffle_order_engine            [system] { header "__random/shuffle_order_engine.h" }
+module std_private_random_student_t_distribution          [system] { header "__random/student_t_distribution.h" }
+module std_private_random_subtract_with_carry_engine      [system] { header "__random/subtract_with_carry_engine.h" }
+module std_private_random_uniform_int_distribution        [system] { header "__random/uniform_int_distribution.h" }
+module std_private_random_uniform_random_bit_generator    [system] { header "__random/uniform_random_bit_generator.h" }
+module std_private_random_uniform_real_distribution       [system] { header "__random/uniform_real_distribution.h" }
+module std_private_random_weibull_distribution            [system] { header "__random/weibull_distribution.h" }
+
+module std_private_ranges_access                     [system] { header "__ranges/access.h" }
+module std_private_ranges_all                        [system] {
+  header "__ranges/all.h"
+  export std_private_functional_compose
+  export std_private_functional_perfect_forward
+  export std_private_ranges_owning_view
+}
+module std_private_ranges_as_rvalue_view             [system] { header "__ranges/as_rvalue_view.h" }
+module std_private_ranges_chunk_by_view              [system] { header "__ranges/chunk_by_view.h" }
+module std_private_ranges_common_view                [system] { header "__ranges/common_view.h" }
+module std_private_ranges_concepts                   [system] {
+  header "__ranges/concepts.h"
+  export std_private_iterator_concepts
+}
+module std_private_ranges_container_compatible_range [system] { header "__ranges/container_compatible_range.h" }
+module std_private_ranges_counted                    [system] {
+  header "__ranges/counted.h"
+  export std_span
+}
+module std_private_ranges_dangling                   [system] { header "__ranges/dangling.h" }
+module std_private_ranges_data                       [system] { header "__ranges/data.h" }
+module std_private_ranges_drop_view                  [system] { header "__ranges/drop_view.h" }
+module std_private_ranges_drop_while_view            [system] { header "__ranges/drop_while_view.h" }
+module std_private_ranges_elements_view              [system] { header "__ranges/elements_view.h" }
+module std_private_ranges_empty                      [system] { header "__ranges/empty.h" }
+module std_private_ranges_empty_view                 [system] { header "__ranges/empty_view.h" }
+module std_private_ranges_enable_borrowed_range      [system] { header "__ranges/enable_borrowed_range.h" }
+module std_private_ranges_enable_view                [system] { header "__ranges/enable_view.h" }
+module std_private_ranges_filter_view                [system] {
+  header "__ranges/filter_view.h"
+  export std_private_ranges_range_adaptor
+}
+module std_private_ranges_from_range                 [system] { header "__ranges/from_range.h" }
+module std_private_ranges_iota_view                  [system] { header "__ranges/iota_view.h" }
+module std_private_ranges_istream_view               [system] {
+  header "__ranges/istream_view.h"
+}
+module std_private_ranges_join_view                  [system] {
+  header "__ranges/join_view.h"
+  export std_private_iterator_iterator_with_data
+  export std_private_iterator_segmented_iterator
+}
+module std_private_ranges_lazy_split_view            [system] {
+  header "__ranges/lazy_split_view.h"
+  export std_private_ranges_non_propagating_cache
+}
+module std_private_ranges_movable_box                [system] { header "__ranges/movable_box.h" }
+module std_private_ranges_non_propagating_cache      [system] { header "__ranges/non_propagating_cache.h" }
+module std_private_ranges_owning_view                [system] { header "__ranges/owning_view.h" }
+module std_private_ranges_range_adaptor              [system] { header "__ranges/range_adaptor.h" }
+module std_private_ranges_rbegin                     [system] { header "__ranges/rbegin.h" }
+module std_private_ranges_ref_view                   [system] { header "__ranges/ref_view.h" }
+module std_private_ranges_rend                       [system] { header "__ranges/rend.h" }
+module std_private_ranges_repeat_view                [system] { header "__ranges/repeat_view.h" }
+module std_private_ranges_reverse_view               [system] { header "__ranges/reverse_view.h" }
+module std_private_ranges_single_view                [system] { header "__ranges/single_view.h" }
+module std_private_ranges_size                       [system] {
+  header "__ranges/size.h"
+  export std_private_type_traits_make_unsigned
+}
+module std_private_ranges_split_view                 [system] { header "__ranges/split_view.h" }
+module std_private_ranges_subrange                   [system] {
+  header "__ranges/subrange.h"
+  export std_private_ranges_subrange_fwd
+}
+module std_private_ranges_subrange_fwd               [system] {
+  header "__fwd/subrange.h"
+  export std_private_iterator_concepts
+}
+module std_private_ranges_take_view                  [system] { header "__ranges/take_view.h" }
+module std_private_ranges_take_while_view            [system] { header "__ranges/take_while_view.h" }
+module std_private_ranges_to                         [system] { header "__ranges/to.h" }
+module std_private_ranges_transform_view             [system] {
+  header "__ranges/transform_view.h"
+  export std_private_functional_bind_back
+  export std_private_functional_perfect_forward
+  export std_private_ranges_movable_box
+}
+module std_private_ranges_view_interface             [system] { header "__ranges/view_interface.h" }
+module std_private_ranges_views                      [system] { header "__ranges/views.h" }
+module std_private_ranges_zip_view                   [system] {
+  header "__ranges/zip_view.h"
+  export std_private_utility_pair
+}
+
+module std_private_span_span_fwd [system] { header "__fwd/span.h" }
+
+module std_private_stack_fwd [system] { header "__fwd/stack.h" }
+
+module std_private_stop_token_atomic_unique_lock   [system] { header "__stop_token/atomic_unique_lock.h" }
+module std_private_stop_token_intrusive_list_view  [system] { header "__stop_token/intrusive_list_view.h" }
+module std_private_stop_token_intrusive_shared_ptr [system] { header "__stop_token/intrusive_shared_ptr.h" }
+module std_private_stop_token_stop_callback        [system] { header "__stop_token/stop_callback.h" }
+module std_private_stop_token_stop_source          [system] {
+  header "__stop_token/stop_source.h"
+  export *
+}
+module std_private_stop_token_stop_state           [system] {
+  header "__stop_token/stop_state.h"
+  export *
+}
+module std_private_stop_token_stop_token           [system] {
+  header "__stop_token/stop_token.h"
   export *
 }
 
-// This header is used by other C compatibility headers so it needs to be in its own module.
-module std_private_mbstate_t [system] {
-  header "__mbstate_t.h"
+module std_private_string_char_traits           [system] {
+  header "__string/char_traits.h"
+  export *
+}
+module std_private_string_constexpr_c_functions [system] {
+  header "__string/constexpr_c_functions.h"
+  export std_private_type_traits_is_equality_comparable
+}
+module std_private_string_extern_template_lists [system] { header "__string/extern_template_lists.h" }
+module std_private_string_string_fwd            [system] { header "__fwd/string.h" }
+
+module std_private_string_view_string_view_fwd [system] { header "__fwd/string_view.h" }
+
+module std_private_system_error_errc            [system] { header "__system_error/errc.h" }
+module std_private_system_error_error_category  [system] { header "__system_error/error_category.h" }
+module std_private_system_error_error_code      [system] {
+  header "__system_error/error_code.h"
+  export std_private_functional_hash
+  export std_private_functional_unary_function
+}
+module std_private_system_error_error_condition [system] {
+  header "__system_error/error_condition.h"
+  export std_private_functional_hash
+  export std_private_functional_unary_function
+}
+module std_private_system_error_system_error    [system] { header "__system_error/system_error.h" }
+
+module std_private_thread_formatter            [system] { header "__thread/formatter.h" }
+module std_private_thread_id                   [system] { header "__thread/id.h" }
+module std_private_thread_jthread              [system] {
+  header "__thread/jthread.h"
+  export *
+}
+module std_private_thread_poll_with_backoff    [system] { header "__thread/poll_with_backoff.h" }
+module std_private_thread_support              [system] {
+  header "__thread/support.h"
+  export *
+}
+module std_private_thread_support_c11          [system] { textual header "__thread/support/c11.h" }
+module std_private_thread_support_external     [system] { textual header "__thread/support/external.h" }
+module std_private_thread_support_pthread      [system] { textual header "__thread/support/pthread.h" }
+module std_private_thread_support_windows      [system] { textual header "__thread/support/windows.h" }
+module std_private_thread_this_thread          [system] { header "__thread/this_thread.h" }
+module std_private_thread_thread               [system] {
+  header "__thread/thread.h"
+  export *
+}
+module std_private_thread_timed_backoff_policy [system] { header "__thread/timed_backoff_policy.h" }
+
+module std_private_tuple_find_index             [system] { header "__tuple/find_index.h" }
+module std_private_tuple_make_tuple_types       [system] { header "__tuple/make_tuple_types.h" }
+module std_private_tuple_tuple_like_no_subrange [system] {
+  header "__tuple/tuple_like_no_subrange.h"
+}
+module std_private_tuple_sfinae_helpers         [system] { header "__tuple/sfinae_helpers.h" }
+module std_private_tuple_tuple_element          [system] { header "__tuple/tuple_element.h" }
+module std_private_tuple_tuple_fwd              [system] { header "__fwd/tuple.h" }
+module std_private_tuple_tuple_indices          [system] { header "__tuple/tuple_indices.h" }
+module std_private_tuple_tuple_like             [system] {
+  header "__tuple/tuple_like.h"
   export *
 }
+module std_private_tuple_tuple_like_ext         [system] { header "__tuple/tuple_like_ext.h" }
+module std_private_tuple_tuple_size             [system] { header "__tuple/tuple_size.h" }
+module std_private_tuple_tuple_types            [system] { header "__tuple/tuple_types.h" }
+
+module std_private_type_traits_add_const                                 [system] { header "__type_traits/add_const.h" }
+module std_private_type_traits_add_cv                                    [system] { header "__type_traits/add_cv.h" }
+module std_private_type_traits_add_lvalue_reference                      [system] {
+  header "__type_traits/add_lvalue_reference.h"
+  export std_private_type_traits_is_referenceable
+}
+module std_private_type_traits_add_pointer                               [system] { header "__type_traits/add_pointer.h" }
+module std_private_type_traits_add_rvalue_reference                      [system] { header "__type_traits/add_rvalue_reference.h" }
+module std_private_type_traits_add_volatile                              [system] { header "__type_traits/add_volatile.h" }
+module std_private_type_traits_aligned_storage                           [system] { header "__type_traits/aligned_storage.h" }
+module std_private_type_traits_aligned_union                             [system] { header "__type_traits/aligned_union.h" }
+module std_private_type_traits_alignment_of                              [system] { header "__type_traits/alignment_of.h" }
+module std_private_type_traits_can_extract_key                           [system] { header "__type_traits/can_extract_key.h" }
+module std_private_type_traits_common_reference                          [system] {
+  header "__type_traits/common_reference.h"
+  export std_private_type_traits_remove_cvref
+}
+module std_private_type_traits_common_type                               [system] {
+  header "__type_traits/common_type.h"
+  export std_private_utility_declval
+}
+module std_private_type_traits_conditional                               [system] { header "__type_traits/conditional.h" }
+module std_private_type_traits_conjunction                               [system] { header "__type_traits/conjunction.h" }
+module std_private_type_traits_copy_cv                                   [system] { header "__type_traits/copy_cv.h" }
+module std_private_type_traits_copy_cvref                                [system] { header "__type_traits/copy_cvref.h" }
+module std_private_type_traits_datasizeof                                [system] { header "__type_traits/datasizeof.h" }
+module std_private_type_traits_decay                                     [system] {
+  header "__type_traits/decay.h"
+  export std_private_type_traits_add_pointer
+}
+module std_private_type_traits_dependent_type                            [system] { header "__type_traits/dependent_type.h" }
+module std_private_type_traits_desugars_to                               [system] { header "__type_traits/desugars_to.h" }
+module std_private_type_traits_disjunction                               [system] { header "__type_traits/disjunction.h" }
+module std_private_type_traits_enable_if                                 [system] { header "__type_traits/enable_if.h" }
+module std_private_type_traits_extent                                    [system] { header "__type_traits/extent.h" }
+module std_private_type_traits_has_unique_object_representation          [system] { header "__type_traits/has_unique_object_representation.h" }
+module std_private_type_traits_has_virtual_destructor                    [system] { header "__type_traits/has_virtual_destructor.h" }
+module std_private_type_traits_integral_constant                         [system] { header "__type_traits/integral_constant.h" }
+module std_private_type_traits_invoke                                    [system] {
+  header "__type_traits/invoke.h"
+  export std_private_type_traits_conditional
+  export std_private_type_traits_decay
+  export std_private_type_traits_decay
+  export std_private_type_traits_enable_if
+  export std_private_type_traits_is_base_of
+  export std_private_type_traits_is_core_convertible
+  export std_private_type_traits_is_reference_wrapper
+  export std_private_type_traits_is_same
+  export std_private_type_traits_is_void
+  export std_private_type_traits_nat
+  export std_private_type_traits_remove_cv
+}
+module std_private_type_traits_is_abstract                               [system] { header "__type_traits/is_abstract.h" }
+module std_private_type_traits_is_aggregate                              [system] { header "__type_traits/is_aggregate.h" }
+module std_private_type_traits_is_allocator                              [system] { header "__type_traits/is_allocator.h" }
+module std_private_type_traits_is_always_bitcastable                     [system] { header "__type_traits/is_always_bitcastable.h" }
+module std_private_type_traits_is_arithmetic                             [system] {
+  header "__type_traits/is_arithmetic.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_array                                  [system] {
+  header "__type_traits/is_array.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_assignable                             [system] { header "__type_traits/is_assignable.h" }
+module std_private_type_traits_is_base_of                                [system] { header "__type_traits/is_base_of.h" }
+module std_private_type_traits_is_bounded_array                          [system] { header "__type_traits/is_bounded_array.h" }
+module std_private_type_traits_is_callable                               [system] { header "__type_traits/is_callable.h" }
+module std_private_type_traits_is_char_like_type                         [system] { header "__type_traits/is_char_like_type.h" }
+module std_private_type_traits_is_class                                  [system] { header "__type_traits/is_class.h" }
+module std_private_type_traits_is_compound                               [system] { header "__type_traits/is_compound.h" }
+module std_private_type_traits_is_const                                  [system] { header "__type_traits/is_const.h" }
+module std_private_type_traits_is_constant_evaluated                     [system] { header "__type_traits/is_constant_evaluated.h" }
+module std_private_type_traits_is_constructible                          [system] { header "__type_traits/is_constructible.h" }
+module std_private_type_traits_is_convertible                            [system] {
+  header "__type_traits/is_convertible.h"
+  export std_private_type_traits_is_array
+}
+module std_private_type_traits_is_copy_assignable                        [system] { header "__type_traits/is_copy_assignable.h" }
+module std_private_type_traits_is_copy_constructible                     [system] { header "__type_traits/is_copy_constructible.h" }
+module std_private_type_traits_is_core_convertible                       [system] {
+  header "__type_traits/is_core_convertible.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_destructible                           [system] { header "__type_traits/is_destructible.h" }
+module std_private_type_traits_is_empty                                  [system] { header "__type_traits/is_empty.h" }
+module std_private_type_traits_is_enum                                   [system] {
+  header "__type_traits/is_enum.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_equality_comparable                    [system] {
+  header "__type_traits/is_equality_comparable.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_execution_policy                       [system] {
+  header "__type_traits/is_execution_policy.h"
+  export std_private_type_traits_remove_cvref
+}
+module std_private_type_traits_is_final                                  [system] { header "__type_traits/is_final.h" }
+module std_private_type_traits_is_floating_point                         [system] { header "__type_traits/is_floating_point.h" }
+module std_private_type_traits_is_function                               [system] { header "__type_traits/is_function.h" }
+module std_private_type_traits_is_fundamental                            [system] { header "__type_traits/is_fundamental.h" }
+module std_private_type_traits_is_implicitly_default_constructible       [system] { header "__type_traits/is_implicitly_default_constructible.h" }
+module std_private_type_traits_is_integral                               [system] { header "__type_traits/is_integral.h" }
+module std_private_type_traits_is_literal_type                           [system] { header "__type_traits/is_literal_type.h" }
+module std_private_type_traits_is_member_function_pointer                [system] { header "__type_traits/is_member_function_pointer.h" }
+module std_private_type_traits_is_member_object_pointer                  [system] { header "__type_traits/is_member_object_pointer.h" }
+module std_private_type_traits_is_member_pointer                         [system] { header "__type_traits/is_member_pointer.h" }
+module std_private_type_traits_is_nothrow_assignable                     [system] { header "__type_traits/is_nothrow_assignable.h" }
+module std_private_type_traits_is_nothrow_constructible                  [system] {
+  header "__type_traits/is_nothrow_constructible.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_nothrow_convertible                    [system] { header "__type_traits/is_nothrow_convertible.h" }
+module std_private_type_traits_is_nothrow_destructible                   [system] {
+  header "__type_traits/is_nothrow_destructible.h"
+  export std_private_type_traits_is_destructible
+}
+module std_private_type_traits_is_null_pointer                           [system] {
+  header "__type_traits/is_null_pointer.h"
+  export std_cstddef
+}
+module std_private_type_traits_is_object                                 [system] {
+  header "__type_traits/is_object.h"
+  export std_private_type_traits_is_scalar
+}
+module std_private_type_traits_is_pod                                    [system] { header "__type_traits/is_pod.h" }
+module std_private_type_traits_is_pointer                                [system] { header "__type_traits/is_pointer.h" }
+module std_private_type_traits_is_polymorphic                            [system] { header "__type_traits/is_polymorphic.h" }
+module std_private_type_traits_is_primary_template                       [system] {
+  header "__type_traits/is_primary_template.h"
+  export std_private_type_traits_enable_if
+}
+module std_private_type_traits_is_reference                              [system] { header "__type_traits/is_reference.h" }
+module std_private_type_traits_is_reference_wrapper                      [system] { header "__type_traits/is_reference_wrapper.h" }
+module std_private_type_traits_is_referenceable                          [system] { header "__type_traits/is_referenceable.h" }
+module std_private_type_traits_is_same                                   [system] {
+  header "__type_traits/is_same.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_scalar                                 [system] {
+  header "__type_traits/is_scalar.h"
+  export std_private_type_traits_is_null_pointer
+}
+module std_private_type_traits_is_scoped_enum                            [system] { header "__type_traits/is_scoped_enum.h" }
+module std_private_type_traits_is_signed                                 [system] { header "__type_traits/is_signed.h" }
+module std_private_type_traits_is_signed_integer                         [system] { header "__type_traits/is_signed_integer.h" }
+module std_private_type_traits_is_specialization                         [system] { header "__type_traits/is_specialization.h" }
+module std_private_type_traits_is_standard_layout                        [system] { header "__type_traits/is_standard_layout.h" }
+module std_private_type_traits_is_swappable                              [system] {
+  header "__type_traits/is_swappable.h"
+  export std_private_type_traits_is_move_constructible
+}
+module std_private_type_traits_is_trivial                                [system] { header "__type_traits/is_trivial.h" }
+module std_private_type_traits_is_trivially_assignable                   [system] { header "__type_traits/is_trivially_assignable.h" }
+module std_private_type_traits_is_trivially_constructible                [system] { header "__type_traits/is_trivially_constructible.h" }
+module std_private_type_traits_is_trivially_copyable                     [system] { header "__type_traits/is_trivially_copyable.h" }
+module std_private_type_traits_is_trivially_destructible                 [system] { header "__type_traits/is_trivially_destructible.h" }
+module std_private_type_traits_is_trivially_lexicographically_comparable [system] { header "__type_traits/is_trivially_lexicographically_comparable.h" }
+module std_private_type_traits_is_trivially_relocatable                  [system] { header "__type_traits/is_trivially_relocatable.h" }
+module std_private_type_traits_is_unbounded_array                        [system] { header "__type_traits/is_unbounded_array.h" }
+module std_private_type_traits_is_union                                  [system] { header "__type_traits/is_union.h" }
+module std_private_type_traits_is_unsigned                               [system] { header "__type_traits/is_unsigned.h" }
+module std_private_type_traits_is_unsigned_integer                       [system] { header "__type_traits/is_unsigned_integer.h" }
+module std_private_type_traits_is_valid_expansion                        [system] { header "__type_traits/is_valid_expansion.h" }
+module std_private_type_traits_is_void                                   [system] {
+  header "__type_traits/is_void.h"
+  export std_private_type_traits_integral_constant
+}
+module std_private_type_traits_is_volatile                               [system] { header "__type_traits/is_volatile.h" }
+module std_private_type_traits_lazy                                      [system] { header "__type_traits/lazy.h" }
+module std_private_type_traits_make_32_64_or_128_bit                     [system] { header "__type_traits/make_32_64_or_128_bit.h" }
+module std_private_type_traits_make_const_lvalue_ref                     [system] { header "__type_traits/make_const_lvalue_ref.h" }
+module std_private_type_traits_make_signed                               [system] { header "__type_traits/make_signed.h" }
+module std_private_type_traits_make_unsigned                             [system] {
+  header "__type_traits/make_unsigned.h"
+  export std_private_type_traits_is_unsigned
+}
+module std_private_type_traits_maybe_const                               [system] { header "__type_traits/maybe_const.h" }
+module std_private_type_traits_nat                                       [system] { header "__type_traits/nat.h" }
+module std_private_type_traits_negation                                  [system] { header "__type_traits/negation.h" }
+module std_private_type_traits_noexcept_move_assign_container            [system] { header "__type_traits/noexcept_move_assign_container.h" }
+module std_private_type_traits_promote                                   [system] { header "__type_traits/promote.h" }
+module std_private_type_traits_rank                                      [system] { header "__type_traits/rank.h" }
+module std_private_type_traits_remove_all_extents                        [system] { header "__type_traits/remove_all_extents.h" }
+module std_private_type_traits_remove_const                              [system] { header "__type_traits/remove_const.h" }
+module std_private_type_traits_remove_const_ref                          [system] { header "__type_traits/remove_const_ref.h" }
+module std_private_type_traits_remove_cv                                 [system] {
+  header "__type_traits/remove_cv.h"
+  export std_private_type_traits_remove_const
+  export std_private_type_traits_remove_volatile
+}
+module std_private_type_traits_remove_cvref                              [system] { header "__type_traits/remove_cvref.h" }
+module std_private_type_traits_remove_extent                             [system] { header "__type_traits/remove_extent.h" }
+module std_private_type_traits_remove_pointer                            [system] { header "__type_traits/remove_pointer.h" }
+module std_private_type_traits_remove_reference                          [system] { header "__type_traits/remove_reference.h" }
+module std_private_type_traits_remove_volatile                           [system] { header "__type_traits/remove_volatile.h" }
+module std_private_type_traits_result_of                                 [system] { header "__type_traits/result_of.h" }
+module std_private_type_traits_strip_signature                           [system] { header "__type_traits/strip_signature.h" }
+module std_private_type_traits_type_identity                             [system] { header "__type_traits/type_identity.h" }
+module std_private_type_traits_type_list                                 [system] { header "__type_traits/type_list.h" }
+module std_private_type_traits_underlying_type                           [system] {
+  header "__type_traits/underlying_type.h"
+  export std_private_type_traits_is_enum
+}
+module std_private_type_traits_unwrap_ref                                [system] { header "__type_traits/unwrap_ref.h" }
+module std_private_type_traits_void_t                                    [system] { header "__type_traits/void_t.h" }
+
+module std_private_utility_as_const               [system] { header "__utility/as_const.h" }
+module std_private_utility_as_lvalue              [system] { header "__utility/as_lvalue.h" }
+module std_private_utility_auto_cast              [system] {
+  header "__utility/auto_cast.h"
+  export std_private_type_traits_decay
+}
+module std_private_utility_cmp                    [system] {
+  header "__utility/cmp.h"
+  export std_private_type_traits_make_unsigned
+}
+module std_private_utility_convert_to_integral    [system] { header "__utility/convert_to_integral.h" }
+module std_private_utility_declval                [system] { header "__utility/declval.h" }
+module std_private_utility_empty                  [system] { header "__utility/empty.h" }
+module std_private_utility_exception_guard        [system] { header "__utility/exception_guard.h" }
+module std_private_utility_exchange               [system] { header "__utility/exchange.h" }
+module std_private_utility_forward                [system] { header "__utility/forward.h" }
+module std_private_utility_forward_like           [system] { header "__utility/forward_like.h" }
+module std_private_utility_in_place               [system] { header "__utility/in_place.h" }
+module std_private_utility_integer_sequence       [system] { header "__utility/integer_sequence.h" }
+module std_private_utility_is_pointer_in_range    [system] { header "__utility/is_pointer_in_range.h" }
+module std_private_utility_is_valid_range         [system] { header "__utility/is_valid_range.h" }
+module std_private_utility_move                   [system] {
+  header "__utility/move.h"
+  export std_private_type_traits_is_copy_constructible
+  export std_private_type_traits_is_nothrow_move_constructible
+  export std_private_type_traits_remove_reference
+}
+module std_private_utility_no_destroy             [system] { header "__utility/no_destroy.h" }
+module std_private_utility_pair                   [system] {
+  header "__utility/pair.h"
+  export std_private_ranges_subrange_fwd
+  export std_private_tuple_pair_like
+  export std_private_type_traits_is_assignable
+  export std_private_type_traits_is_constructible
+  export std_private_type_traits_is_convertible
+  export std_private_type_traits_is_copy_assignable
+  export std_private_type_traits_is_move_assignable
+  export std_private_type_traits_is_nothrow_copy_constructible
+  export std_private_type_traits_is_nothrow_default_constructible
+  export std_private_type_traits_is_nothrow_move_assignable
+  export std_private_utility_pair_fwd
+}
+module std_private_utility_pair_fwd                [system] { header "__fwd/pair.h" }
+module std_private_utility_piecewise_construct     [system] { header "__utility/piecewise_construct.h" }
+module std_private_utility_priority_tag            [system] { header "__utility/priority_tag.h" }
+module std_private_utility_private_constructor_tag [system] { header "__utility/private_constructor_tag.h" }
+module std_private_utility_rel_ops                 [system] { header "__utility/rel_ops.h" }
+module std_private_utility_small_buffer            [system] { header "__utility/small_buffer.h" }
+module std_private_utility_swap                    [system] {
+  header "__utility/swap.h"
+  export std_private_type_traits_is_swappable
+}
+module std_private_utility_to_underlying           [system] { header "__utility/to_underlying.h" }
+module std_private_utility_unreachable             [system] { header "__utility/unreachable.h" }
+
+module std_private_variant_monostate               [system] { header "__variant/monostate.h" }
+
+module std_private_vector_fwd                      [system] { header "__fwd/vector.h" }
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/fill_offload.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/fill_offload.pass.cpp
new file mode 100644
index 00000000000000..cdde2c3d0a9b9d
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/fill_offload.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test will fail if the number of devices detected by OpenMP is larger
+// than zero but std::for_each(std::execution::par_unseq,...) is not executed on
+// the device.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+#include <omp.h>
+
+int main(int, char**) {
+  // We only run the test if a device is detected by OpenMP
+  if (omp_get_num_devices() < 1)
+    return 0;
+
+  // Initializing test array
+  const int test_size = 10000;
+  std::vector<int> v(test_size, 2);
+
+  // By making an extra map, we can control when the data is mapped to and from
+  // the device, because the map inside std::fill will then only increment and
+  // decrement reference counters and not move data.
+  int* data = v.data();
+#pragma omp target enter data map(to : data[0 : v.size()])
+  std::fill(std::execution::par_unseq, v.begin(), v.end(), -2);
+
+  // At this point v should only contain the value 2
+  for (int vi : v)
+    assert(vi == 2 &&
+           "std::fill transferred data from device to the host but should only have decreased the reference counter.");
+
+// After moving the result back to the host it should now be -2
+#pragma omp target update from(data[0 : v.size()])
+  for (int vi : v)
+    assert(vi == -2 && "std::fill did not update the result on the device.");
+
+#pragma omp target exit data map(delete : data[0 : v.size()])
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if.pass.cpp
new file mode 100644
index 00000000000000..7508d82156e54a
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that std::find_if(std::execution::par_unseq,...) always
+// finds the first entry in a vector matching the condition. If it was confused
+// with std::any_of, it could return the indexes in a non-increasing order.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <execution>
+#include <vector>
+
+template <class _Tp>
+void check_find_if(_Tp& data) {
+  const int len = data.end() - data.begin();
+  // Decrementing the values in the test indices
+  int idx[11] = {0, len / 10, len / 9, len / 8, len / 7, len / 6, len / 5, len / 4, len / 3, len / 2, len - 1};
+  for (auto i : idx) {
+    data[i] -= 1;
+  };
+
+  // Asserting that the minimas are found in the correct order
+  for (auto i : idx) {
+    auto found_min = std::find_if(
+        std::execution::par_unseq, data.begin(), data.end(), [&](decltype(data[0])& n) -> bool { return n < 2; });
+    assert(found_min == (data.begin() + i));
+    // Incrementing the minimum, so the next one can be found
+    (*found_min) += 1;
+  }
+}
+
+int main(int, char**) {
+  const int test_size = 10000;
+  // Testing with vector of doubles
+  {
+    std::vector<double> v(test_size, 2.0);
+    check_find_if(v);
+  }
+  // Testing with vector of integers
+  {
+    std::vector<int> v(test_size, 2);
+    check_find_if(v);
+  }
+  // Testing with array of doubles
+  {
+    std::array<double, test_size> a;
+    a.fill(2.0);
+    check_find_if(a);
+  }
+  // Testing with array of integers
+  {
+    std::array<int, test_size> a;
+    a.fill(2);
+    check_find_if(a);
+  }
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_funptr.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_funptr.pass.cpp
new file mode 100644
index 00000000000000..b84dd68ad3f1b3
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_funptr.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that we can provide function pointers as input to
+// std::find_if. The OpenMP declare target directive with the `indirect` clause
+// makes an implicit mapping of the host and device function pointers.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+#include <omp.h>
+
+bool is_odd(int& i) { return (i % 2) == 1; }
+#pragma omp declare target indirect to(is_odd)
+
+int main(int, char**) {
+  const int test_size = 10000;
+  std::vector<int> v(test_size, 2.0);
+  v[123] = 3;
+
+  // Providing for_each a function pointer
+  auto idx = std::find_if(std::execution::par_unseq, v.begin(), v.end(), is_odd);
+
+  assert(idx - v.begin() == 123 && "std::find_if(std::execution::par_unseq,...) does not accept function pointers");
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_offload.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_offload.pass.cpp
new file mode 100644
index 00000000000000..7afed4740a0f84
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/find_if_offload.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test will fail if the number of devices detected by OpenMP is larger
+// than zero but syd::find_if(std::execution::par_unseq,...) is not executed on
+// the device.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+#include <omp.h>
+
+int main(int, char**) {
+  // We only run the test if a device is detected by OpenMP
+  if (omp_get_num_devices() < 1)
+    return 0;
+
+  // Initializing test array
+  const int test_size = 10000;
+  std::vector<double> v(test_size, 1);
+
+  auto idx = std::find_if(std::execution::par_unseq, v.begin(), v.end(), [](double&) -> bool {
+    // Returns true if executed on the host
+    return omp_is_initial_device();
+  });
+  assert(idx == v.end() &&
+         "omp_is_initial_device() returned true in the target region. std::find_if was not offloaded.");
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_funptr.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_funptr.pass.cpp
new file mode 100644
index 00000000000000..4b9c23860800c8
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_funptr.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that we can provide function pointers as input to
+// std::for_each. The OpenMP declare target directive with the `indirect` clause
+// makes an implicit mapping of the host and device function pointers.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+#include <omp.h>
+
+void cube(double& d) { d *= d * d; }
+#pragma omp declare target indirect to(cube)
+
+int main(int, char**) {
+  const int test_size = 10000;
+  std::vector<double> v(test_size, 2.0);
+
+  // Providing for_each a function pointer
+  std::for_each(std::execution::par_unseq, v.begin(), v.end(), cube);
+
+  for (int vi : v)
+    assert(vi == 8 && "std::for_each(std::execution::par_unseq,...) does not accept function pointers");
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_lambda.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_lambda.pass.cpp
new file mode 100644
index 00000000000000..e0b0f18df27268
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_lambda.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that we can provide a lambda as input to std::for_each in
+// different ways.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+#include <omp.h>
+
+template <class Function, class Tp>
+void test_lambda(Function fun, Tp initial_value, Tp final_value) {
+  const int test_size = 10000;
+  std::vector<double> v(test_size, initial_value);
+
+  // Providing for_each a function pointer
+  std::for_each(std::execution::par_unseq, v.begin(), v.end(), fun);
+
+  for (int vi : v)
+    assert(vi == final_value && "std::for_each(std::execution::par_unseq,...) does not accept lambdas");
+}
+
+int main(int, char**) {
+  // Capturing by reference
+  auto cube_ref = [&](double& a) { a *= a * a; };
+  test_lambda(cube_ref, 2.0, 8.0);
+
+  // Capturing by value
+  auto cube_val = [=](double& a) { a *= a * a; };
+  test_lambda(cube_val, 2.0, 8.0);
+
+  // Capturing by reference when using additional input
+  double c1       = 1.0;
+  auto cube_ref_2 = [&](double& a) { a = a * a * a + c1; };
+#pragma omp target data map(to : c1)
+  test_lambda(cube_ref_2, 2.0, 9.0);
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_offload.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_offload.pass.cpp
new file mode 100644
index 00000000000000..4021e7b18e5f43
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_offload.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test will fail if the number of devices detected by OpenMP is larger
+// than zero but for_each(std::execution::par_unseq,...) is not executed on the
+// device.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+#include <omp.h>
+
+int main(int, char**) {
+  // We only run the test if a device is detected by OpenMP
+  if (omp_get_num_devices() < 1)
+    return 0;
+
+  // Initializing test array
+  const int test_size = 10000;
+  std::vector<int> v(test_size);
+  std::for_each(std::execution::par_unseq, v.begin(), v.end(), [](int& n) {
+    // Returns true if executed on the host
+    n = omp_is_initial_device();
+  });
+
+  for (int vi : v)
+    assert(vi == 0 && "omp_is_initial_device() returned true in the target region. std::for_each was not offloaded.");
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_overwrite_input.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_overwrite_input.pass.cpp
new file mode 100644
index 00000000000000..74f177b75e69cb
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/for_each_overwrite_input.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that you can overwrite the input in
+// std::for_each(std::execution::par_unseq,...). If the result was not copied
+// back from the device to the host, this test would fail.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <execution>
+#include <vector>
+
+template <class _Tp, class _Predicate, class _Up>
+void overwrite(_Tp& data, _Predicate pred, const _Up& value) {
+  // This function assumes that pred will never be the identity transformation
+
+  // Updating the array with a lambda
+  std::for_each(std::execution::par_unseq, data.begin(), data.end(), pred);
+
+  // Asserting that no elements have the intial value
+  for (int di : data)
+    assert(
+        di != value &&
+        "The GPU implementation of std::for_each does not allow users to mutate the input as the C++ standard does.");
+}
+
+int main(int, char**) {
+  const double value  = 2.0;
+  const int test_size = 10000;
+  // Testing with vector of doubles
+  {
+    std::vector<double> v(test_size, value);
+    overwrite(v, [&](double& n) { n *= n; }, value);
+  }
+  // Testing with vector of integers
+  {
+    std::vector<int> v(test_size, (int)value);
+    overwrite(v, [&](int& n) { n *= n; }, (int)value);
+  }
+  // Testing with array of doubles
+  {
+    std::array<double, test_size> a;
+    a.fill(value);
+    overwrite(a, [&](double& n) { n *= n; }, value);
+  }
+  // Testing with array of integers
+  {
+    std::array<int, test_size> a;
+    a.fill((int)value);
+    overwrite(a, [&](int& n) { n *= n; }, (int)value);
+  }
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/gpu_environment_variables.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/gpu_environment_variables.pass.cpp
new file mode 100644
index 00000000000000..801693a3d1eb84
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/gpu_environment_variables.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that the libc++ test configuration forwards the AMD and
+// NVIDIA environment variables specifying the visible devices. Intially when
+// developing the OpenMP offloading tests, this was not the case, and this test
+// will reveal if the configuration is wrong another time.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <string>
+#include <cassert>
+#include <omp.h>
+#include <iostream>
+
+std::string get_env_var(std::string const& env_var_name, int& flag) {
+  char* val;
+  val                = getenv(env_var_name.c_str());
+  std::string retval = "";
+  flag               = (val != NULL);
+  return (val != NULL) ? val : "";
+}
+
+int main(int, char**) {
+  // Stores whether the environment variable was found
+  int status = 0;
+
+  // Checking for AMD's enviroment variable for specifying visible devices
+  std::string rocr_visible_devices = get_env_var("ROCR_VISIBLE_DEVICES", status);
+  if (status)
+    assert(
+        (rocr_visible_devices.empty() || (omp_get_num_devices() > 0)) &&
+        "ROCR_VISIBLE_DEVICES was set but no devices were detected by OpenMP. The libc++ test suite is misconfigured.");
+
+  // Checking for NVIDIA's enviroment variable for specifying visible devices
+  std::string cuda_visible_devices = get_env_var("CUDA_VISIBLE_DEVICES", status);
+  if (status)
+    assert(
+        (cuda_visible_devices.empty() || (omp_get_num_devices() > 0)) &&
+        "CUDA_VISIBLE_DEVICES was set but no devices were detected by OpenMP. The libc++ test suite is misconfigured.");
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_40.verify.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_40.verify.cpp
new file mode 100644
index 00000000000000..85b2656788cf35
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_40.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// OpenMP target offloading has only been supported since version 4.5. This test
+// verifies that a diagnostic error is prompted if the OpenMP version is below
+// the minimum required version.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -fopenmp -fopenmp-version=40
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+
+// expected-error at __algorithm/pstl_backends/openmp/backend.h:26 {{"OpenMP target offloading has been supported since OpenMP version 4.5 (201511). Please use a more recent version of OpenMP."}}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_45.verify.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_45.verify.cpp
new file mode 100644
index 00000000000000..4765ca0d540b34
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_45.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// OpenMP target offloading has only been supported since version 4.5. This test
+// verifies that one can include algorithm without any diagnostics when using
+// the minimum required version of OpenMP.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -fopenmp -fopenmp-version=45
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+
+// expected-no-diagnostics
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_51.verify.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_51.verify.cpp
new file mode 100644
index 00000000000000..b7836cb9425486
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/openmp_version_51.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// OpenMP target offloading has only been supported since version 4.5. This test
+// verifies that one can include algorithm without any diagnostics when using a
+// version that is newer than the minimum requirement.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -fopenmp -fopenmp-version=51
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+
+// expected-no-diagnostics
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_offload.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_offload.pass.cpp
new file mode 100644
index 00000000000000..f660bc23bbbf75
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_offload.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test will fail if the number of devices detected by OpenMP is larger
+// than zero but std::transform(std::execution::par_unseq,...) is not executed
+// on the device.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <vector>
+#include <omp.h>
+
+int main(int, char**) {
+  // We only run the test if a device is detected by OpenMP
+  if (omp_get_num_devices() < 1)
+    return 0;
+
+  // Initializing test arrays
+  const int test_size = 10000;
+  std::vector<int> host(test_size);
+  std::vector<int> device(test_size);
+  // Should execute on host
+  std::transform(std::execution::unseq, host.begin(), host.end(), host.begin(), [](int& h) {
+    // Returns true if executed on the host
+    h = omp_is_initial_device();
+    return h;
+  });
+
+  // Asserting the std::transform(std::execution::unseq,...) executed on the host
+  for (int hi : host)
+    assert(hi && "omp_is_initial_device() returned false. std::transform was offloaded but shouldn't be.");
+
+  // Should execute on device
+  std::transform(
+      std::execution::par_unseq, device.begin(), device.end(), host.begin(), device.begin(), [](int& d, int& h) {
+        // Should return fals
+        d = omp_is_initial_device();
+        return h == d;
+      });
+
+  // Asserting the std::transform(std::execution::par_unseq,...) executed on the device
+  for (int di : device)
+    assert(!di && "omp_is_initial_device() returned true in the target region. std::transform was not offloaded.");
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_offload.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_offload.pass.cpp
new file mode 100644
index 00000000000000..bf059fadf70633
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_offload.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test will fail if the number of devices detected by OpenMP is larger
+// than zero but std::transform_reduce(std::execution::par_unseq,...) is not
+// executed on the device.
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <execution>
+#include <functional>
+#include <vector>
+#include <omp.h>
+
+int main(int, char**) {
+  // We only run the test if a device is detected by OpenMP
+  if (omp_get_num_devices() < 1)
+    return 0;
+
+  // Initializing test array
+  const int test_size = 10000;
+  std::vector<int> v(test_size, 1);
+  std::vector<int> w(test_size, 1);
+
+  int result = std::transform_reduce(
+      std::execution::par_unseq, v.begin(), v.end(), w.begin(), (int)0, std::plus{}, [](int& n, int& m) {
+        return n + m + omp_is_initial_device(); // Gives 2 if executed on device, 3 if executed on host
+      });
+  assert(result == 2 * test_size &&
+         "omp_is_initial_device() returned true in the target region. std::transform_reduce was not offloaded.");
+  return 0;
+}
diff --git a/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_supported_binary_operations.pass.cpp b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_supported_binary_operations.pass.cpp
new file mode 100644
index 00000000000000..fb324d6db69db1
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/alg.pstl.openmp/transform_reduce_supported_binary_operations.pass.cpp
@@ -0,0 +1,199 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that std::transform_reduce(std::execution::par_unseq,...)
+// can be offloaded for a number of supported binary operations. The following
+// binary operations should be supported for the reducer:
+// - std::plus
+// - std::minus
+// - std::multiplies
+// - std::logical_and
+// - std::logical_or
+// - std::bit_and
+// - std::bit_or
+// - std::bit_xor
+
+// UNSUPPORTED: c++03, c++11, c++14, gcc
+
+// REQUIRES: libcpp-pstl-backend-openmp
+
+#include <algorithm>
+#include <cassert>
+#include <cmath>
+#include <execution>
+#include <functional>
+#include <vector>
+#include <omp.h>
+#include <iostream>
+
+int main(int, char**) {
+  // We only run the test if a device is detected by OpenMP
+  if (omp_get_num_devices() < 1)
+    return 0;
+
+  // Initializing test array
+  const int test_size = 10000;
+
+  //===--------------------------------------------------------------------===//
+  // Arithmetic binary operators
+  //===--------------------------------------------------------------------===//
+
+  // Addition with doubles
+  {
+    std::vector<double> v(test_size, 1.0);
+    std::vector<double> w(test_size, 2.0);
+    double result = std::transform_reduce(
+        std::execution::par_unseq, v.begin(), v.end(), w.begin(), 5.0, std::plus{}, [](double& a, double& b) {
+          return 0.5 * (b - a) * ((double)!omp_is_initial_device());
+        });
+    assert((std::abs(result - 0.5 * ((double)test_size) - 5.0) < 1e-8) &&
+           "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the binary "
+           "operation std::plus.");
+  }
+
+  // Subtraction of floats
+  {
+    std::vector<float> v(test_size, 1.0f);
+    std::vector<float> w(test_size, 1.5f);
+    float result = std::transform_reduce(
+        std::execution::par_unseq,
+        v.begin(),
+        v.end(),
+        w.begin(),
+        1.25 * ((float)test_size),
+        std::minus{},
+        [](float& a, float& b) { return 0.5 * (a + b) * ((float)!omp_is_initial_device()); });
+    assert((std::abs(result) < 1e-8f) &&
+           "std::transform_reduce(std::execution::par_unseq,...) does not have the "
+           "intended effect for the binary operation std::minus.");
+  }
+
+  // Multiplication of doubles
+  {
+    std::vector<double> v(test_size, 1.0);
+    std::vector<double> w(test_size, 0.0001);
+    double result = std::transform_reduce(
+        std::execution::par_unseq, v.begin(), v.end(), w.begin(), -1.0, std::multiplies{}, [](double& a, double& b) {
+          return (a + b) * ((double)!omp_is_initial_device());
+        });
+    assert((std::abs(result + pow(1.0001, test_size)) < 1e-8) &&
+           "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the binary "
+           "operation std::multiplies.");
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Logical binary operators
+  //===--------------------------------------------------------------------===//
+
+  // Logical and
+  {
+    std::vector<int> v(test_size, 1);
+    // The result should be true with an initial value of 1
+    int result =
+        std::transform_reduce(std::execution::par_unseq, v.begin(), v.end(), 1, std::logical_and{}, [](int& a) {
+          return a && !omp_is_initial_device();
+        });
+    assert(result &&
+           "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the binary "
+           "operation std::logical_and.");
+
+    // And false by an initial value of 0
+    result = std::transform_reduce(std::execution::par_unseq, v.begin(), v.end(), 0, std::logical_and{}, [](int& a) {
+      return a && !omp_is_initial_device();
+    });
+    assert(!result &&
+           "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the binary "
+           "operation std::logical_and.");
+  }
+
+  // Logical or
+  {
+    std::vector<int> v(test_size, 0);
+    // The result should be true with an initial value of 1
+    int result = std::transform_reduce(std::execution::par_unseq, v.begin(), v.end(), 1, std::logical_or{}, [](int& a) {
+      return a && !omp_is_initial_device();
+    });
+    assert(result &&
+           "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the binary "
+           "operation std::logical_or.");
+
+    // And false by an initial value of 0
+    result = std::transform_reduce(std::execution::par_unseq, v.begin(), v.end(), 0, std::logical_or{}, [](int& a) {
+      return a && !omp_is_initial_device();
+    });
+    assert(!result && "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the "
+                      "binary operation std::logical_or.");
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Bitwise binary operators
+  //===--------------------------------------------------------------------===//
+
+  // Bitwise and
+  {
+    std::vector<unsigned int> v(test_size, 3);
+    std::vector<unsigned int> w(test_size, 2);
+    // For odd numbers the result should be true
+    int result =
+        std::transform_reduce(std::execution::par_unseq, v.begin(), v.end(), 0x1, std::bit_and{}, [](unsigned int& a) {
+          return a + omp_is_initial_device();
+        });
+    assert(result && "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the "
+                     "binary operation std::bit_and.");
+
+    // For even numbers the result should be false
+    result =
+        std::transform_reduce(std::execution::par_unseq, w.begin(), w.end(), 0x1, std::bit_and{}, [](unsigned int& a) {
+          return a + omp_is_initial_device();
+        });
+    assert(!result && "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the "
+                      "binary operation std::bit_and.");
+  }
+
+  // Bitwise or
+  {
+    std::vector<unsigned int> v(test_size, 0);
+    int result = std::transform_reduce(
+        std::execution::par_unseq, v.begin(), v.end(), 0, std::bit_or{}, [](unsigned int& a) -> unsigned int {
+          return a || omp_is_initial_device();
+        });
+    assert(!result && "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the "
+                      "binary operation std::bit_or.");
+
+    // After adding a one, the result should be true
+    v[v.size() / 2] = 1;
+    result          = std::transform_reduce(
+        std::execution::par_unseq, v.begin(), v.end(), 0, std::bit_or{}, [](unsigned int& a) -> unsigned int {
+          return a && !omp_is_initial_device();
+        });
+    assert(result && "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for the "
+                     "binary operation std::bit_or.");
+  }
+
+  // Bitwise xor
+  {
+    std::vector<unsigned int> v(test_size, 0xef);
+    int result =
+        std::transform_reduce(std::execution::par_unseq, v.begin(), v.end(), 0, std::bit_xor{}, [](unsigned int& a) {
+          return a << omp_is_initial_device();
+        });
+    assert(result == 0 && "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for "
+                          "the binary operation std::bit_or.");
+
+    // After adding a one, the result should be true
+    v[v.size() / 2] = 0xea;
+    result =
+        std::transform_reduce(std::execution::par_unseq, v.begin(), v.end(), 0, std::bit_xor{}, [](unsigned int& a) {
+          return a << omp_is_initial_device();
+        });
+    assert(result == 5 && "std::transform_reduce(std::execution::par_unseq,...) does not have the intended effect for "
+                          "the binary operation std::bit_or.");
+  }
+
+  return 0;
+}
diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot
index 3df7b00a8aa09d..842ff584ddc15d 100755
--- a/libcxx/utils/ci/run-buildbot
+++ b/libcxx/utils/ci/run-buildbot
@@ -1,13 +1,13 @@
 #!/usr/bin/env bash
-# ===----------------------------------------------------------------------===##
+#===----------------------------------------------------------------------===##
 #
 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 # See https://llvm.org/LICENSE.txt for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
-# ===----------------------------------------------------------------------===##
+#===----------------------------------------------------------------------===##
 
-set -e
+set -ex
 set -o pipefail
 unset LANG
 unset LC_ALL
@@ -28,6 +28,10 @@ ${PROGNAME} [options] <BUILDER>
 --build-dir <DIR>   The directory to use for building the library. By default,
                     this is '<llvm-root>/build/<builder>'.
 
+--osx-roots <DIR>   Path to pre-downloaded macOS dylibs. By default, we download
+                    them from Green Dragon. This is only relevant at all when
+                    running back-deployment testing if one wants to override
+                    the old dylibs we use to run the tests with different ones.
 Environment variables
 CC                  The C compiler to use, this value is used by CMake. This
                     variable is optional.
@@ -62,6 +66,10 @@ while [[ $# -gt 0 ]]; do
             BUILD_DIR="${2}"
             shift; shift
             ;;
+        --osx-roots)
+            OSX_ROOTS="${2}"
+            shift; shift
+            ;;
         *)
             BUILDER="${1}"
             shift
@@ -96,37 +104,12 @@ if [ -z "${CMAKE}" ]; then
     fi
 fi
 
-function step() {
-  endstep
-  set +x
-  if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then
-    echo "::group::$1"
-    export IN_GROUP=1
-  else
-    echo "--- $1"
-  fi
-  set -x
-}
-
-function endstep() {
-  set +x
-  if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then
-    echo "::endgroup::"
-    unset IN_GROUP
-  fi
-  set -x
-}
-
-function error() {
-    echo "::error::$1"
-}
-
 function clean() {
     rm -rf "${BUILD_DIR}"
 }
 
 function generate-cmake-base() {
-    step "Generating CMake"
+    echo "--- Generating CMake"
     ${CMAKE} \
           -S "${MONOREPO_ROOT}/runtimes" \
           -B "${BUILD_DIR}" \
@@ -147,6 +130,26 @@ function generate-cmake() {
           "${@}"
 }
 
+function generate-cmake-openmp() {
+    echo "--- Generating CMake"
+    ${CMAKE} \
+          -S "${MONOREPO_ROOT}/llvm" \
+          -B "${BUILD_DIR}" \
+          -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
+          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+          -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
+          -DLIBCXX_ENABLE_WERROR=YES \
+          -DLIBCXXABI_ENABLE_WERROR=YES \
+          -DLIBUNWIND_ENABLE_WERROR=YES \
+          -DLIBCXX_ENABLE_CLANG_TIDY=${ENABLE_CLANG_TIDY} \
+          -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
+          -DLLVM_ENABLE_PROJECTS="clang;openmp" \
+          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;offload" \
+          -DLIBCXX_PSTL_BACKEND="openmp" \
+          -DLIBCXX_CXX_ABI=libcxxabi \
+          "${@}"
+}
+
 function generate-cmake-libcxx-win() {
     generate-cmake-base \
           -DLLVM_ENABLE_RUNTIMES="libcxx" \
@@ -163,43 +166,57 @@ function generate-cmake-android() {
 }
 
 function check-runtimes() {
-    step "Building libc++ test dependencies"
-    ${NINJA} -vC "${BUILD_DIR}" cxx-test-depends
-
-    step "Running the libc++ tests"
+    echo "+++ Running the libc++ tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx
 
-    step "Running the libc++abi tests"
+    echo "+++ Running the libc++abi tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxxabi
 
-    step "Running the libunwind tests"
+    echo "+++ Running the libunwind tests"
     ${NINJA} -vC "${BUILD_DIR}" check-unwind
+
+    # TODO: On macOS 13.5, the linker seems to have an issue where it will pick up
+    #       a library if it exists inside a -L search path, even if we don't link
+    #       against that library. This happens with libunwind.dylib if it is built
+    #       at the point when we run the libc++ tests, which causes issues cause we
+    #       are also linking against the system unwinder.
+    #
+    #       I believe this is a linker regression and I reported it as rdar://115842730.
+    #       It should be possible to move this installation step back to the top once
+    #       that issue has been resolved, but in the meantime it doesn't really hurt to
+    #       have it here.
+    echo "--- Installing libc++, libc++abi and libunwind to a fake location"
+    ${NINJA} -vC "${BUILD_DIR}" install-cxx install-cxxabi install-unwind
 }
 
 # TODO: The goal is to test this against all configurations. We should also move
 #       this to the Lit test suite instead of being a separate CMake target.
 function check-abi-list() {
-    step "Running the libc++ ABI list test"
+    echo "+++ Running the libc++ ABI list test"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx-abilist || (
-        error "Generating the libc++ ABI list after failed check"
+        echo "+++ Generating the libc++ ABI list after failed check"
         ${NINJA} -vC "${BUILD_DIR}" generate-cxx-abilist
         false
     )
 }
 
+function check-cxx-benchmarks() {
+    echo "--- Running the benchmarks"
+    ${NINJA} -vC "${BUILD_DIR}" check-cxx-benchmarks
+}
+
 function test-armv7m-picolibc() {
     clean
 
     # To make it easier to get this builder up and running, build picolibc
     # from scratch. Anecdotally, the build-picolibc script takes about 16 seconds.
     # This could be optimised by building picolibc into the Docker container.
-    step "Building picolibc from source"
     ${MONOREPO_ROOT}/libcxx/utils/ci/build-picolibc.sh \
         --build-dir "${BUILD_DIR}" \
         --install-dir "${INSTALL_DIR}" \
         --target armv7m-none-eabi
 
-    step "Generating CMake for compiler-rt"
+    echo "--- Generating CMake"
     flags="--sysroot=${INSTALL_DIR}"
     ${CMAKE} \
         -S "${MONOREPO_ROOT}/compiler-rt" \
@@ -211,8 +228,6 @@ function test-armv7m-picolibc() {
         -DCMAKE_CXX_FLAGS="${flags}" \
         -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
         "${@}"
-
-    step "Generating CMake for libc++"
     generate-cmake \
         -DLIBCXX_TEST_CONFIG="armv7m-picolibc-libc++.cfg.in" \
         -DLIBCXXABI_TEST_CONFIG="armv7m-picolibc-libc++abi.cfg.in" \
@@ -221,7 +236,6 @@ function test-armv7m-picolibc() {
         -DCMAKE_CXX_FLAGS="${flags}" \
         "${@}"
 
-    step "Installing compiler-rt"
     ${NINJA} -vC "${BUILD_DIR}/compiler-rt" install
 
     # Prior to clang 19, armv7m-none-eabi normalised to armv7m-none-unknown-eabi.
@@ -235,9 +249,9 @@ function test-armv7m-picolibc() {
 }
 
 # Print the version of a few tools to aid diagnostics in some cases
-step "Diagnose tools in use"
 ${CMAKE} --version
 ${NINJA} --version
+
 if [ ! -z "${CXX}" ]; then ${CXX} --version; fi
 
 case "${BUILDER}" in
@@ -247,9 +261,10 @@ check-generated-output)
     clean
     generate-cmake
 
-    # Reject patches that forgot to re-run the generator scripts.
-    step "Making sure the generator scripts were run"
     set +x # Printing all the commands below just creates extremely confusing output
+
+    # Reject patches that forgot to re-run the generator scripts.
+    echo "+++ Making sure the generator scripts were run"
     ${NINJA} -vC "${BUILD_DIR}" libcxx-generate-files
     git diff | tee ${BUILD_DIR}/generated_output.patch
     git ls-files -o --exclude-standard | tee ${BUILD_DIR}/generated_output.status
@@ -261,9 +276,10 @@ check-generated-output)
         false
     fi
 
-    # This depends on LC_COLLATE set at the top of this script.
-    step "Reject patches that introduce non-ASCII characters or hard tabs."
-    ! grep -rn '[^ -~]' libcxx/include libcxx/src libcxx/test \
+    # Reject patches that introduce non-ASCII characters or hard tabs.
+    # Depends on LC_COLLATE set at the top of this script.
+    set -x
+    ! grep -rn '[^ -~]' libcxx/include libcxx/src libcxx/test libcxx/benchmarks \
            --exclude '*.dat' \
            --exclude '*unicode*.cpp' \
            --exclude '*print*.sh.cpp' \
@@ -370,7 +386,7 @@ generic-ubsan)
 bootstrapping-build)
     clean
 
-    step "Generating CMake"
+    echo "--- Generating CMake"
     ${CMAKE} \
           -S "${MONOREPO_ROOT}/llvm" \
           -B "${BUILD_DIR}" \
@@ -387,14 +403,13 @@ bootstrapping-build)
           -DLLVM_ENABLE_ASSERTIONS=ON \
           -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests"
 
-    step "Running the LLDB libc++ data formatter tests"
-    ${NINJA} -vC "${BUILD_DIR}" lldb-api-test-deps
-    ${BUILD_DIR}/bin/llvm-lit -sv --param dotest-args='--category libc++' "${MONOREPO_ROOT}/lldb/test/API"
+    echo "+++ Running the LLDB libc++ data formatter tests"
+    ${NINJA} -vC "${BUILD_DIR}" check-lldb-api-functionalities-data-formatter-data-formatter-stl-libcxx
 
-    step "Running the libc++ and libc++abi tests"
+    echo "--- Running the libc++ and libc++abi tests"
     ${NINJA} -vC "${BUILD_DIR}" check-runtimes
 
-    step "Installing libc++ and libc++abi to a fake location"
+    echo "+++ Installing libc++ and libc++abi to a fake location"
     ${NINJA} -vC "${BUILD_DIR}" install-runtimes
 
     ccache -s
@@ -422,7 +437,7 @@ generic-hardening-mode-fast-with-abi-breaks)
     clean
     generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake"
     check-runtimes
-    # Not checking ABI list since we purposefully enable ABI breaking changes
+    check-abi-list
 ;;
 generic-hardening-mode-extensive)
     clean
@@ -474,11 +489,6 @@ generic-no-localization)
     generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-localization.cmake"
     check-runtimes
 ;;
-generic-no-terminal)
-    clean
-    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-terminal.cmake"
-    check-runtimes
-;;
 generic-no-unicode)
     clean
     generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-unicode.cmake"
@@ -524,10 +534,21 @@ generic-optimized-speed)
     generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-optimized-speed.cmake"
     check-runtimes
 ;;
-apple-configuration)
+generic-pstl-openmp)
+    clean
+    # TODO: Pass different host and device triples to the test configuration.
+    # For now, the OpenMP buildbot offloads to the host. To set the correct host target triple,
+    # we pass it via the LIBCXX test parameters.
+    PARAMS="target_triple=$(${CXX} --print-target-triple)"
+    generate-cmake-openmp -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-pstl-openmp.cmake" \
+                          ${MONOREPO_ROOT}/llvm -DLIBCXX_TEST_PARAMS="${PARAMS}"
+    echo "+++ Installing OpenMP and Clang"
+    ${NINJA} -vC "${BUILD_DIR}" install
+    check-runtimes
+;;
+apple-system)
     clean
 
-    step "Installing libc++ with the Apple system configuration"
     arch="$(uname -m)"
     xcrun --sdk macosx                                              \
         ${MONOREPO_ROOT}/libcxx/utils/ci/apple-install-libcxx.sh    \
@@ -538,102 +559,88 @@ apple-configuration)
             --architectures "${arch}"                               \
             --version "999.99"
 
-    step "Running tests against Apple-configured libc++"
     # TODO: It would be better to run the tests against the fake-installed version of libc++ instead
     xcrun --sdk macosx ninja -vC "${BUILD_DIR}/${arch}" check-cxx check-cxxabi check-cxx-abilist
 ;;
-apple-system-hardened)
+apple-system-backdeployment-hardened-*)
     clean
 
-    arch="$(uname -m)"
-    version="$(sw_vers --productVersion)"
-    params="target_triple=${arch}-apple-macosx${version}"
-    params+=";hardening_mode=fast"
+    if [[ "${OSX_ROOTS}" == "" ]]; then
+        echo "--- Downloading previous macOS dylibs"
+        PREVIOUS_DYLIBS_URL="https://dl.dropboxusercontent.com/s/gmcfxwgl9f9n6pu/libcxx-roots.tar.gz"
+        OSX_ROOTS="${BUILD_DIR}/macos-roots"
+        mkdir -p "${OSX_ROOTS}"
+        curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${OSX_ROOTS}"
+    fi
 
-    # In the Apple system configuration, we build libc++ and libunwind separately.
-    step "Installing libc++ and libc++abi in Apple-system configuration"
-    ${CMAKE} \
-        -S "${MONOREPO_ROOT}/runtimes" \
-        -B "${BUILD_DIR}/cxx" \
-        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
-        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/cxx" \
-        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
-        -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
-        -DLIBCXX_CXX_ABI=libcxxabi \
-        -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
-        -DLIBCXX_TEST_CONFIG="apple-libc++-system.cfg.in" \
-        -DLIBCXXABI_TEST_CONFIG="apple-libc++abi-system.cfg.in" \
-        -DLIBCXX_TEST_PARAMS="${params}" \
-        -DLIBCXXABI_TEST_PARAMS="${params}"
-
-    step "Installing libunwind in Apple-system configuration"
-    ${CMAKE} \
-        -S "${MONOREPO_ROOT}/runtimes" \
-        -B "${BUILD_DIR}/unwind" \
-        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
-        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/unwind" \
-        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
-        -DLLVM_ENABLE_RUNTIMES="libunwind" \
-        -DLIBUNWIND_TEST_CONFIG="apple-libunwind-system.cfg.in" \
-        -DLIBUNWIND_TEST_PARAMS="${params}" \
-        -DCMAKE_INSTALL_NAME_DIR="/usr/lib/system"
+    DEPLOYMENT_TARGET="${BUILDER#apple-system-backdeployment-hardened-}"
 
-    step "Running the libc++ tests"
-    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxx
+    # TODO: On Apple platforms, we never produce libc++abi.1.dylib or libunwind.1.dylib,
+    #       only libc++abi.dylib and libunwind.dylib. Fix that in the build so that the
+    #       tests stop searching for @rpath/libc++abi.1.dylib and @rpath/libunwind.1.dylib.
+    cp "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.dylib" \
+       "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.1.dylib"
+    cp "${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.dylib" \
+       "${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.1.dylib"
+
+    arch="$(uname -m)"
+    PARAMS="target_triple=${arch}-apple-macosx${DEPLOYMENT_TARGET}"
+    PARAMS+=";cxx_runtime_root=${OSX_ROOTS}/macOS/libc++/${DEPLOYMENT_TARGET}"
+    PARAMS+=";abi_runtime_root=${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}"
+    PARAMS+=";unwind_runtime_root=${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}"
+    PARAMS+=";hardening_mode=fast"
 
-    step "Running the libc++abi tests"
-    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxxabi
+    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
+                   -DLIBCXX_TEST_CONFIG="apple-libc++-backdeployment.cfg.in" \
+                   -DLIBCXXABI_TEST_CONFIG="apple-libc++abi-backdeployment.cfg.in" \
+                   -DLIBUNWIND_TEST_CONFIG="apple-libunwind-backdeployment.cfg.in" \
+                   -DLIBCXX_TEST_PARAMS="${PARAMS}" \
+                   -DLIBCXXABI_TEST_PARAMS="${PARAMS}" \
+                   -DLIBUNWIND_TEST_PARAMS="${PARAMS}"
 
-    step "Running the libunwind tests"
-    ${NINJA} -vC "${BUILD_DIR}/unwind" check-unwind
+    check-runtimes
 ;;
-apple-system)
+apple-system-backdeployment-*)
     clean
 
-    arch="$(uname -m)"
-    version="$(sw_vers --productVersion)"
-    params="target_triple=${arch}-apple-macosx${version}"
+    if [[ "${OSX_ROOTS}" == "" ]]; then
+        echo "--- Downloading previous macOS dylibs"
+        PREVIOUS_DYLIBS_URL="https://dl.dropboxusercontent.com/s/gmcfxwgl9f9n6pu/libcxx-roots.tar.gz"
+        OSX_ROOTS="${BUILD_DIR}/macos-roots"
+        mkdir -p "${OSX_ROOTS}"
+        curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${OSX_ROOTS}"
+    fi
 
-    # In the Apple system configuration, we build libc++ and libunwind separately.
-    step "Installing libc++ and libc++abi in Apple-system configuration"
-    ${CMAKE} \
-        -S "${MONOREPO_ROOT}/runtimes" \
-        -B "${BUILD_DIR}/cxx" \
-        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
-        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/cxx" \
-        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
-        -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
-        -DLIBCXX_CXX_ABI=libcxxabi \
-        -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
-        -DLIBCXX_TEST_CONFIG="apple-libc++-system.cfg.in" \
-        -DLIBCXXABI_TEST_CONFIG="apple-libc++abi-system.cfg.in" \
-        -DLIBCXX_TEST_PARAMS="${params}" \
-        -DLIBCXXABI_TEST_PARAMS="${params}"
-
-    step "Installing libunwind in Apple-system configuration"
-    ${CMAKE} \
-        -S "${MONOREPO_ROOT}/runtimes" \
-        -B "${BUILD_DIR}/unwind" \
-        -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \
-        -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/unwind" \
-        -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
-        -DLLVM_ENABLE_RUNTIMES="libunwind" \
-        -DLIBUNWIND_TEST_CONFIG="apple-libunwind-system.cfg.in" \
-        -DLIBUNWIND_TEST_PARAMS="${params}" \
-        -DCMAKE_INSTALL_NAME_DIR="/usr/lib/system"
+    DEPLOYMENT_TARGET="${BUILDER#apple-system-backdeployment-}"
+
+    # TODO: On Apple platforms, we never produce libc++abi.1.dylib or libunwind.1.dylib,
+    #       only libc++abi.dylib and libunwind.dylib. Fix that in the build so that the
+    #       tests stop searching for @rpath/libc++abi.1.dylib and @rpath/libunwind.1.dylib.
+    cp "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.dylib" \
+       "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.1.dylib"
+    cp "${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.dylib" \
+       "${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.1.dylib"
 
-    step "Running the libc++ tests"
-    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxx
+    arch="$(uname -m)"
+    PARAMS="target_triple=${arch}-apple-macosx${DEPLOYMENT_TARGET}"
+    PARAMS+=";cxx_runtime_root=${OSX_ROOTS}/macOS/libc++/${DEPLOYMENT_TARGET}"
+    PARAMS+=";abi_runtime_root=${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}"
+    PARAMS+=";unwind_runtime_root=${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}"
 
-    step "Running the libc++abi tests"
-    ${NINJA} -vC "${BUILD_DIR}/cxx" check-cxxabi
+    generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
+                   -DLIBCXX_TEST_CONFIG="apple-libc++-backdeployment.cfg.in" \
+                   -DLIBCXXABI_TEST_CONFIG="apple-libc++abi-backdeployment.cfg.in" \
+                   -DLIBUNWIND_TEST_CONFIG="apple-libunwind-backdeployment.cfg.in" \
+                   -DLIBCXX_TEST_PARAMS="${PARAMS}" \
+                   -DLIBCXXABI_TEST_PARAMS="${PARAMS}" \
+                   -DLIBUNWIND_TEST_PARAMS="${PARAMS}"
 
-    step "Running the libunwind tests"
-    ${NINJA} -vC "${BUILD_DIR}/unwind" check-unwind
+    check-runtimes
+;;
+benchmarks)
+    clean
+    generate-cmake
+    check-cxx-benchmarks
 ;;
 aarch64)
     clean
@@ -690,13 +697,13 @@ clang-cl-dll)
     # anyway), thus just disable the experimental library. Remove this
     # setting when cmake and the test driver does the right thing automatically.
     generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False"
-    step "Running the libc++ tests"
+    echo "+++ Running the libc++ tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx
 ;;
 clang-cl-static)
     clean
     generate-cmake-libcxx-win -DLIBCXX_ENABLE_SHARED=OFF
-    step "Running the libc++ tests"
+    echo "+++ Running the libc++ tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx
 ;;
 clang-cl-no-vcruntime)
@@ -707,14 +714,14 @@ clang-cl-no-vcruntime)
     # exceptions enabled.
     generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False" \
                               -DLIBCXX_TEST_CONFIG="llvm-libc++-shared-no-vcruntime-clangcl.cfg.in"
-    step "Running the libc++ tests"
+    echo "+++ Running the libc++ tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx
 ;;
 clang-cl-debug)
     clean
     generate-cmake-libcxx-win -DLIBCXX_TEST_PARAMS="enable_experimental=False" \
                               -DCMAKE_BUILD_TYPE=Debug
-    step "Running the libc++ tests"
+    echo "+++ Running the libc++ tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx
 ;;
 clang-cl-static-crt)
@@ -723,18 +730,27 @@ clang-cl-static-crt)
     # the static CRT, as opposed to "MultiThreadedDLL" which is the default).
     generate-cmake-libcxx-win -DLIBCXX_ENABLE_SHARED=OFF \
                               -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
-    step "Running the libc++ tests"
+    echo "+++ Running the libc++ tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx
 ;;
 mingw-dll)
     clean
+    # Explicitly specify the compiler with a triple prefix. The CI
+    # environment has got two installations of Clang; the default one
+    # defaults to MSVC mode, while there's an installation of llvm-mingw
+    # further back in PATH. By calling the compiler with an explicit
+    # triple prefix, we use the one that is bundled with a mingw sysroot.
     generate-cmake \
+          -DCMAKE_C_COMPILER=x86_64-w64-mingw32-clang \
+          -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-clang++ \
           -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
     check-runtimes
 ;;
 mingw-static)
     clean
     generate-cmake \
+          -DCMAKE_C_COMPILER=x86_64-w64-mingw32-clang \
+          -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-clang++ \
           -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake" \
           -DLIBCXX_ENABLE_SHARED=OFF \
           -DLIBUNWIND_ENABLE_SHARED=OFF
@@ -748,30 +764,6 @@ mingw-dll-i686)
           -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
     check-runtimes
 ;;
-mingw-incomplete-sysroot)
-    # When bringing up a new cross compiler from scratch, we build
-    # libunwind/libcxx in a setup where the toolchain is incomplete and
-    # unable to perform the normal linker checks; this requires a few
-    # special cases in the CMake files.
-    #
-    # Building in an incomplete setup requires setting CMAKE_*_COMPILER_WORKS,
-    # as CMake fails to probe the compiler. This case also requires
-    # setting CMAKE_CXX_COMPILER_TARGET, as LLVM's heuristics for setting
-    # the triple fails when CMake hasn't been able to probe the environment.
-    # (This is what one has to do when building the initial libunwind/libcxx
-    # for a new toolchain.)
-    clean
-    generate-cmake \
-          -DCMAKE_C_COMPILER_WORKS=TRUE \
-          -DCMAKE_CXX_COMPILER_WORKS=TRUE \
-          -DCMAKE_C_COMPILER_TARGET=x86_64-w64-windows-gnu \
-          -DCMAKE_CXX_COMPILER_TARGET=x86_64-w64-windows-gnu \
-          -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
-    # Only test that building succeeds; there's not much extra value in running
-    # the tests here, as it would be equivalent to the mingw-dll config above.
-    step "Building the runtimes"
-    ${NINJA} -vC "${BUILD_DIR}"
-;;
 aix)
     clean
     generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/AIX.cmake" \
@@ -787,7 +779,7 @@ android-ndk-*)
     ANDROID_EMU_IMG="${BUILDER#android-ndk-}"
     . "${MONOREPO_ROOT}/libcxx/utils/ci/vendor/android/emulator-functions.sh"
     if ! validate_emu_img "${ANDROID_EMU_IMG}"; then
-        error "android-ndk suffix must be a valid emulator image (${ANDROID_EMU_IMG})" >&2
+        echo "error: android-ndk suffix must be a valid emulator image (${ANDROID_EMU_IMG})" >&2
         exit 1
     fi
     ARCH=$(arch_of_emu_img ${ANDROID_EMU_IMG})
@@ -819,9 +811,9 @@ android-ndk-*)
     # directories.
     adb shell mkdir -p /data/local/tmp/adb_run
     adb push "${BUILD_DIR}/lib/libc++_shared.so" /data/local/tmp/libc++/libc++_shared.so
-    step "Running the libc++ tests"
+    echo "+++ Running the libc++ tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxx
-    step "Running the libc++abi tests"
+    echo "+++ Running the libc++abi tests"
     ${NINJA} -vC "${BUILD_DIR}" check-cxxabi
 ;;
 #################################################################
@@ -837,5 +829,3 @@ android-ndk-*)
     exit 1
 ;;
 esac
-
-endstep # Make sure we close any still-open output group
diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index 49b61c8935e1ba..f516da9c552bc4 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -231,8 +231,7 @@ def _mingwSupportsModules(cfg):
     # https://developercommunity.visualstudio.com/t/utf-8-locales-break-ctype-functions-for-wchar-type/1653678
     Feature(
         name="win32-broken-utf8-wchar-ctype",
-        when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg)
-        or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1"
+        when=lambda cfg: not "_LIBCPP_HAS_NO_LOCALIZATION" in compilerMacros(cfg)
         and "_WIN32" in compilerMacros(cfg)
         and not programSucceeds(
             cfg,
@@ -264,32 +263,11 @@ def _mingwSupportsModules(cfg):
           """,
         ),
     ),
-    # Check for a Windows UCRT bug (not fixed upstream yet).
-    # With UCRT, printf("%a", 0.0) produces "0x0.0000000000000p+0",
-    # while other C runtimes produce just "0x0p+0".
-    # https://developercommunity.visualstudio.com/t/Printf-formatting-of-float-as-hex-prints/1660844
-    Feature(
-        name="win32-broken-printf-a-precision",
-        when=lambda cfg: "_WIN32" in compilerMacros(cfg)
-        and not programSucceeds(
-            cfg,
-            """
-            #include <stdio.h>
-            #include <string.h>
-            int main(int, char**) {
-              char buf[100];
-              snprintf(buf, sizeof(buf), "%a", 0.0);
-              return strcmp(buf, "0x0p+0");
-            }
-          """,
-        ),
-    ),
     # Check for Glibc < 2.27, where the ru_RU.UTF-8 locale had
     # mon_decimal_point == ".", which our tests don't handle.
     Feature(
         name="glibc-old-ru_RU-decimal-point",
-        when=lambda cfg: not "_LIBCPP_HAS_LOCALIZATION" in compilerMacros(cfg)
-        or compilerMacros(cfg)["_LIBCPP_HAS_LOCALIZATION"] == "1"
+        when=lambda cfg: not "_LIBCPP_HAS_NO_LOCALIZATION" in compilerMacros(cfg)
         and not programSucceeds(
             cfg,
             """
@@ -357,27 +335,31 @@ def _mingwSupportsModules(cfg):
 ]
 
 # Deduce and add the test features that that are implied by the #defines in
-# the <__config> header.
+# the <__config_site> header.
 #
 # For each macro of the form `_LIBCPP_XXX_YYY_ZZZ` defined below that
-# is defined after including <__config>, add a Lit feature called
+# is defined after including <__config_site>, add a Lit feature called
 # `libcpp-xxx-yyy-zzz`. When a macro is defined to a specific value
 # (e.g. `_LIBCPP_ABI_VERSION=2`), the feature is `libcpp-xxx-yyy-zzz=<value>`.
 #
 # Note that features that are more strongly tied to libc++ are named libcpp-foo,
 # while features that are more general in nature are not prefixed with 'libcpp-'.
 macros = {
+    "_LIBCPP_HAS_NO_MONOTONIC_CLOCK": "no-monotonic-clock",
+    "_LIBCPP_HAS_NO_THREADS": "no-threads",
+    "_LIBCPP_HAS_THREAD_API_EXTERNAL": "libcpp-has-thread-api-external",
+    "_LIBCPP_HAS_THREAD_API_PTHREAD": "libcpp-has-thread-api-pthread",
     "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime",
     "_LIBCPP_ABI_VERSION": "libcpp-abi-version",
     "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators",
-    "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING": "libcpp-has-abi-bounded-iterators-in-string",
-    "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR": "libcpp-has-abi-bounded-iterators-in-vector",
-    "_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY": "libcpp-has-abi-bounded-iterators-in-std-array",
-    "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr",
-    "_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE": "libcpp-has-abi-fix-unordered-container-size-type",
-    "_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor",
-    "_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING": "libcpp-abi-no-compressed-pair-padding",
+    "_LIBCPP_HAS_NO_FILESYSTEM": "no-filesystem",
+    "_LIBCPP_HAS_NO_RANDOM_DEVICE": "no-random-device",
+    "_LIBCPP_HAS_NO_LOCALIZATION": "no-localization",
+    "_LIBCPP_HAS_NO_WIDE_CHARACTERS": "no-wide-characters",
+    "_LIBCPP_HAS_NO_TIME_ZONE_DATABASE": "no-tzdb",
+    "_LIBCPP_HAS_NO_UNICODE": "libcpp-has-no-unicode",
     "_LIBCPP_PSTL_BACKEND_LIBDISPATCH": "libcpp-pstl-backend-libdispatch",
+    "_LIBCPP_PSTL_BACKEND_OPENMP": "openmp_pstl_backend",
 }
 for macro, feature in macros.items():
     DEFAULT_FEATURES.append(
@@ -387,39 +369,27 @@ def _mingwSupportsModules(cfg):
         )
     )
 
-true_false_macros = {
-    "_LIBCPP_HAS_THREAD_API_EXTERNAL": "libcpp-has-thread-api-external",
-    "_LIBCPP_HAS_THREAD_API_PTHREAD": "libcpp-has-thread-api-pthread",
-}
-for macro, feature in true_false_macros.items():
-    DEFAULT_FEATURES.append(
-        Feature(
-            name=feature,
-            when=lambda cfg, m=macro: m in compilerMacros(cfg)
-            and compilerMacros(cfg)[m] == "1",
-        )
-    )
-
-inverted_macros = {
-    "_LIBCPP_HAS_TIME_ZONE_DATABASE": "no-tzdb",
-    "_LIBCPP_HAS_FILESYSTEM": "no-filesystem",
-    "_LIBCPP_HAS_LOCALIZATION": "no-localization",
-    "_LIBCPP_HAS_THREADS": "no-threads",
-    "_LIBCPP_HAS_MONOTONIC_CLOCK": "no-monotonic-clock",
-    "_LIBCPP_HAS_WIDE_CHARACTERS": "no-wide-characters",
-    "_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS": "libcpp-has-no-availability-markup",
-    "_LIBCPP_HAS_RANDOM_DEVICE": "no-random-device",
-    "_LIBCPP_HAS_UNICODE": "libcpp-has-no-unicode",
-    "_LIBCPP_HAS_TERMINAL": "no-terminal",
-}
-for macro, feature in inverted_macros.items():
-    DEFAULT_FEATURES.append(
-        Feature(
-            name=feature,
-            when=lambda cfg, m=macro: m in compilerMacros(cfg)
-            and compilerMacros(cfg)[m] == "0",
-        )
+DEFAULT_FEATURES.append(
+    Feature(
+        name="libcpp-pstl-backend-openmp",
+        when=lambda cfg: "_LIBCPP_PSTL_BACKEND_OPENMP" in compilerMacros(cfg),
+        actions=[
+            AddFlagIfSupported("-fopenmp"),
+            # The linker needs to find the correct version of libomptarget
+            AddLinkFlag("-Wl,-rpath,%{lib-dir}"),
+            # The preprocessor needs to find the omp.h header. If OpenMP was
+            # installed as a project, the header lives in the following
+            # directory
+            AddFlag("-I %{lib-dir}/../../projects/openmp/runtime/src/"),
+            # And if it was installed as a runtime it lives in the following:
+            AddFlag("-I %{lib-dir}/../../runtimes/runtimes-bins/openmp/runtime/src"),
+            # TODO: Add conditional to test if a GPU target has been detected.
+            # For now, we only offload to the host in this test configuration.
+            # If a GPU were present, we should instead pass --offload-arch=native.
+            AddFlagIfSupported("-fopenmp-targets=%{triple}"),
+        ],
     )
+)
 
 # Mapping from canonical locale names (used in the tests) to possible locale
 # names on various systems. Each locale is considered supported if any of the
@@ -520,14 +490,6 @@ def _mingwSupportsModules(cfg):
           """,
         ),
     ),
-    Feature(
-        name="LIBCXX-AMDGPU-FIXME",
-        when=lambda cfg: "__AMDGPU__" in compilerMacros(cfg),
-    ),
-    Feature(
-        name="LIBCXX-NVPTX-FIXME",
-        when=lambda cfg: "__NVPTX__" in compilerMacros(cfg),
-    ),
     Feature(
         name="can-create-symlinks",
         when=lambda cfg: "_WIN32" not in compilerMacros(cfg)
@@ -639,143 +601,107 @@ def check_gdb(cfg):
     )
 ]
 
-# Helpers to define correspondances between LLVM versions and vendor system versions.
-# Those are used for backdeployment features below, do not use directly in tests.
+# Define features for back-deployment testing.
+#
+# These features can be used to XFAIL tests that fail when deployed on (or compiled
+# for) an older system. For example, if a test exhibits a bug in the libc on a
+# particular system version, or if it uses a symbol that is not available on an
+# older version of the dylib, it can be marked as XFAIL with these features.
+#
+# It is sometimes useful to check that a test fails specifically when compiled for a
+# given deployment target. For example, this is the case when testing availability
+# markup, where we want to make sure that using the annotated facility on a deployment
+# target that doesn't support it will fail at compile time, not at runtime. This can
+# be achieved by creating a `.verify.cpp` test that checks for the right errors, and
+# mark that test as requiring `stdlib=<vendor>-libc++ && target=<target>`.
+#
+# Since it is not always known which deployment target to pick there are
+# short-hands based on the LLVM version like using-built-library-before-llvm-xx.
+# These short-hands make it easy for libc++ developers to select the proper
+# version the feature will be available in and allows vendors to set the proper
+# target information.
 DEFAULT_FEATURES += [
+    # Backdeployment short-hands
     Feature(
-        name="_target-has-llvm-18",
-        when=lambda cfg: BooleanExpression.evaluate(
-            "target={{.+}}-apple-macosx{{15(.[0-9]+)?(.[0-9]+)?}}",
-            cfg.available_features,
-        ),
-    ),
-    Feature(
-        name="_target-has-llvm-17",
-        when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-18 || target={{.+}}-apple-macosx{{14.[4-9](.[0-9]+)?}} || target={{.+}}-apple-macosx{{1[5-9]([.].+)?}}",
-            cfg.available_features,
-        ),
-    ),
-    Feature(
-        name="_target-has-llvm-16",
+        name="using-built-library-before-llvm-11",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-17 || target={{.+}}-apple-macosx{{14.[0-3](.[0-9]+)?}}",
+            "stdlib=apple-libc++ && target={{.+}}-apple-macosx{{(10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0)(.0)?}}",
             cfg.available_features,
         ),
     ),
     Feature(
-        name="_target-has-llvm-15",
+        name="using-built-library-before-llvm-12",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-16 || target={{.+}}-apple-macosx{{13.[4-9](.[0-9]+)?}}",
+            "using-built-library-before-llvm-11 || (stdlib=apple-libc++ && target={{.+}}-apple-macosx12.{{(0|1|2)}}.0)",
             cfg.available_features,
         ),
     ),
+
     Feature(
-        name="_target-has-llvm-14",
+        name="using-built-library-before-llvm-13",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-15",
+            "using-built-library-before-llvm-12 || (stdlib=apple-libc++ && target={{.+}}-apple-macosx{{((12.(3|4|5|6|7))|(13.(0|1|2|3)))}}.0)",
             cfg.available_features,
         ),
     ),
+
     Feature(
-        name="_target-has-llvm-13",
+        name="using-built-library-before-llvm-14",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-14 || target={{.+}}-apple-macosx{{13.[0-3](.[0-9]+)?}}",
+            "using-built-library-before-llvm-13",
             cfg.available_features,
         ),
     ),
+
     Feature(
-        name="_target-has-llvm-12",
+        name="using-built-library-before-llvm-15",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-13 || target={{.+}}-apple-macosx{{12.[3-9](.[0-9]+)?}}",
+            "using-built-library-before-llvm-14 || (stdlib=apple-libc++ && target={{.+}}-apple-macosx13.{{(4|5|6)}}.0)",
             cfg.available_features,
         ),
     ),
+
     Feature(
-        name="_target-has-llvm-11",
+        name="using-built-library-before-llvm-16",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-12 || target={{.+}}-apple-macosx{{(11.[0-9]|12.[0-2])(.[0-9]+)?}}",
+            "using-built-library-before-llvm-15 || (stdlib=apple-libc++ && target={{.+}}-apple-macosx14.{{(0|1|2|3)}}.0)",
             cfg.available_features,
         ),
     ),
+
     Feature(
-        name="_target-has-llvm-10",
+        name="using-built-library-before-llvm-17",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-11",
+            "using-built-library-before-llvm-16",
             cfg.available_features,
         ),
     ),
+
     Feature(
-        name="_target-has-llvm-9",
+        name="using-built-library-before-llvm-18",
         when=lambda cfg: BooleanExpression.evaluate(
-            "_target-has-llvm-10 || target={{.+}}-apple-macosx{{10.15(.[0-9]+)?}}",
+            # For now, no released version of macOS contains LLVM 18
+            # TODO(ldionne) Please provide the correct value.
+            "using-built-library-before-llvm-17 || stdlib=apple-libc++ && target={{.+}}-apple-macosx{{.+}}",
             cfg.available_features,
         ),
     ),
-]
 
-# Define features for back-deployment testing.
-#
-# These features can be used to XFAIL tests that fail when deployed on (or compiled
-# for) an older system. For example, if a test exhibits a bug in the libc++ on a
-# particular system version, or if it uses a symbol that is not available on an
-# older version of the dylib, it can be marked as XFAIL with these features.
-#
-# We have two families of Lit features:
-#
-# The first one is `using-built-library-before-llvm-XYZ`. These features encode the
-# fact that the test suite is being *run* against a version of the shared/static library
-# that predates LLVM version XYZ. This is useful to represent the use case of compiling
-# a program against the latest libc++ but then deploying it and running it on an older
-# system with an older version of the (usually shared) library.
-#
-# This feature is built up using the target triple passed to the compiler and the
-# `stdlib=system` Lit feature, which encodes that we're running against the same library
-# as described by the target triple.
-#
-# The second set of features is `availability-<FEATURE>-missing`. This family of Lit
-# features encodes the presence of availability markup in the libc++ headers. This is
-# useful to check that a test fails specifically when compiled for a given deployment
-# target, such as when testing availability markup where we want to make sure that
-# using the annotated facility on a deployment target that doesn't support it will fail
-# at compile time. This can be achieved by creating a `.verify.cpp` test that checks for
-# the right errors and marking the test as `REQUIRES: availability-<FEATURE>-missing`.
-#
-# This feature is built up using the presence of availability markup detected inside
-# __config, the flavor of the library being tested and the target triple passed to the
-# compiler.
-#
-# Note that both families of Lit features are similar but different in important ways.
-# For example, tests for availability markup should be expected to produce diagnostics
-# regardless of whether we're running against a system library, as long as we're using
-# a libc++ flavor that enables availability markup. Similarly, a test could fail when
-# run against the system library of an older version of FreeBSD, even though FreeBSD
-# doesn't provide availability markup at the time of writing this.
-for version in ("9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"):
-    DEFAULT_FEATURES.append(
-        Feature(
-            name="using-built-library-before-llvm-{}".format(version),
-            when=lambda cfg, v=version: BooleanExpression.evaluate(
-                "stdlib=system && !_target-has-llvm-{}".format(v),
-                cfg.available_features,
-            ),
-        )
-    )
-
-DEFAULT_FEATURES += [
-    # Tests that require std::filesystem support in the built library
     Feature(
-        name="availability-filesystem-missing",
+        name="using-built-library-before-llvm-19",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-9)",
+            # For now, no released version of macOS contains LLVM 19
+            # TODO(ldionne) Please provide the correct value.
+            "using-built-library-before-llvm-18 || stdlib=apple-libc++ && target={{.+}}-apple-macosx{{.+}}",
             cfg.available_features,
         ),
     ),
-    # Tests that require the C++20 synchronization library (P1135R6 implemented by https://llvm.org/D68480) in the built library
+
+    # Tests that require std::to_chars(floating-point) in the built library
     Feature(
-        name="availability-synchronization_library-missing",
+        name="availability-fp_to_chars-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-11)",
+            "using-built-library-before-llvm-13",
             cfg.available_features,
         ),
     ),
@@ -783,39 +709,39 @@ def check_gdb(cfg):
     Feature(
         name="availability-char8_t_support-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-12)",
+            "using-built-library-before-llvm-11",
             cfg.available_features,
         ),
     ),
-    # Tests that require std::to_chars(floating-point) in the built library
+    # Tests that require __libcpp_verbose_abort support in the built library
     Feature(
-        name="availability-fp_to_chars-missing",
+        name="availability-verbose_abort-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-14)",
+            "using-built-library-before-llvm-13",
             cfg.available_features,
         ),
     ),
-    # Tests that require __libcpp_verbose_abort support in the built library
+    # Tests that require std::pmr support in the built library
     Feature(
-        name="availability-verbose_abort-missing",
+        name="availability-pmr-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-15)",
+            "using-built-library-before-llvm-13",
             cfg.available_features,
         ),
     ),
-    # Tests that require std::pmr support in the built library
+    # Tests that require std::filesystem support in the built library
     Feature(
-        name="availability-pmr-missing",
+        name="availability-filesystem-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-16)",
+            "stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{(13|14)(.0)?}}",
             cfg.available_features,
         ),
     ),
-    # Tests that require support for <print> and std::print in <ostream> in the built library.
+    # Tests that require the C++20 synchronization library (P1135R6 implemented by https://llvm.org/D68480) in the built library
     Feature(
-        name="availability-print-missing",
+        name="availability-synchronization_library-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-18)",
+            "stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{(13|14|15)(.0)?}}",
             cfg.available_features,
         ),
     ),
@@ -823,15 +749,15 @@ def check_gdb(cfg):
     Feature(
         name="availability-tzdb-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-19)",
+            "using-built-library-before-llvm-19",
             cfg.available_features,
         ),
     ),
-    # Tests that require std::from_chars(floating-point) in the built library
+    # Tests that require support for <print> and std::print in <ostream> in the built library.
     Feature(
-        name="availability-fp_from_chars-missing",
+        name="availability-print-missing",
         when=lambda cfg: BooleanExpression.evaluate(
-            "!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-20)",
+            "using-built-library-before-llvm-18",
             cfg.available_features,
         ),
     ),
diff --git a/libcxx/utils/run.py b/libcxx/utils/run.py
index 6b4d615444bcfa..427e96b91fa370 100755
--- a/libcxx/utils/run.py
+++ b/libcxx/utils/run.py
@@ -64,6 +64,21 @@ def main():
         if "TEMP" in os.environ:
             env["TEMP"] = os.environ.get("TEMP")
 
+    # Forwarding the environment variable CUDA_VISIBLE_DEVICES which configures
+    # the visible NVIDIA GPUs.
+    if "CUDA_VISIBLE_DEVICES" in os.environ:
+        env["CUDA_VISIBLE_DEVICES"] = os.environ["CUDA_VISIBLE_DEVICES"]
+
+    # Forwarding the environment variable ROCR_VISIBLE_DEVICES which configures
+    # the visible AMD GPUs.
+    if "ROCR_VISIBLE_DEVICES" in os.environ:
+        env["ROCR_VISIBLE_DEVICES"] = os.environ["ROCR_VISIBLE_DEVICES"]
+
+    # Pass the OpenMP debug flag. Can be used to print information about the
+    # GPU execution of the tests.
+    if "LIBOMPTARGET_DEBUG" in os.environ:
+        env["LIBOMPTARGET_DEBUG"] = os.environ["LIBOMPTARGET_DEBUG"]
+
     # Run the command line with the given environment in the execution directory.
     return subprocess.call(commandLine, cwd=args.execdir, env=env, shell=False)
 
diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt
index da0e8b286cddc1..186fd3ed308490 100644
--- a/libcxxabi/CMakeLists.txt
+++ b/libcxxabi/CMakeLists.txt
@@ -407,6 +407,14 @@ if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
   add_definitions("-D_XOPEN_SOURCE=700")
 endif()
 
+# If the OpenMP PSTL backend has been enabled for libcxx, OpenMP must be
+# enabled during compilation
+if (DEFINED LIBCXX_PSTL_BACKEND)
+  if (LIBCXX_PSTL_BACKEND STREQUAL "openmp")
+    add_compile_options(-fopenmp)
+  endif()
+endif()
+
 #===============================================================================
 # Setup Source Code
 #===============================================================================

>From b13df7751e1cde7aaa9df1641fdaa3a3a62e1ce1 Mon Sep 17 00:00:00 2001
From: Vedant Tewari <vedanttewari541 at gmail.com>
Date: Mon, 12 Aug 2024 01:23:46 -0500
Subject: [PATCH 2/3] Algorithms for ranges shift left and shift right

---
 .../include/__algorithm/ranges_shift_left.h   | 74 ++++++++++++++++++
 .../include/__algorithm/ranges_shift_right.h  | 75 +++++++++++++++++++
 2 files changed, 149 insertions(+)
 create mode 100644 libcxx/include/__algorithm/ranges_shift_left.h
 create mode 100644 libcxx/include/__algorithm/ranges_shift_right.h

diff --git a/libcxx/include/__algorithm/ranges_shift_left.h b/libcxx/include/__algorithm/ranges_shift_left.h
new file mode 100644
index 00000000000000..5f2d47c7805d55
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_shift_left.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SHIFT_LEFT_H
+#define _LIBCPP___ALGORITHM_RANGES_SHIFT_LEFT_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/subrange.h>
+#include <__utility/move.h>
+#include <__utility/forward.h>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+namespace __shift_left {
+
+struct __fn {
+  template <std::permutable _Iter, std::sentinel_for<_Iter> _Sent>
+  _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+  operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __n) const {
+    if (__n <= 0) {
+      return {__first, __first};
+    }
+
+    auto __dist = std::ranges::distance(__first, __last);
+    if (__n >= __dist) {
+      return {__first, __first};
+    }
+
+    auto __mid = std::ranges::next(__first, __n);
+    auto __new_last = std::move(__mid, __last, __first);
+    return {__first, __new_last};
+  }
+
+  template <std::ranges::forward_range _Range>
+  requires std::permutable<iterator_t<_Range>>
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, range_difference_t<_Range> __n) const {
+    return (*this)(std::ranges::begin(__range), std::ranges::end(__range), __n);
+  }
+};
+
+} // namespace __shift_left
+
+inline namespace __cpo {
+  inline constexpr auto shift_left = __shift_left::__fn{};
+} // namespace __cpo
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SHIFT_LEFT_H
diff --git a/libcxx/include/__algorithm/ranges_shift_right.h b/libcxx/include/__algorithm/ranges_shift_right.h
new file mode 100644
index 00000000000000..de4405446ba86f
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_shift_right.h
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_SHIFT_RIGHT_H
+#define _LIBCPP___ALGORITHM_RANGES_SHIFT_RIGHT_H
+
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/subrange.h>
+#include <__utility/move.h>
+#include <__utility/forward.h>
+#include <__iterator/advance.h>
+#include <__iterator/distance.h>
+#include <algorithm>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+namespace __shift_right {
+
+struct __fn {
+  template <std::permutable _Iter, std::sentinel_for<_Iter> _Sent>
+  _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
+  operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __n) const {
+    if (__n <= 0) {
+      return {__last, __last};
+    }
+
+    auto __dist = std::ranges::distance(__first, __last);
+    if (__n >= __dist) {
+      return {__last, __last};
+    }
+
+    auto __new_first = std::ranges::next(__first, __dist - __n);
+    std::move_backward(__first, __new_first, __last);
+    return {__new_first, __last};
+  }
+
+  template <std::ranges::forward_range _Range>
+  requires std::permutable<iterator_t<_Range>>
+  _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
+  operator()(_Range&& __range, range_difference_t<_Range> __n) const {
+    return (*this)(std::ranges::begin(__range), std::ranges::end(__range), __n);
+  }
+};
+
+} // namespace __shift_right
+
+inline namespace __cpo {
+  inline constexpr auto shift_right = __shift_right::__fn{};
+} // namespace __cpo
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_RANGES_SHIFT_RIGHT_H

>From 77954368b32e49bb8c5d15a78c43b750ab53c66e Mon Sep 17 00:00:00 2001
From: Vedant Tewari <vedanttewari541 at gmail.com>
Date: Mon, 2 Sep 2024 18:47:31 -0500
Subject: [PATCH 3/3] Algorithms for ranges_find_last, find_last_if, and
 find_last_if_not

---
 .../include/__algorithm/ranges_find_last_if.h | 81 +++++++++++++++++++
 .../__algorithm/ranges_find_last_if_not.h     | 81 +++++++++++++++++++
 2 files changed, 162 insertions(+)
 create mode 100644 libcxx/include/__algorithm/ranges_find_last_if.h
 create mode 100644 libcxx/include/__algorithm/ranges_find_last_if_not.h

diff --git a/libcxx/include/__algorithm/ranges_find_last_if.h b/libcxx/include/__algorithm/ranges_find_last_if.h
new file mode 100644
index 00000000000000..7a4f26cd5c07b2
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_last_if.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H
+#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+namespace __find_last_if {
+
+struct __fn {
+  template <forward_iterator _Ip,
+            sentinel_for<_Ip> _Sp,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Ip>
+  operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
+    std::optional<_Ip> __found;
+    for (; __first != __last; ++__first) {
+      if (std::invoke(__pred, std::invoke(__proj, *__first))) {
+        __found = __first;
+      }
+    }
+    if (!__found)
+      return {__first, __first};
+    return {*__found, std::ranges::next(*__found, __last)};
+  }
+
+  template <forward_range _Rp,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Rp>
+  operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
+    return this->operator()(ranges::begin(__r), ranges::end(__r), std::ref(__pred), std::ref(__proj));
+  }
+};
+
+} // namespace __find_last_if
+
+inline namespace __cpo {
+inline constexpr auto find_last_if = __find_last_if::__fn{};
+} // namespace __cpo
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H
diff --git a/libcxx/include/__algorithm/ranges_find_last_if_not.h b/libcxx/include/__algorithm/ranges_find_last_if_not.h
new file mode 100644
index 00000000000000..d6d06335b9518b
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_last_if_not.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_NOT_H
+#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_NOT_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__ranges/dangling.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+namespace __find_last_if_not {
+
+struct __fn {
+  template <forward_iterator _Ip,
+            sentinel_for<_Ip> _Sp,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Ip>
+  operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
+    std::optional<_Ip> __found;
+    for (; __first != __last; ++__first) {
+      if (!std::invoke(__pred, std::invoke(__proj, *__first))) {
+        __found = __first;
+      }
+    }
+    if (!__found)
+      return {__first, __first};
+    return {*__found, std::ranges::next(*__found, __last)};
+  }
+
+  template <forward_range _Rp,
+            class _Proj = identity,
+            indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Rp>
+  operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
+    return this->operator()(ranges::begin(__r), ranges::end(__r), std::ref(__pred), std::ref(__proj));
+  }
+};
+
+} // namespace __find_last_if_not
+
+inline namespace __cpo {
+inline constexpr auto find_last_if_not = __find_last_if_not::__fn{};
+} // namespace __cpo
+
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_NOT_H



More information about the libcxx-commits mailing list