Import Cobalt 25.master.0.1033734
diff --git a/third_party/llvm-project/libcxx/METADATA b/third_party/llvm-project/libcxx/METADATA
index 485156c..b067d6c 100644
--- a/third_party/llvm-project/libcxx/METADATA
+++ b/third_party/llvm-project/libcxx/METADATA
@@ -3,16 +3,16 @@
"Filtered subtree at third_party/llvm-project/libcxx."
third_party {
- url {
- type: LOCAL_SOURCE
- value: "https://cobalt.googlesource.com/third_party/llvm-project/libcxx_filtered_mirror"
+ identifier {
+ type: "ChromiumVersion"
+ value: "111.0.5563.150" # from https://chromereleases.googleblog.com/2023/03/stable-channel-update-for-chromeos_29.html
}
- url {
- type: GIT
- value: "https://github.com/llvm/llvm-project.git"
+ identifier {
+ type: "Git"
+ value: "https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git"
+ version: "1127c78cf90cf253be614a1e1d3645da57edbeb4"
+ # from https://chromium.googlesource.com/chromium/src/+/111.0.5563.150/DEPS#486
}
- # Closest commit hash to llvm-project's 39da55e8f548a11f7dadefa73ea73d809a5f1729.
- version: "5c30f21b42b422fe507d923ce32f9f268f10d88b"
last_upgrade_date {
year: 2023
month: 1
diff --git a/third_party/llvm-project/libcxx/benchmarks/CMakeLists.txt b/third_party/llvm-project/libcxx/benchmarks/CMakeLists.txt
index a792230..7eb76ac 100644
--- a/third_party/llvm-project/libcxx/benchmarks/CMakeLists.txt
+++ b/third_party/llvm-project/libcxx/benchmarks/CMakeLists.txt
@@ -176,6 +176,7 @@
algorithms/stable_sort.bench.cpp
allocation.bench.cpp
deque.bench.cpp
+ deque_iterator.bench.cpp
filesystem.bench.cpp
format_to_n.bench.cpp
format_to.bench.cpp
@@ -184,6 +185,7 @@
formatter_float.bench.cpp
formatter_int.bench.cpp
function.bench.cpp
+ join_view.bench.cpp
map.bench.cpp
monotonic_buffer.bench.cpp
ordered_set.bench.cpp
diff --git a/third_party/llvm-project/libcxx/benchmarks/deque_iterator.bench.cpp b/third_party/llvm-project/libcxx/benchmarks/deque_iterator.bench.cpp
new file mode 100644
index 0000000..0eb23f2
--- /dev/null
+++ b/third_party/llvm-project/libcxx/benchmarks/deque_iterator.bench.cpp
@@ -0,0 +1,232 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <deque>
+
+#include "benchmark/benchmark.h"
+
+namespace {
+void run_sizes(auto benchmark) {
+ benchmark->Arg(0)
+ ->Arg(1)
+ ->Arg(2)
+ ->Arg(64)
+ ->Arg(512)
+ ->Arg(1024)
+ ->Arg(4000)
+ ->Arg(4096)
+ ->Arg(5500)
+ ->Arg(64000)
+ ->Arg(65536)
+ ->Arg(70000);
+}
+
+template <class FromContainer, class ToContainer, class Func>
+void benchmark_containers(benchmark::State& state, FromContainer& d, ToContainer& v, Func&& func) {
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(v);
+ benchmark::DoNotOptimize(d);
+ func(d.begin(), d.end(), v.begin());
+ }
+}
+
+template <class Func>
+void benchmark_deque_vector(benchmark::State& state, Func&& func) {
+ auto size = state.range(0);
+ std::deque<int> d;
+ d.resize(size);
+ std::ranges::fill(d, 10);
+ std::vector<int> v;
+ v.resize(size);
+ benchmark_containers(state, d, v, func);
+}
+
+template <class Func>
+void benchmark_deque_deque(benchmark::State& state, Func&& func) {
+ auto size = state.range(0);
+ std::deque<int> d;
+ d.resize(size);
+ std::ranges::fill(d, 10);
+ std::deque<int> v;
+ v.resize(size);
+ benchmark_containers(state, d, v, func);
+}
+
+template <class Func>
+void benchmark_vector_deque(benchmark::State& state, Func&& func) {
+ auto size = state.range(0);
+ std::vector<int> d;
+ d.resize(size);
+ std::ranges::fill(d, 10);
+ std::deque<int> v;
+ v.resize(size);
+ benchmark_containers(state, d, v, func);
+}
+
+template <class FromContainer, class ToContainer, class Func>
+void benchmark_containers_backward(benchmark::State& state, FromContainer& d, ToContainer& v, Func&& func) {
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(v);
+ benchmark::DoNotOptimize(d);
+ func(d.begin(), d.end(), v.end());
+ }
+}
+
+template <class Func>
+void benchmark_deque_vector_backward(benchmark::State& state, Func&& func) {
+ auto size = state.range(0);
+ std::deque<int> d;
+ d.resize(size);
+ std::ranges::fill(d, 10);
+ std::vector<int> v;
+ v.resize(size);
+ benchmark_containers_backward(state, d, v, func);
+}
+
+template <class Func>
+void benchmark_deque_deque_backward(benchmark::State& state, Func&& func) {
+ auto size = state.range(0);
+ std::deque<int> d;
+ d.resize(size);
+ std::ranges::fill(d, 10);
+ std::deque<int> v;
+ v.resize(size);
+ benchmark_containers_backward(state, d, v, func);
+}
+
+template <class Func>
+void benchmark_vector_deque_backward(benchmark::State& state, Func&& func) {
+ auto size = state.range(0);
+ std::vector<int> d;
+ d.resize(size);
+ std::ranges::fill(d, 10);
+ std::deque<int> v;
+ v.resize(size);
+ benchmark_containers_backward(state, d, v, func);
+}
+
+struct CopyFunctor {
+ template <class... Args>
+ auto operator()(Args... args) const {
+ std::copy(std::forward<Args>(args)...);
+ }
+} copy;
+
+struct MoveFunctor {
+ template <class... Args>
+ auto operator()(Args... args) const {
+ std::move(std::forward<Args>(args)...);
+ }
+} move;
+
+struct CopyBackwardFunctor {
+ template <class... Args>
+ auto operator()(Args... args) const {
+ std::copy_backward(std::forward<Args>(args)...);
+ }
+} copy_backward;
+
+struct MoveBackwardFunctor {
+ template <class... Args>
+ auto operator()(Args... args) const {
+ std::move_backward(std::forward<Args>(args)...);
+ }
+} move_backward;
+
+// copy
+void BM_deque_vector_copy(benchmark::State& state) { benchmark_deque_vector(state, copy); }
+BENCHMARK(BM_deque_vector_copy)->Apply(run_sizes);
+
+void BM_deque_vector_ranges_copy(benchmark::State& state) { benchmark_deque_vector(state, std::ranges::copy); }
+BENCHMARK(BM_deque_vector_ranges_copy)->Apply(run_sizes);
+
+void BM_deque_deque_copy(benchmark::State& state) { benchmark_deque_deque(state, copy); }
+BENCHMARK(BM_deque_deque_copy)->Apply(run_sizes);
+
+void BM_deque_deque_ranges_copy(benchmark::State& state) { benchmark_deque_deque(state, std::ranges::copy); }
+BENCHMARK(BM_deque_deque_ranges_copy)->Apply(run_sizes);
+
+void BM_vector_deque_copy(benchmark::State& state) { benchmark_vector_deque(state, copy); }
+BENCHMARK(BM_vector_deque_copy)->Apply(run_sizes);
+
+void BM_vector_deque_ranges_copy(benchmark::State& state) { benchmark_vector_deque(state, std::ranges::copy); }
+BENCHMARK(BM_vector_deque_ranges_copy)->Apply(run_sizes);
+
+// move
+void BM_deque_vector_move(benchmark::State& state) { benchmark_deque_vector(state, move); }
+BENCHMARK(BM_deque_vector_move)->Apply(run_sizes);
+
+void BM_deque_vector_ranges_move(benchmark::State& state) { benchmark_deque_vector(state, std::ranges::move); }
+BENCHMARK(BM_deque_vector_ranges_move)->Apply(run_sizes);
+
+void BM_deque_deque_move(benchmark::State& state) { benchmark_deque_deque(state, move); }
+BENCHMARK(BM_deque_deque_move)->Apply(run_sizes);
+
+void BM_deque_deque_ranges_move(benchmark::State& state) { benchmark_deque_deque(state, std::ranges::move); }
+BENCHMARK(BM_deque_deque_ranges_move)->Apply(run_sizes);
+
+void BM_vector_deque_move(benchmark::State& state) { benchmark_vector_deque(state, move); }
+BENCHMARK(BM_vector_deque_move)->Apply(run_sizes);
+
+void BM_vector_deque_ranges_move(benchmark::State& state) { benchmark_vector_deque(state, std::ranges::move); }
+BENCHMARK(BM_vector_deque_ranges_move)->Apply(run_sizes);
+
+// copy_backward
+void BM_deque_vector_copy_backward(benchmark::State& state) { benchmark_deque_vector_backward(state, copy_backward); }
+BENCHMARK(BM_deque_vector_copy_backward)->Apply(run_sizes);
+
+void BM_deque_vector_ranges_copy_backward(benchmark::State& state) {
+ benchmark_deque_vector_backward(state, std::ranges::copy_backward);
+}
+BENCHMARK(BM_deque_vector_ranges_copy_backward)->Apply(run_sizes);
+
+void BM_deque_deque_copy_backward(benchmark::State& state) { benchmark_deque_deque_backward(state, copy_backward); }
+BENCHMARK(BM_deque_deque_copy_backward)->Apply(run_sizes);
+
+void BM_deque_deque_ranges_copy_backward(benchmark::State& state) {
+ benchmark_deque_deque_backward(state, std::ranges::copy_backward);
+}
+BENCHMARK(BM_deque_deque_ranges_copy_backward)->Apply(run_sizes);
+
+void BM_vector_deque_copy_backward(benchmark::State& state) { benchmark_vector_deque_backward(state, copy_backward); }
+BENCHMARK(BM_vector_deque_copy_backward)->Apply(run_sizes);
+
+void BM_vector_deque_ranges_copy_backward(benchmark::State& state) {
+ benchmark_vector_deque_backward(state, std::ranges::copy_backward);
+}
+BENCHMARK(BM_vector_deque_ranges_copy_backward)->Apply(run_sizes);
+
+// move_backward
+void BM_deque_vector_move_backward(benchmark::State& state) { benchmark_deque_vector_backward(state, move_backward); }
+BENCHMARK(BM_deque_vector_move_backward)->Apply(run_sizes);
+
+void BM_deque_vector_ranges_move_backward(benchmark::State& state) {
+ benchmark_deque_vector_backward(state, std::ranges::move_backward);
+}
+BENCHMARK(BM_deque_vector_ranges_move_backward)->Apply(run_sizes);
+
+void BM_deque_deque_move_backward(benchmark::State& state) { benchmark_deque_deque_backward(state, move_backward); }
+BENCHMARK(BM_deque_deque_move_backward)->Apply(run_sizes);
+
+void BM_deque_deque_ranges_move_backward(benchmark::State& state) {
+ benchmark_deque_deque_backward(state, std::ranges::move_backward);
+}
+BENCHMARK(BM_deque_deque_ranges_move_backward)->Apply(run_sizes);
+
+void BM_vector_deque_move_backward(benchmark::State& state) { benchmark_vector_deque_backward(state, move_backward); }
+BENCHMARK(BM_vector_deque_move_backward)->Apply(run_sizes);
+
+void BM_vector_deque_ranges_move_backward(benchmark::State& state) {
+ benchmark_vector_deque_backward(state, std::ranges::move_backward);
+}
+BENCHMARK(BM_vector_deque_ranges_move_backward)->Apply(run_sizes);
+
+} // namespace
+
+BENCHMARK_MAIN();
diff --git a/third_party/llvm-project/libcxx/benchmarks/join_view.bench.cpp b/third_party/llvm-project/libcxx/benchmarks/join_view.bench.cpp
new file mode 100644
index 0000000..c789a39
--- /dev/null
+++ b/third_party/llvm-project/libcxx/benchmarks/join_view.bench.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <deque>
+#include <ranges>
+
+#include "benchmark/benchmark.h"
+
+namespace {
+void run_sizes(auto benchmark) {
+ benchmark->Arg(0)
+ ->Arg(1)
+ ->Arg(2)
+ ->Arg(64)
+ ->Arg(512)
+ ->Arg(1024)
+ ->Arg(4000)
+ ->Arg(4096)
+ ->Arg(5500)
+ ->Arg(64000)
+ ->Arg(65536)
+ ->Arg(70000);
+}
+
+void BM_join_view_in_vectors(benchmark::State& state) {
+ auto size = state.range(0);
+ std::vector<std::vector<int>> input(size, std::vector<int>(32));
+ std::ranges::fill(input | std::views::join, 10);
+ std::vector<int> output;
+ output.resize(size * 32);
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(input);
+ benchmark::DoNotOptimize(output);
+ std::ranges::copy(input | std::views::join, output.begin());
+ }
+}
+BENCHMARK(BM_join_view_in_vectors)->Apply(run_sizes);
+
+void BM_join_view_out_vectors(benchmark::State& state) {
+ auto size = state.range(0);
+ std::vector<std::vector<int>> output(size, std::vector<int>(32));
+ std::vector<int> input;
+ input.resize(size * 32);
+ std::ranges::fill(input, 10);
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(output);
+ benchmark::DoNotOptimize(input);
+ std::ranges::copy(input, (output | std::views::join).begin());
+ }
+}
+BENCHMARK(BM_join_view_out_vectors)->Apply(run_sizes);
+
+void BM_join_view_deques(benchmark::State& state) {
+ auto size = state.range(0);
+ std::deque<std::deque<int>> deque(size, std::deque<int>(32));
+ std::ranges::fill(deque | std::views::join, 10);
+ std::vector<int> output;
+ output.resize(size * 32);
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(deque);
+ benchmark::DoNotOptimize(output);
+ std::ranges::copy(deque | std::views::join, output.begin());
+ }
+}
+BENCHMARK(BM_join_view_deques)->Apply(run_sizes);
+} // namespace
+
+BENCHMARK_MAIN();
diff --git a/third_party/llvm-project/libcxx/cmake/caches/Generic-no-transitive-includes.cmake b/third_party/llvm-project/libcxx/cmake/caches/Generic-no-transitive-includes.cmake
deleted file mode 100644
index 31e8073..0000000
--- a/third_party/llvm-project/libcxx/cmake/caches/Generic-no-transitive-includes.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-set(LIBCXX_TEST_PARAMS "enable_transitive_includes=False" CACHE STRING "")
-set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
diff --git a/third_party/llvm-project/libcxx/docs/Contributing.rst b/third_party/llvm-project/libcxx/docs/Contributing.rst
index faa904c..186ac66 100644
--- a/third_party/llvm-project/libcxx/docs/Contributing.rst
+++ b/third_party/llvm-project/libcxx/docs/Contributing.rst
@@ -70,6 +70,8 @@
2. Update the version number in ``libcxx/docs/conf.py``
3. Update ``_LIBCPPABI_VERSION`` in ``libcxxabi/include/cxxabi.h``
4. Update ``_LIBUNWIND_VERSION`` in ``libunwind/include/__libunwind_config.h``
+5. Update the list of supported clang versions in ``libcxx/docs/index.rst``
+6. Remove the in-progress warning from ``libcxx/docs/ReleaseNotes.rst``
Exporting new symbols from the library
======================================
diff --git a/third_party/llvm-project/libcxx/docs/FeatureTestMacroTable.rst b/third_party/llvm-project/libcxx/docs/FeatureTestMacroTable.rst
index a71e1e6..b46fc8c 100644
--- a/third_party/llvm-project/libcxx/docs/FeatureTestMacroTable.rst
+++ b/third_party/llvm-project/libcxx/docs/FeatureTestMacroTable.rst
@@ -262,7 +262,7 @@
------------------------------------------------- -----------------
``__cpp_lib_polymorphic_allocator`` ``201902L``
------------------------------------------------- -----------------
- ``__cpp_lib_ranges`` ``201811L``
+ ``__cpp_lib_ranges`` ``202106L``
------------------------------------------------- -----------------
``__cpp_lib_remove_cvref`` ``201711L``
------------------------------------------------- -----------------
diff --git a/third_party/llvm-project/libcxx/docs/ReleaseNotes.rst b/third_party/llvm-project/libcxx/docs/ReleaseNotes.rst
index 6f08d95..88a4859 100644
--- a/third_party/llvm-project/libcxx/docs/ReleaseNotes.rst
+++ b/third_party/llvm-project/libcxx/docs/ReleaseNotes.rst
@@ -1,5 +1,5 @@
=========================================
-Libc++ 16.0.0 (In-Progress) Release Notes
+Libc++ 17.0.0 (In-Progress) Release Notes
=========================================
.. contents::
@@ -10,7 +10,7 @@
.. warning::
- These are in-progress notes for the upcoming libc++ 16 release.
+ These are in-progress notes for the upcoming libc++ 17 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.
@@ -18,7 +18,7 @@
============
This document contains the release notes for the libc++ C++ Standard Library,
-part of the LLVM Compiler Infrastructure, release 16.0.0. Here we describe the
+part of the LLVM Compiler Infrastructure, release 17.0.0. Here we describe the
status of libc++ in some detail, including major improvements from the previous
release and new feature work. For the general LLVM release notes, see `the LLVM
documentation <https://llvm.org/docs/ReleaseNotes.html>`_. All LLVM releases may
@@ -32,137 +32,30 @@
the current one. To see the release notes for a specific release, please
see the `releases page <https://llvm.org/releases/>`_.
-What's New in Libc++ 16.0.0?
+What's New in Libc++ 17.0.0?
============================
-The main focus of the libc++ team has been to implement new C++20 and C++23
-features.
-
-The C++20 format library has improved but it not yet considered stable. The
-main improvements are additional formatters for the chrono calendar types. Work
-on formatting ranges has started.
-
-The C++20 ranges library has been completed and is no longer experimental. Some
-``views`` have not been implemented yet. Work on C++23 ranges has started.
-
-The C++20 spaceship operator has been added to more types, the work is still
-ongoing.
-
Implemented Papers
------------------
-- P2499R0 - ``string_view`` range constructor should be ``explicit``
-- P2417R2 - A more constexpr bitset
-- P2445R1 - ``std::forward_like``
-- P2273R3 - Making ``std::unique_ptr`` constexpr
-- P0591R4 - Utility functions to implement uses-allocator construction
-- P2291R3 - Add Constexpr Modifiers to Functions ``to_chars`` and
- ``from_chars`` for Integral Types in ``<charconv>`` Header
-- P0220R1 - Adopt Library Fundamentals V1 TS Components for C++17
-- P0482R6 - char8_t: A type for UTF-8 characters and strings
-- P2438R2 - ``std::string::substr() &&``
-- P0600R1 - ``nodiscard`` in the library
-- P0339R6 - ``polymorphic_allocator<>`` as a vocabulary type
-- P1169R4 - ``static operator()``
-- P0415R1 - ``constexpr`` for ``std::complex``
-- P1208R6 - ``std::source_location``
-- P0323R12 - ``std::expected``
-- P1035R7 - Input Range Adaptors
Improvements and New Features
-----------------------------
-- Declarations of ``std::c8rtomb()`` and ``std::mbrtoc8()`` from P0482R6 are
- now provided when implementations in the global namespace are provided by
- the C library.
-- Implemented ``<memory_resource>`` header from C++17
-- `D122780 <https://reviews.llvm.org/D122780>`_ Improved the performance of std::sort
Deprecations and Removals
-------------------------
-- ``unary_function`` and ``binary_function`` are no longer provided in C++17 and newer Standard modes.
- They can be re-enabled with ``_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION``.
-
-- Several incidental transitive includes have been removed from libc++. Those
- includes are removed based on the language version used. Incidental transitive
- inclusions of the following headers have been removed:
-
- - C++11, C++14, C++17, and C++20: ``chrono``
- - C++2b: ``algorithm``, ``array``, ``atomic``, ``bit``, ``chrono``,
- ``climits``, ``cmath``, ``compare``, ``concepts``, ``cstdarg``, ``cstddef``,
- ``cstdint``, ``cstdlib``, ``cstring``, ``ctime``, ``exception``,
- ``functional``, ``initializer_list``, ``iosfwd``, ``iterator``, ``limits``,
- ``memory``, ``new``, ``numeric``, ``optional``, ``ratio``, ``stdexcept``,
- ``string``, ``tuple``, ``type_traits``, ``typeinfo``, ``unordered_map``,
- ``utility``, ``variant``, ``vector``.
-
- Users can also remove all incidental transitive includes by defining
- ``_LIBCPP_REMOVE_TRANSITIVE_INCLUDES`` regardless of the language version
- in use. Note that in the future, libc++ reserves the right to remove
- incidental transitive includes more aggressively, in particular regardless
- of the language version in use.
-
-- The legacy testing system for libc++, libc++abi, and libunwind has been removed.
- All known clients have been migrated to the new configuration system, but please
- reach out to the libc++ developers if you find something missing in the new
- configuration system.
-
-- The functions ``to_chars`` and ``from_chars`` for integral types are
- available starting with C++17. Libc++ offered these functions in C++11 and
- C++14 as an undocumented extension. This extension makes it hard to implement
- the C++23 paper that makes these functions ``constexpr``, therefore the
- extension has been removed.
-
-- The ``_LIBCPP_ENABLE_CXX03_FUNCTION`` macro that allowed re-enabling the now-deprecated C++03 implementation of
- ``std::function`` has been removed. Users who need to use ``std::function`` should switch to C++11 and above.
-
-- The contents of ``<experimental/memory_resource>`` are now deprecated since libc++ ships ``<memory_resource>`` now.
- Please migrate to ``<memory_resource>`` instead. Per libc++'s TS deprecation policy,
- ``<experimental/memory_resource>`` will be removed in LLVM 18.
-
-- The ``_LIBCPP_DEBUG`` macro is not honored anymore, and it is an error to try to use it. Please migrate to
- ``_LIBCPP_ENABLE_DEBUG_MODE`` instead.
Upcoming Deprecations and Removals
----------------------------------
-- The base template for ``std::char_traits`` has been marked as deprecated and will be removed in LLVM 18. If
- you are using ``std::char_traits`` with types other than ``char``, ``wchar_t``, ``char8_t``, ``char16_t``,
- ``char32_t`` or a custom character type for which you specialized ``std::char_traits``, your code will stop
- working when we remove the base template. The Standard does not mandate that a base template is provided,
- and such a base template is bound to be incorrect for some types, which could currently cause unexpected
- behavior while going undetected.
+
+- The ``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED`` macro will not be honored anymore in LLVM 18.
+ Please see the updated documentation about the safe libc++ mode and in particular the ``_LIBCPP_VERBOSE_ABORT``
+ macro for details.
API Changes
-----------
-- The comparison operators on ``thread::id`` are now defined as free-standing
- functions instead of as hidden friends, in conformance with the C++ standard.
- Also see `issue 56187 <https://github.com/llvm/llvm-project/issues/56187>`_.
-
-- ``_LIBCPP_ENABLE_NODISCARD`` and ``_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17`` are no longer respected.
- Any standards-required ``[[nodiscard]]`` applications in C++20 are now always enabled. Any extended applications
- are now enabled by default and can be disabled by defining ``_LIBCPP_DISABLE_NODISCARD_EXT``.
-
-- ``_LIBCPP_VERSION`` was previously defined to e.g. ``15001`` to represent LLVM 15.0.01, but this value had been
- left undocumented. Starting with LLVM 16, ``_LIBCPP_VERSION`` will contain the version of LLVM represented as
- ``XXYYZZ``. In other words, ``_LIBCPP_VERSION`` is gaining a digit. This should not be an issue for existing
- code, since using e.g. ``_LIBCPP_VERSION > 15000`` will still give the right answer now that ``_LIBCPP_VERSION``
- is defined as e.g. ``160000`` (with one more digit).
ABI Affecting Changes
---------------------
-- In freestanding mode, ``atomic<small enum class>`` does not contain a lock byte anymore if the platform
- can implement lockfree atomics for that size. More specifically, in LLVM <= 11.0.1, an ``atomic<small enum class>``
- would not contain a lock byte. This was broken in LLVM >= 12.0.0, where it started including a lock byte despite
- the platform supporting lockfree atomics for that size. Starting in LLVM 15.0.1, the ABI for these types has been
- restored to what it used to be (no lock byte), which is the most efficient implementation.
-
- This ABI break only affects users that compile with ``-ffreestanding``, and only for ``atomic<T>`` where ``T``
- is a non-builtin type that could be lockfree on the platform. See https://llvm.org/D133377 for more details.
-
-- When building libc++ against newlib/picolibc, the type of ``regex_type_traits::char_class_type`` was changed to
- ``uint16_t`` since all values of ``ctype_base::mask`` are taken. This is technically an ABI break, but including
- ``<regex> `` has triggered a ``static_assert`` failure since libc++ 14, so it is unlikely that this causes
- problems for existing users.
Build System Changes
--------------------
-- Support for ``libcxx``, ``libcxxabi`` and ``libunwind`` in ``LLVM_ENABLE_PROJECTS`` has officially
- been removed. Instead, please build according to :ref:`these instructions <build instructions>`.
diff --git a/third_party/llvm-project/libcxx/docs/Status/Cxx20Issues.csv b/third_party/llvm-project/libcxx/docs/Status/Cxx20Issues.csv
index 48bc936..db05461 100644
--- a/third_party/llvm-project/libcxx/docs/Status/Cxx20Issues.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/Cxx20Issues.csv
@@ -230,7 +230,7 @@
"`3299 <https://wg21.link/LWG3299>`__","Pointers don't need customized iterator behavior","Prague","|Complete|","15.0","|ranges|"
"`3300 <https://wg21.link/LWG3300>`__","Non-array ``ssize``\ overload is underconstrained","Prague","|Nothing To Do|",""
"`3301 <https://wg21.link/LWG3301>`__","``transform_view::iterator``\ has incorrect ``iterator_category``\ ","Prague","|Complete|","15.0","|ranges|"
-"`3302 <https://wg21.link/LWG3302>`__","Range adaptor objects ``keys``\ and ``values``\ are unspecified","Prague","","","|ranges|"
+"`3302 <https://wg21.link/LWG3302>`__","Range adaptor objects ``keys``\ and ``values``\ are unspecified","Prague","|Complete|","16.0","|ranges|"
"`3303 <https://wg21.link/LWG3303>`__","Bad ""``constexpr``\ "" marker for ``destroy/destroy_n``\ ","Prague","",""
"`3304 <https://wg21.link/LWG3304>`__","Allocate functions of ``std::polymorphic_allocator``\ should require ``[[nodiscard]]``\ ","Prague","|Complete|","16.0"
"`3307 <https://wg21.link/LWG3307>`__","``std::allocator<void>().allocate(n)``\ ","Prague","",""
@@ -244,7 +244,7 @@
"`3319 <https://wg21.link/LWG3319>`__","Properly reference specification of IANA time zone database","Prague","","","|chrono|"
"`3320 <https://wg21.link/LWG3320>`__","``span::cbegin/cend``\ methods produce different results than ``std::[ranges::]cbegin/cend``\ ","Prague","|Complete|",""
"`3321 <https://wg21.link/LWG3321>`__","``uninitialized_construct_using_allocator``\ should use ``construct_at``\ ","Prague","|Complete|","16.0"
-"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","","","|ranges|"
+"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","|Complete|","16.0","|ranges|"
"`3324 <https://wg21.link/LWG3324>`__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","|Complete|","14.0","|spaceship|"
"`3325 <https://wg21.link/LWG3325>`__","Constrain return type of transformation function for ``transform_view``\ ","Prague","|Complete|","15.0","|ranges|"
"`3326 <https://wg21.link/LWG3326>`__","``enable_view``\ has false positives","Prague","|Complete|","15.0","|ranges|"
@@ -261,7 +261,7 @@
"`3346 <https://wg21.link/LWG3346>`__","``pair``\ and ``tuple``\ copy and move constructor have backwards specification","Prague","",""
"`3347 <https://wg21.link/LWG3347>`__","``std::pair<T, U>``\ now requires ``T``\ and ``U``\ to be less-than-comparable","Prague","",""
"`3348 <https://wg21.link/LWG3348>`__","``__cpp_lib_unwrap_ref``\ in wrong header","Prague","|Complete|","12.0"
-"`3349 <https://wg21.link/LWG3349>`__","Missing ``__cpp_lib_constexpr_complex``\ for P0415R1","Prague","",""
+"`3349 <https://wg21.link/LWG3349>`__","Missing ``__cpp_lib_constexpr_complex``\ for P0415R1","Prague","|Complete|","16.0"
"`3350 <https://wg21.link/LWG3350>`__","Simplify return type of ``lexicographical_compare_three_way``\ ","Prague","","","|spaceship|"
"`3351 <https://wg21.link/LWG3351>`__","``ranges::enable_safe_range``\ should not be constrained","Prague","|Complete|","15.0","|ranges|"
"`3352 <https://wg21.link/LWG3352>`__","``strong_equality``\ isn't a thing","Prague","|Nothing To Do|","","|spaceship|"
@@ -273,7 +273,7 @@
"`3360 <https://wg21.link/LWG3360>`__","``three_way_comparable_with``\ is inconsistent with similar concepts","Prague","|Nothing To Do|","","|spaceship|"
"`3362 <https://wg21.link/LWG3362>`__","Strike ``stop_source``\ 's ``operator!=``\ ","Prague","",""
"`3363 <https://wg21.link/LWG3363>`__","``drop_while_view``\ should opt-out of ``sized_range``\ ","Prague","|Nothing To Do|","","|ranges|"
-"`3364 <https://wg21.link/LWG3364>`__","Initialize data members of ranges and their iterators","Prague","","","|ranges|"
+"`3364 <https://wg21.link/LWG3364>`__","Initialize data members of ranges and their iterators","Prague","|Complete|","16.0","|ranges|"
"`3367 <https://wg21.link/LWG3367>`__","Integer-class conversions should not throw","Prague","|Nothing To Do|",""
"`3369 <https://wg21.link/LWG3369>`__","``span``\ 's deduction-guide for built-in arrays doesn't work","Prague","|Complete|","14.0"
"`3371 <https://wg21.link/LWG3371>`__","``visit_format_arg``\ and ``make_format_args``\ are not hidden friends","Prague","|Complete|","14.0","|format|"
@@ -290,7 +290,7 @@
"`3384 <https://wg21.link/LWG3384>`__","``transform_view::*sentinel*``\ has an incorrect ``operator-``\ ","Prague","|Complete|","15.0","|ranges|"
"`3385 <https://wg21.link/LWG3385>`__","``common_iterator``\ is not sufficiently constrained for non-copyable iterators","Prague","|Complete|","15.0","|ranges|"
"`3387 <https://wg21.link/LWG3387>`__","|sect|\ [range.reverse.view] ``reverse_view<V>``\ unintentionally requires ``range<const V>``\ ","Prague","|Complete|","15.0","|ranges|"
-"`3388 <https://wg21.link/LWG3388>`__","``view``\ iterator types have ill-formed ``<=>``\ operators","Prague","","","|ranges|"
+"`3388 <https://wg21.link/LWG3388>`__","``view``\ iterator types have ill-formed ``<=>``\ operators","Prague","|Complete|","16.0","|ranges|"
"`3389 <https://wg21.link/LWG3389>`__","A move-only iterator still does not have a ``counted_iterator``\ ","Prague","|Complete|","15.0","|ranges|"
"`3390 <https://wg21.link/LWG3390>`__","``make_move_iterator()``\ cannot be used to construct a ``move_iterator``\ for a move-only iterator","Prague","|Complete|","14.0","|ranges|"
"`3393 <https://wg21.link/LWG3393>`__","Missing/incorrect feature test macro for coroutines","Prague","|Complete|","14.0"
diff --git a/third_party/llvm-project/libcxx/docs/Status/Cxx20Papers.csv b/third_party/llvm-project/libcxx/docs/Status/Cxx20Papers.csv
index 10fde39..6b01966 100644
--- a/third_party/llvm-project/libcxx/docs/Status/Cxx20Papers.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/Cxx20Papers.csv
@@ -67,7 +67,7 @@
"`P0972R0 <https://wg21.link/P0972R0>`__","LWG","<chrono> ``zero()``\ , ``min()``\ , and ``max()``\ should be noexcept","San Diego","|Complete|","8.0"
"`P1006R1 <https://wg21.link/P1006R1>`__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0"
"`P1007R3 <https://wg21.link/P1007R3>`__","LWG","``std::assume_aligned``\ ","San Diego","|Complete|","15.0"
-"`P1020R1 <https://wg21.link/P1020R1>`__","LWG","Smart pointer creation with default initialization","San Diego","* *",""
+"`P1020R1 <https://wg21.link/P1020R1>`__","LWG","Smart pointer creation with default initialization","San Diego","|Complete|","16.0"
"`P1032R1 <https://wg21.link/P1032R1>`__","LWG","Misc constexpr bits","San Diego","|Complete|","13.0"
"`P1085R2 <https://wg21.link/P1085R2>`__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0"
"`P1123R0 <https://wg21.link/P1123R0>`__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *",""
@@ -131,8 +131,8 @@
"`P1651R0 <https://wg21.link/P1651R0>`__","LWG","bind_front should not unwrap reference_wrapper","Cologne","|Complete|","13.0"
"`P1652R1 <https://wg21.link/P1652R1>`__","LWG","Printf corner cases in std::format","Cologne","|Complete|","14.0"
"`P1661R1 <https://wg21.link/P1661R1>`__","LWG","Remove dedicated precalculated hash lookup interface","Cologne","|Nothing To Do|",""
-"`P1754R1 <https://wg21.link/P1754R1>`__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|In Progress|","","|ranges|"
-"","","","","","",""
+"`P1754R1 <https://wg21.link/P1754R1>`__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|Complete|","15.0","|ranges|"
+"","","","","",""
"`P0883R2 <https://wg21.link/P0883R2>`__","LWG","Fixing Atomic Initialization","Belfast","|Complete| [#note-P0883.1]_ [#note-P0883.2]_","14.0"
"`P1391R4 <https://wg21.link/P1391R4>`__","LWG","Range constructor for std::string_view","Belfast","|Complete|","14.0","|ranges|"
"`P1394R4 <https://wg21.link/P1394R4>`__","LWG","Range constructor for std::span","Belfast","|Complete|","14.0","|ranges|"
@@ -149,7 +149,7 @@
"`P1722R2 <https://wg21.link/P1722R2>`__","LWG","Mandating the Standard Library: Clause 30 - Regular Expression library","Belfast","* *",""
"`P1723R2 <https://wg21.link/P1723R2>`__","LWG","Mandating the Standard Library: Clause 31 - Atomics library","Belfast","* *",""
"`P1855R0 <https://wg21.link/P1855R0>`__","LWG","Make ``<compare>``\ freestanding","Belfast","* *",""
-"`P1862R1 <https://wg21.link/P1862R1>`__","LWG","Ranges adaptors for non-copyable iterators","Belfast","* *","","|ranges|"
+"`P1862R1 <https://wg21.link/P1862R1>`__","LWG","Ranges adaptors for non-copyable iterators","Belfast","|Complete|","16.0","|ranges|"
"`P1865R1 <https://wg21.link/P1865R1>`__","LWG","Add max() to latch and barrier","Belfast","|Complete|","11.0"
"`P1869R1 <https://wg21.link/P1869R1>`__","LWG","Rename 'condition_variable_any' interruptible wait methods","Belfast","* *",""
"`P1870R1 <https://wg21.link/P1870R1>`__","LWG","forwarding-range is too subtle","Belfast","|Complete|","15.0","|ranges|"
@@ -174,15 +174,15 @@
"`P1937R2 <https://wg21.link/P1937R2>`__","CWG","Fixing inconsistencies between constexpr and consteval functions","Prague","* *",""
"`P1956R1 <https://wg21.link/P1956R1>`__","LWG","On the names of low-level bit manipulation functions","Prague","|Complete|","12.0"
"`P1957R2 <https://wg21.link/P1957R2>`__","CWG","Converting from ``T*``\ to bool should be considered narrowing (re: US 212)","Prague","* *",""
-"`P1963R0 <https://wg21.link/P1963R0>`__","LWG","Fixing US 313","Prague","* *","","|ranges|"
+"`P1963R0 <https://wg21.link/P1963R0>`__","LWG","Fixing US 313","Prague","* *","",""
"`P1964R2 <https://wg21.link/P1964R2>`__","LWG","Wording for boolean-testable","Prague","|Complete|","13.0"
"`P1970R2 <https://wg21.link/P1970R2>`__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","|Complete|","15.0","|ranges|"
-"`P1973R1 <https://wg21.link/P1973R1>`__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","* *",""
+"`P1973R1 <https://wg21.link/P1973R1>`__","LWG","Rename ""_default_init"" Functions, Rev1","Prague","|Complete|","16.0"
"`P1976R2 <https://wg21.link/P1976R2>`__","LWG","Fixed-size span construction from dynamic range","Prague","|Complete|","11.0","|ranges|"
"`P1981R0 <https://wg21.link/P1981R0>`__","LWG","Rename leap to leap_second","Prague","* *",""
"`P1982R0 <https://wg21.link/P1982R0>`__","LWG","Rename link to time_zone_link","Prague","* *",""
"`P1983R0 <https://wg21.link/P1983R0>`__","LWG","Wording for GB301, US296, US292, US291, and US283","Prague","|Complete|","15.0","|ranges|"
-"`P1994R1 <https://wg21.link/P1994R1>`__","LWG","elements_view needs its own sentinel","Prague","Complete","16.0","|ranges|"
+"`P1994R1 <https://wg21.link/P1994R1>`__","LWG","elements_view needs its own sentinel","Prague","|Complete|","16.0","|ranges|"
"`P2002R1 <https://wg21.link/P2002R1>`__","CWG","Defaulted comparison specification cleanups","Prague","* *",""
"`P2045R1 <https://wg21.link/P2045R1>`__","LWG","Missing Mandates for the standard library","Prague","* *",""
"`P2085R0 <https://wg21.link/P2085R0>`__","CWG","Consistent defaulted comparisons","Prague","* *",""
@@ -193,12 +193,12 @@
"`P2116R0 <https://wg21.link/P2116R0>`__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0"
"","","","","","",""
"`P2231R1 <https://wg21.link/P2231R1>`__","LWG","Missing constexpr in std::optional and std::variant","June 2021","|Partial| [#note-P2231]_","13.0"
-"`P2325R3 <https://wg21.link/P2325R3>`__","LWG","Views should not be required to be default constructible","June 2021","|In progress|","","|ranges|"
-"`P2210R2 <https://wg21.link/P2210R2>`__","LWG",Superior String Splitting,"June 2021","|In progress|","","|ranges|"
-"`P2216R3 <https://wg21.link/P2216R3>`__","LWG",std::format improvements,"June 2021","|Complete|","15.0"
-"`P2281R1 <https://wg21.link/P2281R1>`__","LWG",Clarifying range adaptor objects,"June 2021","|Complete|","14.0","|ranges|"
-"`P2328R1 <https://wg21.link/P2328R1>`__","LWG",join_view should join all views of ranges,"June 2021","","","|ranges|"
-"`P2367R0 <https://wg21.link/P2367R0>`__","LWG",Remove misuses of list-initialization from Clause 24,"June 2021","","","|ranges|"
+"`P2325R3 <https://wg21.link/P2325R3>`__","LWG","Views should not be required to be default constructible","June 2021","|Complete|","16.0","|ranges|"
+"`P2210R2 <https://wg21.link/P2210R2>`__","LWG","Superior String Splitting","June 2021","|Complete|","16.0","|ranges|"
+"`P2216R3 <https://wg21.link/P2216R3>`__","LWG","std::format improvements","June 2021","|Complete|","15.0"
+"`P2281R1 <https://wg21.link/P2281R1>`__","LWG","Clarifying range adaptor objects","June 2021","|Complete|","14.0","|ranges|"
+"`P2328R1 <https://wg21.link/P2328R1>`__","LWG","join_view should join all views of ranges","June 2021","|Complete|","15.0","|ranges|"
+"`P2367R0 <https://wg21.link/P2367R0>`__","LWG","Remove misuses of list-initialization from Clause 24","June 2021","|Complete|","15.0","|ranges|"
"","","","","","",""
"`P2372R3 <https://wg21.link/P2372R3>`__","LWG","Fixing locale handling in chrono formatters","October 2021","|In Progress|",""
"`P2415R2 <https://wg21.link/P2415R2>`__","LWG","What is a ``view``","October 2021","|Complete|","14.0","|ranges|"
diff --git a/third_party/llvm-project/libcxx/docs/Status/Cxx2b.rst b/third_party/llvm-project/libcxx/docs/Status/Cxx2b.rst
index 41b790e..e79ed28 100644
--- a/third_party/llvm-project/libcxx/docs/Status/Cxx2b.rst
+++ b/third_party/llvm-project/libcxx/docs/Status/Cxx2b.rst
@@ -39,8 +39,9 @@
.. note::
- .. [#note-P2273] P2273: ``make_unique_for_overwrite`` isn't done yet since `P1020` hasn't been implemented yet.
.. [#note-P0533R9] P0533R9: ``isfinite``, ``isinf``, ``isnan`` and ``isnormal`` are implemented.
+ .. [#note-P1413R3] P1413R3: ``std::aligned_storage_t`` and ``std::aligned_union_t`` are marked deprecated, but
+ clang doesn't issue a diagnostic for deprecated using template declarations.
.. _issues-status-cxx2b:
diff --git a/third_party/llvm-project/libcxx/docs/Status/Cxx2bIssues.csv b/third_party/llvm-project/libcxx/docs/Status/Cxx2bIssues.csv
index e92cfc3..b2cc710 100644
--- a/third_party/llvm-project/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/Cxx2bIssues.csv
@@ -131,7 +131,7 @@
`3581 <https://wg21.link/LWG3581>`__,"The range constructor makes ``basic_string_view`` not trivially move constructible","October 2021","|Complete|","14.0","|ranges|"
`3585 <https://wg21.link/LWG3585>`__,"``variant`` converting assignment with immovable alternative","October 2021","",""
`3589 <https://wg21.link/LWG3589>`__,"The ``const`` lvalue reference overload of ``get`` for ``subrange`` does not constrain ``I`` to be ``copyable`` when ``N == 0``","October 2021","|Complete|","14.0","|ranges|"
-`3590 <https://wg21.link/LWG3590>`__,"``split_view::base() const &`` is overconstrained","October 2021","","","|ranges|"
+`3590 <https://wg21.link/LWG3590>`__,"``split_view::base() const &`` is overconstrained","October 2021","|Complete|","16.0","|ranges|"
`3591 <https://wg21.link/LWG3591>`__,"``lazy_split_view<input_view>::inner-iterator::base() &&`` invalidates outer iterators","October 2021","","","|ranges|"
`3592 <https://wg21.link/LWG3592>`__,"``lazy_split_view`` needs to check the simpleness of Pattern","October 2021","","","|ranges|"
`3593 <https://wg21.link/LWG3593>`__,"Several iterators' ``base() const &`` and ``lazy_split_view::outer-iterator::value_type::end()`` missing ``noexcept``","October 2021","","","|ranges|"
@@ -167,11 +167,11 @@
"`3671 <https://wg21.link/LWG3671>`__","``atomic_fetch_xor`` missing from ``stdatomic.h``","July 2022","",""
"`3672 <https://wg21.link/LWG3672>`__","``common_iterator::operator->()`` should return by value","July 2022","","","|ranges|"
"`3683 <https://wg21.link/LWG3683>`__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","July 2022","",""
-"`3687 <https://wg21.link/LWG3687>`__","``expected<cv void, E>`` move constructor should move","July 2022","Complete","16.0"
+"`3687 <https://wg21.link/LWG3687>`__","``expected<cv void, E>`` move constructor should move","July 2022","|Complete|","16.0"
"`3692 <https://wg21.link/LWG3692>`__","``zip_view::iterator``'s ``operator<=>`` is overconstrained","July 2022","","","|ranges| |spaceship|"
"`3701 <https://wg21.link/LWG3701>`__","Make ``formatter<remove_cvref_t<const charT[N]>, charT>`` requirement explicit","July 2022","","","|format|"
"`3702 <https://wg21.link/LWG3702>`__","Should ``zip_transform_view::iterator`` remove ``operator<``","July 2022","","","|ranges| |spaceship|"
-"`3703 <https://wg21.link/LWG3703>`__","Missing requirements for ``expected<T, E>`` requires ``is_void<T>``","July 2022","Complete","16.0"
+"`3703 <https://wg21.link/LWG3703>`__","Missing requirements for ``expected<T, E>`` requires ``is_void<T>``","July 2022","|Complete|","16.0"
"`3704 <https://wg21.link/LWG3704>`__","LWG 2059 added overloads that might be ill-formed for sets","July 2022","",""
"`3705 <https://wg21.link/LWG3705>`__","Hashability shouldn't depend on basic_string's allocator","July 2022","|Complete|","16.0"
"`3707 <https://wg21.link/LWG3707>`__","chunk_view::outer-iterator::value_type::size should return unsigned type","July 2022","","","|ranges|"
diff --git a/third_party/llvm-project/libcxx/docs/Status/Cxx2bPapers.csv b/third_party/llvm-project/libcxx/docs/Status/Cxx2bPapers.csv
index dd6590b..e3f39d4 100644
--- a/third_party/llvm-project/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/Cxx2bPapers.csv
@@ -42,9 +42,9 @@
"`P0533R9 <https://wg21.link/P0533R9>`__","LWG","``constexpr`` for ``<cmath>`` and ``<cstdlib>``","February 2022","|In progress| [#note-P0533R9]_",""
"`P0627R6 <https://wg21.link/P0627R6>`__","LWG","Function to mark unreachable code","February 2022","|Complete|","15.0"
"`P1206R7 <https://wg21.link/P1206R7>`__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","","","|ranges|"
-"`P1413R3 <https://wg21.link/P1413R3>`__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","",""
+"`P1413R3 <https://wg21.link/P1413R3>`__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","|Complete| [#note-P1413R3]_",""
"`P2255R2 <https://wg21.link/P2255R2>`__","LWG","A type trait to detect reference binding to temporary","February 2022","",""
-"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Partial| [#note-P2273]_","16.0"
+"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0"
"`P2387R3 <https://wg21.link/P2387R3>`__","LWG","Pipe support for user-defined range adaptors","February 2022","","","|ranges|"
"`P2440R1 <https://wg21.link/P2440R1>`__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","","","|ranges|"
"`P2441R2 <https://wg21.link/P2441R2>`__","LWG","``views::join_with``","February 2022","","","|ranges|"
@@ -62,7 +62,7 @@
"`P2093R14 <https://wg21.link/P2093R14>`__","LWG","Formatted output","July 2022","",""
"`P2165R4 <https://wg21.link/P2165R4>`__","LWG","Compatibility between ``tuple``, ``pair`` and ``tuple-like`` objects","July 2022","",""
"`P2278R4 <https://wg21.link/P2278R4>`__","LWG","``cbegin`` should always return a constant iterator","July 2022","","","|ranges|"
-"`P2286R8 <https://wg21.link/P2286R8>`__","LWG","Formatting Ranges","July 2022","|Partial|","","|format| |ranges|"
+"`P2286R8 <https://wg21.link/P2286R8>`__","LWG","Formatting Ranges","July 2022","|Complete|","16.0","|format| |ranges|"
"`P2291R3 <https://wg21.link/P2291R3>`__","LWG","Add Constexpr Modifiers to Functions ``to_chars`` and ``from_chars`` for Integral Types in ``<charconv>`` Header","July 2022","|Complete|","16.0"
"`P2302R4 <https://wg21.link/P2302R4>`__","LWG","``std::ranges::contains``","July 2022","","","|ranges|"
"`P2322R6 <https://wg21.link/P2322R6>`__","LWG","``ranges::fold``","July 2022","","","|ranges|"
@@ -73,7 +73,7 @@
"`P2419R2 <https://wg21.link/P2419R2>`__","LWG","Clarify handling of encodings in localized formatting of chrono types","July 2022","",""
"`P2438R2 <https://wg21.link/P2438R2>`__","LWG","``std::string::substr() &&``","July 2022","|Complete|","16.0"
"`P2445R1 <https://wg21.link/P2445R1>`__","LWG","``forward_like``","July 2022","|Complete|","16.0"
-"`P2446R2 <https://wg21.link/P2446R2>`__","LWG","``views::as_rvalue``","July 2022","","","|ranges|"
+"`P2446R2 <https://wg21.link/P2446R2>`__","LWG","``views::as_rvalue``","July 2022","|Complete|","16.0","|ranges|"
"`P2460R2 <https://wg21.link/P2460R2>`__","LWG","Relax requirements on ``wchar_t`` to match existing practices","July 2022","",""
"`P2465R3 <https://wg21.link/P2465R3>`__","LWG","Standard Library Modules ``std`` and ``std.compat``","July 2022","",""
"`P2467R1 <https://wg21.link/P2467R1>`__","LWG","Support exclusive mode for ``fstreams``","July 2022","",""
diff --git a/third_party/llvm-project/libcxx/docs/Status/FormatIssues.csv b/third_party/llvm-project/libcxx/docs/Status/FormatIssues.csv
index 86876d8..3299b6d 100644
--- a/third_party/llvm-project/libcxx/docs/Status/FormatIssues.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/FormatIssues.csv
@@ -6,7 +6,7 @@
`P2216 <https://wg21.link/P2216>`_,"std::format improvements","C++20",Mark de Wever,|Complete|,Clang 15
`P2418 <https://wg21.link/P2418>`__,"Add support for ``std::generator``-like types to ``std::format``","C++20",Mark de Wever,|Complete|, Clang 15
"`P2093R14 <https://wg21.link/P2093R14>`__","Formatted output","C++23"
-"`P2286R8 <https://wg21.link/P2286R8>`__","Formatting Ranges","C++23","Mark de Wever","|In Progress|"
+"`P2286R8 <https://wg21.link/P2286R8>`__","Formatting Ranges","C++23","Mark de Wever","|Complete|",Clang 16
"`P2508R1 <https://wg21.link/P2508R1>`__","Exposing ``std::basic-format-string``","C++23","Mark de Wever","|Complete|", Clang 15
"`P2585R0 <https://wg21.link/P2585R0>`__","Improving default container formatting","C++23","Mark de Wever","|In progress|"
"`P2539R4 <https://wg21.link/P2539R4>`__","Should the output of ``std::print`` to a terminal be synchronized with the underlying stream?","C++23"
diff --git a/third_party/llvm-project/libcxx/docs/Status/FormatPaper.csv b/third_party/llvm-project/libcxx/docs/Status/FormatPaper.csv
index 4a5f1c4..01585c0 100644
--- a/third_party/llvm-project/libcxx/docs/Status/FormatPaper.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/FormatPaper.csv
@@ -30,8 +30,11 @@
`P2286R8 <https://wg21.link/P2286R8>`__,"Formatting ranges"
`[format.syn] <https://wg21.link/format.syn>`_,"Concept ``formattable``",,Mark de Wever,|Complete|, Clang 16
`[format.string.std] <https://wg21.link/format.string.std>`_,"std-format-spec ``type`` debug",,Mark de Wever,|Complete|,Clang 16
-`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: sequences",,Mark de Wever,|In Progress|,
-`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: associative",,Mark de Wever,,
-`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: container adaptors",,Mark de Wever,,
+`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: sequences",,Mark de Wever,|Complete|,Clang 16
+`[format.range.fmtmap] <https://wg21.link/format.range.fmtmap>`_,"Formatting for ranges: map",,Mark de Wever,|Complete|,Clang 16
+`[format.range.fmtset] <https://wg21.link/format.range.fmtset>`_,"Formatting for ranges: set",,Mark de Wever,|Complete|,Clang 16
+`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: container adaptors",,Mark de Wever,|Complete|,Clang 16
`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: ``pair`` and ``tuple``",,Mark de Wever,|Complete|,Clang 16
-`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: ``vector<bool>``",,Mark de Wever,,
+`[format.range] <https://wg21.link/format.range>`_,"Formatting for ranges: ``vector<bool>``",,Mark de Wever,|Complete|,Clang 16
+"`P2585R0 <https://wg21.link/P2585R0>`__","Improving default container formatting"
+`[format.range.fmtstr] <https://wg21.link/format.range.fmtstr>`_,"Formatting for ranges: strings",,Mark de Wever,|In Progress|,
diff --git a/third_party/llvm-project/libcxx/docs/Status/RangesMajorFeatures.csv b/third_party/llvm-project/libcxx/docs/Status/RangesMajorFeatures.csv
index 161d643..d569f14 100644
--- a/third_party/llvm-project/libcxx/docs/Status/RangesMajorFeatures.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/RangesMajorFeatures.csv
@@ -1,4 +1,4 @@
Standard,Name,Assignee,CL,Status
C++23,`ranges::to <https://wg21.link/P1206R7>`_,Unassigned,No patch yet,Not started
C++23,`Pipe support for user-defined range adaptors <https://wg21.link/P2387R3>`_,Unassigned,No patch yet,Not started
-C++23,`Formatting Ranges <https://wg21.link/P2286R8>`_,Mark de Wever,Various,In progress
+C++23,`Formatting Ranges <https://wg21.link/P2286R8>`_,Mark de Wever,Various,Complete
diff --git a/third_party/llvm-project/libcxx/docs/Status/RangesViews.csv b/third_party/llvm-project/libcxx/docs/Status/RangesViews.csv
index 8d59383..3bc9c62 100644
--- a/third_party/llvm-project/libcxx/docs/Status/RangesViews.csv
+++ b/third_party/llvm-project/libcxx/docs/Status/RangesViews.csv
@@ -17,7 +17,7 @@
C++20,`counted <https://wg21.link/P0896R4>`_,Zoe Carver,`D106923 <https://llvm.org/D106923>`_,✅
C++20,`common <https://wg21.link/P0896R4>`_,Zoe Carver,`D105753 <https://llvm.org/D105753>`_,✅
C++20,`reverse <https://wg21.link/P0896R4>`_,Zoe Carver,`D107096 <https://llvm.org/D107096>`_,✅
-C++20,`elements / keys / values <https://wg21.link/P1035R7>`_,Hui Xie,`D136268 <https://llvm.org/D136268>`_,Under review
+C++20,`elements / keys / values <https://wg21.link/P1035R7>`_,Hui Xie,`D136268 <https://llvm.org/D136268>`_,✅
C++20,`istream <https://wg21.link/P1035R7>`_,Hui Xie,`D133317 <https://llvm.org/D133317>`_,✅
,,,,
,,,,
@@ -33,5 +33,5 @@
C++23,`chunk <https://wg21.link/P2442R1>`_,Unassigned,No patch yet,Not started
C++23,`chunk_by <https://wg21.link/P2443R1>`_,Unassigned,No patch yet,Not started
C++23,`as_const <https://wg21.link/P2278R4>`_,Unassigned,No patch yet,Not started
-C++23,`as_rvalue <https://wg21.link/P2446R2>`_,Nikolas Klauser,`D137637 <https://llvm.org/D137637>`_,Under review
+C++23,`as_rvalue <https://wg21.link/P2446R2>`_,Nikolas Klauser,`D137637 <https://llvm.org/D137637>`_,Complete
C++23,`stride <https://wg21.link/P1899R3>`_,Unassigned,No patch yet,Not started
diff --git a/third_party/llvm-project/libcxx/docs/TestingLibcxx.rst b/third_party/llvm-project/libcxx/docs/TestingLibcxx.rst
index 9f18547..283646a 100644
--- a/third_party/llvm-project/libcxx/docs/TestingLibcxx.rst
+++ b/third_party/llvm-project/libcxx/docs/TestingLibcxx.rst
@@ -98,8 +98,7 @@
The libc++ test suite uses a few optional tools to improve the code quality.
These tools are:
-- clang-query
-- clang-tidy
+- clang-tidy (you might need additional dev packages to compile libc++-specific clang-tidy checks)
Writing Tests
-------------
diff --git a/third_party/llvm-project/libcxx/docs/UsingLibcxx.rst b/third_party/llvm-project/libcxx/docs/UsingLibcxx.rst
index 6fac013..3b64adb 100644
--- a/third_party/llvm-project/libcxx/docs/UsingLibcxx.rst
+++ b/third_party/llvm-project/libcxx/docs/UsingLibcxx.rst
@@ -172,12 +172,19 @@
that this function is provided by the static or shared library, so it is only available when deploying
to a platform where the compiled library is sufficiently recent. On older platforms, the program will
terminate in an unspecified unsuccessful manner, but the quality of diagnostics won't be great.
-However, users can also override that function with their own, which can be useful to either provide
-custom behavior or when deploying to an older platform where the default function isn't available.
+However, users can also override that mechanism at two different levels. First, the mechanism can be
+overriden at compile-time by defining the ``_LIBCPP_VERBOSE_ABORT(format, args...)`` variadic macro.
+When that macro is defined, it will be called with a format string as the first argument, followed by
+a series of arguments to format using printf-style formatting. Compile-time customization may be
+interesting to get precise control over code generation, however it is also inconvenient to use in
+some cases. Indeed, compile-time customization of the verbose termination function requires that all
+translation units be compiled with a consistent definition for ``_LIBCPP_VERBOSE_ABORT`` to avoid ODR
+violations, which can add complexity in the build system of users.
-Replacing the default verbose termination function is done by defining the
-``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED`` macro in all translation units of your program
-and defining the following function in exactly one translation unit:
+Otherwise, if compile-time customization is not necessary, link-time customization of the handler is also
+possible, similarly to how replacing ``operator new`` works. This mechanism trades off fine-grained control
+over the call site where the termination is initiated in exchange for more ergonomics. Link-time customization
+is done by simply defining the following function in exactly one translation unit of your program:
.. code-block:: cpp
diff --git a/third_party/llvm-project/libcxx/docs/conf.py b/third_party/llvm-project/libcxx/docs/conf.py
index 12876d1..f680969 100644
--- a/third_party/llvm-project/libcxx/docs/conf.py
+++ b/third_party/llvm-project/libcxx/docs/conf.py
@@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
-version = '16.0'
+version = '17.0'
# The full version, including alpha/beta/rc tags.
-release = '16.0'
+release = '17.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/third_party/llvm-project/libcxx/docs/index.rst b/third_party/llvm-project/libcxx/docs/index.rst
index db49944..265d23c 100644
--- a/third_party/llvm-project/libcxx/docs/index.rst
+++ b/third_party/llvm-project/libcxx/docs/index.rst
@@ -105,7 +105,7 @@
============ =============== ========================== =====================
Compiler Versions Restrictions Support policy
============ =============== ========================== =====================
-Clang 14, 15 latest two stable releases per `LLVM's release page <https://releases.llvm.org>`_
+Clang 14, 15, 16-git latest two stable releases per `LLVM's release page <https://releases.llvm.org>`_ and the development version
AppleClang 14 latest stable release per `Xcode's release page <https://developer.apple.com/documentation/xcode-release-notes>`_
Open XL 17.1 (AIX) latest stable release per `Open XL's documentation page <https://www.ibm.com/docs/en/openxl-c-and-cpp-aix>`_
GCC 12 In C++11 or later only latest stable release per `GCC's release page <https://gcc.gnu.org/releases.html>`_
diff --git a/third_party/llvm-project/libcxx/include/CMakeLists.txt b/third_party/llvm-project/libcxx/include/CMakeLists.txt
index ea52f20..a12aa1d 100644
--- a/third_party/llvm-project/libcxx/include/CMakeLists.txt
+++ b/third_party/llvm-project/libcxx/include/CMakeLists.txt
@@ -302,6 +302,7 @@
__filesystem/u8path.h
__format/buffer.h
__format/concepts.h
+ __format/container_adaptor.h
__format/enable_insertable.h
__format/escaped_output_table.h
__format/extended_grapheme_cluster_table.h
@@ -327,6 +328,7 @@
__format/formatter_tuple.h
__format/parser_std_format_spec.h
__format/range_default_formatter.h
+ __format/range_formatter.h
__format/unicode.h
__functional/binary_function.h
__functional/binary_negate.h
@@ -390,6 +392,7 @@
__iterator/iter_swap.h
__iterator/iterator.h
__iterator/iterator_traits.h
+ __iterator/iterator_with_data.h
__iterator/mergeable.h
__iterator/move_iterator.h
__iterator/move_sentinel.h
@@ -402,6 +405,7 @@
__iterator/readable_traits.h
__iterator/reverse_access.h
__iterator/reverse_iterator.h
+ __iterator/segmented_iterator.h
__iterator/size.h
__iterator/sortable.h
__iterator/unreachable_sentinel.h
@@ -496,6 +500,7 @@
__random/weibull_distribution.h
__ranges/access.h
__ranges/all.h
+ __ranges/as_rvalue_view.h
__ranges/common_view.h
__ranges/concepts.h
__ranges/copyable_box.h
@@ -523,6 +528,7 @@
__ranges/reverse_view.h
__ranges/single_view.h
__ranges/size.h
+ __ranges/split_view.h
__ranges/subrange.h
__ranges/take_view.h
__ranges/take_while_view.h
@@ -700,6 +706,7 @@
__utility/cmp.h
__utility/convert_to_integral.h
__utility/declval.h
+ __utility/exception_guard.h
__utility/exchange.h
__utility/forward.h
__utility/forward_like.h
@@ -712,7 +719,6 @@
__utility/rel_ops.h
__utility/swap.h
__utility/to_underlying.h
- __utility/transaction.h
__utility/unreachable.h
__variant/monostate.h
__verbose_abort
@@ -904,13 +910,18 @@
)
endforeach()
- # Install the generated __config_site and the generated modulemap file.
+ # Install the generated __config_site file to the per-target include dir.
install(FILES "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site"
- "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap"
DESTINATION "${LIBCXX_INSTALL_INCLUDE_TARGET_DIR}"
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
COMPONENT cxx-headers)
+ # Install the generated modulemap file to the generic include dir.
+ install(FILES "${LIBCXX_GENERATED_INCLUDE_DIR}/module.modulemap"
+ DESTINATION "${LIBCXX_INSTALL_INCLUDE_DIR}"
+ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+ COMPONENT cxx-headers)
+
if (NOT CMAKE_CONFIGURATION_TYPES)
add_custom_target(install-cxx-headers
DEPENDS cxx-headers
diff --git a/third_party/llvm-project/libcxx/include/__algorithm/copy.h b/third_party/llvm-project/libcxx/include/__algorithm/copy.h
index f33d7fe..193a6df 100644
--- a/third_party/llvm-project/libcxx/include/__algorithm/copy.h
+++ b/third_party/llvm-project/libcxx/include/__algorithm/copy.h
@@ -11,7 +11,10 @@
#include <__algorithm/copy_move_common.h>
#include <__algorithm/iterator_operations.h>
+#include <__algorithm/min.h>
#include <__config>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -19,8 +22,15 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class, class _InIter, class _Sent, class _OutIter>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
+
+template <class _AlgPolicy>
struct __copy_loop {
template <class _InIter, class _Sent, class _OutIter>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
@@ -33,6 +43,57 @@
return std::make_pair(std::move(__first), std::move(__result));
}
+
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, std::move(__iters.second));
+ }
+
+ __result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ while (__sfirst != __slast) {
+ __result =
+ std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ }
+ __result =
+ std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
+ return std::make_pair(__last, std::move(__result));
+ }
+
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
+
+ if (__first == __last)
+ return std::make_pair(std::move(__first), std::move(__result));
+
+ auto __local_first = _Traits::__local(__result);
+ auto __segment_iterator = _Traits::__segment(__result);
+ while (true) {
+ auto __local_last = _Traits::__end(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iters = std::__copy<_AlgPolicy>(__first, __first + __size, __local_first);
+ __first = std::move(__iters.first);
+
+ if (__first == __last)
+ return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
+
+ __local_first = _Traits::__begin(++__segment_iterator);
+ }
+ }
};
struct __copy_trivial {
@@ -46,20 +107,20 @@
};
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
-pair<_InIter, _OutIter>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
__copy(_InIter __first, _Sent __last, _OutIter __result) {
- return std::__dispatch_copy_or_move<_AlgPolicy, __copy_loop, __copy_trivial>(
+ return std::__dispatch_copy_or_move<_AlgPolicy, __copy_loop<_AlgPolicy>, __copy_trivial>(
std::move(__first), std::move(__last), std::move(__result));
}
template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-_OutputIterator
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_COPY_H
diff --git a/third_party/llvm-project/libcxx/include/__algorithm/copy_backward.h b/third_party/llvm-project/libcxx/include/__algorithm/copy_backward.h
index be8c1ae..bb2a432 100644
--- a/third_party/llvm-project/libcxx/include/__algorithm/copy_backward.h
+++ b/third_party/llvm-project/libcxx/include/__algorithm/copy_backward.h
@@ -11,7 +11,10 @@
#include <__algorithm/copy_move_common.h>
#include <__algorithm/iterator_operations.h>
+#include <__algorithm/min.h>
#include <__config>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -20,8 +23,15 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
+__copy_backward(_InIter __first, _Sent __last, _OutIter __result);
+
template <class _AlgPolicy>
struct __copy_backward_loop {
template <class _InIter, class _Sent, class _OutIter>
@@ -36,6 +46,64 @@
return std::make_pair(std::move(__original_last_iter), std::move(__result));
}
+
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters =
+ std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, __iters.second);
+ }
+
+ __result =
+ std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
+ .second;
+ --__slast;
+ while (__sfirst != __slast) {
+ __result =
+ std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
+ .second;
+ --__slast;
+ }
+ __result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
+ .second;
+ return std::make_pair(__last, std::move(__result));
+ }
+
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ auto __orig_last = __last;
+ auto __segment_iterator = _Traits::__segment(__result);
+
+ // When the range contains no elements, __result might not be a valid iterator
+ if (__first == __last)
+ return std::make_pair(__first, __result);
+
+ auto __local_last = _Traits::__local(__result);
+ while (true) {
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
+
+ auto __local_first = _Traits::__begin(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iter = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
+ __last -= __size;
+
+ if (__first == __last)
+ return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
+ --__segment_iterator;
+ __local_last = _Traits::__end(__segment_iterator);
+ }
+ }
};
struct __copy_backward_trivial {
@@ -49,8 +117,7 @@
};
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-pair<_BidirectionalIterator1, _BidirectionalIterator2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
__copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
return std::__dispatch_copy_or_move<_AlgPolicy, __copy_backward_loop<_AlgPolicy>, __copy_backward_trivial>(
std::move(__first), std::move(__last), std::move(__result));
@@ -71,4 +138,6 @@
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H
diff --git a/third_party/llvm-project/libcxx/include/__algorithm/move.h b/third_party/llvm-project/libcxx/include/__algorithm/move.h
index 2581a41..ac95bda 100644
--- a/third_party/llvm-project/libcxx/include/__algorithm/move.h
+++ b/third_party/llvm-project/libcxx/include/__algorithm/move.h
@@ -11,7 +11,10 @@
#include <__algorithm/copy_move_common.h>
#include <__algorithm/iterator_operations.h>
+#include <__algorithm/min.h>
#include <__config>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -20,8 +23,15 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+__move(_InIter __first, _Sent __last, _OutIter __result);
+
template <class _AlgPolicy>
struct __move_loop {
template <class _InIter, class _Sent, class _OutIter>
@@ -34,6 +44,57 @@
}
return std::make_pair(std::move(__first), std::move(__result));
}
+
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, std::move(__iters.second));
+ }
+
+ __result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ while (__sfirst != __slast) {
+ __result =
+ std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second;
+ ++__sfirst;
+ }
+ __result =
+ std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second;
+ return std::make_pair(__last, std::move(__result));
+ }
+
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
+
+ if (__first == __last)
+ return std::make_pair(std::move(__first), std::move(__result));
+
+ auto __local_first = _Traits::__local(__result);
+ auto __segment_iterator = _Traits::__segment(__result);
+ while (true) {
+ auto __local_last = _Traits::__end(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iters = std::__move<_AlgPolicy>(__first, __first + __size, __local_first);
+ __first = std::move(__iters.first);
+
+ if (__first == __last)
+ return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
+
+ __local_first = _Traits::__begin(++__segment_iterator);
+ }
+ }
};
struct __move_trivial {
@@ -47,23 +108,23 @@
};
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
-pair<_InIter, _OutIter>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
__move(_InIter __first, _Sent __last, _OutIter __result) {
return std::__dispatch_copy_or_move<_AlgPolicy, __move_loop<_AlgPolicy>, __move_trivial>(
std::move(__first), std::move(__last), std::move(__result));
}
template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-_OutputIterator move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
static_assert(is_copy_constructible<_InputIterator>::value, "Iterators has to be copy constructible.");
static_assert(is_copy_constructible<_OutputIterator>::value, "The output iterator has to be copy constructible.");
- return std::__move<_ClassicAlgPolicy>(
- std::move(__first), std::move(__last), std::move(__result)).second;
+ return std::__move<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_MOVE_H
diff --git a/third_party/llvm-project/libcxx/include/__algorithm/move_backward.h b/third_party/llvm-project/libcxx/include/__algorithm/move_backward.h
index 6636ca6..d4f013b 100644
--- a/third_party/llvm-project/libcxx/include/__algorithm/move_backward.h
+++ b/third_party/llvm-project/libcxx/include/__algorithm/move_backward.h
@@ -11,7 +11,10 @@
#include <__algorithm/copy_move_common.h>
#include <__algorithm/iterator_operations.h>
+#include <__algorithm/min.h>
#include <__config>
+#include <__iterator/segmented_iterator.h>
+#include <__type_traits/common_type.h>
#include <__type_traits/is_copy_constructible.h>
#include <__utility/move.h>
#include <__utility/pair.h>
@@ -20,8 +23,15 @@
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
+__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result);
+
template <class _AlgPolicy>
struct __move_backward_loop {
template <class _InIter, class _Sent, class _OutIter>
@@ -36,6 +46,64 @@
return std::make_pair(std::move(__original_last_iter), std::move(__result));
}
+
+ template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) const {
+ using _Traits = __segmented_iterator_traits<_InIter>;
+ auto __sfirst = _Traits::__segment(__first);
+ auto __slast = _Traits::__segment(__last);
+ if (__sfirst == __slast) {
+ auto __iters =
+ std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
+ return std::make_pair(__last, __iters.second);
+ }
+
+ __result =
+ std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
+ .second;
+ --__slast;
+ while (__sfirst != __slast) {
+ __result =
+ std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
+ .second;
+ --__slast;
+ }
+ __result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
+ .second;
+ return std::make_pair(__last, std::move(__result));
+ }
+
+ template <class _InIter,
+ class _OutIter,
+ __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value &&
+ !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
+ int> = 0>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+ operator()(_InIter __first, _InIter __last, _OutIter __result) {
+ using _Traits = __segmented_iterator_traits<_OutIter>;
+ using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
+
+ // When the range contains no elements, __result might not be a valid iterator
+ if (__first == __last)
+ return std::make_pair(__first, __result);
+
+ auto __orig_last = __last;
+
+ auto __local_last = _Traits::__local(__result);
+ auto __segment_iterator = _Traits::__segment(__result);
+ while (true) {
+ auto __local_first = _Traits::__begin(__segment_iterator);
+ auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
+ auto __iter = std::__move_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
+ __last -= __size;
+
+ if (__first == __last)
+ return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
+
+ __local_last = _Traits::__end(--__segment_iterator);
+ }
+ }
};
struct __move_backward_trivial {
@@ -49,8 +117,7 @@
};
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
-pair<_BidirectionalIterator1, _BidirectionalIterator2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible.");
@@ -60,15 +127,13 @@
}
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
-_BidirectionalIterator2
-move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
- _BidirectionalIterator2 __result)
-{
- return std::__move_backward<_ClassicAlgPolicy>(
- std::move(__first), std::move(__last), std::move(__result)).second;
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2
+move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
+ return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
diff --git a/third_party/llvm-project/libcxx/include/__assert b/third_party/llvm-project/libcxx/include/__assert
index afe7304..9c0cd1b 100644
--- a/third_party/llvm-project/libcxx/include/__assert
+++ b/third_party/llvm-project/libcxx/include/__assert
@@ -41,7 +41,7 @@
# define _LIBCPP_ASSERT(expression, message) \
(__builtin_expect(static_cast<bool>(expression), 1) ? \
(void)0 : \
- ::std::__libcpp_verbose_abort("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
+ _LIBCPP_VERBOSE_ABORT("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message))
#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume)
# define _LIBCPP_ASSERT(expression, message) \
(_LIBCPP_DIAGNOSTIC_PUSH \
diff --git a/third_party/llvm-project/libcxx/include/__availability b/third_party/llvm-project/libcxx/include/__availability
index 72ff663..6dfca3f 100644
--- a/third_party/llvm-project/libcxx/include/__availability
+++ b/third_party/llvm-project/libcxx/include/__availability
@@ -156,20 +156,9 @@
# define _LIBCPP_AVAILABILITY_FORMAT
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
- // This controls whether the default verbose termination function is
- // provided by the library.
- //
- // Note that when users provide their own custom function, it doesn't
- // matter whether the dylib provides a default function, and the
- // availability markup can actually give a false positive diagnostic
- // (it will think that no function is provided, when in reality the
- // user has provided their own).
- //
- // Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED
- // to the compiler to tell the library not to define its own verbose abort.
- // Note that defining this macro but failing to define a custom function
- // will lead to a load-time error on back-deployment targets, so it should
- // be avoided.
+ // This controls whether the library claims to provide a default verbose
+ // termination function, and consequently whether the headers will try
+ // to use it when the mechanism isn't overriden at compile-time.
// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
#elif defined(__APPLE__)
diff --git a/third_party/llvm-project/libcxx/include/__bit_reference b/third_party/llvm-project/libcxx/include/__bit_reference
index b954c10..2665749 100644
--- a/third_party/llvm-project/libcxx/include/__bit_reference
+++ b/third_party/llvm-project/libcxx/include/__bit_reference
@@ -55,6 +55,8 @@
friend class __bit_const_reference<_Cp>;
friend class __bit_iterator<_Cp, false>;
public:
+ using __container = typename _Cp::__self;
+
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
__bit_reference(const __bit_reference&) = default;
diff --git a/third_party/llvm-project/libcxx/include/__config b/third_party/llvm-project/libcxx/include/__config
index a5d54d4..40c9deb 100644
--- a/third_party/llvm-project/libcxx/include/__config
+++ b/third_party/llvm-project/libcxx/include/__config
@@ -35,9 +35,9 @@
#ifdef __cplusplus
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
-// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is
+// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is
// defined to XXYYZZ.
-# define _LIBCPP_VERSION 160000
+# define _LIBCPP_VERSION 170000
# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
@@ -629,7 +629,11 @@
# else
# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# endif
-# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
+# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
+
+// This macro provides a HIDE_FROM_ABI equivalent that can be applied to extern
+// "C" function, as those lack mangling.
+# define _LIBCPP_HIDE_FROM_ABI_C _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
# ifdef _LIBCPP_BUILDING_LIBRARY
# if _LIBCPP_ABI_VERSION > 1
@@ -802,6 +806,12 @@
# define _LIBCPP_DEPRECATED_IN_CXX20
# endif
+#if _LIBCPP_STD_VER >= 23
+# define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED
+#else
+# define _LIBCPP_DEPRECATED_IN_CXX23
+#endif
+
# if !defined(_LIBCPP_HAS_NO_CHAR8_T)
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
# else
diff --git a/third_party/llvm-project/libcxx/include/__coroutine/coroutine_handle.h b/third_party/llvm-project/libcxx/include/__coroutine/coroutine_handle.h
index 8f7ed2e..0a6cc1c 100644
--- a/third_party/llvm-project/libcxx/include/__coroutine/coroutine_handle.h
+++ b/third_party/llvm-project/libcxx/include/__coroutine/coroutine_handle.h
@@ -13,8 +13,9 @@
#include <__config>
#include <__functional/hash.h>
#include <__memory/addressof.h>
+#include <__type_traits/remove_cv.h>
#include <compare>
-#include <type_traits>
+#include <cstddef>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/third_party/llvm-project/libcxx/include/__coroutine/coroutine_traits.h b/third_party/llvm-project/libcxx/include/__coroutine/coroutine_traits.h
index 87eb218..d513075 100644
--- a/third_party/llvm-project/libcxx/include/__coroutine/coroutine_traits.h
+++ b/third_party/llvm-project/libcxx/include/__coroutine/coroutine_traits.h
@@ -10,7 +10,7 @@
#define _LIBCPP___COROUTINE_COROUTINE_TRAITS_H
#include <__config>
-#include <type_traits>
+#include <__type_traits/void_t.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/third_party/llvm-project/libcxx/include/__expected/expected.h b/third_party/llvm-project/libcxx/include/__expected/expected.h
index 593ec4b..e1f590c 100644
--- a/third_party/llvm-project/libcxx/include/__expected/expected.h
+++ b/third_party/llvm-project/libcxx/include/__expected/expected.h
@@ -44,11 +44,11 @@
#include <__type_traits/negation.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
+#include <__utility/exception_guard.h>
#include <__utility/forward.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
#include <__utility/swap.h>
-#include <__utility/transaction.h>
#include <cstdlib> // for std::abort
#include <initializer_list>
@@ -81,8 +81,8 @@
!is_function_v<_Tp> &&
!is_same_v<remove_cv_t<_Tp>, in_place_t> &&
!is_same_v<remove_cv_t<_Tp>, unexpect_t> &&
- !__unexpected::__is_unexpected<remove_cv_t<_Tp>>::value &&
- __unexpected::__valid_unexpected<_Err>::value
+ !__is_std_unexpected<remove_cv_t<_Tp>>::value &&
+ __valid_std_unexpected<_Err>::value
,
"[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
"reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
@@ -198,7 +198,7 @@
template <class _Up = _Tp>
requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
- !__unexpected::__is_unexpected<remove_cvref_t<_Up>>::value && is_constructible_v<_Tp, _Up>)
+ !__is_std_unexpected<remove_cvref_t<_Up>>::value && is_constructible_v<_Tp, _Up>)
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
expected(_Up&& __u)
noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
@@ -292,7 +292,7 @@
"be reverted to the previous state in case an exception is thrown during the assignment.");
_T2 __tmp(std::move(__oldval));
std::destroy_at(std::addressof(__oldval));
- __transaction __trans([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); });
+ __exception_guard __trans([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); });
std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
__trans.__complete();
}
@@ -357,7 +357,7 @@
template <class _Up = _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
requires(!is_same_v<expected, remove_cvref_t<_Up>> &&
- !__unexpected::__is_unexpected<remove_cvref_t<_Up>>::value &&
+ !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
is_constructible_v<_Tp, _Up> &&
is_assignable_v<_Tp&, _Up> &&
(is_nothrow_constructible_v<_Tp, _Up> ||
@@ -451,7 +451,7 @@
if constexpr (is_nothrow_move_constructible_v<_Err>) {
_Err __tmp(std::move(__with_err.__union_.__unex_));
std::destroy_at(std::addressof(__with_err.__union_.__unex_));
- __transaction __trans([&] {
+ __exception_guard __trans([&] {
std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp));
});
std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_));
@@ -464,7 +464,9 @@
"that it can be reverted to the previous state in case an exception is thrown during swap.");
_Tp __tmp(std::move(__with_val.__union_.__val_));
std::destroy_at(std::addressof(__with_val.__union_.__val_));
- __transaction __trans([&] { std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp)); });
+ __exception_guard __trans([&] {
+ std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp));
+ });
std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
__trans.__complete();
std::destroy_at(std::addressof(__with_err.__union_.__unex_));
@@ -646,7 +648,7 @@
template <class _Tp, class _Err>
requires is_void_v<_Tp>
class expected<_Tp, _Err> {
- static_assert(__unexpected::__valid_unexpected<_Err>::value,
+ static_assert(__valid_std_unexpected<_Err>::value,
"[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
"valid argument for unexpected<E> is ill-formed");
diff --git a/third_party/llvm-project/libcxx/include/__expected/unexpected.h b/third_party/llvm-project/libcxx/include/__expected/unexpected.h
index 22c307d..075963a 100644
--- a/third_party/llvm-project/libcxx/include/__expected/unexpected.h
+++ b/third_party/llvm-project/libcxx/include/__expected/unexpected.h
@@ -38,28 +38,24 @@
template <class _Err>
class unexpected;
-namespace __unexpected {
-
template <class _Tp>
-struct __is_unexpected : false_type {};
+struct __is_std_unexpected : false_type {};
template <class _Err>
-struct __is_unexpected<unexpected<_Err>> : true_type {};
+struct __is_std_unexpected<unexpected<_Err>> : true_type {};
template <class _Tp>
-using __valid_unexpected = _BoolConstant< //
- is_object_v<_Tp> && //
- !is_array_v<_Tp> && //
- !__is_unexpected<_Tp>::value && //
- !is_const_v<_Tp> && //
- !is_volatile_v<_Tp> //
+using __valid_std_unexpected = _BoolConstant< //
+ is_object_v<_Tp> && //
+ !is_array_v<_Tp> && //
+ !__is_std_unexpected<_Tp>::value && //
+ !is_const_v<_Tp> && //
+ !is_volatile_v<_Tp> //
>;
-} // namespace __unexpected
-
template <class _Err>
class unexpected {
- static_assert(__unexpected::__valid_unexpected<_Err>::value,
+ static_assert(__valid_std_unexpected<_Err>::value,
"[expected.un.general] states a program that instantiates std::unexpected for a non-object type, an "
"array type, a specialization of unexpected, or a cv-qualified type is ill-formed.");
diff --git a/third_party/llvm-project/libcxx/include/__external_threading b/third_party/llvm-project/libcxx/include/__external_threading
index 75f107b..af119e9 100644
--- a/third_party/llvm-project/libcxx/include/__external_threading
+++ b/third_party/llvm-project/libcxx/include/__external_threading
@@ -9,7 +9,6 @@
#include "starboard/mutex.h"
#include "starboard/once.h"
#include "starboard/thread.h"
-#include "starboard/time.h"
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
@@ -202,7 +201,7 @@
timespec* __ts) {
// Convert the duration provided by __ts to a Starboard time. The conversion
// is from seconds (10^1) and nanoseconds (10^-9) to microseconds (10^-6).
- const SbTime duration = __ts->tv_sec * 1000000 + __ts->tv_nsec / 1000;
+ const int64_t duration = __ts->tv_sec * 1000000 + __ts->tv_nsec / 1000;
return SbConditionVariableWaitTimed(__cv, __m, duration);
}
@@ -265,7 +264,7 @@
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) {
// Convert nanoseconds (10^-9) to microseconds (10^-6).
- const SbTime duration = __ns.count() / 1000;
+ const int64_t duration = __ns.count() / 1000;
SbThreadSleep(duration);
}
diff --git a/third_party/llvm-project/libcxx/include/__format/buffer.h b/third_party/llvm-project/libcxx/include/__format/buffer.h
index 60c1f80..ddfe767 100644
--- a/third_party/llvm-project/libcxx/include/__format/buffer.h
+++ b/third_party/llvm-project/libcxx/include/__format/buffer.h
@@ -31,6 +31,7 @@
#include <cstddef>
#include <string_view>
#include <type_traits>
+#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -493,6 +494,74 @@
return {_VSTD::move(this->__writer_).__out_it(), this->__size_};
}
};
+
+// A dynamically growing buffer intended to be used for retargeting a context.
+//
+// P2286 Formatting ranges adds range formatting support. It allows the user to
+// specify the minimum width for the entire formatted range. The width of the
+// range is not known until the range is formatted. Formatting is done to an
+// output_iterator so there's no guarantee it would be possible to add the fill
+// to the front of the output. Instead the range is formatted to a temporary
+// buffer and that buffer is formatted as a string.
+//
+// There is an issue with that approach, the format context used in
+// std::formatter<T>::format contains the output iterator used as part of its
+// type. So using this output iterator means there needs to be a new format
+// context and the format arguments need to be retargeted to the new context.
+// This retargeting is done by a basic_format_context specialized for the
+// __iterator of this container.
+template <__fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
+public:
+ using value_type = _CharT;
+
+ struct __iterator {
+ using difference_type = ptrdiff_t;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer)
+ : __buffer_(std::addressof(__buffer)) {}
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(const _CharT& __c) {
+ __buffer_->push_back(__c);
+ return *this;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(_CharT&& __c) {
+ __buffer_->push_back(__c);
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator*() { return *this; }
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { return *this; }
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { return *this; }
+ __retarget_buffer* __buffer_;
+ };
+
+ _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { __buffer_.reserve(__size_hint); }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; }
+
+ _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { __buffer_.push_back(__c); }
+
+ template <__fmt_char_type _InCharT>
+ _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) {
+ __buffer_.insert(__buffer_.end(), __str.begin(), __str.end());
+ }
+
+ template <__fmt_char_type _InCharT, class _UnaryOperation>
+ _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) {
+ _LIBCPP_ASSERT(__first <= __last, "not a valid range");
+ std::transform(__first, __last, std::back_inserter(__buffer_), std::move(__operation));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __buffer_.insert(__buffer_.end(), __n, __value); }
+
+ _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__buffer_.data(), __buffer_.size()}; }
+
+private:
+ // Use vector instead of string to avoid adding zeros after every append
+ // operation. The buffer is exposed as a string_view and not as a c-string.
+ vector<_CharT> __buffer_;
+};
+
} // namespace __format
#endif //_LIBCPP_STD_VER > 17
diff --git a/third_party/llvm-project/libcxx/include/__format/container_adaptor.h b/third_party/llvm-project/libcxx/include/__format/container_adaptor.h
new file mode 100644
index 0000000..62b6981
--- /dev/null
+++ b/third_party/llvm-project/libcxx/include/__format/container_adaptor.h
@@ -0,0 +1,70 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___FORMAT_CONTAINER_ADAPTOR_H
+#define _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__availability>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/formatter.h>
+#include <__format/range_default_formatter.h>
+#include <queue>
+#include <stack>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+// [container.adaptors.format] only specifies the library should provide the
+// formatter specializations, not which header should provide them.
+// Since <format> includes a lot of headers, add these headers here instead of
+// adding more dependencies like, locale, optinal, string, tuple, etc. to the
+// adaptor headers. To use the format functions users already include <format>.
+
+template <class _Adaptor, class _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor {
+private:
+ using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>;
+ formatter<typename _Adaptor::container_type, _CharT> __underlying_;
+
+public:
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ format(__maybe_const_adaptor& __adaptor, _FormatContext& __ctx) const {
+ return __underlying_.format(__adaptor.__get_container(), __ctx);
+ }
+};
+
+template <class _CharT, class _Tp, formattable<_CharT> _Container>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<queue<_Tp, _Container>, _CharT>
+ : public __formatter_container_adaptor<queue<_Tp, _Container>, _CharT> {};
+
+template <class _CharT, class _Tp, class _Container, class _Compare>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
+ : public __formatter_container_adaptor<priority_queue<_Tp, _Container, _Compare>, _CharT> {};
+
+template <class _CharT, class _Tp, formattable<_CharT> _Container>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<stack<_Tp, _Container>, _CharT>
+ : public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {};
+
+#endif //_LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
diff --git a/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h b/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h
index 0e00670..1ffcfeb 100644
--- a/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h
+++ b/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h
@@ -111,7 +111,7 @@
/// - https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
///
/// The data has 3 values
-/// - bits [0, 3] The property. One of the values generated form the datafiles
+/// - bits [0, 3] The property. One of the values generated from the datafiles
/// of \ref __property
/// - bits [4, 10] The size of the range.
/// - bits [11, 31] The lower bound code point of the range. The upper bound of
diff --git a/third_party/llvm-project/libcxx/include/__format/format_context.h b/third_party/llvm-project/libcxx/include/__format/format_context.h
index 882a604..85e00eb 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_context.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_context.h
@@ -11,13 +11,19 @@
#define _LIBCPP___FORMAT_FORMAT_CONTEXT_H
#include <__availability>
+#include <__concepts/same_as.h>
#include <__config>
#include <__format/buffer.h>
+#include <__format/format_arg.h>
+#include <__format/format_arg_store.h>
#include <__format/format_args.h>
+#include <__format/format_error.h>
#include <__format/format_fwd.h>
#include <__iterator/back_insert_iterator.h>
#include <__iterator/concepts.h>
+#include <__memory/addressof.h>
#include <__utility/move.h>
+#include <__variant/monostate.h>
#include <cstddef>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
@@ -138,8 +144,78 @@
: __out_it_(_VSTD::move(__out_it)), __args_(__args) {}
#endif
};
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
+// A specialization for __retarget_buffer
+//
+// See __retarget_buffer for the motivation for this specialization.
+//
+// This context holds a reference to the instance of the basic_format_context
+// that is retargeted. It converts a formatting argument when it is requested
+// during formatting. It is expected that the usage of the arguments is rare so
+// the lookups are not expected to be used often. An alternative would be to
+// convert all elements during construction.
+//
+// The elements of the retargets context are only used when an underlying
+// formatter uses a locale specific formatting or an formatting argument is
+// part for the format spec. For example
+// format("{:256:{}}", input, 8);
+// Here the width of an element in input is determined dynamically.
+// Note when the top-level element has no width the retargeting is not needed.
+template <class _CharT>
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
+ basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> {
+public:
+ using iterator = typename __format::__retarget_buffer<_CharT>::__iterator;
+ using char_type = _CharT;
+ template <class _Tp>
+ using formatter_type = formatter<_Tp, _CharT>;
+
+ template <class _Context>
+ _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(iterator __out_it, _Context& __ctx)
+ : __out_it_(std::move(__out_it)),
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ __loc_([](void* __c) { return static_cast<_Context*>(__c)->locale(); }),
+# endif
+ __ctx_(std::addressof(__ctx)),
+ __arg_([](void* __c, size_t __id) {
+ return std::visit_format_arg(
+ [&](auto __arg) -> basic_format_arg<basic_format_context> {
+ if constexpr (same_as<decltype(__arg), monostate>)
+ return {};
+ else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Context>::handle>)
+ // At the moment it's not possible for formatting to use a re-targeted handle.
+ // TODO FMT add this when support is needed.
+ std::__throw_format_error("Re-targeting handle not supported");
+ else
+ return basic_format_arg<basic_format_context>{
+ __format::__determine_arg_t<basic_format_context, decltype(__arg)>(),
+ __basic_format_arg_value<basic_format_context>(__arg)};
+ },
+ static_cast<_Context*>(__c)->arg(__id));
+ }) {
+ }
+
+ _LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
+ return __arg_(__ctx_, __id);
+ }
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { return __loc_(__ctx_); }
+# endif
+ _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); }
+ _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); }
+
+private:
+ iterator __out_it_;
+
+# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+ std::locale (*__loc_)(void* __ctx);
+# endif
+
+ void* __ctx_;
+ basic_format_arg<basic_format_context> (*__arg_)(void* __ctx, size_t __id);
+};
+
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
#endif //_LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_output.h b/third_party/llvm-project/libcxx/include/__format/formatter_output.h
index 70eae15..4676925 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_output.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_output.h
@@ -102,6 +102,10 @@
if constexpr (_VSTD::same_as<decltype(__out_it), _VSTD::back_insert_iterator<__format::__output_buffer<_OutCharT>>>) {
__out_it.__get_container()->__copy(__str);
return __out_it;
+ } else if constexpr (_VSTD::same_as<decltype(__out_it),
+ typename __format::__retarget_buffer<_OutCharT>::__iterator>) {
+ __out_it.__buffer_->__copy(__str);
+ return __out_it;
} else {
return std::ranges::copy(__str, _VSTD::move(__out_it)).out;
}
@@ -132,6 +136,10 @@
if constexpr (_VSTD::same_as<decltype(__out_it), _VSTD::back_insert_iterator<__format::__output_buffer<_OutCharT>>>) {
__out_it.__get_container()->__transform(__first, __last, _VSTD::move(__operation));
return __out_it;
+ } else if constexpr (_VSTD::same_as<decltype(__out_it),
+ typename __format::__retarget_buffer<_OutCharT>::__iterator>) {
+ __out_it.__buffer_->__transform(__first, __last, _VSTD::move(__operation));
+ return __out_it;
} else {
return std::ranges::transform(__first, __last, _VSTD::move(__out_it), __operation).out;
}
@@ -145,6 +153,9 @@
if constexpr (_VSTD::same_as<decltype(__out_it), _VSTD::back_insert_iterator<__format::__output_buffer<_CharT>>>) {
__out_it.__get_container()->__fill(__n, __value);
return __out_it;
+ } else if constexpr (_VSTD::same_as<decltype(__out_it), typename __format::__retarget_buffer<_CharT>::__iterator>) {
+ __out_it.__buffer_->__fill(__n, __value);
+ return __out_it;
} else {
return std::ranges::fill_n(_VSTD::move(__out_it), __n, __value);
}
diff --git a/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h b/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h
index 36f6505..c03cec9 100644
--- a/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h
+++ b/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h
@@ -139,6 +139,7 @@
# if _LIBCPP_STD_VER > 20
inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true};
+inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true};
# endif
enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
diff --git a/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h b/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h
index 56558f3..774887b 100644
--- a/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h
+++ b/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h
@@ -15,13 +15,16 @@
#endif
#include <__availability>
+#include <__chrono/statically_widen.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__format/concepts.h>
#include <__format/formatter.h>
+#include <__format/range_formatter.h>
#include <__ranges/concepts.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/pair.h>
+#include <string_view>
#include <tuple>
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -104,17 +107,80 @@
template <ranges::input_range _Rp, class _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::sequence, _Rp, _CharT> {
- __range_default_formatter() = delete; // TODO FMT Implement
+private:
+ using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>;
+ range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+ __underlying_.set_separator(__separator);
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr void
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ __underlying_.set_brackets(__opening_bracket, __closing_bracket);
+ }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const {
+ return __underlying_.format(__range, __ctx);
+ }
};
template <ranges::input_range _Rp, class _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::map, _Rp, _CharT> {
- __range_default_formatter() = delete; // TODO FMT Implement
+private:
+ using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>;
+ using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>;
+ range_formatter<__element_type, _CharT> __underlying_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter()
+ requires(__fmt_pair_like<__element_type>)
+ {
+ __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
+ __underlying_.underlying().set_brackets({}, {});
+ __underlying_.underlying().set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
+ }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ format(__maybe_const_map& __range, _FormatContext& __ctx) const {
+ return __underlying_.format(__range, __ctx);
+ }
};
template <ranges::input_range _Rp, class _CharT>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::set, _Rp, _CharT> {
- __range_default_formatter() = delete; // TODO FMT Implement
+private:
+ using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>;
+ using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>;
+ range_formatter<__element_type, _CharT> __underlying_;
+
+public:
+ _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter() {
+ __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
+ }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ format(__maybe_const_set& __range, _FormatContext& __ctx) const {
+ return __underlying_.format(__range, __ctx);
+ }
};
template <range_format _Kp, ranges::input_range _Rp, class _CharT>
@@ -123,8 +189,6 @@
__range_default_formatter() = delete; // TODO FMT Implement
};
-// Dispatcher to select the specialization based on the type of the range.
-
template <ranges::input_range _Rp, class _CharT>
requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>)
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT>
diff --git a/third_party/llvm-project/libcxx/include/__format/range_formatter.h b/third_party/llvm-project/libcxx/include/__format/range_formatter.h
new file mode 100644
index 0000000..9ea61a7
--- /dev/null
+++ b/third_party/llvm-project/libcxx/include/__format/range_formatter.h
@@ -0,0 +1,255 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___FORMAT_RANGE_FORMATTER_H
+#define _LIBCPP___FORMAT_RANGE_FORMATTER_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__algorithm/ranges_copy.h>
+#include <__availability>
+#include <__chrono/statically_widen.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__format/buffer.h>
+#include <__format/concepts.h>
+#include <__format/format_args.h>
+#include <__format/format_context.h>
+#include <__format/format_error.h>
+#include <__format/formatter.h>
+#include <__format/formatter_output.h>
+#include <__format/parser_std_format_spec.h>
+#include <__iterator/back_insert_iterator.h>
+#include <__ranges/concepts.h>
+#include <__ranges/data.h>
+#include <__ranges/size.h>
+#include <__type_traits/remove_cvref.h>
+#include <string_view>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+template <class _Tp, class _CharT = char>
+ requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+ __separator_ = __separator;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr void
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ __opening_bracket_ = __opening_bracket;
+ __closing_bracket_ = __closing_bracket;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; }
+
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
+ const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range);
+ const _CharT* __end = __parse_ctx.end();
+ if (__begin == __end)
+ return __begin;
+
+ // The n field overrides a possible m type, therefore delay applying the
+ // effect of n until the type has been procesed.
+ bool __clear_brackets = (*__begin == _CharT('n'));
+ if (__clear_brackets) {
+ ++__begin;
+ if (__begin == __end) {
+ // Since there is no more data, clear the brackets before returning.
+ set_brackets({}, {});
+ return __begin;
+ }
+ }
+
+ __parse_type(__begin, __end);
+ if (__clear_brackets)
+ set_brackets({}, {});
+ if (__begin == __end)
+ return __begin;
+
+ bool __has_range_underlying_spec = *__begin == _CharT(':');
+ if (__parser_.__type_ != __format_spec::__type::__default) {
+ // [format.range.formatter]/6
+ // If the range-type is s or ?s, then there shall be no n option and no
+ // range-underlying-spec.
+ if (__clear_brackets) {
+ if (__parser_.__type_ == __format_spec::__type::__string)
+ std::__throw_format_error("The n option and type s can't be used together");
+ std::__throw_format_error("The n option and type ?s can't be used together");
+ }
+ if (__has_range_underlying_spec) {
+ if (__parser_.__type_ == __format_spec::__type::__string)
+ std::__throw_format_error("Type s and an underlying format specification can't be used together");
+ std::__throw_format_error("Type ?s and an underlying format specification can't be used together");
+ }
+ } else if (!__has_range_underlying_spec)
+ std::__set_debug_format(__underlying_);
+
+ if (__has_range_underlying_spec) {
+ // range-underlying-spec:
+ // : format-spec
+ ++__begin;
+ if (__begin == __end)
+ return __begin;
+
+ __parse_ctx.advance_to(__begin);
+ __begin = __underlying_.parse(__parse_ctx);
+ }
+
+ if (__begin != __end && *__begin != _CharT('}'))
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+
+ return __begin;
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ requires formattable<ranges::range_reference_t<_Rp>, _CharT> &&
+ same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Tp>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Rp&& __range, _FormatContext& __ctx) const {
+ __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
+
+ if (!__specs.__has_width())
+ return __format_range(__range, __ctx, __specs);
+
+ // The size of the buffer needed is:
+ // - open bracket characters
+ // - close bracket character
+ // - n elements where every element may have a different size
+ // - (n -1) separators
+ // The size of the element is hard to predict, knowing the type helps but
+ // it depends on the format-spec. As an initial estimate we guess 6
+ // characters.
+ // Typically both brackets are 1 character and the separator is 2
+ // characters. Which means there will be
+ // (n - 1) * 2 + 1 + 1 = n * 2 character
+ // So estimate 8 times the range size as buffer.
+ std::size_t __capacity_hint = 0;
+ if constexpr (std::ranges::sized_range<_Rp>)
+ __capacity_hint = 8 * ranges::size(__range);
+ __format::__retarget_buffer<_CharT> __buffer{__capacity_hint};
+ basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> __c{
+ __buffer.__make_output_iterator(), __ctx};
+
+ __format_range(__range, __c, __specs);
+
+ return __formatter::__write_string_no_precision(__buffer.__view(), __ctx.out(), __specs);
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI
+ __format_range(_Rp&& __range, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) const {
+ if constexpr (same_as<_Tp, _CharT>) {
+ switch (__specs.__std_.__type_) {
+ case __format_spec::__type::__string:
+ case __format_spec::__type::__debug:
+ return __format_as_string(__range, __ctx, __specs.__std_.__type_ == __format_spec::__type::__debug);
+ default:
+ return __format_as_sequence(__range, __ctx);
+ }
+ } else
+ return __format_as_sequence(__range, __ctx);
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ __format_as_string(_Rp&& __range, _FormatContext& __ctx, bool __debug_format) const {
+ // When the range is contiguous use a basic_string_view instead to avoid a
+ // copy of the underlying data. The basic_string_view formatter
+ // specialization is the "basic" string formatter in libc++.
+ if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>) {
+ std::formatter<basic_string_view<_CharT>, _CharT> __formatter;
+ if (__debug_format)
+ __formatter.set_debug_format();
+ return __formatter.format(
+ basic_string_view<_CharT>{
+ ranges::data(__range),
+ ranges::size(__range),
+ },
+ __ctx);
+ } else {
+ std::formatter<basic_string<_CharT>, _CharT> __formatter;
+ if (__debug_format)
+ __formatter.set_debug_format();
+ // P2106's from_range has not been implemented yet. Instead use a simple
+ // copy operation.
+ // TODO FMT use basic_string's "from_range" constructor.
+ // return std::formatter<basic_string<_CharT>, _CharT>{}.format(basic_string<_CharT>{from_range, __range}, __ctx);
+ basic_string<_CharT> __str;
+ ranges::copy(__range, back_insert_iterator{__str});
+ return __formatter.format(__str, __ctx);
+ }
+ }
+
+ template <ranges::input_range _Rp, class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ __format_as_sequence(_Rp&& __range, _FormatContext& __ctx) const {
+ __ctx.advance_to(ranges::copy(__opening_bracket_, __ctx.out()).out);
+ bool __use_separator = false;
+ for (auto&& __e : __range) {
+ if (__use_separator)
+ __ctx.advance_to(ranges::copy(__separator_, __ctx.out()).out);
+ else
+ __use_separator = true;
+
+ __ctx.advance_to(__underlying_.format(__e, __ctx));
+ }
+
+ return ranges::copy(__closing_bracket_, __ctx.out()).out;
+ }
+
+ __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left};
+
+private:
+ _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) {
+ switch (*__begin) {
+ case _CharT('m'):
+ if constexpr (__fmt_pair_like<_Tp>) {
+ set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
+ set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", "));
+ ++__begin;
+ } else
+ std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple");
+ break;
+
+ case _CharT('s'):
+ if constexpr (same_as<_Tp, _CharT>) {
+ __parser_.__type_ = __format_spec::__type::__string;
+ ++__begin;
+ } else
+ std::__throw_format_error("The range-format-spec type s requires formatting a character type");
+ break;
+
+ case _CharT('?'):
+ ++__begin;
+ if (__begin == __end || *__begin != _CharT('s'))
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+ if constexpr (same_as<_Tp, _CharT>) {
+ __parser_.__type_ = __format_spec::__type::__debug;
+ ++__begin;
+ } else
+ std::__throw_format_error("The range-format-spec type ?s requires formatting a character type");
+ }
+ }
+
+ formatter<_Tp, _CharT> __underlying_;
+ basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", ");
+ basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "[");
+ basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]");
+};
+
+#endif //_LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_RANGE_FORMATTER_H
diff --git a/third_party/llvm-project/libcxx/include/__functional/function.h b/third_party/llvm-project/libcxx/include/__functional/function.h
index 8f34d01..ca79d33 100644
--- a/third_party/llvm-project/libcxx/include/__functional/function.h
+++ b/third_party/llvm-project/libcxx/include/__functional/function.h
@@ -382,7 +382,9 @@
template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<3 * sizeof(void*)>::type __buf_;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
typedef __base<_Rp(_ArgTypes...)> __func;
__func* __f_;
@@ -515,7 +517,9 @@
return;
if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_)
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
__func* __t = __as_base(&__tempbuf);
__f_->__clone(__t);
__f_->destroy();
diff --git a/third_party/llvm-project/libcxx/include/__iterator/iterator_with_data.h b/third_party/llvm-project/libcxx/include/__iterator/iterator_with_data.h
new file mode 100644
index 0000000..06c2fa6
--- /dev/null
+++ b/third_party/llvm-project/libcxx/include/__iterator/iterator_with_data.h
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___ITERATOR_ITERATOR_WITH_DATA_H
+#define _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H
+
+#include <__compare/compare_three_way_result.h>
+#include <__compare/three_way_comparable.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/readable_traits.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <forward_iterator _Iterator, class _Data>
+class __iterator_with_data {
+ _Iterator __iter_{};
+ _Data __data_{};
+
+public:
+ using value_type = iter_value_t<_Iterator>;
+ using difference_type = iter_difference_t<_Iterator>;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator_with_data() = default;
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data(_Iterator __iter, _Data __data)
+ : __iter_(std::move(__iter)), __data_(std::move(__data)) {}
+
+ constexpr _LIBCPP_HIDE_FROM_ABI _Iterator __get_iter() const { return __iter_; }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI _Data __get_data() && { return std::move(__data_); }
+
+ friend constexpr _LIBCPP_HIDE_FROM_ABI bool
+ operator==(const __iterator_with_data& __lhs, const __iterator_with_data& __rhs) {
+ return __lhs.__iter_ == __rhs.__iter_;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator++() {
+ ++__iter_;
+ return *this;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator++(int) {
+ auto __tmp = *this;
+ __iter_++;
+ return __tmp;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data& operator--()
+ requires bidirectional_iterator<_Iterator>
+ {
+ --__iter_;
+ return *this;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI __iterator_with_data operator--(int)
+ requires bidirectional_iterator<_Iterator>
+ {
+ auto __tmp = *this;
+ --__iter_;
+ return __tmp;
+ }
+
+ constexpr _LIBCPP_HIDE_FROM_ABI iter_reference_t<_Iterator> operator*() const { return *__iter_; }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iterator>
+ iter_move(const __iterator_with_data& __iter) noexcept(noexcept(ranges::iter_move(__iter.__iter_))) {
+ return ranges::iter_move(__iter.__iter_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr void
+ iter_swap(const __iterator_with_data& __lhs,
+ const __iterator_with_data& __rhs) noexcept(noexcept(ranges::iter_swap(__lhs.__iter_, __rhs.__iter_)))
+ requires indirectly_swappable<_Iterator>
+ {
+ return ranges::iter_swap(__lhs.__data_, __rhs.__iter_);
+ }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H
diff --git a/third_party/llvm-project/libcxx/include/__iterator/move_sentinel.h b/third_party/llvm-project/libcxx/include/__iterator/move_sentinel.h
index 5adf877..0d7336a 100644
--- a/third_party/llvm-project/libcxx/include/__iterator/move_sentinel.h
+++ b/third_party/llvm-project/libcxx/include/__iterator/move_sentinel.h
@@ -50,6 +50,8 @@
_Sent __last_ = _Sent();
};
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel);
+
#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__iterator/reverse_iterator.h b/third_party/llvm-project/libcxx/include/__iterator/reverse_iterator.h
index 942235a..f272e03 100644
--- a/third_party/llvm-project/libcxx/include/__iterator/reverse_iterator.h
+++ b/third_party/llvm-project/libcxx/include/__iterator/reverse_iterator.h
@@ -25,6 +25,7 @@
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/readable_traits.h>
+#include <__iterator/segmented_iterator.h>
#include <__memory/addressof.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
diff --git a/third_party/llvm-project/libcxx/include/__iterator/segmented_iterator.h b/third_party/llvm-project/libcxx/include/__iterator/segmented_iterator.h
new file mode 100644
index 0000000..f3cd1e5
--- /dev/null
+++ b/third_party/llvm-project/libcxx/include/__iterator/segmented_iterator.h
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___SEGMENTED_ITERATOR_H
+#define _LIBCPP___SEGMENTED_ITERATOR_H
+
+// Segmented iterators are iterators over (not necessarily contiguous) sub-ranges.
+//
+// For example, std::deque stores its data into multiple blocks of contiguous memory,
+// which are not stored contiguously themselves. The concept of segmented iterators
+// allows algorithms to operate over these multi-level iterators natively, opening the
+// door to various optimizations. See http://lafstern.org/matt/segmented.pdf for details.
+//
+// If __segmented_iterator_traits can be instantiated, the following functions and associated types must be provided:
+// - Traits::__local_iterator
+// The type of iterators used to iterate inside a segment.
+//
+// - Traits::__segment_iterator
+// The type of iterators used to iterate over segments.
+// Segment iterators can be forward iterators or bidirectional iterators, depending on the
+// underlying data structure.
+//
+// - static __segment_iterator Traits::__segment(It __it)
+// Returns an iterator to the segment that the provided iterator is in.
+//
+// - static __local_iterator Traits::__local(It __it)
+// Returns the local iterator pointing to the element that the provided iterator points to.
+//
+// - static __local_iterator Traits::__begin(__segment_iterator __it)
+// Returns the local iterator to the beginning of the segment that the provided iterator is pointing into.
+//
+// - static __local_iterator Traits::__end(__segment_iterator __it)
+// Returns the one-past-the-end local iterator to the segment that the provided iterator is pointing into.
+//
+// - static It Traits::__compose(__segment_iterator, __local_iterator)
+// Returns the iterator composed of the segment iterator and local iterator.
+
+#include <__config>
+#include <__type_traits/integral_constant.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Iterator>
+struct __segmented_iterator_traits;
+/* exposition-only:
+{
+ using __segment_iterator = ...;
+ using __local_iterator = ...;
+
+ static __segment_iterator __segment(_Iterator);
+ static __local_iterator __local(_Iterator);
+ static __local_iterator __begin(__segment_iterator);
+ static __local_iterator __end(__segment_iterator);
+ static _Iterator __compose(__segment_iterator, __local_iterator);
+};
+*/
+
+template <class _Tp, size_t = 0>
+struct __has_specialization : false_type {};
+
+template <class _Tp>
+struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {};
+
+template <class _Iterator>
+using __is_segmented_iterator = __has_specialization<__segmented_iterator_traits<_Iterator> >;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___SEGMENTED_ITERATOR_H
diff --git a/third_party/llvm-project/libcxx/include/__memory/allocate_at_least.h b/third_party/llvm-project/libcxx/include/__memory/allocate_at_least.h
index 7ce588a..ef205f8 100644
--- a/third_party/llvm-project/libcxx/include/__memory/allocate_at_least.h
+++ b/third_party/llvm-project/libcxx/include/__memory/allocate_at_least.h
@@ -25,6 +25,7 @@
_Pointer ptr;
size_t count;
};
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(allocation_result);
template <class _Alloc>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr
diff --git a/third_party/llvm-project/libcxx/include/__memory/shared_ptr.h b/third_party/llvm-project/libcxx/include/__memory/shared_ptr.h
index a76e262..b77ce92 100644
--- a/third_party/llvm-project/libcxx/include/__memory/shared_ptr.h
+++ b/third_party/llvm-project/libcxx/include/__memory/shared_ptr.h
@@ -260,6 +260,8 @@
__a.deallocate(_PTraits::pointer_to(*this), 1);
}
+struct __default_initialize_tag {};
+
template <class _Tp, class _Alloc>
struct __shared_ptr_emplace
: __shared_weak_count
@@ -278,6 +280,16 @@
#endif
}
+
+#if _LIBCPP_STD_VER >= 20
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __shared_ptr_emplace(__default_initialize_tag, _Alloc __a)
+ : __storage_(std::move(__a))
+ {
+ ::new ((void*)__get_elem()) _Tp;
+ }
+#endif
+
_LIBCPP_HIDE_FROM_ABI
_Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
@@ -945,6 +957,29 @@
return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
}
+#if _LIBCPP_STD_VER >= 20
+
+template<class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
+{
+ using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
+ using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
+ __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
+ ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__default_initialize_tag{}, __a);
+ auto __control_block = __guard.__release_ptr();
+ return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
+}
+
+template<class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared_for_overwrite()
+{
+ return std::allocate_shared_for_overwrite<_Tp>(allocator<_Tp>());
+}
+
+#endif // _LIBCPP_STD_VER >= 20
+
#if _LIBCPP_STD_VER > 14
template <size_t _Alignment>
@@ -975,6 +1010,17 @@
std::__uninitialized_allocator_value_construct_n(__alloc_, std::begin(__data_), __count_);
}
+#if _LIBCPP_STD_VER >= 20
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, __default_initialize_tag)
+ : __alloc_(__alloc), __count_(__count)
+ {
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
+ std::uninitialized_default_construct_n(std::begin(__data_), __count_);
+ }
+#endif
+
// Returns the number of bytes required to store a control block followed by the given number
// of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
_LIBCPP_HIDE_FROM_ABI
@@ -1058,6 +1104,15 @@
std::__uninitialized_allocator_value_construct_n(__alloc_, std::addressof(__data_[0]), _Count);
}
+#if _LIBCPP_STD_VER >= 20
+ _LIBCPP_HIDE_FROM_ABI
+ explicit __bounded_array_control_block(_Alloc const& __alloc, __default_initialize_tag) : __alloc_(__alloc) {
+ // We are purposefully not using an allocator-aware default construction because the spec says so.
+ // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
+ std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count);
+ }
+#endif
+
_LIBCPP_HIDE_FROM_ABI_VIRTUAL
~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
@@ -1101,6 +1156,7 @@
#if _LIBCPP_STD_VER > 17
+// bounded array variants
template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> allocate_shared(const _Alloc& __a)
@@ -1115,18 +1171,11 @@
return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
}
-template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+template<class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI
-shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n)
+shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
{
- return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
-}
-
-template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
-_LIBCPP_HIDE_FROM_ABI
-shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u)
-{
- return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
+ return std::__allocate_shared_bounded_array<_Tp>(__a, __default_initialize_tag{});
}
template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
@@ -1143,6 +1192,35 @@
return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
}
+template<class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared_for_overwrite()
+{
+ return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __default_initialize_tag{});
+}
+
+// unbounded array variants
+template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n)
+{
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
+}
+
+template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u)
+{
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
+}
+
+template<class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)
+{
+ return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __default_initialize_tag{});
+}
+
template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> make_shared(size_t __n)
@@ -1157,6 +1235,13 @@
return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
}
+template<class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI
+shared_ptr<_Tp> make_shared_for_overwrite(size_t __n)
+{
+ return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __default_initialize_tag{});
+}
+
#endif // _LIBCPP_STD_VER > 17
template<class _Tp, class _Up>
diff --git a/third_party/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h b/third_party/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h
index ed6cc4c..63a45b2 100644
--- a/third_party/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h
+++ b/third_party/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h
@@ -31,9 +31,9 @@
#include <__type_traits/negation.h>
#include <__type_traits/remove_const.h>
#include <__type_traits/remove_extent.h>
+#include <__utility/exception_guard.h>
#include <__utility/move.h>
#include <__utility/pair.h>
-#include <__utility/transaction.h>
#include <new>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -421,7 +421,10 @@
_Tp& __array = *__loc;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); });
+ __exception_guard __guard([&]() {
+ std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i);
+ });
+
for (; __i != extent_v<_Tp>; ++__i) {
std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]));
}
@@ -458,7 +461,9 @@
_Tp& __array = *__loc;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i); });
+ __exception_guard __guard([&]() {
+ std::__allocator_destroy_multidimensional(__elem_alloc, __array, __array + __i);
+ });
for (; __i != extent_v<_Tp>; ++__i) {
std::__allocator_construct_at(__elem_alloc, std::addressof(__array[__i]), __arg[__i]);
}
@@ -483,7 +488,7 @@
_BidirIter __begin = __it;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
+ __exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
for (; __n != 0; --__n, ++__it) {
std::__allocator_construct_at(__value_alloc, std::addressof(*__it), __value);
}
@@ -500,7 +505,7 @@
_BidirIter __begin = __it;
// If an exception is thrown, destroy what we have constructed so far in reverse order.
- __transaction __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
+ __exception_guard __guard([&]() { std::__allocator_destroy_multidimensional(__value_alloc, __begin, __it); });
for (; __n != 0; --__n, ++__it) {
std::__allocator_construct_at(__value_alloc, std::addressof(*__it));
}
@@ -541,21 +546,15 @@
template <class _Alloc, class _Iter1, class _Sent1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2
__uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
auto __destruct_first = __first2;
- try {
-#endif
+ auto __guard =
+ std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
while (__first1 != __last1) {
allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), *__first1);
++__first1;
++__first2;
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
- } catch (...) {
- _AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)();
- throw;
- }
-#endif
+ __guard.__complete();
return __first2;
}
@@ -597,10 +596,9 @@
_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) {
static_assert(__is_cpp17_move_insertable<_Alloc>::value,
"The specified type does not meet the requirements of Cpp17MoveInsertable");
-#ifndef _LIBCPP_NO_EXCEPTIONS
auto __destruct_first = __first2;
- try {
-#endif
+ auto __guard =
+ std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
while (__first1 != __last1) {
#ifndef _LIBCPP_NO_EXCEPTIONS
allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move_if_noexcept(*__first1));
@@ -610,12 +608,7 @@
++__first1;
++__first2;
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
- } catch (...) {
- _AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)();
- throw;
- }
-#endif
+ __guard.__complete();
return __first2;
}
diff --git a/third_party/llvm-project/libcxx/include/__memory/unique_ptr.h b/third_party/llvm-project/libcxx/include/__memory/unique_ptr.h
index bb5399d..9cdbda8 100644
--- a/third_party/llvm-project/libcxx/include/__memory/unique_ptr.h
+++ b/third_party/llvm-project/libcxx/include/__memory/unique_ptr.h
@@ -699,6 +699,25 @@
#endif // _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single
+make_unique_for_overwrite() {
+ return unique_ptr<_Tp>(new _Tp);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound
+make_unique_for_overwrite(size_t __n) {
+ return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]);
+}
+
+template<class _Tp, class... _Args>
+typename __unique_if<_Tp>::__unique_array_known_bound make_unique_for_overwrite(_Args&&...) = delete;
+
+#endif // _LIBCPP_STD_VER >= 20
+
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
template <class _Tp, class _Dp>
diff --git a/third_party/llvm-project/libcxx/include/__memory_resource/polymorphic_allocator.h b/third_party/llvm-project/libcxx/include/__memory_resource/polymorphic_allocator.h
index 8e59dfc..2489502 100644
--- a/third_party/llvm-project/libcxx/include/__memory_resource/polymorphic_allocator.h
+++ b/third_party/llvm-project/libcxx/include/__memory_resource/polymorphic_allocator.h
@@ -12,7 +12,7 @@
#include <__assert>
#include <__config>
#include <__memory_resource/memory_resource.h>
-#include <__utility/transaction.h>
+#include <__utility/exception_guard.h>
#include <cstddef>
#include <limits>
#include <new>
@@ -98,7 +98,7 @@
template <class _Type, class... _CtorArgs>
[[nodiscard]] _Type* new_object(_CtorArgs&&... __ctor_args) {
_Type* __ptr = allocate_object<_Type>();
- __transaction __guard([&] { deallocate_object(__ptr); });
+ __exception_guard __guard([&] { deallocate_object(__ptr); });
construct(__ptr, std::forward<_CtorArgs>(__ctor_args)...);
__guard.__complete();
return __ptr;
diff --git a/third_party/llvm-project/libcxx/include/__memory_resource/unsynchronized_pool_resource.h b/third_party/llvm-project/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
index 2ecddcf..91d38aa 100644
--- a/third_party/llvm-project/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
+++ b/third_party/llvm-project/libcxx/include/__memory_resource/unsynchronized_pool_resource.h
@@ -85,7 +85,7 @@
void do_deallocate(void* __p, size_t __bytes, size_t __align) override;
- _LIBCPP_HIDE_FROM_ABI bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
+ _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
return &__other == this;
}
diff --git a/third_party/llvm-project/libcxx/include/__numeric/gcd_lcm.h b/third_party/llvm-project/libcxx/include/__numeric/gcd_lcm.h
index b3d776b..5a3f81b 100644
--- a/third_party/llvm-project/libcxx/include/__numeric/gcd_lcm.h
+++ b/third_party/llvm-project/libcxx/include/__numeric/gcd_lcm.h
@@ -12,8 +12,12 @@
#include <__assert>
#include <__config>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_signed.h>
+#include <__type_traits/make_unsigned.h>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/third_party/llvm-project/libcxx/include/__numeric/midpoint.h b/third_party/llvm-project/libcxx/include/__numeric/midpoint.h
index ada6adf..bac3642 100644
--- a/third_party/llvm-project/libcxx/include/__numeric/midpoint.h
+++ b/third_party/llvm-project/libcxx/include/__numeric/midpoint.h
@@ -11,8 +11,18 @@
#define _LIBCPP___NUMERIC_MIDPOINT_H
#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_floating_point.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_null_pointer.h>
+#include <__type_traits/is_object.h>
+#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/is_void.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/remove_pointer.h>
+#include <cstddef>
#include <limits>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
diff --git a/third_party/llvm-project/libcxx/include/__ranges/as_rvalue_view.h b/third_party/llvm-project/libcxx/include/__ranges/as_rvalue_view.h
new file mode 100644
index 0000000..422d8a8
--- /dev/null
+++ b/third_party/llvm-project/libcxx/include/__ranges/as_rvalue_view.h
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___RANGES_AS_RVALUE_H
+#define _LIBCPP___RANGES_AS_RVALUE_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__iterator/move_iterator.h>
+#include <__iterator/move_sentinel.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+template <view _View>
+ requires input_range<_View>
+class as_rvalue_view : public view_interface<as_rvalue_view<_View>> {
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+
+public:
+ _LIBCPP_HIDE_FROM_ABI as_rvalue_view()
+ requires default_initializable<_View>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit as_rvalue_view(_View __base) : __base_(std::move(__base)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_View>)
+ {
+ return move_iterator(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _View>
+ {
+ return move_iterator(ranges::begin(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View>)
+ {
+ if constexpr (common_range<_View>) {
+ return move_iterator(ranges::end(__base_));
+ } else {
+ return move_sentinel(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _View>
+ {
+ if constexpr (common_range<const _View>) {
+ return move_iterator(ranges::end(__base_));
+ } else {
+ return move_sentinel(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_View>
+ {
+ return ranges::size(__base_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _View>
+ {
+ return ranges::size(__base_);
+ }
+};
+
+template <class _Range>
+as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
+
+template <class _View>
+inline constexpr bool enable_borrowed_range<as_rvalue_view<_View>> = enable_borrowed_range<_View>;
+
+namespace views {
+namespace __as_rvalue {
+struct __fn : __range_adaptor_closure<__fn> {
+ template <class _Range>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(/**/ as_rvalue_view(std::forward<_Range>(__range))))
+ -> decltype(/*--*/ as_rvalue_view(std::forward<_Range>(__range))) {
+ return /*-------------*/ as_rvalue_view(std::forward<_Range>(__range));
+ }
+
+ template <class _Range>
+ requires same_as<range_rvalue_reference_t<_Range>, range_reference_t<_Range>>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
+ noexcept(noexcept(/**/ views::all(std::forward<_Range>(__range))))
+ -> decltype(/*--*/ views::all(std::forward<_Range>(__range))) {
+ return /*-------------*/ views::all(std::forward<_Range>(__range));
+ }
+};
+} // namespace __as_rvalue
+
+inline namespace __cpo {
+constexpr auto as_rvalue = __as_rvalue::__fn{};
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+#endif // _LIBCPP___RANGES_AS_RVALUE_H
diff --git a/third_party/llvm-project/libcxx/include/__ranges/iota_view.h b/third_party/llvm-project/libcxx/include/__ranges/iota_view.h
index 8f9148a..3654096 100644
--- a/third_party/llvm-project/libcxx/include/__ranges/iota_view.h
+++ b/third_party/llvm-project/libcxx/include/__ranges/iota_view.h
@@ -83,6 +83,14 @@
{ __j - __j } -> convertible_to<_IotaDiffT<_Iter>>;
};
+ template <weakly_incrementable _Start>
+ requires copyable<_Start>
+ struct __iota_view_iterator;
+
+ template <weakly_incrementable _Start, semiregular _BoundSentinel>
+ requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
+ struct __iota_view_sentinel;
+
template<class>
struct __iota_iterator_category {};
@@ -94,211 +102,9 @@
template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
- struct __iterator : public __iota_iterator_category<_Start> {
- friend class iota_view;
- using iterator_concept =
- _If<__advanceable<_Start>, random_access_iterator_tag,
- _If<__decrementable<_Start>, bidirectional_iterator_tag,
- _If<incrementable<_Start>, forward_iterator_tag,
- /*Else*/ input_iterator_tag>>>;
-
- using value_type = _Start;
- using difference_type = _IotaDiffT<_Start>;
-
- _Start __value_ = _Start();
-
- _LIBCPP_HIDE_FROM_ABI
- __iterator() requires default_initializable<_Start> = default;
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
- return __value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator++() {
- ++__value_;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr void operator++(int) { ++*this; }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator++(int) requires incrementable<_Start> {
- auto __tmp = *this;
- ++*this;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator--() requires __decrementable<_Start> {
- --__value_;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator--(int) requires __decrementable<_Start> {
- auto __tmp = *this;
- --*this;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator+=(difference_type __n)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
- if (__n >= difference_type(0)) {
- __value_ += static_cast<_Start>(__n);
- } else {
- __value_ -= static_cast<_Start>(-__n);
- }
- } else {
- __value_ += __n;
- }
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator-=(difference_type __n)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
- if (__n >= difference_type(0)) {
- __value_ -= static_cast<_Start>(__n);
- } else {
- __value_ += static_cast<_Start>(-__n);
- }
- } else {
- __value_ -= __n;
- }
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- constexpr _Start operator[](difference_type __n) const
- requires __advanceable<_Start>
- {
- return _Start(__value_ + __n);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
- requires equality_comparable<_Start>
- {
- return __x.__value_ == __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return __x.__value_ < __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return __y < __x;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return !(__y < __x);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start>
- {
- return !(__x < __y);
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
- requires totally_ordered<_Start> && three_way_comparable<_Start>
- {
- return __x.__value_ <=> __y.__value_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator+(__iterator __i, difference_type __n)
- requires __advanceable<_Start>
- {
- __i += __n;
- return __i;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator+(difference_type __n, __iterator __i)
- requires __advanceable<_Start>
- {
- return __i + __n;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr __iterator operator-(__iterator __i, difference_type __n)
- requires __advanceable<_Start>
- {
- __i -= __n;
- return __i;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
- requires __advanceable<_Start>
- {
- if constexpr (__integer_like<_Start>) {
- if constexpr (__signed_integer_like<_Start>) {
- return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
- }
- if (__y.__value_ > __x.__value_) {
- return difference_type(-difference_type(__y.__value_ - __x.__value_));
- }
- return difference_type(__x.__value_ - __y.__value_);
- }
- return __x.__value_ - __y.__value_;
- }
- };
-
- struct __sentinel {
- friend class iota_view;
-
- private:
- _BoundSentinel __bound_sentinel_ = _BoundSentinel();
-
- public:
- _LIBCPP_HIDE_FROM_ABI
- __sentinel() = default;
- constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
- return __x.__value_ == __y.__bound_sentinel_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y)
- requires sized_sentinel_for<_BoundSentinel, _Start>
- {
- return __x.__value_ - __y.__bound_sentinel_;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y)
- requires sized_sentinel_for<_BoundSentinel, _Start>
- {
- return -(__y - __x);
- }
- };
+ using __iterator = __iota_view_iterator<_Start>;
+ using __sentinel = __iota_view_sentinel<_Start, _BoundSentinel>;
_Start __value_ = _Start();
_BoundSentinel __bound_sentinel_ = _BoundSentinel();
@@ -379,6 +185,224 @@
template <class _Start, class _BoundSentinel>
inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
+ template <weakly_incrementable _Start>
+ requires copyable<_Start>
+ struct __iota_view_iterator : public __iota_iterator_category<_Start> {
+
+ template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
+ requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
+ friend class iota_view;
+
+ using iterator_concept =
+ _If<__advanceable<_Start>, random_access_iterator_tag,
+ _If<__decrementable<_Start>, bidirectional_iterator_tag,
+ _If<incrementable<_Start>, forward_iterator_tag,
+ /*Else*/ input_iterator_tag>>>;
+
+ using value_type = _Start;
+ using difference_type = _IotaDiffT<_Start>;
+
+ _Start __value_ = _Start();
+
+ _LIBCPP_HIDE_FROM_ABI
+ __iota_view_iterator() requires default_initializable<_Start> = default;
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr explicit __iota_view_iterator(_Start __value) : __value_(std::move(__value)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
+ return __value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator++() {
+ ++__value_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr void operator++(int) { ++*this; }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator operator++(int) requires incrementable<_Start> {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator--() requires __decrementable<_Start> {
+ --__value_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator operator--(int) requires __decrementable<_Start> {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator+=(difference_type __n)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+ if (__n >= difference_type(0)) {
+ __value_ += static_cast<_Start>(__n);
+ } else {
+ __value_ -= static_cast<_Start>(-__n);
+ }
+ } else {
+ __value_ += __n;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr __iota_view_iterator& operator-=(difference_type __n)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
+ if (__n >= difference_type(0)) {
+ __value_ -= static_cast<_Start>(__n);
+ } else {
+ __value_ += static_cast<_Start>(-__n);
+ }
+ } else {
+ __value_ -= __n;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ constexpr _Start operator[](difference_type __n) const
+ requires __advanceable<_Start>
+ {
+ return _Start(__value_ + __n);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires equality_comparable<_Start>
+ {
+ return __x.__value_ == __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return __x.__value_ < __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator<=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator>=(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start>
+ {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr auto operator<=>(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires totally_ordered<_Start> && three_way_comparable<_Start>
+ {
+ return __x.__value_ <=> __y.__value_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iota_view_iterator operator+(__iota_view_iterator __i, difference_type __n)
+ requires __advanceable<_Start>
+ {
+ __i += __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iota_view_iterator operator+(difference_type __n, __iota_view_iterator __i)
+ requires __advanceable<_Start>
+ {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr __iota_view_iterator operator-(__iota_view_iterator __i, difference_type __n)
+ requires __advanceable<_Start>
+ {
+ __i -= __n;
+ return __i;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr difference_type operator-(const __iota_view_iterator& __x, const __iota_view_iterator& __y)
+ requires __advanceable<_Start>
+ {
+ if constexpr (__integer_like<_Start>) {
+ if constexpr (__signed_integer_like<_Start>) {
+ return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
+ }
+ if (__y.__value_ > __x.__value_) {
+ return difference_type(-difference_type(__y.__value_ - __x.__value_));
+ }
+ return difference_type(__x.__value_ - __y.__value_);
+ }
+ return __x.__value_ - __y.__value_;
+ }
+ };
+
+ template <weakly_incrementable _Start, semiregular _BoundSentinel>
+ requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
+ struct __iota_view_sentinel {
+
+ template <weakly_incrementable _StartT, semiregular _BoundSentinelT>
+ requires __weakly_equality_comparable_with<_StartT, _BoundSentinelT> && copyable<_StartT>
+ friend class iota_view;
+
+ using __iterator = __iota_view_iterator<_Start>;
+
+ private:
+ _BoundSentinel __bound_sentinel_ = _BoundSentinel();
+
+ public:
+ _LIBCPP_HIDE_FROM_ABI
+ __iota_view_sentinel() = default;
+ constexpr explicit __iota_view_sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {}
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr bool operator==(const __iterator& __x, const __iota_view_sentinel& __y) {
+ return __x.__value_ == __y.__bound_sentinel_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __iota_view_sentinel& __y)
+ requires sized_sentinel_for<_BoundSentinel, _Start>
+ {
+ return __x.__value_ - __y.__bound_sentinel_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ friend constexpr iter_difference_t<_Start> operator-(const __iota_view_sentinel& __x, const __iterator& __y)
+ requires sized_sentinel_for<_BoundSentinel, _Start>
+ {
+ return -(__y - __x);
+ }
+ };
+
namespace views {
namespace __iota {
struct __fn {
diff --git a/third_party/llvm-project/libcxx/include/__ranges/join_view.h b/third_party/llvm-project/libcxx/include/__ranges/join_view.h
index 293926c..869540f 100644
--- a/third_party/llvm-project/libcxx/include/__ranges/join_view.h
+++ b/third_party/llvm-project/libcxx/include/__ranges/join_view.h
@@ -20,9 +20,12 @@
#include <__iterator/iter_move.h>
#include <__iterator/iter_swap.h>
#include <__iterator/iterator_traits.h>
+#include <__iterator/iterator_with_data.h>
+#include <__iterator/segmented_iterator.h>
#include <__ranges/access.h>
#include <__ranges/all.h>
#include <__ranges/concepts.h>
+#include <__ranges/empty.h>
#include <__ranges/non_propagating_cache.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/view_interface.h>
@@ -63,6 +66,14 @@
>;
};
+ template <input_range _View, bool _Const>
+ requires view<_View> && input_range<range_reference_t<_View>>
+ struct __join_view_iterator;
+
+ template <input_range _View, bool _Const>
+ requires view<_View> && input_range<range_reference_t<_View>>
+ struct __join_view_sentinel;
+
template<input_range _View>
requires view<_View> && input_range<range_reference_t<_View>>
class join_view
@@ -70,8 +81,22 @@
private:
using _InnerRange = range_reference_t<_View>;
- template<bool> struct __iterator;
- template<bool> struct __sentinel;
+ template<bool _Const>
+ using __iterator = __join_view_iterator<_View, _Const>;
+
+ template<bool _Const>
+ using __sentinel = __join_view_sentinel<_View, _Const>;
+
+ template <input_range _View2, bool _Const2>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_iterator;
+
+ template <input_range _View2, bool _Const2>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_sentinel;
+
+ template <class>
+ friend struct std::__segmented_iterator_traits;
static constexpr bool _UseCache = !is_reference_v<_InnerRange>;
using _Cache = _If<_UseCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>;
@@ -139,49 +164,57 @@
}
};
- template<input_range _View>
+ template<input_range _View, bool _Const>
requires view<_View> && input_range<range_reference_t<_View>>
- template<bool _Const> struct join_view<_View>::__sentinel {
- template<bool> friend struct __sentinel;
+ struct __join_view_sentinel {
+ template<input_range _View2, bool>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_sentinel;
private:
- using _Parent = __maybe_const<_Const, join_view>;
+ using _Parent = __maybe_const<_Const, join_view<_View>>;
using _Base = __maybe_const<_Const, _View>;
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
public:
_LIBCPP_HIDE_FROM_ABI
- __sentinel() = default;
+ __join_view_sentinel() = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr explicit __sentinel(_Parent& __parent)
+ constexpr explicit __join_view_sentinel(_Parent& __parent)
: __end_(ranges::end(__parent.__base_)) {}
_LIBCPP_HIDE_FROM_ABI
- constexpr __sentinel(__sentinel<!_Const> __s)
+ constexpr __join_view_sentinel(__join_view_sentinel<_View, !_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)) {}
template<bool _OtherConst>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ friend constexpr bool operator==(const __join_view_iterator<_View, _OtherConst>& __x, const __join_view_sentinel& __y) {
return __x.__outer_ == __y.__end_;
}
};
- template<input_range _View>
+ template<input_range _View, bool _Const>
requires view<_View> && input_range<range_reference_t<_View>>
- template<bool _Const> struct join_view<_View>::__iterator
+ struct __join_view_iterator
: public __join_view_iterator_category<__maybe_const<_Const, _View>> {
- template<bool> friend struct __iterator;
+ template<input_range _View2, bool>
+ requires view<_View2> && input_range<range_reference_t<_View2>>
+ friend struct __join_view_iterator;
+
+ template <class>
+ friend struct std::__segmented_iterator_traits;
private:
- using _Parent = __maybe_const<_Const, join_view>;
+ using _Parent = __maybe_const<_Const, join_view<_View>>;
using _Base = __maybe_const<_Const, _View>;
using _Outer = iterator_t<_Base>;
using _Inner = iterator_t<range_reference_t<_Base>>;
+ using _InnerRange = range_reference_t<_View>;
static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>;
@@ -210,6 +243,9 @@
__inner_.reset();
}
+ _LIBCPP_HIDE_FROM_ABI constexpr __join_view_iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
+ : __outer_(std::move(__outer)), __inner_(std::move(__inner)), __parent_(__parent) {}
+
public:
using iterator_concept = _If<
__ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
@@ -228,17 +264,17 @@
range_difference_t<_Base>, range_difference_t<range_reference_t<_Base>>>;
_LIBCPP_HIDE_FROM_ABI
- __iterator() requires default_initializable<_Outer> = default;
+ __join_view_iterator() requires default_initializable<_Outer> = default;
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator(_Parent& __parent, _Outer __outer)
+ constexpr __join_view_iterator(_Parent& __parent, _Outer __outer)
: __outer_(std::move(__outer))
, __parent_(std::addressof(__parent)) {
__satisfy();
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator(__iterator<!_Const> __i)
+ constexpr __join_view_iterator(__join_view_iterator<_View, !_Const> __i)
requires _Const &&
convertible_to<iterator_t<_View>, _Outer> &&
convertible_to<iterator_t<_InnerRange>, _Inner>
@@ -259,7 +295,7 @@
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator++() {
+ constexpr __join_view_iterator& operator++() {
auto&& __inner = [&]() -> auto&& {
if constexpr (__ref_is_glvalue)
return *__outer_;
@@ -279,7 +315,7 @@
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator++(int)
+ constexpr __join_view_iterator operator++(int)
requires __ref_is_glvalue &&
forward_range<_Base> &&
forward_range<range_reference_t<_Base>>
@@ -290,7 +326,7 @@
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator& operator--()
+ constexpr __join_view_iterator& operator--()
requires __ref_is_glvalue &&
bidirectional_range<_Base> &&
bidirectional_range<range_reference_t<_Base>> &&
@@ -309,7 +345,7 @@
}
_LIBCPP_HIDE_FROM_ABI
- constexpr __iterator operator--(int)
+ constexpr __join_view_iterator operator--(int)
requires __ref_is_glvalue &&
bidirectional_range<_Base> &&
bidirectional_range<range_reference_t<_Base>> &&
@@ -321,7 +357,7 @@
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
+ friend constexpr bool operator==(const __join_view_iterator& __x, const __join_view_iterator& __y)
requires __ref_is_glvalue &&
equality_comparable<iterator_t<_Base>> &&
equality_comparable<iterator_t<range_reference_t<_Base>>>
@@ -330,14 +366,14 @@
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr decltype(auto) iter_move(const __iterator& __i)
+ friend constexpr decltype(auto) iter_move(const __join_view_iterator& __i)
noexcept(noexcept(ranges::iter_move(*__i.__inner_)))
{
return ranges::iter_move(*__i.__inner_);
}
_LIBCPP_HIDE_FROM_ABI
- friend constexpr void iter_swap(const __iterator& __x, const __iterator& __y)
+ friend constexpr void iter_swap(const __join_view_iterator& __x, const __join_view_iterator& __y)
noexcept(noexcept(ranges::iter_swap(*__x.__inner_, *__y.__inner_)))
requires indirectly_swappable<_Inner>
{
@@ -365,6 +401,50 @@
} // namespace views
} // namespace ranges
+template <class _View, bool _Const>
+ requires(ranges::common_range<typename ranges::__join_view_iterator<_View, _Const>::_Parent> &&
+ __is_cpp17_random_access_iterator<typename ranges::__join_view_iterator<_View, _Const>::_Outer>::value &&
+ __is_cpp17_random_access_iterator<typename ranges::__join_view_iterator<_View, _Const>::_Inner>::value)
+struct __segmented_iterator_traits<ranges::__join_view_iterator<_View, _Const>> {
+ using _JoinViewIterator = ranges::__join_view_iterator<_View, _Const>;
+
+ using __segment_iterator =
+ _LIBCPP_NODEBUG __iterator_with_data<typename _JoinViewIterator::_Outer, typename _JoinViewIterator::_Parent*>;
+ using __local_iterator = typename _JoinViewIterator::_Inner;
+
+ // TODO: Would it make sense to enable the optimization for other iterator types?
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_JoinViewIterator __iter) {
+ if (ranges::empty(__iter.__parent_->__base_))
+ return {};
+ if (!__iter.__inner_.has_value())
+ return __segment_iterator(--__iter.__outer_, __iter.__parent_);
+ return __segment_iterator(__iter.__outer_, __iter.__parent_);
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_JoinViewIterator __iter) {
+ if (ranges::empty(__iter.__parent_->__base_))
+ return {};
+ if (!__iter.__inner_.has_value())
+ return ranges::end(*--__iter.__outer_);
+ return *__iter.__inner_;
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) {
+ return ranges::begin(*__iter.__get_iter());
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
+ return ranges::end(*__iter.__get_iter());
+ }
+
+ static constexpr _LIBCPP_HIDE_FROM_ABI _JoinViewIterator
+ __compose(__segment_iterator __seg_iter, __local_iterator __local_iter) {
+ return _JoinViewIterator(
+ std::move(__seg_iter).__get_data(), std::move(__seg_iter).__get_iter(), std::move(__local_iter));
+ }
+};
+
#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__ranges/split_view.h b/third_party/llvm-project/libcxx/include/__ranges/split_view.h
new file mode 100644
index 0000000..9758ee9
--- /dev/null
+++ b/third_party/llvm-project/libcxx/include/__ranges/split_view.h
@@ -0,0 +1,232 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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___RANGES_SPLIT_VIEW_H
+#define _LIBCPP___RANGES_SPLIT_VIEW_H
+
+#include <__algorithm/ranges_search.h>
+#include <__concepts/constructible.h>
+#include <__config>
+#include <__functional/bind_back.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/empty.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/single_view.h>
+#include <__ranges/subrange.h>
+#include <__ranges/view_interface.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+namespace ranges {
+
+template <class _View, class _Pattern>
+struct __split_view_iterator;
+
+template <class _View, class _Pattern>
+struct __split_view_sentinel;
+
+template <forward_range _View, forward_range _Pattern>
+ requires view<_View> && view<_Pattern> &&
+ indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to>
+class split_view : public view_interface<split_view<_View, _Pattern>> {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern();
+ using _Cache = __non_propagating_cache<subrange<iterator_t<_View>>>;
+ _Cache __cached_begin_ = _Cache();
+
+ template <class, class>
+ friend struct __split_view_iterator;
+
+ template <class, class>
+ friend struct __split_view_sentinel;
+
+ using __iterator = __split_view_iterator<_View, _Pattern>;
+ using __sentinel = __split_view_sentinel<_View, _Pattern>;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr subrange<iterator_t<_View>> __find_next(iterator_t<_View> __it) {
+ auto [__begin, __end] = ranges::search(subrange(__it, ranges::end(__base_)), __pattern_);
+ if (__begin != ranges::end(__base_) && ranges::empty(__pattern_)) {
+ ++__begin;
+ ++__end;
+ }
+ return {__begin, __end};
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI split_view()
+ requires default_initializable<_View> && default_initializable<_Pattern>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr split_view(_View __base, _Pattern __pattern)
+ : __base_(std::move(__base)), __pattern_(std::move((__pattern))) {}
+
+ template <forward_range _Range>
+ requires constructible_from<_View, views::all_t<_Range>> &&
+ constructible_from<_Pattern, single_view<range_value_t<_Range>>>
+ _LIBCPP_HIDE_FROM_ABI constexpr split_view(_Range&& __range, range_value_t<_Range> __elem)
+ : __base_(views::all(std::forward<_Range>(__range))), __pattern_(views::single(std::move(__elem))) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
+ if (!__cached_begin_.__has_value()) {
+ __cached_begin_.__emplace(__find_next(ranges::begin(__base_)));
+ }
+ return {*this, ranges::begin(__base_), *__cached_begin_};
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() {
+ if constexpr (common_range<_View>) {
+ return __iterator{*this, ranges::end(__base_), {}};
+ } else {
+ return __sentinel{*this};
+ }
+ }
+};
+
+template <class _Range, class _Pattern>
+split_view(_Range&&, _Pattern&&) -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
+
+template <forward_range _Range>
+split_view(_Range&&, range_value_t<_Range>) -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
+
+template <class _View, class _Pattern>
+struct __split_view_iterator {
+private:
+ split_view<_View, _Pattern>* __parent_ = nullptr;
+ _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __cur_ = iterator_t<_View>();
+ _LIBCPP_NO_UNIQUE_ADDRESS subrange<iterator_t<_View>> __next_ = subrange<iterator_t<_View>>();
+ bool __trailing_empty_ = false;
+
+ template <class, class>
+ friend struct __split_view_sentinel;
+
+public:
+ using iterator_concept = forward_iterator_tag;
+ using iterator_category = input_iterator_tag;
+ using value_type = subrange<iterator_t<_View>>;
+ using difference_type = range_difference_t<_View>;
+
+ _LIBCPP_HIDE_FROM_ABI __split_view_iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator(
+ split_view<_View, _Pattern>& __parent, iterator_t<_View> __current, subrange<iterator_t<_View>> __next)
+ : __parent_(std::addressof(__parent)), __cur_(std::move(__current)), __next_(std::move(__next)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() const { return __cur_; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return {__cur_, __next_.begin()}; }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator& operator++() {
+ __cur_ = __next_.begin();
+ if (__cur_ != ranges::end(__parent_->__base_)) {
+ __cur_ = __next_.end();
+ if (__cur_ == ranges::end(__parent_->__base_)) {
+ __trailing_empty_ = true;
+ __next_ = {__cur_, __cur_};
+ } else {
+ __next_ = __parent_->__find_next(__cur_);
+ }
+ } else {
+ __trailing_empty_ = false;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __split_view_iterator operator++(int) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __split_view_iterator& __x, const __split_view_iterator& __y) {
+ return __x.__cur_ == __y.__cur_ && __x.__trailing_empty_ == __y.__trailing_empty_;
+ }
+};
+
+template <class _View, class _Pattern>
+struct __split_view_sentinel {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_View> __end_ = sentinel_t<_View>();
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool
+ __equals(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+ return __x.__cur_ == __y.__end_ && !__x.__trailing_empty_;
+ }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __split_view_sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __split_view_sentinel(split_view<_View, _Pattern>& __parent)
+ : __end_(ranges::end(__parent.__base_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const __split_view_iterator<_View, _Pattern>& __x, const __split_view_sentinel& __y) {
+ return __equals(__x, __y);
+ }
+};
+
+namespace views {
+namespace __split_view {
+struct __fn : __range_adaptor_closure<__fn> {
+ // clang-format off
+ template <class _Range, class _Pattern>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const
+ noexcept(noexcept(split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))))
+ -> decltype( split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))
+ { return split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)); }
+ // clang-format on
+
+ template <class _Pattern>
+ requires constructible_from<decay_t<_Pattern>, _Pattern>
+ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const
+ noexcept(is_nothrow_constructible_v<decay_t<_Pattern>, _Pattern>) {
+ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern)));
+ }
+};
+} // namespace __split_view
+
+inline namespace __cpo {
+inline constexpr auto split = __split_view::__fn{};
+} // namespace __cpo
+} // namespace views
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_SPLIT_VIEW_H
diff --git a/third_party/llvm-project/libcxx/include/__ranges/take_while_view.h b/third_party/llvm-project/libcxx/include/__ranges/take_while_view.h
index 77d7390..59c0a4f 100644
--- a/third_party/llvm-project/libcxx/include/__ranges/take_while_view.h
+++ b/third_party/llvm-project/libcxx/include/__ranges/take_while_view.h
@@ -53,11 +53,17 @@
concept __take_while_const_is_range =
range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>>;
+template <class, class, bool>
+class __take_while_view_sentinel;
+
template <view _View, class _Pred>
requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
- template <bool>
- class __sentinel;
+ template <class, class, bool>
+ friend class __take_while_view_sentinel;
+
+ template <bool _Const>
+ using __sentinel = __take_while_view_sentinel<_View, _Pred, _Const>;
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
@@ -108,37 +114,37 @@
template <class _Range, class _Pred>
take_while_view(_Range&&, _Pred) -> take_while_view<views::all_t<_Range>, _Pred>;
-template <view _View, class _Pred>
- requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
-template <bool _Const>
-class take_while_view<_View, _Pred>::__sentinel {
+template <class _View, class _Pred, bool _Const>
+class __take_while_view_sentinel {
using _Base = __maybe_const<_Const, _View>;
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
const _Pred* __pred_ = nullptr;
- friend class __sentinel<!_Const>;
+ template <class, class, bool>
+ friend class __take_while_view_sentinel;
public:
- _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
+ _LIBCPP_HIDE_FROM_ABI __take_while_view_sentinel() = default;
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __take_while_view_sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
: __end_(std::move(__end)), __pred_(__pred) {}
- _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s)
+ _LIBCPP_HIDE_FROM_ABI constexpr __take_while_view_sentinel(__take_while_view_sentinel<_View, _Pred, !_Const> __s)
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
: __end_(std::move(__s.__end_)), __pred_(__s.__pred_) {}
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
- _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const iterator_t<_Base>& __x, const __sentinel& __y) {
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
+ operator==(const iterator_t<_Base>& __x, const __take_while_view_sentinel& __y) {
return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
}
template <bool _OtherConst = !_Const>
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
- operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __sentinel& __y) {
+ operator==(const iterator_t<__maybe_const<_OtherConst, _View>>& __x, const __take_while_view_sentinel& __y) {
return __x == __y.__end_ || !std::invoke(*__y.__pred_, *__x);
}
};
diff --git a/third_party/llvm-project/libcxx/include/__support/android/locale_bionic.h b/third_party/llvm-project/libcxx/include/__support/android/locale_bionic.h
index 5f4a89a..30e345c 100644
--- a/third_party/llvm-project/libcxx/include/__support/android/locale_bionic.h
+++ b/third_party/llvm-project/libcxx/include/__support/android/locale_bionic.h
@@ -46,18 +46,15 @@
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI float
-strtof_l(const char* __nptr, char** __endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C float strtof_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtof(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI double
-strtod_l(const char* __nptr, char** __endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C double strtod_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtod(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long
-strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtol(__nptr, __endptr, __base);
}
diff --git a/third_party/llvm-project/libcxx/include/__support/musl/xlocale.h b/third_party/llvm-project/libcxx/include/__support/musl/xlocale.h
index 4ff07ba..fe1dcf6 100644
--- a/third_party/llvm-project/libcxx/include/__support/musl/xlocale.h
+++ b/third_party/llvm-project/libcxx/include/__support/musl/xlocale.h
@@ -24,28 +24,24 @@
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI long long
-strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
+strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoull(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI long long
-wcstoll_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-wcstoull_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoull(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI long double
-wcstold_l(const wchar_t *__nptr, wchar_t **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) {
return ::wcstold(__nptr, __endptr);
}
diff --git a/third_party/llvm-project/libcxx/include/__support/openbsd/xlocale.h b/third_party/llvm-project/libcxx/include/__support/openbsd/xlocale.h
index 0269e81..b969ae9 100644
--- a/third_party/llvm-project/libcxx/include/__support/openbsd/xlocale.h
+++ b/third_party/llvm-project/libcxx/include/__support/openbsd/xlocale.h
@@ -20,18 +20,14 @@
extern "C" {
#endif
-
-inline _LIBCPP_HIDE_FROM_ABI long
-strtol_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long strtol_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtol(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long
-strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long strtoul_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoul(__nptr, __endptr, __base);
}
-
#ifdef __cplusplus
}
#endif
diff --git a/third_party/llvm-project/libcxx/include/__support/xlocale/__nop_locale_mgmt.h b/third_party/llvm-project/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
index 23727a5..4b3caa8 100644
--- a/third_party/llvm-project/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
+++ b/third_party/llvm-project/libcxx/include/__support/xlocale/__nop_locale_mgmt.h
@@ -19,24 +19,13 @@
// Patch over lack of extended locale support
typedef void *locale_t;
-inline _LIBCPP_HIDE_FROM_ABI locale_t
-duplocale(locale_t) {
- return NULL;
-}
+inline _LIBCPP_HIDE_FROM_ABI_C locale_t duplocale(locale_t) { return NULL; }
-inline _LIBCPP_HIDE_FROM_ABI void
-freelocale(locale_t) {
-}
+inline _LIBCPP_HIDE_FROM_ABI_C void freelocale(locale_t) {}
-inline _LIBCPP_HIDE_FROM_ABI locale_t
-newlocale(int, const char *, locale_t) {
- return NULL;
-}
+inline _LIBCPP_HIDE_FROM_ABI_C locale_t newlocale(int, const char*, locale_t) { return NULL; }
-inline _LIBCPP_HIDE_FROM_ABI locale_t
-uselocale(locale_t) {
- return NULL;
-}
+inline _LIBCPP_HIDE_FROM_ABI_C locale_t uselocale(locale_t) { return NULL; }
#define LC_COLLATE_MASK (1 << LC_COLLATE)
#define LC_CTYPE_MASK (1 << LC_CTYPE)
diff --git a/third_party/llvm-project/libcxx/include/__support/xlocale/__posix_l_fallback.h b/third_party/llvm-project/libcxx/include/__support/xlocale/__posix_l_fallback.h
index 8196c23..774081a 100644
--- a/third_party/llvm-project/libcxx/include/__support/xlocale/__posix_l_fallback.h
+++ b/third_party/llvm-project/libcxx/include/__support/xlocale/__posix_l_fallback.h
@@ -27,144 +27,83 @@
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI int isalnum_l(int __c, locale_t) {
- return ::isalnum(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isalnum_l(int __c, locale_t) { return ::isalnum(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isalpha_l(int __c, locale_t) {
- return ::isalpha(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isalpha_l(int __c, locale_t) { return ::isalpha(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isblank_l(int __c, locale_t) {
- return ::isblank(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isblank_l(int __c, locale_t) { return ::isblank(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iscntrl_l(int __c, locale_t) {
- return ::iscntrl(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iscntrl_l(int __c, locale_t) { return ::iscntrl(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isdigit_l(int __c, locale_t) {
- return ::isdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isdigit_l(int __c, locale_t) { return ::isdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isgraph_l(int __c, locale_t) {
- return ::isgraph(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isgraph_l(int __c, locale_t) { return ::isgraph(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int islower_l(int __c, locale_t) {
- return ::islower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int islower_l(int __c, locale_t) { return ::islower(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isprint_l(int __c, locale_t) {
- return ::isprint(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isprint_l(int __c, locale_t) { return ::isprint(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int ispunct_l(int __c, locale_t) {
- return ::ispunct(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int ispunct_l(int __c, locale_t) { return ::ispunct(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isspace_l(int __c, locale_t) {
- return ::isspace(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isspace_l(int __c, locale_t) { return ::isspace(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isupper_l(int __c, locale_t) {
- return ::isupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isupper_l(int __c, locale_t) { return ::isupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int isxdigit_l(int __c, locale_t) {
- return ::isxdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int isxdigit_l(int __c, locale_t) { return ::isxdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int toupper_l(int __c, locale_t) {
- return ::toupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int toupper_l(int __c, locale_t) { return ::toupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int tolower_l(int __c, locale_t) {
- return ::tolower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int tolower_l(int __c, locale_t) { return ::tolower(__c); }
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI int iswalnum_l(wint_t __c, locale_t) {
- return ::iswalnum(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswalnum_l(wint_t __c, locale_t) { return ::iswalnum(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswalpha_l(wint_t __c, locale_t) {
- return ::iswalpha(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswalpha_l(wint_t __c, locale_t) { return ::iswalpha(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswblank_l(wint_t __c, locale_t) {
- return ::iswblank(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswblank_l(wint_t __c, locale_t) { return ::iswblank(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswcntrl_l(wint_t __c, locale_t) {
- return ::iswcntrl(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswcntrl_l(wint_t __c, locale_t) { return ::iswcntrl(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswdigit_l(wint_t __c, locale_t) {
- return ::iswdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswdigit_l(wint_t __c, locale_t) { return ::iswdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswgraph_l(wint_t __c, locale_t) {
- return ::iswgraph(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswgraph_l(wint_t __c, locale_t) { return ::iswgraph(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswlower_l(wint_t __c, locale_t) {
- return ::iswlower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswlower_l(wint_t __c, locale_t) { return ::iswlower(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswprint_l(wint_t __c, locale_t) {
- return ::iswprint(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswprint_l(wint_t __c, locale_t) { return ::iswprint(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswpunct_l(wint_t __c, locale_t) {
- return ::iswpunct(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswpunct_l(wint_t __c, locale_t) { return ::iswpunct(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswspace_l(wint_t __c, locale_t) {
- return ::iswspace(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswspace_l(wint_t __c, locale_t) { return ::iswspace(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswupper_l(wint_t __c, locale_t) {
- return ::iswupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswupper_l(wint_t __c, locale_t) { return ::iswupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI int iswxdigit_l(wint_t __c, locale_t) {
- return ::iswxdigit(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C int iswxdigit_l(wint_t __c, locale_t) { return ::iswxdigit(__c); }
-inline _LIBCPP_HIDE_FROM_ABI wint_t towupper_l(wint_t __c, locale_t) {
- return ::towupper(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C wint_t towupper_l(wint_t __c, locale_t) { return ::towupper(__c); }
-inline _LIBCPP_HIDE_FROM_ABI wint_t towlower_l(wint_t __c, locale_t) {
- return ::towlower(__c);
-}
+inline _LIBCPP_HIDE_FROM_ABI_C wint_t towlower_l(wint_t __c, locale_t) { return ::towlower(__c); }
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI int
-strcoll_l(const char *__s1, const char *__s2, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C int strcoll_l(const char* __s1, const char* __s2, locale_t) {
return ::strcoll(__s1, __s2);
}
-inline _LIBCPP_HIDE_FROM_ABI size_t
-strxfrm_l(char *__dest, const char *__src, size_t __n, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C size_t strxfrm_l(char* __dest, const char* __src, size_t __n, locale_t) {
return ::strxfrm(__dest, __src, __n);
}
-inline _LIBCPP_HIDE_FROM_ABI size_t
-strftime_l(char *__s, size_t __max, const char *__format, const struct tm *__tm,
- locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C size_t
+strftime_l(char* __s, size_t __max, const char* __format, const struct tm* __tm, locale_t) {
return ::strftime(__s, __max, __format, __tm);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI int
-wcscoll_l(const wchar_t *__ws1, const wchar_t *__ws2, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C int wcscoll_l(const wchar_t* __ws1, const wchar_t* __ws2, locale_t) {
return ::wcscoll(__ws1, __ws2);
}
-inline _LIBCPP_HIDE_FROM_ABI size_t
-wcsxfrm_l(wchar_t *__dest, const wchar_t *__src, size_t __n, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C size_t wcsxfrm_l(wchar_t* __dest, const wchar_t* __src, size_t __n, locale_t) {
return ::wcsxfrm(__dest, __src, __n);
}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
diff --git a/third_party/llvm-project/libcxx/include/__support/xlocale/__strtonum_fallback.h b/third_party/llvm-project/libcxx/include/__support/xlocale/__strtonum_fallback.h
index d1ef8aa..ae8e13a 100644
--- a/third_party/llvm-project/libcxx/include/__support/xlocale/__strtonum_fallback.h
+++ b/third_party/llvm-project/libcxx/include/__support/xlocale/__strtonum_fallback.h
@@ -26,44 +26,38 @@
extern "C" {
#endif
-inline _LIBCPP_HIDE_FROM_ABI float
-strtof_l(const char *__nptr, char **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C float strtof_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtof(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI double
-strtod_l(const char *__nptr, char **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C double strtod_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtod(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long double
-strtold_l(const char *__nptr, char **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long double strtold_l(const char* __nptr, char** __endptr, locale_t) {
return ::strtold(__nptr, __endptr);
}
-inline _LIBCPP_HIDE_FROM_ABI long long
-strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long strtoll_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
+strtoull_l(const char* __nptr, char** __endptr, int __base, locale_t) {
return ::strtoull(__nptr, __endptr, __base);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI long long
-wcstoll_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoll(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-wcstoull_l(const wchar_t *__nptr, wchar_t **__endptr, int __base, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long
+wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) {
return ::wcstoull(__nptr, __endptr, __base);
}
-inline _LIBCPP_HIDE_FROM_ABI long double
-wcstold_l(const wchar_t *__nptr, wchar_t **__endptr, locale_t) {
+inline _LIBCPP_HIDE_FROM_ABI_C long double wcstold_l(const wchar_t* __nptr, wchar_t** __endptr, locale_t) {
return ::wcstold(__nptr, __endptr);
}
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
diff --git a/third_party/llvm-project/libcxx/include/__type_traits/aligned_storage.h b/third_party/llvm-project/libcxx/include/__type_traits/aligned_storage.h
index a9f1244..c564d58 100644
--- a/third_party/llvm-project/libcxx/include/__type_traits/aligned_storage.h
+++ b/third_party/llvm-project/libcxx/include/__type_traits/aligned_storage.h
@@ -83,7 +83,7 @@
: public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
-struct _LIBCPP_TEMPLATE_VIS aligned_storage
+struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage
{
typedef typename __find_pod<__all_types, _Align>::type _Aligner;
union type
@@ -94,13 +94,17 @@
};
#if _LIBCPP_STD_VER > 11
+
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
- using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
+ using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
+
#endif
#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
template <size_t _Len>\
-struct _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
+struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\
{\
struct _ALIGNAS(n) type\
{\
diff --git a/third_party/llvm-project/libcxx/include/__type_traits/aligned_union.h b/third_party/llvm-project/libcxx/include/__type_traits/aligned_union.h
index 31eb935..2c64130 100644
--- a/third_party/llvm-project/libcxx/include/__type_traits/aligned_union.h
+++ b/third_party/llvm-project/libcxx/include/__type_traits/aligned_union.h
@@ -37,7 +37,7 @@
};
template <size_t _Len, class _Type0, class ..._Types>
-struct aligned_union
+struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union
{
static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0),
_LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value;
@@ -47,7 +47,8 @@
};
#if _LIBCPP_STD_VER > 11
-template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
+template <size_t _Len, class... _Types>
+using aligned_union_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_union<_Len, _Types...>::type;
#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__utility/exception_guard.h b/third_party/llvm-project/libcxx/include/__utility/exception_guard.h
new file mode 100644
index 0000000..737d1a6
--- /dev/null
+++ b/third_party/llvm-project/libcxx/include/__utility/exception_guard.h
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___UTILITY_TRANSACTION_H
+#define _LIBCPP___UTILITY_TRANSACTION_H
+
+#include <__assert>
+#include <__config>
+#include <__type_traits/is_nothrow_move_constructible.h>
+#include <__utility/exchange.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// __exception_guard is a helper class for writing code with the strong exception guarantee.
+//
+// When writing code that can throw an exception, one can store rollback instructions in an
+// exception guard so that if an exception is thrown at any point during the lifetime of the
+// exception guard, it will be rolled back automatically. When the exception guard is done, one
+// must mark it as being complete so it isn't rolled back when the exception guard is destroyed.
+//
+// Exception guards are not default constructible, they can't be copied or assigned to, but
+// they can be moved around for convenience.
+//
+// __exception_guard is a no-op in -fno-exceptions mode to produce better code-gen. This means
+// that we don't provide the strong exception guarantees. However, Clang doesn't generate cleanup
+// code with exceptions disabled, so even if we wanted to provide the strong exception guarantees
+// we couldn't. This is also only relevant for constructs with a stack of
+// -fexceptions > -fno-exceptions > -fexceptions code, since the exception can't be caught where
+// exceptions are disabled. While -fexceptions > -fno-exceptions is quite common
+// (e.g. libc++.dylib > -fno-exceptions), having another layer with exceptions enabled seems a lot
+// less common, especially one that tries to catch an exception through -fno-exceptions code.
+//
+// __exception_guard can help greatly simplify code that would normally be cluttered by
+// `#if _LIBCPP_NO_EXCEPTIONS`. For example:
+//
+// template <class Iterator, class Size, class OutputIterator>
+// Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) {
+// typedef typename iterator_traits<Iterator>::value_type value_type;
+// __exception_guard guard([start=out, &out] {
+// std::destroy(start, out);
+// });
+//
+// for (; n > 0; ++iter, ++out, --n) {
+// ::new ((void*)std::addressof(*out)) value_type(*iter);
+// }
+// guard.__complete();
+// return out;
+// }
+//
+
+#ifndef _LIBCPP_NO_EXCEPTIONS
+template <class _Rollback>
+struct __exception_guard {
+ __exception_guard() = delete;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __exception_guard(_Rollback __rollback)
+ : __rollback_(std::move(__rollback)), __completed_(false) {}
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __exception_guard(__exception_guard&& __other)
+ _NOEXCEPT_(is_nothrow_move_constructible<_Rollback>::value)
+ : __rollback_(std::move(__other.__rollback_)), __completed_(__other.__completed_) {
+ __other.__completed_ = true;
+ }
+
+ __exception_guard(__exception_guard const&) = delete;
+ __exception_guard& operator=(__exception_guard const&) = delete;
+ __exception_guard& operator=(__exception_guard&&) = delete;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __complete() _NOEXCEPT { __completed_ = true; }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__exception_guard() {
+ if (!__completed_)
+ __rollback_();
+ }
+
+private:
+ _Rollback __rollback_;
+ bool __completed_;
+};
+#else // _LIBCPP_NO_EXCEPTIONS
+template <class _Rollback>
+struct __exception_guard {
+ __exception_guard() = delete;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG explicit __exception_guard(_Rollback) {}
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG __exception_guard(__exception_guard&& __other)
+ _NOEXCEPT_(is_nothrow_move_constructible<_Rollback>::value)
+ : __completed_(__other.__completed_) {
+ __other.__completed_ = true;
+ }
+
+ __exception_guard(__exception_guard const&) = delete;
+ __exception_guard& operator=(__exception_guard const&) = delete;
+ __exception_guard& operator=(__exception_guard&&) = delete;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG void __complete() _NOEXCEPT {
+ __completed_ = true;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG ~__exception_guard() {
+ _LIBCPP_ASSERT(__completed_, "__exception_guard not completed with exceptions disabled");
+ }
+
+private:
+ bool __completed_ = false;
+};
+#endif // _LIBCPP_NO_EXCEPTIONS
+
+_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard);
+
+template <class _Rollback>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exception_guard(_Rollback __rollback) {
+ return __exception_guard<_Rollback>(std::move(__rollback));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___UTILITY_TRANSACTION_H
diff --git a/third_party/llvm-project/libcxx/include/__utility/transaction.h b/third_party/llvm-project/libcxx/include/__utility/transaction.h
deleted file mode 100644
index 3baedd2..0000000
--- a/third_party/llvm-project/libcxx/include/__utility/transaction.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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___UTILITY_TRANSACTION_H
-#define _LIBCPP___UTILITY_TRANSACTION_H
-
-#include <__config>
-#include <__type_traits/is_nothrow_move_constructible.h>
-#include <__utility/exchange.h>
-#include <__utility/move.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-// __transaction is a helper class for writing code with the strong exception guarantee.
-//
-// When writing code that can throw an exception, one can store rollback instructions in a
-// transaction so that if an exception is thrown at any point during the lifetime of the
-// transaction, it will be rolled back automatically. When the transaction is done, one
-// must mark it as being complete so it isn't rolled back when the transaction is destroyed.
-//
-// Transactions are not default constructible, they can't be copied or assigned to, but
-// they can be moved around for convenience.
-//
-// __transaction can help greatly simplify code that would normally be cluttered by
-// `#if _LIBCPP_NO_EXCEPTIONS`. For example:
-//
-// template <class Iterator, class Size, class OutputIterator>
-// Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) {
-// typedef typename iterator_traits<Iterator>::value_type value_type;
-// __transaction transaction([start=out, &out] {
-// std::destroy(start, out);
-// });
-//
-// for (; n > 0; ++iter, ++out, --n) {
-// ::new ((void*)std::addressof(*out)) value_type(*iter);
-// }
-// transaction.__complete();
-// return out;
-// }
-//
-template <class _Rollback>
-struct __transaction {
- __transaction() = delete;
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __transaction(_Rollback __rollback)
- : __rollback_(_VSTD::move(__rollback))
- , __completed_(false)
- { }
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 __transaction(__transaction&& __other)
- _NOEXCEPT_(is_nothrow_move_constructible<_Rollback>::value)
- : __rollback_(_VSTD::move(__other.__rollback_))
- , __completed_(__other.__completed_)
- {
- __other.__completed_ = true;
- }
-
- __transaction(__transaction const&) = delete;
- __transaction& operator=(__transaction const&) = delete;
- __transaction& operator=(__transaction&&) = delete;
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 void __complete() _NOEXCEPT {
- __completed_ = true;
- }
-
- _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__transaction() {
- if (!__completed_)
- __rollback_();
- }
-
-private:
- _Rollback __rollback_;
- bool __completed_;
-};
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__transaction);
-
-template <class _Rollback>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __transaction<_Rollback> __make_transaction(_Rollback __rollback) {
- return __transaction<_Rollback>(std::move(__rollback));
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___UTILITY_TRANSACTION_H
diff --git a/third_party/llvm-project/libcxx/include/__verbose_abort b/third_party/llvm-project/libcxx/include/__verbose_abort
index 3559c52..a16d75d 100644
--- a/third_party/llvm-project/libcxx/include/__verbose_abort
+++ b/third_party/llvm-project/libcxx/include/__verbose_abort
@@ -17,32 +17,41 @@
# pragma GCC system_header
#endif
-// Provide a default implementation of __libcpp_verbose_abort if we know that neither the built
-// library nor the user is providing one. Otherwise, just declare it and use the one from the
-// built library or the one provided by the user.
-//
-// We can't provide a great implementation because it needs to be pretty much
-// dependency-free (this is included everywhere else in the library).
-#if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && !defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
-
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_NORETURN _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) _LIBCPP_HIDE_FROM_ABI inline
-void __libcpp_verbose_abort(const char *, ...) {
- __builtin_abort();
-}
-
-_LIBCPP_END_NAMESPACE_STD
-
-#else
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
+// This function should never be called directly from the code -- it should only be called through
+// the _LIBCPP_VERBOSE_ABORT macro.
_LIBCPP_NORETURN _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
void __libcpp_verbose_abort(const char *__format, ...);
-_LIBCPP_END_NAMESPACE_STD
+// _LIBCPP_VERBOSE_ABORT(format, args...)
+//
+// This macro is used to abort the program abnormally while providing additional diagnostic information.
+//
+// The first argument is a printf-style format string, and the remaining arguments are values to format
+// into the format-string. This macro can be customized by users to provide fine-grained control over
+// how verbose termination is triggered.
+//
+// If the user does not supply their own version of the _LIBCPP_VERBOSE_ABORT macro, we pick the default
+// behavior based on whether we know the built library we're running against provides support for the
+// verbose termination handler or not. If it does, we call it. If it doesn't, we call __builtin_abort to
+// make sure that the program terminates but without taking any complex dependencies in this header.
+#if !defined(_LIBCPP_VERBOSE_ABORT)
-#endif
+// Support _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED until LLVM 18, but tell people
+// to move to customizing _LIBCPP_VERBOSE_ABORT instead.
+# if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
+# undef _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
+# warning _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED is deprecated, please customize _LIBCPP_VERBOSE_ABORT instead
+# endif
+
+# if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY)
+# define _LIBCPP_VERBOSE_ABORT(...) __builtin_abort()
+# else
+# define _LIBCPP_VERBOSE_ABORT(...) ::std::__libcpp_verbose_abort(__VA_ARGS__)
+# endif
+#endif // !defined(_LIBCPP_VERBOSE_ABORT)
+
+_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___VERBOSE_ABORT
diff --git a/third_party/llvm-project/libcxx/include/any b/third_party/llvm-project/libcxx/include/any
index ec5171f..92cbc9a 100644
--- a/third_party/llvm-project/libcxx/include/any
+++ b/third_party/llvm-project/libcxx/include/any
@@ -138,7 +138,9 @@
namespace __any_imp
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Tp>
using _IsSmallObject = integral_constant<bool
diff --git a/third_party/llvm-project/libcxx/include/coroutine b/third_party/llvm-project/libcxx/include/coroutine
index e0ce323..f264570 100644
--- a/third_party/llvm-project/libcxx/include/coroutine
+++ b/third_party/llvm-project/libcxx/include/coroutine
@@ -57,6 +57,7 @@
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <iosfwd>
+# include <type_traits>
#endif
#endif // _LIBCPP_COROUTINE
diff --git a/third_party/llvm-project/libcxx/include/deque b/third_party/llvm-project/libcxx/include/deque
index 8445883..f2b8076 100644
--- a/third_party/llvm-project/libcxx/include/deque
+++ b/third_party/llvm-project/libcxx/include/deque
@@ -176,6 +176,7 @@
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/reverse_iterator.h>
+#include <__iterator/segmented_iterator.h>
#include <__memory/allocator_destructor.h>
#include <__memory/pointer_traits.h>
#include <__memory/temp_value.h>
@@ -216,98 +217,6 @@
template <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;
-template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
- class _DiffType, _DiffType _BlockSize>
-class _LIBCPP_TEMPLATE_VIS __deque_iterator;
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
template <class _ValueType, class _DiffType>
struct __deque_block_size {
static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
@@ -478,105 +387,36 @@
template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
+ template <class>
+ friend struct __segmented_iterator_traits;
+};
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
+template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>
+struct __segmented_iterator_traits<
+ __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > {
+private:
+ using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+public:
+ using __is_segmented_iterator = true_type;
+ using __segment_iterator = _MapPointer;
+ using __local_iterator = _Pointer;
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
+ static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }
+ static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }
+ static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; }
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
+ static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
+ return *__iter + _Iterator::__block_size;
+ }
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
-
- template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
- friend
- _OutputIterator
- move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r);
-
- template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
- friend
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
- move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+ static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) {
+ if (__local == __end(__segment)) {
+ ++__segment;
+ return _Iterator(__segment, *__segment);
+ }
+ return _Iterator(__segment, __local);
+ }
};
template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
@@ -585,358 +425,6 @@
_DiffType, _BlockSize>::__block_size =
__deque_block_size<_ValueType, _DiffType>::value;
-// copy
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
- while (__f != __l)
- {
- pointer __rb = __r.__ptr_;
- pointer __re = *__r.__m_iter_ + __block_size;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __l;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __f + __n;
- }
- _VSTD::copy(__f, __m, __rb);
- __f = __m;
- __r += __n;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::copy(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::copy(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
-
-// copy_backward
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- while (__f != __l)
- {
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
- pointer __rb = *__rp.__m_iter_;
- pointer __re = __rp.__ptr_ + 1;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __f;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __l - __n;
- }
- _VSTD::copy_backward(__m, __l, __re);
- __l = __m;
- __r -= __n;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
- }
- __r = _VSTD::copy_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
- }
- __r = _VSTD::copy_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
-
-// move
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::__block_size;
- while (__f != __l)
- {
- pointer __rb = __r.__ptr_;
- pointer __re = *__r.__m_iter_ + __block_size;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __l;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __f + __n;
- }
- _VSTD::move(__f, __m, __rb);
- __f = __m;
- __r += __n;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::move(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- const difference_type __block_size = __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::__block_size;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- pointer __fb = __f.__ptr_;
- pointer __fe = *__f.__m_iter_ + __block_size;
- difference_type __bs = __fe - __fb;
- if (__bs > __n)
- {
- __bs = __n;
- __fe = __fb + __bs;
- }
- __r = _VSTD::move(__fb, __fe, __r);
- __n -= __bs;
- __f += __bs;
- }
- return __r;
-}
-
-// move_backward
-
-template <class _RAIter,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(_RAIter __f,
- _RAIter __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
- typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*)
-{
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
- typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
- while (__f != __l)
- {
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
- pointer __rb = *__rp.__m_iter_;
- pointer __re = __rp.__ptr_ + 1;
- difference_type __bs = __re - __rb;
- difference_type __n = __l - __f;
- _RAIter __m = __f;
- if (__n > __bs)
- {
- __n = __bs;
- __m = __l - __n;
- }
- _VSTD::move_backward(__m, __l, __re);
- __l = __m;
- __r -= __n;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _OutputIterator>
-_LIBCPP_HIDE_FROM_ABI _OutputIterator
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- _OutputIterator __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
- }
- __r = _VSTD::move_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
-
-template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
- class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
-_LIBCPP_HIDE_FROM_ABI __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
-move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
- __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
- __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
-{
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
- typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
- difference_type __n = __l - __f;
- while (__n > 0)
- {
- --__l;
- pointer __lb = *__l.__m_iter_;
- pointer __le = __l.__ptr_ + 1;
- difference_type __bs = __le - __lb;
- if (__bs > __n)
- {
- __bs = __n;
- __lb = __le - __bs;
- }
- __r = _VSTD::move_backward(__lb, __le, __r);
- __n -= __bs;
- __l -= __bs - 1;
- }
- return __r;
-}
-
template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS deque
{
diff --git a/third_party/llvm-project/libcxx/include/format b/third_party/llvm-project/libcxx/include/format
index 900f27c..2c583c1 100644
--- a/third_party/llvm-project/libcxx/include/format
+++ b/third_party/llvm-project/libcxx/include/format
@@ -130,6 +130,11 @@
requires same_as<R, remove_cvref_t<R>>
constexpr range_format format_kind<R> = see below; // since C++23
+ // [format.range.formatter], class template range_formatter
+ template<class T, class charT = char>
+ requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+ class range_formatter; // since C++23
+
// [format.range.fmtdef], class template range-default-formatter
template<range_format K, ranges::input_range R, class charT>
struct range-default-formatter; // exposition only, since C++23
@@ -173,6 +178,7 @@
#include <__config>
#include <__format/buffer.h>
#include <__format/concepts.h>
+#include <__format/container_adaptor.h>
#include <__format/enable_insertable.h>
#include <__format/format_arg.h>
#include <__format/format_arg_store.h>
@@ -194,6 +200,7 @@
#include <__format/formatter_tuple.h>
#include <__format/parser_std_format_spec.h>
#include <__format/range_default_formatter.h>
+#include <__format/range_formatter.h>
#include <__format/unicode.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/third_party/llvm-project/libcxx/include/future b/third_party/llvm-project/libcxx/include/future
index dcacd7a..2f14a47 100644
--- a/third_party/llvm-project/libcxx/include/future
+++ b/third_party/llvm-project/libcxx/include/future
@@ -625,7 +625,9 @@
: public __assoc_sub_state
{
typedef __assoc_sub_state base;
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
+_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
_Up __value_;
@@ -1702,7 +1704,9 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_NO_CFI
__base* __get_buf() { return (__base*)&__buf_; }
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<3*sizeof(void*)>::type __buf_;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
__base* __f_;
public:
@@ -1835,7 +1839,9 @@
{
if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
{
+ _LIBCPP_SUPPRESS_DEPRECATED_PUSH
typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+ _LIBCPP_SUPPRESS_DEPRECATED_POP
__base* __t = (__base*)&__tempbuf;
__f_->__move_to(__t);
__f_->destroy();
diff --git a/third_party/llvm-project/libcxx/include/memory b/third_party/llvm-project/libcxx/include/memory
index 48e808e..0a7787a 100644
--- a/third_party/llvm-project/libcxx/include/memory
+++ b/third_party/llvm-project/libcxx/include/memory
@@ -569,6 +569,13 @@
constexpr unique_ptr<T> make_unique(size_t n); // C++14, constexpr since C++23
template<class T, class... Args> unspecified make_unique(Args&&...) = delete; // C++14, T == U[N]
+template<class T>
+ constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not array, C++20, constexpr since C++23
+template<class T>
+ constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[], C++20, constexpr since C++23
+template<class T, class... Args>
+ unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N], C++20
+
template<class E, class T, class Y, class D>
basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
@@ -718,6 +725,16 @@
shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N] (since C++20)
template<class T>
+ shared_ptr<T> make_shared_for_overwrite(); // T is not U[], C++20
+template<class T, class A>
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[], C++20
+
+template<class T>
+ shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[], C++20
+template<class T, class A>
+ shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[], C++20
+
+template<class T>
class weak_ptr
{
public:
diff --git a/third_party/llvm-project/libcxx/include/module.modulemap.in b/third_party/llvm-project/libcxx/include/module.modulemap.in
index 5d4cf53..1f1d67d 100644
--- a/third_party/llvm-project/libcxx/include/module.modulemap.in
+++ b/third_party/llvm-project/libcxx/include/module.modulemap.in
@@ -839,6 +839,7 @@
module __format {
module buffer { private header "__format/buffer.h" }
module concepts { private header "__format/concepts.h" }
+ module container_adaptor { private header "__format/container_adaptor.h" }
module enable_insertable { private header "__format/enable_insertable.h" }
module escaped_output_table { private header "__format/escaped_output_table.h" }
module extended_grapheme_cluster_table { private header "__format/extended_grapheme_cluster_table.h" }
@@ -871,6 +872,7 @@
module formatter_tuple { private header "__format/formatter_tuple.h" }
module parser_std_format_spec { private header "__format/parser_std_format_spec.h" }
module range_default_formatter { private header "__format/range_default_formatter.h" }
+ module range_formatter { private header "__format/range_formatter.h" }
module unicode { private header "__format/unicode.h" }
}
}
@@ -994,6 +996,7 @@
module iter_swap { private header "__iterator/iter_swap.h" }
module iterator { private header "__iterator/iterator.h" }
module iterator_traits { private header "__iterator/iterator_traits.h" }
+ module iterator_with_data { private header "__iterator/iterator_with_data.h" }
module mergeable {
private header "__iterator/mergeable.h"
export functional.__functional.ranges_operations
@@ -1012,6 +1015,7 @@
module readable_traits { private header "__iterator/readable_traits.h" }
module reverse_access { private header "__iterator/reverse_access.h" }
module reverse_iterator { private header "__iterator/reverse_iterator.h" }
+ module segmented_iterator { private header "__iterator/segmented_iterator.h" }
module size { private header "__iterator/size.h" }
module sortable {
private header "__iterator/sortable.h"
@@ -1218,6 +1222,7 @@
export functional.__functional.compose
export functional.__functional.perfect_forward
}
+ module as_rvalue_view { private header "__ranges/as_rvalue_view.h" }
module common_view { private header "__ranges/common_view.h" }
module concepts { private header "__ranges/concepts.h" }
module copyable_box { private header "__ranges/copyable_box.h" }
@@ -1251,6 +1256,7 @@
module reverse_view { private header "__ranges/reverse_view.h" }
module single_view { private header "__ranges/single_view.h" }
module size { private header "__ranges/size.h" }
+ module split_view { private header "__ranges/split_view.h" }
module subrange {
private header "__ranges/subrange.h"
@@ -1560,6 +1566,7 @@
module cmp { private header "__utility/cmp.h" }
module convert_to_integral { private header "__utility/convert_to_integral.h" }
module declval { private header "__utility/declval.h" }
+ module exception_guard { private header "__utility/exception_guard.h" }
module exchange { private header "__utility/exchange.h" }
module forward { private header "__utility/forward.h" }
module forward_like { private header "__utility/forward_like.h" }
@@ -1573,7 +1580,6 @@
module rel_ops { private header "__utility/rel_ops.h" }
module swap { private header "__utility/swap.h" }
module to_underlying { private header "__utility/to_underlying.h" }
- module transaction { private header "__utility/transaction.h" }
module unreachable { private header "__utility/unreachable.h" }
}
}
diff --git a/third_party/llvm-project/libcxx/include/numbers b/third_party/llvm-project/libcxx/include/numbers
index 1d9b6b0..72034a6 100644
--- a/third_party/llvm-project/libcxx/include/numbers
+++ b/third_party/llvm-project/libcxx/include/numbers
@@ -61,7 +61,6 @@
#include <__assert> // all public C++ headers provide the assertion handler
#include <__concepts/arithmetic.h>
#include <__config>
-#include <type_traits>
#include <version>
#if _LIBCPP_STD_VER > 17
@@ -133,6 +132,7 @@
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <concepts>
+# include <type_traits>
#endif
#endif // _LIBCPP_NUMBERS
diff --git a/third_party/llvm-project/libcxx/include/numeric b/third_party/llvm-project/libcxx/include/numeric
index 2fb6f9e..100dbe1 100644
--- a/third_party/llvm-project/libcxx/include/numeric
+++ b/third_party/llvm-project/libcxx/include/numeric
@@ -175,6 +175,7 @@
# include <concepts>
# include <functional>
# include <iterator>
+# include <type_traits>
#endif
#endif // _LIBCPP_NUMERIC
diff --git a/third_party/llvm-project/libcxx/include/queue b/third_party/llvm-project/libcxx/include/queue
index c58da5e..6c1b892 100644
--- a/third_party/llvm-project/libcxx/include/queue
+++ b/third_party/llvm-project/libcxx/include/queue
@@ -382,6 +382,8 @@
swap(c, __q.c);
}
+ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
+
template <class _T1, class _C1>
friend
_LIBCPP_INLINE_VISIBILITY
@@ -633,6 +635,8 @@
void swap(priority_queue& __q)
_NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&
__is_nothrow_swappable<value_compare>::value);
+
+ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
};
#if _LIBCPP_STD_VER >= 17
diff --git a/third_party/llvm-project/libcxx/include/ranges b/third_party/llvm-project/libcxx/include/ranges
index db601d4..f999fa0 100644
--- a/third_party/llvm-project/libcxx/include/ranges
+++ b/third_party/llvm-project/libcxx/include/ranges
@@ -265,8 +265,15 @@
(forward_range<V> || tiny-range<Pattern>)
class lazy_split_view;
+ // [range.split], split view
+ template<forward_range V, forward_range Pattern>
+ requires view<V> && view<Pattern> &&
+ indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
+ class split_view;
+
namespace views {
inline constexpr unspecified lazy_split = unspecified;
+ inline constexpr unspecified split = unspecified;
}
// [range.istream], istream view
@@ -292,6 +299,13 @@
(enable_borrowed_range<Views> && ...);
namespace views { inline constexpr unspecified zip = unspecified; } // C++2b
+
+ // [range.as.rvalue]
+ template <view V>
+ requires input_range<V>
+ class as_rvalue_view; // since C++23
+
+ namespace views { inline constexpr unspecified as_rvalue ) unspecified; } // since C++23
}
namespace std {
@@ -330,6 +344,7 @@
#include <__config>
#include <__ranges/access.h>
#include <__ranges/all.h>
+#include <__ranges/as_rvalue_view.h>
#include <__ranges/common_view.h>
#include <__ranges/concepts.h>
#include <__ranges/counted.h>
@@ -352,6 +367,7 @@
#include <__ranges/reverse_view.h>
#include <__ranges/single_view.h>
#include <__ranges/size.h>
+#include <__ranges/split_view.h>
#include <__ranges/subrange.h>
#include <__ranges/take_view.h>
#include <__ranges/take_while_view.h>
diff --git a/third_party/llvm-project/libcxx/include/stack b/third_party/llvm-project/libcxx/include/stack
index 2abbcd0..d653d1b 100644
--- a/third_party/llvm-project/libcxx/include/stack
+++ b/third_party/llvm-project/libcxx/include/stack
@@ -255,6 +255,8 @@
swap(c, __s.c);
}
+ _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
+
template <class T1, class _C1>
friend
bool
diff --git a/third_party/llvm-project/libcxx/include/type_traits b/third_party/llvm-project/libcxx/include/type_traits
index 757226f..7646f58 100644
--- a/third_party/llvm-project/libcxx/include/type_traits
+++ b/third_party/llvm-project/libcxx/include/type_traits
@@ -158,8 +158,8 @@
// Alignment properties and transformations:
template <class T> struct alignment_of;
template <size_t Len, size_t Align = most_stringent_alignment_requirement>
- struct aligned_storage;
- template <size_t Len, class... Types> struct aligned_union;
+ struct aligned_storage; // deprecated in C++23
+ template <size_t Len, class... Types> struct aligned_union; // deprecated in C++23
template <class T> struct remove_cvref; // C++20
template <class T> struct decay;
diff --git a/third_party/llvm-project/libcxx/include/utility b/third_party/llvm-project/libcxx/include/utility
index 1d56759..a4d8cf8 100644
--- a/third_party/llvm-project/libcxx/include/utility
+++ b/third_party/llvm-project/libcxx/include/utility
@@ -243,6 +243,7 @@
#include <__utility/auto_cast.h>
#include <__utility/cmp.h>
#include <__utility/declval.h>
+#include <__utility/exception_guard.h>
#include <__utility/exchange.h>
#include <__utility/forward.h>
#include <__utility/forward_like.h>
@@ -255,7 +256,6 @@
#include <__utility/rel_ops.h>
#include <__utility/swap.h>
#include <__utility/to_underlying.h>
-#include <__utility/transaction.h>
#include <__utility/unreachable.h>
#include <version>
diff --git a/third_party/llvm-project/libcxx/include/vector b/third_party/llvm-project/libcxx/include/vector
index e9d1b72..4b7ae13 100644
--- a/third_party/llvm-project/libcxx/include/vector
+++ b/third_party/llvm-project/libcxx/include/vector
@@ -267,6 +267,13 @@
typename vector<T, Allocator>::size_type
erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
+
+template<class T>
+ inline constexpr bool is-vector-bool-reference = see below; // exposition only, since C++23
+
+template<class T, class charT> requires is-vector-bool-reference<T> // Since C++23
+ struct formatter<T, charT>;
+
} // std
*/
@@ -281,9 +288,11 @@
#include <__algorithm/unwrap_iter.h>
#include <__assert> // all public C++ headers provide the assertion handler
#include <__bit_reference>
+#include <__concepts/same_as.h>
#include <__config>
#include <__debug>
#include <__format/enable_insertable.h>
+#include <__format/formatter.h>
#include <__functional/hash.h>
#include <__functional/unary_function.h>
#include <__iterator/advance.h>
@@ -299,10 +308,10 @@
#include <__split_buffer>
#include <__type_traits/is_allocator.h>
#include <__type_traits/noexcept_move_assign_container.h>
+#include <__utility/exception_guard.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
-#include <__utility/transaction.h>
#include <climits>
#include <cstdlib>
#include <cstring>
@@ -1064,7 +1073,7 @@
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(size_type __n)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__n > 0)
{
@@ -1080,7 +1089,7 @@
vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__n > 0)
{
@@ -1095,7 +1104,7 @@
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__n > 0)
{
@@ -1112,7 +1121,7 @@
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
for (; __first != __last; ++__first)
emplace_back(*__first);
@@ -1127,7 +1136,7 @@
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
for (; __first != __last; ++__first)
emplace_back(*__first);
@@ -1141,7 +1150,7 @@
_LIBCPP_CONSTEXPR_SINCE_CXX20
vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
@@ -1160,7 +1169,7 @@
vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
@@ -1176,7 +1185,7 @@
vector<_Tp, _Allocator>::vector(const vector& __x)
: __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = __x.size();
if (__n > 0)
@@ -1192,7 +1201,7 @@
vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
: __end_cap_(nullptr, __a)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
size_type __n = __x.size();
if (__n > 0)
@@ -1240,7 +1249,7 @@
else
{
typedef move_iterator<iterator> _Ip;
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
assign(_Ip(__x.begin()), _Ip(__x.end()));
__guard.__complete();
}
@@ -1253,7 +1262,7 @@
inline _LIBCPP_HIDE_FROM_ABI
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__il.size() > 0)
{
@@ -1269,7 +1278,7 @@
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
: __end_cap_(nullptr, __a)
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
std::__debug_db_insert_c(this);
if (__il.size() > 0)
{
@@ -2648,7 +2657,7 @@
__size_(0),
__cap_alloc_(0, __default_init_tag())
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
{
@@ -2667,7 +2676,7 @@
__size_(0),
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
{
- auto __guard = std::__make_transaction(__destroy_vector(*this));
+ auto __guard = std::__make_exception_guard(__destroy_vector(*this));
size_type __n = static_cast<size_type>(std::distance(__first, __last));
if (__n > 0)
{
@@ -3312,6 +3321,27 @@
#endif // _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER > 20
+template <class _Tp, class CharT>
+// Since is-vector-bool-reference is only used once it's inlined here.
+ requires same_as<typename _Tp::__container, vector<bool, typename _Tp::__container::allocator_type>>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Tp, CharT> {
+private:
+ formatter<bool, CharT> __underlying_;
+
+public:
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ return __underlying_.parse(__ctx);
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _Tp& __ref, _FormatContext& __ctx) const {
+ return __underlying_.format(__ref, __ctx);
+ }
+};
+#endif // _LIBCPP_STD_VER > 20
+
_LIBCPP_END_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
diff --git a/third_party/llvm-project/libcxx/include/version b/third_party/llvm-project/libcxx/include/version
index 2b81418..9705229 100644
--- a/third_party/llvm-project/libcxx/include/version
+++ b/third_party/llvm-project/libcxx/include/version
@@ -137,7 +137,7 @@
__cpp_lib_parallel_algorithm 201603L <algorithm> <numeric>
__cpp_lib_polymorphic_allocator 201902L <memory_resource>
__cpp_lib_quoted_string_io 201304L <iomanip>
-__cpp_lib_ranges 201811L <algorithm> <functional> <iterator>
+__cpp_lib_ranges 202106L <algorithm> <functional> <iterator>
<memory> <ranges>
__cpp_lib_ranges_chunk 202202L <ranges>
__cpp_lib_ranges_chunk_by 202202L <ranges>
@@ -356,7 +356,7 @@
# define __cpp_lib_list_remove_return_type 201806L
# define __cpp_lib_math_constants 201907L
# define __cpp_lib_polymorphic_allocator 201902L
-# define __cpp_lib_ranges 201811L
+# define __cpp_lib_ranges 202106L
# define __cpp_lib_remove_cvref 201711L
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)
# define __cpp_lib_semaphore 201907L
diff --git a/third_party/llvm-project/libcxx/src/atomic.cpp b/third_party/llvm-project/libcxx/src/atomic.cpp
index ec7bb7d..7777e88 100644
--- a/third_party/llvm-project/libcxx/src/atomic.cpp
+++ b/third_party/llvm-project/libcxx/src/atomic.cpp
@@ -26,6 +26,11 @@
# define SYS_futex SYS_futex_time64
#endif
+#elif defined(__FreeBSD__)
+
+#include <sys/types.h>
+#include <sys/umtx.h>
+
#else // <- Add other operating systems here
// Baseline needs no new headers
@@ -72,6 +77,22 @@
const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
}
+#elif defined(__FreeBSD__)
+
+static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
+ __cxx_contention_t __val)
+{
+ _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
+ UMTX_OP_WAIT_UINT_PRIVATE, __val, NULL, NULL);
+}
+
+static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr,
+ bool __notify_one)
+{
+ _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr),
+ UMTX_OP_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, NULL, NULL);
+}
+
#else // <- Add other operating systems here
// Baseline is just a timed backoff
diff --git a/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp
index c3da6f0..9c488c2 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp
@@ -15,19 +15,9 @@
#include "test_iterators.h"
-struct ForwardProxyIterator {
- using value_type = int;
- using difference_type = int;
- ForwardProxyIterator& operator++();
- ForwardProxyIterator operator++(int);
- bool operator==(const ForwardProxyIterator&) const;
-
- int operator*() const;
-};
-
static_assert(std::ranges::__nothrow_forward_iterator<forward_iterator<int*>>);
-static_assert(std::forward_iterator<ForwardProxyIterator>);
-static_assert(!std::ranges::__nothrow_forward_iterator<ForwardProxyIterator>);
+static_assert(std::forward_iterator<ForwardProxyIterator<int*>>);
+static_assert(!std::ranges::__nothrow_forward_iterator<ForwardProxyIterator<int*>>);
constexpr bool forward_subsumes_input(std::ranges::__nothrow_forward_iterator auto) {
return true;
diff --git a/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp
index 06af537..2ddfdf6 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp
@@ -16,18 +16,6 @@
#include "test_iterators.h"
#include "test_range.h"
-// Has to be a template to work with `test_range`.
-template <typename>
-struct ForwardProxyIterator {
- using value_type = int;
- using difference_type = int;
- ForwardProxyIterator& operator++();
- ForwardProxyIterator operator++(int);
- bool operator==(const ForwardProxyIterator&) const;
-
- int operator*() const;
-};
-
static_assert(std::ranges::__nothrow_forward_range<test_range<forward_iterator>>);
static_assert(!std::ranges::__nothrow_forward_range<test_range<cpp20_input_iterator>>);
static_assert(std::ranges::forward_range<test_range<ForwardProxyIterator>>);
diff --git a/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.compile-time.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.compile-time.pass.cpp
new file mode 100644
index 0000000..1ea6c36
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.compile-time.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 compile-time customization requires cross-file macros, which doesn't work with modules.
+// UNSUPPORTED: modules-build
+
+// Make sure that we can customize the verbose termination function at compile-time by
+// defining _LIBCPP_VERBOSE_ABORT ourselves. Note that this does not have any
+// deployment target requirements.
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 -D_LIBCPP_VERBOSE_ABORT(...)=my_abort(__VA_ARGS__)
+
+#include <cstdlib>
+
+void my_abort(char const*, ...) {
+ std::exit(EXIT_SUCCESS);
+}
+
+int main(int, char**) {
+ _LIBCPP_ASSERT(false, "message");
+ return EXIT_FAILURE;
+}
diff --git a/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.link-time.pass.cpp
similarity index 91%
rename from third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.pass.cpp
rename to third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.link-time.pass.cpp
index 3ee9b78..c0422dc 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.link-time.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// Test that we can set a custom verbose termination function.
+// Test that we can set a custom verbose termination function at link-time.
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
diff --git a/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.backdeployment.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/assertions/deprecated-link-time-custom-handler.pass.cpp
similarity index 66%
rename from third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.backdeployment.pass.cpp
rename to third_party/llvm-project/libcxx/test/libcxx/assertions/deprecated-link-time-custom-handler.pass.cpp
index 1596267..b699a3d 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/assertions/customize_verbose_abort.backdeployment.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/assertions/deprecated-link-time-custom-handler.pass.cpp
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-// Make sure that we can enable assertions when we back-deploy to older platforms
-// if we define _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED.
-//
-// Note that this test isn't really different from customize_verbose_abort.pass.cpp when
-// run outside of back-deployment scenarios, but we always want to run this test.
+// Make sure that we still support _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED for folks
+// who customize the verbose termination function at link-time in back-deployment environments.
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 -D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED
+// We emit a #warning about the deprecation of this setting, so make sure we don't turn that into an error.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-error
+
#include <cstdlib>
void std::__libcpp_verbose_abort(char const*, ...) {
diff --git a/third_party/llvm-project/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp b/third_party/llvm-project/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
index 7ca6d91..80f3f25 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp
@@ -6,7 +6,9 @@
//
//===----------------------------------------------------------------------===//
-// Test that all public C++ headers define the verbose termination function.
+// Test that all public C++ headers define the verbose termination function, which
+// is required for users to be able to include any public header and then override
+// the function using a strong definition.
// The system-provided <uchar.h> seems to be broken on AIX, which trips up this test.
// XFAIL: LIBCXX-AIX-FIXME
diff --git a/third_party/llvm-project/libcxx/test/libcxx/clang_query.sh.cpp b/third_party/llvm-project/libcxx/test/libcxx/clang_query.sh.cpp
deleted file mode 100644
index c3b9b02..0000000
--- a/third_party/llvm-project/libcxx/test/libcxx/clang_query.sh.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// Run clang-query on the headers - see clang_query/README.md for more information
-
-// REQUIRES: has-clang-query
-
-// The attributes hide_from_abi_of_visible.query relies on aren't applied on windows.
-// XFAIL: windows
-
-// RUN: %{clang-query} -f %S/clang_query/hide_from_abi_or_visible.query %s --use-color -- -Wno-unknown-warning-option %{compile_flags} -fno-modules > %t.output
-// RUN: cat %t.output
-// RUN: cat %t.output | wc -l | grep -Fxq 1
-
-// RUN: %{clang-query} -f %S/clang_query/abi_tag_on_virtual.query %s --use-color -- -Wno-unknown-warning-option %{compile_flags} -fno-modules > %t.output
-// RUN: cat %t.output
-// RUN: cat %t.output | wc -l | grep -Fxq 1
-
-// Prevent <ext/hash_map> from generating deprecated warnings for this test.
-#if defined(__DEPRECATED)
-# undef __DEPRECATED
-#endif
-
-/*
-BEGIN-SCRIPT
-
-for header in public_headers:
- print("{}#{}include <{}>{}".format(
- '#if ' + header_restrictions[header] + '\n' if header in header_restrictions else '',
- 3 * ' ' if header in header_restrictions else '',
- header,
- '\n#endif' if header in header_restrictions else ''
- ))
-
-END-SCRIPT
-*/
-
-// DO NOT MANUALLY EDIT ANYTHING BETWEEN THE MARKERS BELOW
-// GENERATED-MARKER
-#include <algorithm>
-#include <any>
-#include <array>
-#include <atomic>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-# include <barrier>
-#endif
-#include <bit>
-#include <bitset>
-#include <cassert>
-#include <ccomplex>
-#include <cctype>
-#include <cerrno>
-#include <cfenv>
-#include <cfloat>
-#include <charconv>
-#include <chrono>
-#include <cinttypes>
-#include <ciso646>
-#include <climits>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <clocale>
-#endif
-#include <cmath>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <codecvt>
-#endif
-#include <compare>
-#include <complex>
-#include <complex.h>
-#include <concepts>
-#include <condition_variable>
-#include <coroutine>
-#include <csetjmp>
-#include <csignal>
-#include <cstdarg>
-#include <cstdbool>
-#include <cstddef>
-#include <cstdint>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <ctgmath>
-#include <ctime>
-#include <ctype.h>
-#include <cuchar>
-#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-# include <cwchar>
-#endif
-#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-# include <cwctype>
-#endif
-#include <deque>
-#include <errno.h>
-#include <exception>
-#include <execution>
-#include <fenv.h>
-#if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
-# include <filesystem>
-#endif
-#include <float.h>
-#include <format>
-#include <forward_list>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <fstream>
-#endif
-#include <functional>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-# include <future>
-#endif
-#include <initializer_list>
-#include <inttypes.h>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <iomanip>
-#endif
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <ios>
-#endif
-#include <iosfwd>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <iostream>
-#endif
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <istream>
-#endif
-#include <iterator>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-# include <latch>
-#endif
-#include <limits>
-#include <limits.h>
-#include <list>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <locale>
-#endif
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <locale.h>
-#endif
-#include <map>
-#include <math.h>
-#include <memory>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-# include <mutex>
-#endif
-#include <new>
-#include <numbers>
-#include <numeric>
-#include <optional>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <ostream>
-#endif
-#include <queue>
-#include <random>
-#include <ranges>
-#include <ratio>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <regex>
-#endif
-#include <scoped_allocator>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-# include <semaphore>
-#endif
-#include <set>
-#include <setjmp.h>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-# include <shared_mutex>
-#endif
-#include <span>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <sstream>
-#endif
-#include <stack>
-#if __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS)
-# include <stdatomic.h>
-#endif
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdexcept>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <streambuf>
-#endif
-#include <string>
-#include <string.h>
-#include <string_view>
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-# include <strstream>
-#endif
-#include <system_error>
-#include <tgmath.h>
-#if !defined(_LIBCPP_HAS_NO_THREADS)
-# include <thread>
-#endif
-#include <tuple>
-#include <type_traits>
-#include <typeindex>
-#include <typeinfo>
-#include <uchar.h>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <valarray>
-#include <variant>
-#include <vector>
-#include <version>
-#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-# include <wchar.h>
-#endif
-#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
-# include <wctype.h>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/algorithm>
-#endif
-#if __cplusplus >= 201103L && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
-# include <experimental/coroutine>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/deque>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/forward_list>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/functional>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/iterator>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/list>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/map>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/memory_resource>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/propagate_const>
-#endif
-#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
-# include <experimental/regex>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/set>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/simd>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/string>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/type_traits>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/unordered_map>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/unordered_set>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/utility>
-#endif
-#if __cplusplus >= 201103L
-# include <experimental/vector>
-#endif
-#include <ext/hash_map>
-#include <ext/hash_set>
-// GENERATED-MARKER
diff --git a/third_party/llvm-project/libcxx/test/libcxx/clang_query/README.md b/third_party/llvm-project/libcxx/test/libcxx/clang_query/README.md
deleted file mode 100644
index 27f54b0..0000000
--- a/third_party/llvm-project/libcxx/test/libcxx/clang_query/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-
-This directory contains [AST matchers](https://clang.llvm.org/docs/LibASTMatchers.html) for clang-query.
-These allow us to enforce some rules in the libc++ source code which are hard to enforce through other means,
-like clang-tidy or regex matchers.
diff --git a/third_party/llvm-project/libcxx/test/libcxx/clang_query/abi_tag_on_virtual.query b/third_party/llvm-project/libcxx/test/libcxx/clang_query/abi_tag_on_virtual.query
deleted file mode 100644
index ffa465a..0000000
--- a/third_party/llvm-project/libcxx/test/libcxx/clang_query/abi_tag_on_virtual.query
+++ /dev/null
@@ -1,29 +0,0 @@
-#===------------------------------------------------------------------------===#
-#
-# 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 clang-query test ensures that we don't place an abi_tag attribute on
-# virtual functions. This can happen by mistakenly applying a macro like
-# _LIBCPP_HIDE_FROM_ABI on a virtual function.
-#
-# The problem is that arm64e pointer authentication extensions use the mangled
-# name of the function to sign the function pointer in the vtable, which means
-# that the ABI tag effectively influences how the pointers are signed.
-#
-# This can lead to PAC failures when passing an object that holds one of these
-# pointers in its vtable across an ABI boundary if the two sides have been compiled
-# with different versions of libc++: one side will sign the pointer using one function
-# mangling (with one ABI tag), and the other side will authenticate the pointer expecting
-# it to have a different mangled name due to the ABI tag being different, which will crash.
-#
-# This test ensures that we don't re-introduce this issue in the code base.
-
-match
-cxxMethodDecl(isVirtual(),
- hasAttr("attr::AbiTag"),
- unless(isExpansionInSystemHeader())
- )
diff --git a/third_party/llvm-project/libcxx/test/libcxx/clang_query/hide_from_abi_or_visible.query b/third_party/llvm-project/libcxx/test/libcxx/clang_query/hide_from_abi_or_visible.query
deleted file mode 100644
index d287a09..0000000
--- a/third_party/llvm-project/libcxx/test/libcxx/clang_query/hide_from_abi_or_visible.query
+++ /dev/null
@@ -1,37 +0,0 @@
-#===------------------------------------------------------------------------===#
-#
-# 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
-#
-#===------------------------------------------------------------------------===#
-
-# Check that all functions in the libc++ headers are either marked with hidden
-# visibility or default visibility
-
-# TODO: enable the check for all functions once we don't force-inline everything with GCC
-match
-functionDecl(
- unless(
- anyOf(
- hasName("__introsort"),
- hasName("__inplace_merge"),
- hasName("__libcpp_snprintf_l"),
- hasName("__libcpp_asprintf_l"),
- hasName("__libcpp_sscanf_l"),
- hasName("__tree_sub_invariant"),
- hasName("__stable_sort_move"),
- hasName("__stable_sort"),
- hasName("__stable_partition"),
- hasName("__lock_first"),
- hasName("__stable_partition_impl"),
- hasAttr("attr::Visibility"),
- hasAttr("attr::AbiTag"),
- cxxMethodDecl(), # We have explicitly instantiated classes and some of their methods don't have these attributes
- isDeleted(),
- isConsteval(),
- isExpansionInSystemHeader()
- )
- ),
- isDefinition()
-)
diff --git a/third_party/llvm-project/libcxx/test/libcxx/diagnostics/view_adaptors.nodiscard_extensions.verify.cpp b/third_party/llvm-project/libcxx/test/libcxx/diagnostics/view_adaptors.nodiscard_extensions.verify.cpp
new file mode 100644
index 0000000..6cd9739
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/libcxx/diagnostics/view_adaptors.nodiscard_extensions.verify.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that view adaptors are marked [[nodiscard]] as a conforming extension
+
+// UNSUPPORTED: c++03, c++11, c++14 ,c++17, c++20
+
+#include <ranges>
+#include <vector>
+
+void func() {
+ std::vector<int> range;
+
+ auto rvalue_view = std::views::as_rvalue(range);
+ std::views::as_rvalue(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::as_rvalue(rvalue_view); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/third_party/llvm-project/libcxx/test/libcxx/iterators/iterator_with_data.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/iterators/iterator_with_data.pass.cpp
new file mode 100644
index 0000000..a4c2b08
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/libcxx/iterators/iterator_with_data.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include "test_macros.h"
+
+TEST_DIAGNOSTIC_PUSH
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__iterator/iterator_with_data.h>
+TEST_DIAGNOSTIC_POP
+
+#include "test_iterators.h"
+
+static_assert(std::forward_iterator<std::__iterator_with_data<forward_iterator<int*>, int>>);
+static_assert(std::bidirectional_iterator<std::__iterator_with_data<bidirectional_iterator<int*>, int>>);
+static_assert(std::bidirectional_iterator<std::__iterator_with_data<random_access_iterator<int*>, int>>);
+static_assert(std::bidirectional_iterator<std::__iterator_with_data<contiguous_iterator<int*>, int>>);
+
+constexpr bool test() {
+ {
+ std::__iterator_with_data<forward_iterator<int*>, int> iter(forward_iterator<int*>(nullptr), 3);
+ assert(iter == iter);
+ assert(iter.__get_iter() == forward_iterator<int*>(nullptr));
+ assert(std::move(iter).__get_data() == 3);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+}
diff --git a/third_party/llvm-project/libcxx/test/libcxx/modules_include.sh.cpp b/third_party/llvm-project/libcxx/test/libcxx/modules_include.sh.cpp
index 460538b..a45d3d4 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/modules_include.sh.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/modules_include.sh.cpp
@@ -13,6 +13,8 @@
// The system-provided <uchar.h> seems to be broken on AIX
// XFAIL: LIBCXX-AIX-FIXME
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// GCC doesn't support -fcxx-modules
// UNSUPPORTED: gcc
diff --git a/third_party/llvm-project/libcxx/test/libcxx/private_headers.verify.cpp b/third_party/llvm-project/libcxx/test/libcxx/private_headers.verify.cpp
index f88ee37..ebbd50b 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/private_headers.verify.cpp
@@ -334,6 +334,7 @@
#include <__filesystem/u8path.h> // expected-error@*:* {{use of private header from outside its module: '__filesystem/u8path.h'}}
#include <__format/buffer.h> // expected-error@*:* {{use of private header from outside its module: '__format/buffer.h'}}
#include <__format/concepts.h> // expected-error@*:* {{use of private header from outside its module: '__format/concepts.h'}}
+#include <__format/container_adaptor.h> // expected-error@*:* {{use of private header from outside its module: '__format/container_adaptor.h'}}
#include <__format/enable_insertable.h> // expected-error@*:* {{use of private header from outside its module: '__format/enable_insertable.h'}}
#include <__format/escaped_output_table.h> // expected-error@*:* {{use of private header from outside its module: '__format/escaped_output_table.h'}}
#include <__format/extended_grapheme_cluster_table.h> // expected-error@*:* {{use of private header from outside its module: '__format/extended_grapheme_cluster_table.h'}}
@@ -359,6 +360,7 @@
#include <__format/formatter_tuple.h> // expected-error@*:* {{use of private header from outside its module: '__format/formatter_tuple.h'}}
#include <__format/parser_std_format_spec.h> // expected-error@*:* {{use of private header from outside its module: '__format/parser_std_format_spec.h'}}
#include <__format/range_default_formatter.h> // expected-error@*:* {{use of private header from outside its module: '__format/range_default_formatter.h'}}
+#include <__format/range_formatter.h> // expected-error@*:* {{use of private header from outside its module: '__format/range_formatter.h'}}
#include <__format/unicode.h> // expected-error@*:* {{use of private header from outside its module: '__format/unicode.h'}}
#include <__functional/binary_function.h> // expected-error@*:* {{use of private header from outside its module: '__functional/binary_function.h'}}
#include <__functional/binary_negate.h> // expected-error@*:* {{use of private header from outside its module: '__functional/binary_negate.h'}}
@@ -421,6 +423,7 @@
#include <__iterator/iter_swap.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/iter_swap.h'}}
#include <__iterator/iterator.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/iterator.h'}}
#include <__iterator/iterator_traits.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/iterator_traits.h'}}
+#include <__iterator/iterator_with_data.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/iterator_with_data.h'}}
#include <__iterator/mergeable.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/mergeable.h'}}
#include <__iterator/move_iterator.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/move_iterator.h'}}
#include <__iterator/move_sentinel.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/move_sentinel.h'}}
@@ -433,6 +436,7 @@
#include <__iterator/readable_traits.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/readable_traits.h'}}
#include <__iterator/reverse_access.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/reverse_access.h'}}
#include <__iterator/reverse_iterator.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/reverse_iterator.h'}}
+#include <__iterator/segmented_iterator.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/segmented_iterator.h'}}
#include <__iterator/size.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/size.h'}}
#include <__iterator/sortable.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/sortable.h'}}
#include <__iterator/unreachable_sentinel.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/unreachable_sentinel.h'}}
@@ -527,6 +531,7 @@
#include <__random/weibull_distribution.h> // expected-error@*:* {{use of private header from outside its module: '__random/weibull_distribution.h'}}
#include <__ranges/access.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/access.h'}}
#include <__ranges/all.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/all.h'}}
+#include <__ranges/as_rvalue_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/as_rvalue_view.h'}}
#include <__ranges/common_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/common_view.h'}}
#include <__ranges/concepts.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/concepts.h'}}
#include <__ranges/copyable_box.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/copyable_box.h'}}
@@ -554,6 +559,7 @@
#include <__ranges/reverse_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/reverse_view.h'}}
#include <__ranges/single_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/single_view.h'}}
#include <__ranges/size.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/size.h'}}
+#include <__ranges/split_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/split_view.h'}}
#include <__ranges/subrange.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/subrange.h'}}
#include <__ranges/take_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/take_view.h'}}
#include <__ranges/take_while_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/take_while_view.h'}}
@@ -712,6 +718,7 @@
#include <__utility/cmp.h> // expected-error@*:* {{use of private header from outside its module: '__utility/cmp.h'}}
#include <__utility/convert_to_integral.h> // expected-error@*:* {{use of private header from outside its module: '__utility/convert_to_integral.h'}}
#include <__utility/declval.h> // expected-error@*:* {{use of private header from outside its module: '__utility/declval.h'}}
+#include <__utility/exception_guard.h> // expected-error@*:* {{use of private header from outside its module: '__utility/exception_guard.h'}}
#include <__utility/exchange.h> // expected-error@*:* {{use of private header from outside its module: '__utility/exchange.h'}}
#include <__utility/forward.h> // expected-error@*:* {{use of private header from outside its module: '__utility/forward.h'}}
#include <__utility/forward_like.h> // expected-error@*:* {{use of private header from outside its module: '__utility/forward_like.h'}}
@@ -724,7 +731,6 @@
#include <__utility/rel_ops.h> // expected-error@*:* {{use of private header from outside its module: '__utility/rel_ops.h'}}
#include <__utility/swap.h> // expected-error@*:* {{use of private header from outside its module: '__utility/swap.h'}}
#include <__utility/to_underlying.h> // expected-error@*:* {{use of private header from outside its module: '__utility/to_underlying.h'}}
-#include <__utility/transaction.h> // expected-error@*:* {{use of private header from outside its module: '__utility/transaction.h'}}
#include <__utility/unreachable.h> // expected-error@*:* {{use of private header from outside its module: '__utility/unreachable.h'}}
#include <__variant/monostate.h> // expected-error@*:* {{use of private header from outside its module: '__variant/monostate.h'}}
// GENERATED-MARKER
diff --git a/third_party/llvm-project/libcxx/test/libcxx/ranges/range.adaptors/range.split/no_unique_address.compile.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/ranges/range.adaptors/range.split/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000..c04dbd7
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/libcxx/ranges/range.adaptors/range.split/no_unique_address.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// clang-cl and cl currently don't support [[no_unique_address]]
+// XFAIL: msvc
+
+// class split_view {
+// _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+// _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern();
+// };
+
+#include <ranges>
+
+#include "test_iterators.h"
+
+struct EmptyView : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+using SplitView = std::ranges::split_view<EmptyView, EmptyView>;
+static_assert(sizeof(SplitView) == sizeof(std::ranges::__non_propagating_cache<std::ranges::subrange<int*>>));
diff --git a/third_party/llvm-project/libcxx/test/libcxx/selftest/remote-substitutions.sh.cpp b/third_party/llvm-project/libcxx/test/libcxx/selftest/remote-substitutions.sh.cpp
index da25df9..da27979 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/selftest/remote-substitutions.sh.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/selftest/remote-substitutions.sh.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// Make sure that test-executables can appear in RUN lines and be executed
// effectively. This somewhat difficult-to-understand test checks that when
// we run with a remote executor, test-executables are copied to the remote
diff --git a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx03.csv b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx03.csv
index 08f449b..58fe49c 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -354,11 +354,14 @@
format limits
format locale
format optional
+format queue
+format stack
format stdexcept
format string
format string_view
format tuple
format type_traits
+format vector
format version
forward_list algorithm
forward_list atomic
diff --git a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx11.csv b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx11.csv
index 6ecca62..2f9ef7d 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -354,11 +354,14 @@
format limits
format locale
format optional
+format queue
+format stack
format stdexcept
format string
format string_view
format tuple
format type_traits
+format vector
format version
forward_list algorithm
forward_list atomic
diff --git a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx14.csv b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx14.csv
index fb50933..0d10e23 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -356,11 +356,14 @@
format limits
format locale
format optional
+format queue
+format stack
format stdexcept
format string
format string_view
format tuple
format type_traits
+format vector
format version
forward_list algorithm
forward_list atomic
diff --git a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx17.csv b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx17.csv
index fb50933..0d10e23 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -356,11 +356,14 @@
format limits
format locale
format optional
+format queue
+format stack
format stdexcept
format string
format string_view
format tuple
format type_traits
+format vector
format version
forward_list algorithm
forward_list atomic
diff --git a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx20.csv b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx20.csv
index 7e7661d..8f47b61 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -125,6 +125,7 @@
chrono string_view
chrono tuple
chrono type_traits
+chrono vector
chrono version
cinttypes cstdint
cmath type_traits
@@ -364,11 +365,14 @@
format limits
format locale
format optional
+format queue
+format stack
format stdexcept
format string
format string_view
format tuple
format type_traits
+format vector
format version
forward_list algorithm
forward_list atomic
diff --git a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx2b.csv b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx2b.csv
index 21b32bf..23cc6d7 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx2b.csv
+++ b/third_party/llvm-project/libcxx/test/libcxx/transitive_includes/cxx2b.csv
@@ -95,6 +95,7 @@
chrono string_view
chrono tuple
chrono type_traits
+chrono vector
chrono version
cinttypes cstdint
cmath version
@@ -137,7 +138,6 @@
coroutine cstdint
coroutine cstring
coroutine limits
-coroutine type_traits
coroutine version
cstddef version
ctgmath ccomplex
@@ -272,11 +272,14 @@
format limits
format locale
format optional
+format queue
+format stack
format stdexcept
format string
format string_view
format tuple
format type_traits
+format vector
format version
forward_list compare
forward_list cstddef
@@ -448,12 +451,10 @@
new cstdlib
new exception
new version
-numbers type_traits
numbers version
numeric cmath
numeric cstddef
numeric limits
-numeric type_traits
numeric version
optional compare
optional cstddef
diff --git a/third_party/llvm-project/libcxx/test/libcxx/utilities/assert.exception_guard.no_exceptions.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/utilities/assert.exception_guard.no_exceptions.pass.cpp
new file mode 100644
index 0000000..5c9cc38
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/libcxx/utilities/assert.exception_guard.no_exceptions.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// REQUIRES: has-unix-headers
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
+// ADDITIONAL_COMPILE_FLAGS: -fno-exceptions -D_LIBCPP_ENABLE_ASSERTIONS
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-private-header
+
+#include <__utility/exception_guard.h>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::__make_exception_guard([] {}), "__exception_guard not completed with exceptions disabled");
+}
diff --git a/third_party/llvm-project/libcxx/test/libcxx/utilities/exception_guard.no_exceptions.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/utilities/exception_guard.no_exceptions.pass.cpp
new file mode 100644
index 0000000..0b6233e
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/libcxx/utilities/exception_guard.no_exceptions.pass.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// ADDITIONAL_COMPILE_FLAGS: -fno-exceptions -D_LIBCPP_ENABLE_ASSERTIONS
+
+#include <utility>
+
+int main(int, char**) {
+ auto guard = std::__make_exception_guard([] {});
+ auto guard2 = std::move(guard);
+ guard2.__complete();
+}
diff --git a/third_party/llvm-project/libcxx/test/libcxx/utilities/transaction.pass.cpp b/third_party/llvm-project/libcxx/test/libcxx/utilities/exception_guard.pass.cpp
similarity index 81%
rename from third_party/llvm-project/libcxx/test/libcxx/utilities/transaction.pass.cpp
rename to third_party/llvm-project/libcxx/test/libcxx/utilities/exception_guard.pass.cpp
index e517ffd..71e60fc 100644
--- a/third_party/llvm-project/libcxx/test/libcxx/utilities/transaction.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/libcxx/utilities/exception_guard.pass.cpp
@@ -8,7 +8,8 @@
// UNSUPPORTED: c++03
-#include <utility> // for __transaction
+// UNSUPPORTED: no-exceptions
+
#include <cassert>
#include <type_traits>
#include <utility>
@@ -22,7 +23,7 @@
bool rolled_back = false;
{
auto rollback = [&] { rolled_back = true; };
- std::__transaction<decltype(rollback)> t(rollback);
+ std::__exception_guard<decltype(rollback)> g(rollback);
}
assert(rolled_back);
}
@@ -33,8 +34,8 @@
bool rolled_back = false;
{
auto rollback = [&] { rolled_back = true; };
- std::__transaction<decltype(rollback)> t(rollback);
- t.__complete();
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ g.__complete();
}
assert(!rolled_back);
}
@@ -47,8 +48,8 @@
int rollbacks = 0;
{
auto rollback = [&] { ++rollbacks; };
- std::__transaction<decltype(rollback)> t(rollback);
- auto other = std::move(t);
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ auto other = std::move(g);
}
assert(rollbacks == 1);
}
@@ -58,8 +59,8 @@
int rollbacks = 0;
{
auto rollback = [&] { ++rollbacks; };
- std::__transaction<decltype(rollback)> t(rollback);
- auto other = std::move(t);
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ auto other = std::move(g);
other.__complete();
}
assert(rollbacks == 0);
@@ -69,7 +70,7 @@
// Basic properties of the type
{
struct Rollback { void operator()() const { } };
- using Transaction = std::__transaction<Rollback>;
+ using Transaction = std::__exception_guard<Rollback>;
static_assert(!std::is_default_constructible<Transaction>::value, "");
@@ -85,7 +86,7 @@
ThrowOnMove(ThrowOnMove&&) noexcept(false) { }
void operator()() const { }
};
- using ThrowOnMoveTransaction = std::__transaction<ThrowOnMove>;
+ using ThrowOnMoveTransaction = std::__exception_guard<ThrowOnMove>;
ASSERT_NOEXCEPT(std::declval<Transaction>().__complete());
static_assert( std::is_nothrow_move_constructible<Transaction>::value, "");
@@ -104,7 +105,7 @@
bool rolled_back = false;
auto rollback = [&] { rolled_back = true; };
try {
- std::__transaction<decltype(rollback)> t(rollback);
+ std::__exception_guard<decltype(rollback)> g(rollback);
throw 0;
} catch (...) { }
assert(rolled_back);
@@ -116,14 +117,14 @@
bool rolled_back = false;
auto rollback = [&] { rolled_back = true; };
try {
- std::__transaction<decltype(rollback)> t(rollback);
- t.__complete();
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ g.__complete();
throw 0;
} catch (...) { }
assert(!rolled_back);
}
- // Make sure __transaction does not rollback if the transaction is marked as
+ // Make sure __exception_guard does not rollback if the transaction is marked as
// completed within a destructor.
{
struct S {
@@ -131,8 +132,8 @@
~S() {
auto rollback = [this]{ x_ = true; };
- std::__transaction<decltype(rollback)> t(rollback);
- t.__complete();
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ g.__complete();
}
bool& x_;
diff --git a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp
index c241056..7a5c0a7 100644
--- a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.pass.cpp
@@ -20,7 +20,9 @@
#include <algorithm>
#include <array>
#include <cassert>
+#include <deque>
#include <ranges>
+#include <vector>
#include "almost_satisfies_types.h"
#include "test_iterators.h"
@@ -53,20 +55,21 @@
static_assert(std::is_same_v<std::ranges::copy_result<int, long>, std::ranges::in_out_result<int, long>>);
+// clang-format off
template <class In, class Out, class Sent = In>
constexpr void test_iterators() {
{ // simple test
{
- std::array in {1, 2, 3, 4};
+ std::array in{1, 2, 3, 4};
std::array<int, 4> out;
std::same_as<std::ranges::in_out_result<In, Out>> auto ret =
- std::ranges::copy(In(in.data()), Sent(In(in.data() + in.size())), Out(out.data()));
+ std::ranges::copy(In(in.data()), Sent(In(in.data() + in.size())), Out(out.data()));
assert(in == out);
assert(base(ret.in) == in.data() + in.size());
assert(base(ret.out) == out.data() + out.size());
}
{
- std::array in {1, 2, 3, 4};
+ std::array in{1, 2, 3, 4};
std::array<int, 4> out;
auto range = std::ranges::subrange(In(in.data()), Sent(In(in.data() + in.size())));
std::same_as<std::ranges::in_out_result<In, Out>> auto ret = std::ranges::copy(range, Out(out.data()));
@@ -88,12 +91,13 @@
std::array<int, 0> in;
std::array<int, 0> out;
auto range = std::ranges::subrange(In(in.data()), Sent(In(in.data() + in.size())));
- auto ret = std::ranges::copy(range, Out(out.data()));
+ auto ret = std::ranges::copy(range, Out(out.data()));
assert(base(ret.in) == in.data());
assert(base(ret.out) == out.data());
}
}
}
+// clang-format on
constexpr bool test() {
meta::for_each(meta::forward_iterator_list<int*>{}, []<class Out>() {
@@ -122,7 +126,7 @@
}
{ // check that an iterator is returned with a borrowing range
- std::array in {1, 2, 3, 4};
+ std::array in{1, 2, 3, 4};
std::array<int, 4> out;
std::same_as<std::ranges::in_out_result<int*, int*>> auto ret = std::ranges::copy(std::views::all(in), out.data());
assert(ret.in == in.data() + 4);
@@ -132,8 +136,8 @@
{ // check that every element is copied exactly once
struct CopyOnce {
- bool copied = false;
- constexpr CopyOnce() = default;
+ bool copied = false;
+ constexpr CopyOnce() = default;
constexpr CopyOnce(const CopyOnce& other) = delete;
constexpr CopyOnce& operator=(const CopyOnce& other) {
assert(!other.copied);
@@ -142,16 +146,16 @@
}
};
{
- std::array<CopyOnce, 4> in {};
- std::array<CopyOnce, 4> out {};
+ std::array<CopyOnce, 4> in{};
+ std::array<CopyOnce, 4> out{};
auto ret = std::ranges::copy(in.begin(), in.end(), out.begin());
assert(ret.in == in.end());
assert(ret.out == out.end());
assert(std::all_of(out.begin(), out.end(), [](const auto& e) { return e.copied; }));
}
{
- std::array<CopyOnce, 4> in {};
- std::array<CopyOnce, 4> out {};
+ std::array<CopyOnce, 4> in{};
+ std::array<CopyOnce, 4> out{};
auto ret = std::ranges::copy(in, out.begin());
assert(ret.in == in.end());
assert(ret.out == out.end());
@@ -162,8 +166,8 @@
{ // check that the range is copied forwards
struct OnlyForwardsCopyable {
OnlyForwardsCopyable* next = nullptr;
- bool canCopy = false;
- OnlyForwardsCopyable() = default;
+ bool canCopy = false;
+ OnlyForwardsCopyable() = default;
constexpr OnlyForwardsCopyable& operator=(const OnlyForwardsCopyable&) {
assert(canCopy);
if (next != nullptr)
@@ -172,12 +176,12 @@
}
};
{
- std::array<OnlyForwardsCopyable, 3> in {};
- std::array<OnlyForwardsCopyable, 3> out {};
- out[0].next = &out[1];
- out[1].next = &out[2];
+ std::array<OnlyForwardsCopyable, 3> in{};
+ std::array<OnlyForwardsCopyable, 3> out{};
+ out[0].next = &out[1];
+ out[1].next = &out[2];
out[0].canCopy = true;
- auto ret = std::ranges::copy(in.begin(), in.end(), out.begin());
+ auto ret = std::ranges::copy(in.begin(), in.end(), out.begin());
assert(ret.in == in.end());
assert(ret.out == out.end());
assert(out[0].canCopy);
@@ -185,12 +189,12 @@
assert(out[2].canCopy);
}
{
- std::array<OnlyForwardsCopyable, 3> in {};
- std::array<OnlyForwardsCopyable, 3> out {};
- out[0].next = &out[1];
- out[1].next = &out[2];
+ std::array<OnlyForwardsCopyable, 3> in{};
+ std::array<OnlyForwardsCopyable, 3> out{};
+ out[0].next = &out[1];
+ out[1].next = &out[2];
out[0].canCopy = true;
- auto ret = std::ranges::copy(in, out.begin());
+ auto ret = std::ranges::copy(in, out.begin());
assert(ret.in == in.end());
assert(ret.out == out.end());
assert(out[0].canCopy);
diff --git a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp
new file mode 100644
index 0000000..5b8d8b8
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy.segmented.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <deque>
+#include <ranges>
+#include <vector>
+
+#include "test_iterators.h"
+#include "type_algorithms.h"
+
+template <class InContainer, class OutContainer>
+constexpr void test_containers() {
+ using InIter = typename InContainer::iterator;
+ using OutIter = typename OutContainer::iterator;
+
+ {
+ InContainer in{1, 2, 3, 4};
+ OutContainer out(4);
+
+ std::same_as<std::ranges::in_out_result<InIter, OutIter>> auto ret =
+ std::ranges::copy(in.begin(), in.end(), out.begin());
+ assert(std::ranges::equal(in, out));
+ assert(ret.in == in.end());
+ assert(ret.out == out.end());
+ }
+ {
+ InContainer in{1, 2, 3, 4};
+ OutContainer out(4);
+ std::same_as<std::ranges::in_out_result<InIter, OutIter>> auto ret = std::ranges::copy(in, out.begin());
+ assert(std::ranges::equal(in, out));
+ assert(ret.in == in.end());
+ assert(ret.out == out.end());
+ }
+}
+
+template <class Iter, class Sent>
+constexpr void test_join_view() {
+ auto to_subranges = std::views::transform([](auto& vec) {
+ return std::ranges::subrange(Iter(vec.data()), Sent(Iter(vec.data() + vec.size())));
+ });
+
+ { // segmented -> contiguous
+ std::vector<std::vector<int>> vectors = {};
+ auto range = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end());
+ std::array<int, 0> arr;
+
+ std::ranges::copy(subrange_vector | std::views::join, arr.begin());
+ assert(std::ranges::equal(arr, std::array<int, 0>{}));
+ }
+ { // segmented -> contiguous
+ std::vector<std::vector<int>> vectors = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10}, {}};
+ auto range = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end());
+ std::array<int, 10> arr;
+
+ std::ranges::copy(subrange_vector | std::views::join, arr.begin());
+ assert(std::ranges::equal(arr, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
+ }
+ { // contiguous -> segmented
+ std::vector<std::vector<int>> vectors = {{0, 0, 0, 0}, {0, 0}, {0, 0, 0, 0}, {}};
+ auto range = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end());
+ std::array arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+ std::ranges::copy(arr, (subrange_vector | std::views::join).begin());
+ assert(std::ranges::equal(subrange_vector | std::views::join, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
+ }
+ { // segmented -> segmented
+ std::vector<std::vector<int>> vectors = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10}, {}};
+ auto range1 = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range1.begin(), range1.end());
+ std::vector<std::vector<int>> to_vectors = {{0, 0, 0, 0}, {0, 0, 0, 0}, {}, {0, 0}};
+ auto range2 = to_vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> to_subrange_vector(range2.begin(), range2.end());
+
+ std::ranges::copy(subrange_vector | std::views::join, (to_subrange_vector | std::views::join).begin());
+ assert(std::ranges::equal(to_subrange_vector | std::views::join, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
+ }
+}
+
+int main(int, char**) {
+ if (!std::is_constant_evaluated()) {
+ test_containers<std::deque<int>, std::deque<int>>();
+ test_containers<std::deque<int>, std::vector<int>>();
+ test_containers<std::vector<int>, std::deque<int>>();
+ test_containers<std::vector<int>, std::vector<int>>();
+ }
+
+ meta::for_each(meta::forward_iterator_list<int*>{}, []<class Iter> {
+ test_join_view<Iter, Iter>();
+ test_join_view<Iter, sentinel_wrapper<Iter>>();
+ test_join_view<Iter, sized_sentinel<Iter>>();
+ });
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp
index a18ba9d..036dfe5 100644
--- a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.copy/ranges.copy_backward.pass.cpp
@@ -23,7 +23,9 @@
#include <algorithm>
#include <array>
#include <cassert>
+#include <deque>
#include <ranges>
+#include <vector>
#include "almost_satisfies_types.h"
#include "test_iterators.h"
@@ -99,37 +101,138 @@
}
}
-template <class InIter, class OutIter>
+template <class InContainer, class OutContainer, class In, class Out, class Sent = In>
+constexpr void test_containers() {
+ {
+ InContainer in {1, 2, 3, 4};
+ OutContainer out(4);
+ std::same_as<std::ranges::in_out_result<In, Out>> auto ret =
+ std::ranges::copy_backward(In(in.begin()), Sent(In(in.end())), Out(out.end()));
+ assert(std::ranges::equal(in, out));
+ assert(base(ret.in) == in.end());
+ assert(base(ret.out) == out.begin());
+ }
+ {
+ InContainer in {1, 2, 3, 4};
+ OutContainer out(4);
+ auto range = std::ranges::subrange(In(in.begin()), Sent(In(in.end())));
+ std::same_as<std::ranges::in_out_result<In, Out>> auto ret = std::ranges::copy_backward(range, Out(out.end()));
+ assert(std::ranges::equal(in, out));
+ assert(base(ret.in) == in.end());
+ assert(base(ret.out) == out.begin());
+ }
+}
+
+template <class Iter, class Sent>
+constexpr void test_join_view() {
+ auto to_subranges = std::views::transform([](auto& vec) {
+ return std::ranges::subrange(Iter(vec.begin()), Sent(Iter(vec.end())));
+ });
+
+ { // segmented -> contiguous
+ std::vector<std::vector<int>> vectors = {};
+ auto range = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end());
+ std::array<int, 0> arr;
+
+ std::ranges::copy_backward(subrange_vector | std::views::join, arr.end());
+ assert(std::ranges::equal(arr, std::array<int, 0>{}));
+ }
+ { // segmented -> contiguous
+ std::vector<std::vector<int>> vectors = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10}, {}};
+ auto range = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end());
+ std::array<int, 10> arr;
+
+ std::ranges::copy_backward(subrange_vector | std::views::join, arr.end());
+ assert(std::ranges::equal(arr, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
+ }
+ { // contiguous -> segmented
+ std::vector<std::vector<int>> vectors = {{0, 0, 0, 0}, {0, 0}, {0, 0, 0, 0}, {}};
+ auto range = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range.begin(), range.end());
+ std::array arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+ std::ranges::copy_backward(arr, (subrange_vector | std::views::join).end());
+ assert(std::ranges::equal(subrange_vector | std::views::join, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
+ }
+ { // segmented -> segmented
+ std::vector<std::vector<int>> vectors = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10}, {}};
+ auto range1 = vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> subrange_vector(range1.begin(), range1.end());
+ std::vector<std::vector<int>> to_vectors = {{0, 0, 0, 0}, {0, 0, 0, 0}, {}, {0, 0}};
+ auto range2 = to_vectors | to_subranges;
+ std::vector<std::ranges::subrange<Iter, Sent>> to_subrange_vector(range2.begin(), range2.end());
+
+ std::ranges::copy_backward(subrange_vector | std::views::join, (to_subrange_vector | std::views::join).end());
+ assert(std::ranges::equal(to_subrange_vector | std::views::join, std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
+ }
+}
+
+template <class>
+constexpr bool is_proxy_iterator = false;
+
+template <class Iter>
+constexpr bool is_proxy_iterator<ProxyIterator<Iter>> = true;
+
+template <template <class> class InIter, template <class> class OutIter>
constexpr void test_sentinels() {
- test_iterators<InIter, OutIter, InIter>();
- test_iterators<InIter, OutIter, sentinel_wrapper<InIter>>();
- test_iterators<InIter, OutIter, sized_sentinel<InIter>>();
+ test_iterators<InIter<int*>, OutIter<int*>, InIter<int*>>();
+ test_iterators<InIter<int*>, OutIter<int*>, sentinel_wrapper<InIter<int*>>>();
+ test_iterators<InIter<int*>, OutIter<int*>, sized_sentinel<InIter<int*>>>();
+
+ if constexpr (!std::is_same_v<InIter<int*>, contiguous_iterator<int*>> &&
+ !std::is_same_v<OutIter<int*>, contiguous_iterator<int*>> &&
+ !std::is_same_v<InIter<int*>, ContiguousProxyIterator<int*>> &&
+ !std::is_same_v<OutIter<int*>, ContiguousProxyIterator<int*>>) {
+ if (!std::is_constant_evaluated()) {
+ test_containers<std::deque<int>,
+ std::deque<int>,
+ InIter<std::deque<int>::iterator>,
+ OutIter<std::deque<int>::iterator>>();
+ test_containers<std::deque<int>,
+ std::vector<int>,
+ InIter<std::deque<int>::iterator>,
+ OutIter<std::vector<int>::iterator>>();
+ test_containers<std::vector<int>,
+ std::deque<int>,
+ InIter<std::vector<int>::iterator>,
+ OutIter<std::deque<int>::iterator>>();
+ test_containers<std::vector<int>,
+ std::vector<int>,
+ InIter<std::vector<int>::iterator>,
+ OutIter<std::vector<int>::iterator>>();
+ }
+ if constexpr (!is_proxy_iterator<InIter<int*>>)
+ test_join_view<InIter<std::vector<int>::iterator>, InIter<std::vector<int>::iterator>>();
+ }
}
-template <class Out>
+template <template <class> class Out>
constexpr void test_in_iterators() {
- test_sentinels<bidirectional_iterator<int*>, Out>();
- test_sentinels<random_access_iterator<int*>, Out>();
- test_sentinels<contiguous_iterator<int*>, Out>();
- test_sentinels<int*, Out>();
+ test_sentinels<bidirectional_iterator, Out>();
+ test_sentinels<random_access_iterator, Out>();
+ test_sentinels<contiguous_iterator, Out>();
+ test_sentinels<std::type_identity_t, Out>();
}
-template <class Out>
+template <template <class> class Out>
constexpr void test_proxy_in_iterators() {
- test_sentinels<ProxyIterator<bidirectional_iterator<int*>>, Out>();
- test_sentinels<ProxyIterator<random_access_iterator<int*>>, Out>();
- test_sentinels<ProxyIterator<contiguous_iterator<int*>>, Out>();
+ test_sentinels<BidirectionalProxyIterator, Out>();
+ test_sentinels<RandomAccessProxyIterator, Out>();
+ test_sentinels<ContiguousProxyIterator, Out>();
+ test_sentinels<ProxyIterator, Out>();
}
constexpr bool test() {
- test_in_iterators<bidirectional_iterator<int*>>();
- test_in_iterators<random_access_iterator<int*>>();
- test_in_iterators<contiguous_iterator<int*>>();
- test_in_iterators<int*>();
+ test_in_iterators<bidirectional_iterator>();
+ test_in_iterators<random_access_iterator>();
+ test_in_iterators<contiguous_iterator>();
+ test_in_iterators<std::type_identity_t>();
- test_proxy_in_iterators<ProxyIterator<bidirectional_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<random_access_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<contiguous_iterator<int*>>>();
+ test_proxy_in_iterators<BidirectionalProxyIterator>();
+ test_proxy_in_iterators<RandomAccessProxyIterator>();
+ test_proxy_in_iterators<ContiguousProxyIterator>();
{ // check that ranges::dangling is returned
std::array<int, 4> out;
diff --git a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp
index 2963096..18ac692 100644
--- a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp
@@ -22,7 +22,9 @@
#include <algorithm>
#include <array>
#include <cassert>
+#include <deque>
#include <ranges>
+#include <vector>
#include "almost_satisfies_types.h"
#include "MoveOnly.h"
@@ -77,6 +79,28 @@
}
}
+template <class InContainer, class OutContainer, class In, class Out, class Sent = In>
+constexpr void test_containers() {
+ {
+ InContainer in {1, 2, 3, 4};
+ OutContainer out(4);
+ std::same_as<std::ranges::in_out_result<In, Out>> auto ret =
+ std::ranges::move(In(in.begin()), Sent(In(in.end())), Out(out.begin()));
+ assert(std::ranges::equal(in, out));
+ assert(base(ret.in) == in.end());
+ assert(base(ret.out) == out.end());
+ }
+ {
+ InContainer in {1, 2, 3, 4};
+ OutContainer out(4);
+ auto range = std::ranges::subrange(In(in.begin()), Sent(In(in.end())));
+ std::same_as<std::ranges::in_out_result<In, Out>> auto ret = std::ranges::move(range, Out(out.begin()));
+ assert(std::ranges::equal(in, out));
+ assert(base(ret.in) == in.end());
+ assert(base(ret.out) == out.end());
+ }
+}
+
template <class In, class Out, class Sent = In>
constexpr void test_iterators() {
// simple test
@@ -85,23 +109,57 @@
test<In, Out, Sent, 0>({});
}
-template <class Out>
-constexpr void test_in_iterators() {
- test_iterators<cpp20_input_iterator<int*>, Out, sentinel_wrapper<cpp20_input_iterator<int*>>>();
- test_iterators<forward_iterator<int*>, Out>();
- test_iterators<bidirectional_iterator<int*>, Out>();
- test_iterators<random_access_iterator<int*>, Out>();
- test_iterators<contiguous_iterator<int*>, Out>();
- test_iterators<int*, Out>();
+template <template <class> class In, template <class> class Out>
+constexpr void test_sentinels() {
+ test_iterators<In<int*>, Out<int*>>();
+ test_iterators<In<int*>, Out<int*>, sized_sentinel<In<int*>>>();
+ test_iterators<In<int*>, Out<int*>, sentinel_wrapper<In<int*>>>();
+
+ if (!std::is_constant_evaluated()) {
+ if constexpr (!std::is_same_v<In<int*>, contiguous_iterator<int*>> &&
+ !std::is_same_v<Out<int*>, contiguous_iterator<int*>> &&
+ !std::is_same_v<In<int*>, ContiguousProxyIterator<int*>> &&
+ !std::is_same_v<Out<int*>, ContiguousProxyIterator<int*>>) {
+ test_containers<std::deque<int>,
+ std::deque<int>,
+ In<std::deque<int>::iterator>,
+ Out<std::deque<int>::iterator>>();
+ test_containers<std::deque<int>,
+ std::vector<int>,
+ In<std::deque<int>::iterator>,
+ Out<std::vector<int>::iterator>>();
+ test_containers<std::vector<int>,
+ std::deque<int>,
+ In<std::vector<int>::iterator>,
+ Out<std::deque<int>::iterator>>();
+ test_containers<std::vector<int>,
+ std::vector<int>,
+ In<std::vector<int>::iterator>,
+ Out<std::vector<int>::iterator>>();
+ }
+ }
}
-template <class Out>
+template <template <class> class Out>
+constexpr void test_in_iterators() {
+ test_iterators<cpp20_input_iterator<int*>, Out<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>();
+ test_sentinels<forward_iterator, Out>();
+ test_sentinels<bidirectional_iterator, Out>();
+ test_sentinels<random_access_iterator, Out>();
+ test_sentinels<contiguous_iterator, Out>();
+ test_sentinels<std::type_identity_t, Out>();
+}
+
+template <template <class> class Out>
constexpr void test_proxy_in_iterators() {
- test_iterators<ProxyIterator<cpp20_input_iterator<int*>>, Out, sentinel_wrapper<ProxyIterator<cpp20_input_iterator<int*>>>>();
- test_iterators<ProxyIterator<forward_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<bidirectional_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<random_access_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<contiguous_iterator<int*>>, Out>();
+ test_iterators<ProxyIterator<cpp20_input_iterator<int*>>,
+ Out<int*>,
+ sentinel_wrapper<ProxyIterator<cpp20_input_iterator<int*>>>>();
+ test_sentinels<ForwardProxyIterator, Out>();
+ test_sentinels<BidirectionalProxyIterator, Out>();
+ test_sentinels<RandomAccessProxyIterator, Out>();
+ test_sentinels<ContiguousProxyIterator, Out>();
+ test_sentinels<ProxyIterator, Out>();
}
struct IteratorWithMoveIter {
@@ -121,22 +179,27 @@
constexpr bool operator==(const IteratorWithMoveIter& other) const = default;
};
-constexpr bool test() {
- test_in_iterators<cpp17_output_iterator<int*>>();
- test_in_iterators<cpp20_output_iterator<int*>>();
- test_in_iterators<cpp17_input_iterator<int*>>();
- test_in_iterators<cpp20_input_iterator<int*>>();
- test_in_iterators<forward_iterator<int*>>();
- test_in_iterators<bidirectional_iterator<int*>>();
- test_in_iterators<random_access_iterator<int*>>();
- test_in_iterators<contiguous_iterator<int*>>();
- test_in_iterators<int*>();
+// cpp17_intput_iterator has a defaulted template argument
+template <class Iter>
+using Cpp17InIter = cpp17_input_iterator<Iter>;
- test_proxy_in_iterators<ProxyIterator<cpp20_input_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<forward_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<bidirectional_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<random_access_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<contiguous_iterator<int*>>>();
+constexpr bool test() {
+ test_in_iterators<cpp17_output_iterator>();
+ test_in_iterators<cpp20_output_iterator>();
+ test_in_iterators<Cpp17InIter>();
+ test_in_iterators<cpp20_input_iterator>();
+ test_in_iterators<forward_iterator>();
+ test_in_iterators<bidirectional_iterator>();
+ test_in_iterators<random_access_iterator>();
+ test_in_iterators<contiguous_iterator>();
+ test_in_iterators<std::type_identity_t>();
+
+ test_proxy_in_iterators<Cpp20InputProxyIterator>();
+ test_proxy_in_iterators<ForwardProxyIterator>();
+ test_proxy_in_iterators<BidirectionalProxyIterator>();
+ test_proxy_in_iterators<RandomAccessProxyIterator>();
+ test_proxy_in_iterators<ContiguousProxyIterator>();
+ test_proxy_in_iterators<ProxyIterator>();
{ // check that a move-only type works
{
diff --git a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp
index b77c1ed..1a281c6 100644
--- a/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp
@@ -22,7 +22,9 @@
#include <algorithm>
#include <array>
#include <cassert>
+#include <deque>
#include <ranges>
+#include <vector>
#include "almost_satisfies_types.h"
#include "MoveOnly.h"
@@ -85,27 +87,73 @@
test<In, Out, Sent, 0>({});
}
-template <class InIter, class OutIter>
+template <class InContainer, class OutContainer, class In, class Out, class Sent = In>
+constexpr void test_containers() {
+ {
+ InContainer in {1, 2, 3, 4};
+ OutContainer out(4);
+ std::same_as<std::ranges::in_out_result<In, Out>> auto ret =
+ std::ranges::move_backward(In(in.begin()), Sent(In(in.end())), Out(out.end()));
+ assert(std::ranges::equal(in, out));
+ assert(base(ret.in) == in.end());
+ assert(base(ret.out) == out.begin());
+ }
+ {
+ InContainer in {1, 2, 3, 4};
+ OutContainer out(4);
+ auto range = std::ranges::subrange(In(in.begin()), Sent(In(in.end())));
+ std::same_as<std::ranges::in_out_result<In, Out>> auto ret = std::ranges::move_backward(range, Out(out.end()));
+ assert(std::ranges::equal(in, out));
+ assert(base(ret.in) == in.end());
+ assert(base(ret.out) == out.begin());
+ }
+}
+
+template <template <class> class InIter, template <class> class OutIter>
constexpr void test_sentinels() {
- test_iterators<InIter, OutIter, InIter>();
- test_iterators<InIter, OutIter, sentinel_wrapper<InIter>>();
- test_iterators<InIter, OutIter, sized_sentinel<InIter>>();
+ test_iterators<InIter<int*>, OutIter<int*>, InIter<int*>>();
+ test_iterators<InIter<int*>, OutIter<int*>, sentinel_wrapper<InIter<int*>>>();
+ test_iterators<InIter<int*>, OutIter<int*>, sized_sentinel<InIter<int*>>>();
+
+ if (!std::is_constant_evaluated()) {
+ if constexpr (!std::is_same_v<InIter<int*>, contiguous_iterator<int*>> &&
+ !std::is_same_v<OutIter<int*>, contiguous_iterator<int*>> &&
+ !std::is_same_v<InIter<int*>, ContiguousProxyIterator<int*>> &&
+ !std::is_same_v<OutIter<int*>, ContiguousProxyIterator<int*>>) {
+ test_containers<std::deque<int>,
+ std::deque<int>,
+ InIter<std::deque<int>::iterator>,
+ OutIter<std::deque<int>::iterator>>();
+ test_containers<std::deque<int>,
+ std::vector<int>,
+ InIter<std::deque<int>::iterator>,
+ OutIter<std::vector<int>::iterator>>();
+ test_containers<std::vector<int>,
+ std::deque<int>,
+ InIter<std::vector<int>::iterator>,
+ OutIter<std::deque<int>::iterator>>();
+ test_containers<std::vector<int>,
+ std::vector<int>,
+ InIter<std::vector<int>::iterator>,
+ OutIter<std::vector<int>::iterator>>();
+ }
+ }
}
-template <class Out>
+template <template <class> class Out>
constexpr void test_in_iterators() {
- test_sentinels<bidirectional_iterator<int*>, Out>();
- test_sentinels<random_access_iterator<int*>, Out>();
- test_sentinels<contiguous_iterator<int*>, Out>();
- test_sentinels<int*, Out>();
+ test_sentinels<bidirectional_iterator, Out>();
+ test_sentinels<random_access_iterator, Out>();
+ test_sentinels<contiguous_iterator, Out>();
+ test_sentinels<std::type_identity_t, Out>();
}
-template <class Out>
+template <template <class> class Out>
constexpr void test_proxy_in_iterators() {
- test_iterators<ProxyIterator<bidirectional_iterator<int*>>, Out, sentinel_wrapper<ProxyIterator<bidirectional_iterator<int*>>>>();
- test_iterators<ProxyIterator<bidirectional_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<random_access_iterator<int*>>, Out>();
- test_iterators<ProxyIterator<contiguous_iterator<int*>>, Out>();
+ test_sentinels<BidirectionalProxyIterator, Out>();
+ test_sentinels<RandomAccessProxyIterator, Out>();
+ test_sentinels<ContiguousProxyIterator, Out>();
+ test_sentinels<ProxyIterator, Out>();
}
struct IteratorWithMoveIter {
@@ -129,14 +177,15 @@
};
constexpr bool test() {
- test_in_iterators<bidirectional_iterator<int*>>();
- test_in_iterators<random_access_iterator<int*>>();
- test_in_iterators<contiguous_iterator<int*>>();
- test_in_iterators<int*>();
+ test_in_iterators<bidirectional_iterator>();
+ test_in_iterators<random_access_iterator>();
+ test_in_iterators<contiguous_iterator>();
+ test_in_iterators<std::type_identity_t>();
- test_proxy_in_iterators<ProxyIterator<bidirectional_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<random_access_iterator<int*>>>();
- test_proxy_in_iterators<ProxyIterator<contiguous_iterator<int*>>>();
+ test_proxy_in_iterators<BidirectionalProxyIterator>();
+ test_proxy_in_iterators<RandomAccessProxyIterator>();
+ test_proxy_in_iterators<ContiguousProxyIterator>();
+ test_proxy_in_iterators<ProxyIterator>();
{ // check that a move-only type works
{
diff --git a/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.format.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.format.pass.cpp
new file mode 100644
index 0000000..7806576
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.format.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// [container.adaptors.format]
+// For each of queue, priority_queue, and stack, the library provides the
+// following formatter specialization where adaptor-type is the name of the
+// template:
+//
+// template<class charT, class T, formattable<charT> Container, class... U>
+// struct formatter<adaptor-type<T, Container, U...>, charT>
+
+// template<class... Args>
+// string format(format_string<Args...> fmt, Args&&... args);
+// template<class... Args>
+// wstring format(wformat_string<Args...> fmt, Args&&... args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_format_string.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
+ // After P2216 most exceptions thrown by std::format become ill-formed.
+ // Therefore this tests does nothing.
+};
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.tests.h b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.tests.h
new file mode 100644
index 0000000..489de3a
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.tests.h
@@ -0,0 +1,950 @@
+//===----------------------------------------------------------------------===//
+// 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 TEST_STD_CONTAINERS_CONTAINER_ADAPTORS_CONTAINER_ADAPTORS_FORMAT_FORMAT_FUNCTIONS_TESTS_H
+#define TEST_STD_CONTAINERS_CONTAINER_ADAPTORS_CONTAINER_ADAPTORS_FORMAT_FORMAT_FUNCTIONS_TESTS_H
+
+#include <algorithm>
+#include <array>
+#include <charconv>
+#include <concepts>
+#include <format>
+#include <list>
+#include <queue>
+#include <stack>
+
+#include "format.functions.common.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+//
+// Char
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_default(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ // Note when no range-underlying-spec is present the char is escaped,
+ check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{}"), input);
+
+ // when one is present there is no escaping,
+ check(SV("[H, e, l, l, o]"), SV("{::}"), input);
+ // unless forced by the type specifier.
+ check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{::?}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("['H', 'e', 'l', 'l', 'o'] "), SV("{:30}"), input);
+ check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<30}"), input);
+ check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^30}"), input);
+ check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>30}"), input);
+
+ check(SV("['H', 'e', 'l', 'l', 'o'] "), SV("{:{}}"), input, 30);
+ check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<{}}"), input, 30);
+ check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^{}}"), input, 30);
+ check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>{}}"), input, 30);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__'H', 'e', 'l', 'l', 'o'___"), SV("{:_^28n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[H , e , l , l , o ]"), SV("{::4}"), input);
+ check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<4}"), input);
+ check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^4}"), input);
+ check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>4}"), input);
+
+ check(SV("[H , e , l , l , o ]"), SV("{::{}}"), input, 4);
+ check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<{}}"), input, 4);
+ check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^{}}"), input, 4);
+ check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>{}}"), input, 4);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("[72, 101, 108, 108, 111]"), SV("{::-d}"), input);
+ check(SV("[+72, +101, +108, +108, +111]"), SV("{::+d}"), input);
+ check(SV("[ 72, 101, 108, 108, 111]"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("[0x48, 0x65, 0x6c, 0x6c, 0x6f]"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("[00110, 00145, 00154, 00154, 00157]"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[H, e, l, l, o]"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
+ check_exception("The format-spec type has a type not supported for a char argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^25::>2}"), input);
+ check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>2}"), input, 25);
+ check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>{}}"), input, 25, 2);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>2}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 25);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("Hello"), SV("{:s}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("Hello "), SV("{:8s}"), input);
+ check(SV("Hello***"), SV("{:*<8s}"), input);
+ check(SV("_Hello__"), SV("{:_^8s}"), input);
+ check(SV("###Hello"), SV("{:#>8s}"), input);
+
+ check(SV("Hello "), SV("{:{}s}"), input, 8);
+ check(SV("Hello***"), SV("{:*<{}s}"), input, 8);
+ check(SV("_Hello__"), SV("{:_^{}s}"), input, 8);
+ check(SV("###Hello"), SV("{:#>{}s}"), input, 8);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<s}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: s}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#s}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0s}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.s}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:Ls}"), input);
+
+ // *** n
+ check_exception("The n option and type s can't be used together", SV("{:ns}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("Type s and an underlying format specification can't be used together", SV("{:s:}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
+ check_exception("The format-spec type has a type not supported for a char argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check_exception("Type s and an underlying format specification can't be used together", SV("{:5s:5}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_escaped_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV(R"("Hello")"), SV("{:?s}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV(R"("Hello" )"), SV("{:10?s}"), input);
+ check(SV(R"("Hello"***)"), SV("{:*<10?s}"), input);
+ check(SV(R"(_"Hello"__)"), SV("{:_^10?s}"), input);
+ check(SV(R"(###"Hello")"), SV("{:#>10?s}"), input);
+
+ check(SV(R"("Hello" )"), SV("{:{}?s}"), input, 10);
+ check(SV(R"("Hello"***)"), SV("{:*<{}?s}"), input, 10);
+ check(SV(R"(_"Hello"__)"), SV("{:_^{}?s}"), input, 10);
+ check(SV(R"(###"Hello")"), SV("{:#>{}?s}"), input, 10);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<?s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<?s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<?s}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-?s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+?s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: ?s}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#?s}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0?s}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.?s}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L?s}"), input);
+
+ // *** n
+ check_exception("The n option and type ?s can't be used together", SV("{:n?s}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("Type ?s and an underlying format specification can't be used together", SV("{:?s:}"), input);
+
+ // ***** Both have a format-spec
+ check_exception("Type ?s and an underlying format specification can't be used together", SV("{:5?s:5}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char(TestFunction check, ExceptionTest check_exception) {
+ // These values are in numeric order when using ASCII, which is used by the priority_queue.
+ std::array input{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')};
+ test_char_default<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_char_default<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
+ test_char_default<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+
+ test_char_string<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_char_string<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
+ test_char_string<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+
+ test_char_escaped_string<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_char_escaped_string<CharT>(
+ check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
+ test_char_escaped_string<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+}
+
+//
+// char -> wchar_t
+//
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class TestFunction, class ExceptionTest>
+void test_char_to_wchar(TestFunction check, ExceptionTest check_exception) {
+ std::array input{'H', 'e', 'l', 'l', 'o'};
+ test_char_default<wchar_t>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_char_default<wchar_t>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
+ test_char_default<wchar_t>(check, check_exception, std::stack{input.begin(), input.end()});
+
+ // The types s and ?s may only be used when using range_formatter<T, charT>
+ // where the types T and charT are the same. This means this can't be used for
+ // range_formatter<wchar_t, char> even when formatter<wchar_t, char> has a
+ // debug-enabled specialization.
+
+ using CharT = wchar_t;
+ check_exception("The range-format-spec type s requires formatting a character type",
+ SV("{:s}"),
+ std::queue{input.begin(), input.end()});
+ check_exception("The range-format-spec type s requires formatting a character type",
+ SV("{:s}"),
+ std::priority_queue{input.begin(), input.end()});
+ check_exception("The range-format-spec type s requires formatting a character type",
+ SV("{:s}"),
+ std::stack{input.begin(), input.end()});
+ check_exception("The range-format-spec type ?s requires formatting a character type",
+ SV("{:?s}"),
+ std::queue{input.begin(), input.end()});
+ check_exception("The range-format-spec type ?s requires formatting a character type",
+ SV("{:?s}"),
+ std::priority_queue{input.begin(), input.end()});
+ check_exception("The range-format-spec type ?s requires formatting a character type",
+ SV("{:?s}"),
+ std::stack{input.begin(), input.end()});
+}
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+//
+// Bool
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_bool(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[true, true, false]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[true, true, false] "), SV("{:24}"), input);
+ check(SV("[true, true, false]*****"), SV("{:*<24}"), input);
+ check(SV("__[true, true, false]___"), SV("{:_^24}"), input);
+ check(SV("#####[true, true, false]"), SV("{:#>24}"), input);
+
+ check(SV("[true, true, false] "), SV("{:{}}"), input, 24);
+ check(SV("[true, true, false]*****"), SV("{:*<{}}"), input, 24);
+ check(SV("__[true, true, false]___"), SV("{:_^{}}"), input, 24);
+ check(SV("#####[true, true, false]"), SV("{:#>{}}"), input, 24);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__true, true, false___"), SV("{:_^22n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[true , true , false ]"), SV("{::7}"), input);
+ check(SV("[true***, true***, false**]"), SV("{::*<7}"), input);
+ check(SV("[_true__, _true__, _false_]"), SV("{::_^7}"), input);
+ check(SV("[:::true, :::true, ::false]"), SV("{:::>7}"), input);
+
+ check(SV("[true , true , false ]"), SV("{::{}}"), input, 7);
+ check(SV("[true***, true***, false**]"), SV("{::*<{}}"), input, 7);
+ check(SV("[_true__, _true__, _false_]"), SV("{::_^{}}"), input, 7);
+ check(SV("[:::true, :::true, ::false]"), SV("{:::>{}}"), input, 7);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("[1, 1, 0]"), SV("{::-d}"), input);
+ check(SV("[+1, +1, +0]"), SV("{::+d}"), input);
+ check(SV("[ 1, 1, 0]"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("[0x1, 0x1, 0x0]"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("[00001, 00001, 00000]"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[true, true, false]"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX"))
+ check_exception("The format-spec type has a type not supported for a bool argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^32::>7}"), input);
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>7}"), input, 32);
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>{}}"), input, 32, 7);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 32);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_bool(TestFunction check, ExceptionTest check_exception) {
+ std::array input{true, true, false};
+ test_bool<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ // TODO FMT Use std::vector<bool> after it has been implemented.
+ test_bool<CharT>(check, check_exception, std::priority_queue<bool, std::deque<bool>>{input.begin(), input.end()});
+ test_bool<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+}
+
+//
+// Integral
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[-42, 1, 2, 42]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[-42, 1, 2, 42] "), SV("{:20}"), input);
+ check(SV("[-42, 1, 2, 42]*****"), SV("{:*<20}"), input);
+ check(SV("__[-42, 1, 2, 42]___"), SV("{:_^20}"), input);
+ check(SV("#####[-42, 1, 2, 42]"), SV("{:#>20}"), input);
+
+ check(SV("[-42, 1, 2, 42] "), SV("{:{}}"), input, 20);
+ check(SV("[-42, 1, 2, 42]*****"), SV("{:*<{}}"), input, 20);
+ check(SV("__[-42, 1, 2, 42]___"), SV("{:_^{}}"), input, 20);
+ check(SV("#####[-42, 1, 2, 42]"), SV("{:#>{}}"), input, 20);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__-42, 1, 2, 42___"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[ -42, 1, 2, 42]"), SV("{::5}"), input);
+ check(SV("[-42**, 1****, 2****, 42***]"), SV("{::*<5}"), input);
+ check(SV("[_-42_, __1__, __2__, _42__]"), SV("{::_^5}"), input);
+ check(SV("[::-42, ::::1, ::::2, :::42]"), SV("{:::>5}"), input);
+
+ check(SV("[ -42, 1, 2, 42]"), SV("{::{}}"), input, 5);
+ check(SV("[-42**, 1****, 2****, 42***]"), SV("{::*<{}}"), input, 5);
+ check(SV("[_-42_, __1__, __2__, _42__]"), SV("{::_^{}}"), input, 5);
+ check(SV("[::-42, ::::1, ::::2, :::42]"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check(SV("[-42, 1, 2, 42]"), SV("{::-}"), input);
+ check(SV("[-42, +1, +2, +42]"), SV("{::+}"), input);
+ check(SV("[-42, 1, 2, 42]"), SV("{:: }"), input);
+
+ // *** alternate form ***
+ check(SV("[-0x2a, 0x1, 0x2, 0x2a]"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check(SV("[-0042, 00001, 00002, 00042]"), SV("{::05}"), input);
+ check(SV("[-002a, 00001, 00002, 0002a]"), SV("{::05x}"), input);
+ check(SV("[-0x2a, 0x001, 0x002, 0x02a]"), SV("{::#05x}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[-42, 1, 2, 42]"), SV("{::L}"), input); // does nothing in this test, but is accepted.
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX"))
+ check_exception("The format-spec type has a type not supported for an integer argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[::-42, ::::1, ::::2, :::42]^^^"), SV("{:^^33::>5}"), input);
+ check(SV("^^[::-42, ::::1, ::::2, :::42]^^^"), SV("{:^^{}::>5}"), input, 33);
+ check(SV("^^[::-42, ::::1, ::::2, :::42]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 33);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception) {
+ std::array input{-42, 1, 2, 42};
+ test_int<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_int<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
+ test_int<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+}
+
+//
+// Floating point
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_floating_point(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[-42.5, 0, 1.25, 42.5] "), SV("{:27}"), input);
+ check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<27}"), input);
+ check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^27}"), input);
+ check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>27}"), input);
+
+ check(SV("[-42.5, 0, 1.25, 42.5] "), SV("{:{}}"), input, 27);
+ check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<{}}"), input, 27);
+ check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^{}}"), input, 27);
+ check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>{}}"), input, 27);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__-42.5, 0, 1.25, 42.5___"), SV("{:_^25n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::5}"), input);
+ check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<5}"), input);
+ check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^5}"), input);
+ check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>5}"), input);
+
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::{}}"), input, 5);
+ check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<{}}"), input, 5);
+ check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^{}}"), input, 5);
+ check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::-}"), input);
+ check(SV("[-42.5, +0, +1.25, +42.5]"), SV("{::+}"), input);
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{:: }"), input);
+
+ // *** alternate form ***
+ check(SV("[-42.5, 0., 1.25, 42.5]"), SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check(SV("[-42.5, 00000, 01.25, 042.5]"), SV("{::05}"), input);
+ check(SV("[-42.5, 0000., 01.25, 042.5]"), SV("{::#05}"), input);
+
+ // *** precision ***
+ check(SV("[-42, 0, 1.2, 42]"), SV("{::.2}"), input);
+ check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.3f}"), input);
+
+ check(SV("[-42, 0, 1.2, 42]"), SV("{::.{}}"), input, 2);
+ check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.{}f}"), input, 3);
+
+ check_exception("The format-spec precision field doesn't contain a value or arg-id", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input); // does not require locales present
+#ifndef TEST_HAS_NO_LOCALIZATION
+// TODO FMT Enable with locale testing active
+# if 0
+ std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+ check(SV("[-42,5, 0, 1,25, 42,5]"), SV("{::L}"), input);
+
+ std::locale::global(std::locale(LOCALE_en_US_UTF_8));
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input);
+
+ std::locale::global(std::locale::classic());
+# endif
+#endif // TEST_HAS_NO_LOCALIZATION
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("aAeEfFgG"))
+ check_exception("The format-spec type has a type not supported for a floating-point argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^33::>5}"), input);
+ check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>5}"), input, 33);
+ check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
+
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^33::>5.2}"), input);
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>5.2}"), input, 33);
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.2}"), input, 33, 5);
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.{}}"), input, 33, 5, 2);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5.2}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}.2}"), input, 33);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}.{}}"), input, 33, 5);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_floating_point(TestFunction check, ExceptionTest check_exception) {
+ std::array input{-42.5l, 0.0l, 1.25l, 42.5l};
+ test_floating_point<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_floating_point<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
+ test_floating_point<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+}
+
+//
+// Pointer
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pointer(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[0x0]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[0x0] "), SV("{:10}"), input);
+ check(SV("[0x0]*****"), SV("{:*<10}"), input);
+ check(SV("__[0x0]___"), SV("{:_^10}"), input);
+ check(SV("#####[0x0]"), SV("{:#>10}"), input);
+
+ check(SV("[0x0] "), SV("{:{}}"), input, 10);
+ check(SV("[0x0]*****"), SV("{:*<{}}"), input, 10);
+ check(SV("__[0x0]___"), SV("{:_^{}}"), input, 10);
+ check(SV("#####[0x0]"), SV("{:#>{}}"), input, 10);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("_0x0_"), SV("{:_^5n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[ 0x0]"), SV("{::5}"), input);
+ check(SV("[0x0**]"), SV("{::*<5}"), input);
+ check(SV("[_0x0_]"), SV("{::_^5}"), input);
+ check(SV("[::0x0]"), SV("{:::>5}"), input);
+
+ check(SV("[ 0x0]"), SV("{::{}}"), input, 5);
+ check(SV("[0x0**]"), SV("{::*<{}}"), input, 5);
+ check(SV("[_0x0_]"), SV("{::_^{}}"), input, 5);
+ check(SV("[::0x0]"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("p"))
+ check_exception("The format-spec type has a type not supported for a pointer argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
+
+ check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 12);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pointer(TestFunction check, ExceptionTest check_exception) {
+ std::array input{static_cast<void*>(0)};
+ test_pointer<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_pointer<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end()});
+ test_pointer<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+}
+
+//
+// String
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV(R"(["Hello", "world"])"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV(R"(["Hello", "world"] )"), SV("{:23}"), input);
+ check(SV(R"(["Hello", "world"]*****)"), SV("{:*<23}"), input);
+ check(SV(R"(__["Hello", "world"]___)"), SV("{:_^23}"), input);
+ check(SV(R"(#####["Hello", "world"])"), SV("{:#>23}"), input);
+
+ check(SV(R"(["Hello", "world"] )"), SV("{:{}}"), input, 23);
+ check(SV(R"(["Hello", "world"]*****)"), SV("{:*<{}}"), input, 23);
+ check(SV(R"(__["Hello", "world"]___)"), SV("{:_^{}}"), input, 23);
+ check(SV(R"(#####["Hello", "world"])"), SV("{:#>{}}"), input, 23);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV(R"(_"Hello", "world"_)"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV(R"([Hello , world ])"), SV("{::8}"), input);
+ check(SV(R"([Hello***, world***])"), SV("{::*<8}"), input);
+ check(SV(R"([_Hello__, _world__])"), SV("{::_^8}"), input);
+ check(SV(R"([:::Hello, :::world])"), SV("{:::>8}"), input);
+
+ check(SV(R"([Hello , world ])"), SV("{::{}}"), input, 8);
+ check(SV(R"([Hello***, world***])"), SV("{::*<{}}"), input, 8);
+ check(SV(R"([_Hello__, _world__])"), SV("{::_^{}}"), input, 8);
+ check(SV(R"([:::Hello, :::world])"), SV("{:::>{}}"), input, 8);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check(SV(R"([Hel, wor])"), SV("{::.3}"), input);
+
+ check(SV(R"([Hel, wor])"), SV("{::.{}}"), input, 3);
+
+ check_exception("The format-spec precision field doesn't contain a value or arg-id", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s?"))
+ check_exception("The format-spec type has a type not supported for a string argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
+
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>8}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 25);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_string(TestFunction check, ExceptionTest check_exception) {
+ std::array input{STR("Hello"), STR("world")};
+ test_string<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_string<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::greater{}});
+ test_string<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+}
+
+//
+// Handle
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_status(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[0xaaaa, 0x5555, 0xaa55] "), SV("{:29}"), input);
+ check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<29}"), input);
+ check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^29}"), input);
+ check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>29}"), input);
+
+ check(SV("[0xaaaa, 0x5555, 0xaa55] "), SV("{:{}}"), input, 29);
+ check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<{}}"), input, 29);
+ check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^{}}"), input, 29);
+ check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>{}}"), input, 29);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__0xaaaa, 0x5555, 0xaa55___"), SV("{:_^27n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("The format-spec type has a type not supported for a status argument", SV("{::*<7}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("sxX"))
+ check_exception("The format-spec type has a type not supported for a status argument", fmt, input);
+
+ check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{::x}"), input);
+ check(SV("[0XAAAA, 0X5555, 0XAA55]"), SV("{::X}"), input);
+ check(SV("[foo, bar, foobar]"), SV("{::s}"), input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^29:X}"), input);
+ check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^{}:X}"), input, 29);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:X}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_status(TestFunction check, ExceptionTest check_exception) {
+ std::array input{status::foo, status::bar, status::foobar};
+ test_status<CharT>(check, check_exception, std::queue{input.begin(), input.end()});
+ test_status<CharT>(check, check_exception, std::priority_queue{input.begin(), input.end(), std::less{}});
+ test_status<CharT>(check, check_exception, std::stack{input.begin(), input.end()});
+}
+
+//
+// Driver
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void format_tests(TestFunction check, ExceptionTest check_exception) {
+ test_char<CharT>(check, check_exception);
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ if (std::same_as<CharT, wchar_t>) // avoid testing twice
+ test_char_to_wchar(check, check_exception);
+#endif
+ test_bool<CharT>(check, check_exception);
+ test_int<CharT>(check, check_exception);
+ test_floating_point<CharT>(check, check_exception);
+ test_pointer<CharT>(check, check_exception);
+ test_string<CharT>(check, check_exception);
+
+ test_status<CharT>(check, check_exception); // Has its own handler with its own parser
+}
+
+#endif // TEST_STD_CONTAINERS_CONTAINER_ADAPTORS_CONTAINER_ADAPTORS_FORMAT_FORMAT_FUNCTIONS_TESTS_H
diff --git a/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.vformat.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.vformat.pass.cpp
new file mode 100644
index 0000000..27c52fa
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.functions.vformat.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// [container.adaptors.format]
+// For each of queue, priority_queue, and stack, the library provides the
+// following formatter specialization where adaptor-type is the name of the
+// template:
+//
+// template<class charT, class T, formattable<charT> Container, class... U>
+// struct formatter<adaptor-type<T, Container, U...>, charT>
+
+// string vformat(string_view fmt, format_args args);
+// wstring vformat(wstring_view fmt, wformat_args args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception =
+ []<class CharT, class... Args>(
+ [[maybe_unused]] std::string_view what,
+ [[maybe_unused]] std::basic_string_view<CharT> fmt,
+ [[maybe_unused]] Args&&... args) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
+ } catch (const std::format_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+
+ return;
+ }
+ assert(false);
+#endif
+ };
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.pass.cpp
new file mode 100644
index 0000000..8950ece
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/format.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// [container.adaptors.format]
+// For each of queue, priority_queue, and stack, the library provides the
+// following formatter specialization where adaptor-type is the name of the
+// template:
+//
+// template<class charT, class T, formattable<charT> Container, class... U>
+// struct formatter<adaptor-type<T, Container, U...>, charT>
+
+// template<class FormatContext>
+// typename FormatContext::iterator
+// format(maybe-const-adaptor& r, FormatContext& ctx) const;
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <queue>
+#include <stack>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT, class Arg>
+void test_format(StringViewT expected, Arg arg) {
+ using CharT = typename StringViewT::value_type;
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ const std::formatter<Arg, CharT> formatter;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
+ formatter.format(arg, format_ctx);
+ assert(result == expected);
+}
+
+template <class CharT>
+void test_fmt() {
+ std::array input{1, 42, 99, 0};
+ test_format(SV("[1, 42, 99, 0]"), std::queue<int>{input.begin(), input.end()});
+ test_format(SV("[99, 42, 1, 0]"), std::priority_queue<int>{input.begin(), input.end()});
+ test_format(SV("[1, 42, 99, 0]"), std::stack<int>{input.begin(), input.end()});
+}
+
+void test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/parse.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/parse.pass.cpp
new file mode 100644
index 0000000..b620279
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/container.adaptors/container.adaptors.format/parse.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// [container.adaptors.format]
+// For each of queue, priority_queue, and stack, the library provides the
+// following formatter specialization where adaptor-type is the name of the
+// template:
+//
+// template<class charT, class T, formattable<charT> Container, class... U>
+// struct formatter<adaptor-type<T, Container, U...>, charT>
+
+// template<class ParseContext>
+// constexpr typename ParseContext::iterator
+// parse(ParseContext& ctx);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <queue>
+#include <stack>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class Arg, class StringViewT>
+constexpr void test_parse(StringViewT fmt) {
+ using CharT = typename StringViewT::value_type;
+ auto parse_ctx = std::basic_format_parse_context<CharT>(fmt);
+ std::formatter<Arg, CharT> formatter;
+ static_assert(std::semiregular<decltype(formatter)>);
+
+ std::same_as<typename StringViewT::iterator> auto it = formatter.parse(parse_ctx);
+ assert(it == fmt.end() - (!fmt.empty() && fmt.back() == '}'));
+}
+
+template <class StringViewT>
+constexpr void test_parse(StringViewT fmt) {
+ test_parse<std::queue<int>>(fmt);
+ test_parse<std::priority_queue<int>>(fmt);
+ test_parse<std::stack<int>>(fmt);
+}
+
+template <class CharT>
+constexpr void test_fmt() {
+ test_parse(SV(""));
+ test_parse(SV(":d"));
+
+ test_parse(SV("}"));
+ test_parse(SV(":d}"));
+}
+
+constexpr bool test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.format.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.format.pass.cpp
new file mode 100644
index 0000000..61cbfea
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.format.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// <vector>
+
+// template<class T, class charT>
+// requires is-vector-bool-reference<T>
+// struct formatter<T, charT>
+
+// template<class... Args>
+// string format(format_string<Args...> fmt, Args&&... args);
+// template<class... Args>
+// wstring format(wformat_string<Args...> fmt, Args&&... args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_format_string.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
+ // After P2216 most exceptions thrown by std::format become ill-formed.
+ // Therefore this tests does nothing.
+};
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.tests.h b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.tests.h
new file mode 100644
index 0000000..32b68b8
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.tests.h
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+// 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 TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H
+#define TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H
+
+#include <vector>
+
+#include "format.functions.common.h"
+#include "test_macros.h"
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void format_tests(TestFunction check, ExceptionTest check_exception) {
+ std::vector input{true, true, false};
+
+ check(SV("[true, true, false]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[true, true, false] "), SV("{:24}"), input);
+ check(SV("[true, true, false]*****"), SV("{:*<24}"), input);
+ check(SV("__[true, true, false]___"), SV("{:_^24}"), input);
+ check(SV("#####[true, true, false]"), SV("{:#>24}"), input);
+
+ check(SV("[true, true, false] "), SV("{:{}}"), input, 24);
+ check(SV("[true, true, false]*****"), SV("{:*<{}}"), input, 24);
+ check(SV("__[true, true, false]___"), SV("{:_^{}}"), input, 24);
+ check(SV("#####[true, true, false]"), SV("{:#>{}}"), input, 24);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__true, true, false___"), SV("{:_^22n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[true , true , false ]"), SV("{::7}"), input);
+ check(SV("[true***, true***, false**]"), SV("{::*<7}"), input);
+ check(SV("[_true__, _true__, _false_]"), SV("{::_^7}"), input);
+ check(SV("[:::true, :::true, ::false]"), SV("{:::>7}"), input);
+
+ check(SV("[true , true , false ]"), SV("{::{}}"), input, 7);
+ check(SV("[true***, true***, false**]"), SV("{::*<{}}"), input, 7);
+ check(SV("[_true__, _true__, _false_]"), SV("{::_^{}}"), input, 7);
+ check(SV("[:::true, :::true, ::false]"), SV("{:::>{}}"), input, 7);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("[1, 1, 0]"), SV("{::-d}"), input);
+ check(SV("[+1, +1, +0]"), SV("{::+d}"), input);
+ check(SV("[ 1, 1, 0]"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("[0x1, 0x1, 0x0]"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("[00001, 00001, 00000]"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX"))
+ check_exception("The format-spec type has a type not supported for a bool argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^32::>7}"), input);
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>7}"), input, 32);
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>{}}"), input, 32, 7);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 32);
+}
+
+#endif // TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H
diff --git a/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.vformat.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.vformat.pass.cpp
new file mode 100644
index 0000000..9e6db80
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.vformat.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <vector>
+
+// template<class T, class charT>
+// requires is-vector-bool-reference<T>
+// struct formatter<T, charT>
+
+// string vformat(string_view fmt, format_args args);
+// wstring vformat(wstring_view fmt, wformat_args args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception =
+ []<class CharT, class... Args>(
+ [[maybe_unused]] std::string_view what,
+ [[maybe_unused]] std::basic_string_view<CharT> fmt,
+ [[maybe_unused]] Args&&... args) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
+ } catch (const std::format_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+
+ return;
+ }
+ assert(false);
+#endif
+ };
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.pass.cpp
new file mode 100644
index 0000000..acb517a
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/format.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <vector>
+
+// template<class T, class charT>
+// requires is-vector-bool-reference<T>
+// struct formatter<T, charT>
+
+// template<class FormatContext>
+// typename FormatContext::iterator
+// format(const T& r, FormatContext& ctx) const;
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <vector>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+void test_format(StringViewT expected, std::vector<bool>::reference arg) {
+ using CharT = typename StringViewT::value_type;
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ const std::formatter<std::vector<bool>::reference, CharT> formatter;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
+ formatter.format(arg, format_ctx);
+ assert(result == expected);
+}
+
+template <class CharT>
+void test_fmt() {
+ test_format(SV("true"), std::vector<bool>{true}[0]);
+ test_format(SV("false"), std::vector<bool>{false}[0]);
+}
+
+void test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/parse.pass.cpp b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/parse.pass.cpp
new file mode 100644
index 0000000..c099cfe
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/containers/sequences/vector.bool/vector.bool.fmt/parse.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <vector>
+
+// template<class T, class charT>
+// requires is-vector-bool-reference<T>
+// struct formatter<T, charT>
+
+// template<class ParseContext>
+// constexpr typename ParseContext::iterator
+// parse(ParseContext& ctx);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <vector>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+constexpr void test_parse(StringViewT fmt) {
+ using CharT = typename StringViewT::value_type;
+ auto parse_ctx = std::basic_format_parse_context<CharT>(fmt);
+ std::formatter<std::vector<bool, std::allocator<bool>>::reference, CharT> formatter;
+ static_assert(std::semiregular<decltype(formatter)>);
+
+ std::same_as<typename StringViewT::iterator> auto it = formatter.parse(parse_ctx);
+ assert(it == fmt.end() - (!fmt.empty() && fmt.back() == '}'));
+}
+
+template <class CharT>
+constexpr void test_fmt() {
+ test_parse(SV(""));
+ test_parse(SV("b"));
+
+ test_parse(SV("}"));
+ test_parse(SV("b}"));
+}
+
+constexpr bool test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp b/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp
index a33989e..297235e 100644
--- a/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp
@@ -38,7 +38,7 @@
template <size_t S, size_t Align>
void testForSizeAndAlign() {
- using T = typename std::aligned_storage<S, Align>::type;
+ struct T { alignas(Align) char data[S]; };
TestResource R;
ex::polymorphic_allocator<T> a(&R);
@@ -54,7 +54,7 @@
#ifndef TEST_HAS_NO_EXCEPTIONS
template <size_t S>
void testAllocForSizeThrows() {
- using T = typename std::aligned_storage<S>::type;
+ struct T { char data[S]; };
using Alloc = ex::polymorphic_allocator<T>;
using Traits = std::allocator_traits<Alloc>;
NullResource R;
diff --git a/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp b/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp
index ec6059d..0084d37 100644
--- a/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp
@@ -36,7 +36,7 @@
template <size_t S, size_t Align>
void testForSizeAndAlign() {
- using T = typename std::aligned_storage<S, Align>::type;
+ struct T { alignas(Align) char data[S]; };
TestResource R;
ex::polymorphic_allocator<T> a(&R);
diff --git a/third_party/llvm-project/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp b/third_party/llvm-project/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
index f99d2ae..7ac9ddc 100644
--- a/third_party/llvm-project/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03
// <filesystem>
diff --git a/third_party/llvm-project/libcxx/test/std/iterators/predef.iterators/move.iterators/move.sentinel/ctad.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/iterators/predef.iterators/move.iterators/move.sentinel/ctad.compile.pass.cpp
new file mode 100644
index 0000000..9b68bea
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/iterators/predef.iterators/move.iterators/move.sentinel/ctad.compile.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <iterator>
+#include <type_traits>
+
+#include <test_iterators.h>
+
+static_assert(std::is_same_v<decltype(std::move_sentinel(std::default_sentinel_t{})),
+ std::move_sentinel<std::default_sentinel_t>>);
+
+static_assert(
+ std::is_same_v<decltype(std::move_sentinel(sentinel_wrapper<int*>{})), std::move_sentinel<sentinel_wrapper<int*>>>);
diff --git a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
index 8e1ed7f..e871065 100644
--- a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
@@ -19,7 +19,7 @@
__cpp_lib_clamp 201603L [C++17]
__cpp_lib_constexpr_algorithms 201806L [C++20]
__cpp_lib_parallel_algorithm 201603L [C++17]
- __cpp_lib_ranges 201811L [C++20]
+ __cpp_lib_ranges 202106L [C++20]
__cpp_lib_ranges_starts_ends_with 202106L [C++2b]
__cpp_lib_robust_nonmodifying_seq_ops 201304L [C++14]
__cpp_lib_sample 201603L [C++17]
@@ -184,8 +184,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++20"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++20"
# endif
# ifdef __cpp_lib_ranges_starts_ends_with
@@ -245,8 +245,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++2b"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++2b"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
index 2cc8faa..15c0920 100644
--- a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
@@ -24,7 +24,7 @@
__cpp_lib_invoke_r 202106L [C++2b]
__cpp_lib_move_only_function 202110L [C++2b]
__cpp_lib_not_fn 201603L [C++17]
- __cpp_lib_ranges 201811L [C++20]
+ __cpp_lib_ranges 202106L [C++20]
__cpp_lib_result_of_sfinae 201210L [C++14]
__cpp_lib_transparent_operators 201210L [C++14]
201510L [C++17]
@@ -257,8 +257,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++20"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++20"
# endif
# ifndef __cpp_lib_result_of_sfinae
@@ -361,8 +361,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++2b"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++2b"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++2b"
# endif
# ifndef __cpp_lib_result_of_sfinae
diff --git a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
index b4b5cbf..bf7d03b 100644
--- a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
@@ -22,7 +22,7 @@
__cpp_lib_make_reverse_iterator 201402L [C++14]
__cpp_lib_nonmember_container_access 201411L [C++17]
__cpp_lib_null_iterators 201304L [C++14]
- __cpp_lib_ranges 201811L [C++20]
+ __cpp_lib_ranges 202106L [C++20]
__cpp_lib_ssize 201902L [C++20]
*/
@@ -177,8 +177,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++20"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++20"
# endif
# ifndef __cpp_lib_ssize
@@ -228,8 +228,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++2b"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++2b"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++2b"
# endif
# ifndef __cpp_lib_ssize
diff --git a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index e99c75d..2d4b67a 100644
--- a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -27,7 +27,7 @@
__cpp_lib_enable_shared_from_this 201603L [C++17]
__cpp_lib_make_unique 201304L [C++14]
__cpp_lib_out_ptr 202106L [C++2b]
- __cpp_lib_ranges 201811L [C++20]
+ __cpp_lib_ranges 202106L [C++20]
__cpp_lib_raw_memory_algorithms 201606L [C++17]
__cpp_lib_shared_ptr_arrays 201611L [C++17]
201707L [C++20]
@@ -350,8 +350,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++20"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++20"
# endif
# ifndef __cpp_lib_raw_memory_algorithms
@@ -483,8 +483,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++2b"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++2b"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++2b"
# endif
# ifndef __cpp_lib_raw_memory_algorithms
diff --git a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
index d41f5d8..be51d6d 100644
--- a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
@@ -16,7 +16,7 @@
// Test the feature test macros defined by <ranges>
/* Constant Value
- __cpp_lib_ranges 201811L [C++20]
+ __cpp_lib_ranges 202106L [C++20]
__cpp_lib_ranges_chunk 202202L [C++2b]
__cpp_lib_ranges_chunk_by 202202L [C++2b]
__cpp_lib_ranges_join_with 202202L [C++2b]
@@ -110,8 +110,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++20"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++20"
# endif
# ifdef __cpp_lib_ranges_chunk
@@ -139,8 +139,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++2b"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++2b"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 7e1dfd0..9c1816b 100644
--- a/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -127,7 +127,7 @@
__cpp_lib_parallel_algorithm 201603L [C++17]
__cpp_lib_polymorphic_allocator 201902L [C++20]
__cpp_lib_quoted_string_io 201304L [C++14]
- __cpp_lib_ranges 201811L [C++20]
+ __cpp_lib_ranges 202106L [C++20]
__cpp_lib_ranges_chunk 202202L [C++2b]
__cpp_lib_ranges_chunk_by 202202L [C++2b]
__cpp_lib_ranges_iota 202202L [C++2b]
@@ -3236,8 +3236,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++20"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++20"
# endif
# ifdef __cpp_lib_ranges_chunk
@@ -4501,8 +4501,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++2b"
# endif
-# if __cpp_lib_ranges != 201811L
-# error "__cpp_lib_ranges should have the value 201811L in c++2b"
+# if __cpp_lib_ranges != 202106L
+# error "__cpp_lib_ranges should have the value 202106L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
index c3c4198..4cdb257 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
@@ -10,6 +10,7 @@
// XFAIL: netbsd
// XFAIL: LIBCXX-AIX-FIXME
+// XFAIL: LIBCXX-FREEBSD-FIXME
// REQUIRES: locale.zh_CN.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
index 446657b..1aba059 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
@@ -10,6 +10,7 @@
// XFAIL: netbsd
// XFAIL: LIBCXX-AIX-FIXME
+// XFAIL: LIBCXX-FREEBSD-FIXME
// REQUIRES: locale.zh_CN.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp
index 851b8cc..ca5b673 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp
@@ -11,6 +11,8 @@
// NetBSD does not support LC_MONETARY at the moment
// XFAIL: netbsd
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
// REQUIRES: locale.ru_RU.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp
index 72a28dc..a4a9216 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp
@@ -9,6 +9,8 @@
// NetBSD does not support LC_MONETARY at the moment
// XFAIL: netbsd
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
// REQUIRES: locale.ru_RU.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp
index 25dc04a..671620a 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp
@@ -9,6 +9,8 @@
// NetBSD does not support LC_MONETARY at the moment
// XFAIL: netbsd
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
// REQUIRES: locale.ru_RU.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
index 7ec217a..2a70741 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
@@ -9,6 +9,8 @@
// NetBSD does not support LC_MONETARY at the moment
// XFAIL: netbsd
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
// REQUIRES: locale.ru_RU.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp
index c909c5b..1b19f5c 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp
@@ -10,6 +10,8 @@
// REQUIRES: locale.fr_FR.UTF-8
// REQUIRES: locale.zh_CN.UTF-8
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// <locale>
// class time_get_byname<charT, InputIterator>
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp
index ff24169..54eff24 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp
@@ -11,6 +11,8 @@
// REQUIRES: locale.zh_CN.UTF-8
// XFAIL: no-wide-characters
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// <locale>
// class time_get_byname<charT, InputIterator>
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
index 4369a19..35dba46 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
@@ -9,6 +9,8 @@
// NetBSD does not support LC_TIME at the moment
// XFAIL: netbsd
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
// REQUIRES: locale.ru_RU.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
index 3301683..f3a09fe 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
@@ -9,6 +9,8 @@
// NetBSD does not support LC_TIME at the moment
// XFAIL: netbsd
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// XFAIL: no-wide-characters
// REQUIRES: locale.en_US.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
index 2c809f6..a04cb2a 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
@@ -9,6 +9,8 @@
// NetBSD does not support LC_TIME at the moment
// XFAIL: netbsd
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
// REQUIRES: locale.ja_JP.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
index 7f9dbc9..2f2bc2f 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
@@ -10,6 +10,7 @@
// XFAIL: netbsd
// XFAIL: LIBCXX-AIX-FIXME
+// XFAIL: LIBCXX-FREEBSD-FIXME
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
index b353988..d7e1178 100644
--- a/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
@@ -10,6 +10,7 @@
// XFAIL: netbsd
// XFAIL: LIBCXX-AIX-FIXME
+// XFAIL: LIBCXX-FREEBSD-FIXME
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.fr_FR.UTF-8
diff --git a/third_party/llvm-project/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp b/third_party/llvm-project/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp
index 962291d..fab7d78 100644
--- a/third_party/llvm-project/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp
+++ b/third_party/llvm-project/libcxx/test/std/numerics/bit/bit.pow.two/bit_ceil.fail.cpp
@@ -20,8 +20,6 @@
#include <cstdint>
#include <limits>
-#include "test_macros.h"
-
class A{};
enum E1 : unsigned char { rEd };
enum class E2 : unsigned char { red };
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/adaptor.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/adaptor.pass.cpp
new file mode 100644
index 0000000..dbe1523
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/adaptor.pass.cpp
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// std::views::as_rvalue
+
+#include <cassert>
+#include <functional>
+#include <ranges>
+#include <vector>
+
+#include "test_iterators.h"
+
+struct DefaultConstructibleView : std::ranges::view_base {
+ int i_;
+ int* begin();
+ int* end();
+};
+
+struct RValueView : std::ranges::view_base {};
+
+template <class View, class T>
+concept HasPipe = requires(View&& view, T&& t) {
+ { std::forward<View>(view) | std::forward<T>(t) };
+};
+
+struct NoView {};
+static_assert(std::is_invocable_v<decltype(std::views::as_rvalue), DefaultConstructibleView>);
+static_assert(!std::is_invocable_v<decltype(std::views::as_rvalue)>);
+static_assert(!std::is_invocable_v<decltype(std::views::as_rvalue), NoView>);
+static_assert(HasPipe<DefaultConstructibleView&, decltype(std::views::as_rvalue)>);
+static_assert(HasPipe<int (&)[10], decltype(std::views::as_rvalue)>);
+static_assert(!HasPipe<int (&&)[10], decltype(std::views::as_rvalue)>);
+static_assert(!HasPipe<NoView, decltype(std::views::as_rvalue)>);
+static_assert(std::is_same_v<decltype(std::views::as_rvalue), decltype(std::ranges::views::as_rvalue)>);
+
+struct move_iterator_range {
+ constexpr std::move_iterator<int*> begin() const { return {}; }
+ constexpr std::move_iterator<int*> end() const { return {}; }
+};
+
+static_assert(!std::ranges::view<move_iterator_range>);
+static_assert(std::ranges::range<move_iterator_range>);
+
+constexpr bool test() {
+ { // view | views::as_rvalue
+ DefaultConstructibleView v{{}, 3};
+ std::same_as<std::ranges::as_rvalue_view<DefaultConstructibleView>> decltype(auto) view = v | std::views::as_rvalue;
+ assert(view.base().i_ == 3);
+ }
+
+ { // adaptor | views::as_rvalue
+ DefaultConstructibleView v{{}, 3};
+ const auto partial = std::views::transform(std::identity{}) | std::views::as_rvalue;
+ std::same_as<std::ranges::as_rvalue_view<
+ std::ranges::transform_view<DefaultConstructibleView, std::identity>>> decltype(auto) view = partial(v);
+ assert(view.base().base().i_ == 3);
+ }
+
+ { // views::as_rvalue | adaptor
+ DefaultConstructibleView v{{}, 3};
+ const auto partial = std::views::as_rvalue | std::views::transform(std::identity{});
+ std::same_as<std::ranges::transform_view<std::ranges::as_rvalue_view<DefaultConstructibleView>,
+ std::identity>> decltype(auto) view = partial(v);
+ assert(view.base().base().i_ == 3);
+ }
+
+ { // rvalue-view | views::as_rvalue
+ int a[4] = {1, 2, 3, 4};
+ std::ranges::subrange range(rvalue_iterator{a}, rvalue_iterator{a + 4});
+ [[maybe_unused]] std::same_as<std::ranges::subrange<rvalue_iterator<int>>> decltype(auto) rval_range =
+ range | std::views::as_rvalue;
+ }
+
+ { // range | views::as_rvalue
+ [[maybe_unused]] std::same_as<std::ranges::as_rvalue_view<std::views::all_t<std::vector<int>>>> decltype(auto)
+ view = std::vector<int>{} | std::views::as_rvalue;
+ }
+
+ { // rvalue-range | views::as_rvalue
+ [[maybe_unused]] std::same_as<std::views::all_t<move_iterator_range>> decltype(auto) view =
+ move_iterator_range{} | std::views::as_rvalue;
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/base.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/base.pass.cpp
new file mode 100644
index 0000000..ac08f75
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/base.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr V base() const & requires copy_constructible<V> { return base_; }
+// constexpr V base() && { return std::move(base_); }
+
+#include <cassert>
+#include <ranges>
+#include <utility>
+
+#include "MoveOnly.h"
+
+struct SimpleView : std::ranges::view_base {
+ int i;
+ int* begin() const;
+ int* end() const;
+};
+
+struct MoveOnlyView : SimpleView {
+ MoveOnly m;
+};
+
+template <class T>
+concept HasBase = requires(T&& t) { std::forward<T>(t).base(); };
+
+static_assert(HasBase<std::ranges::as_rvalue_view<SimpleView> const&>);
+static_assert(HasBase<std::ranges::as_rvalue_view<SimpleView>&&>);
+
+static_assert(!HasBase<std::ranges::as_rvalue_view<MoveOnlyView> const&>);
+static_assert(HasBase<std::ranges::as_rvalue_view<MoveOnlyView>&&>);
+
+constexpr bool test() {
+ { // const &
+ const std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
+ std::same_as<SimpleView> decltype(auto) v = view.base();
+ assert(v.i == 5);
+ }
+
+ { // &
+ std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
+ std::same_as<SimpleView> decltype(auto) v = view.base();
+ assert(v.i == 5);
+ }
+
+ { // &&
+ std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
+ std::same_as<SimpleView> decltype(auto) v = std::move(view).base();
+ assert(v.i == 5);
+ }
+
+ { // const &&
+ const std::ranges::as_rvalue_view<SimpleView> view(SimpleView{{}, 5});
+ std::same_as<SimpleView> decltype(auto) v = std::move(view).base();
+ assert(v.i == 5);
+ }
+
+ { // move only
+ std::ranges::as_rvalue_view<MoveOnlyView> view(MoveOnlyView{{}, 5});
+ std::same_as<MoveOnlyView> decltype(auto) v = std::move(view).base();
+ assert(v.m.get() == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/begin.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/begin.pass.cpp
new file mode 100644
index 0000000..684cdd8
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/begin.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr auto begin()
+// constexpr auto begin() const
+
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <ranges>
+
+#include "test_iterators.h"
+
+struct SimpleView : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+struct NonSimpleView : std::ranges::view_base {
+ char* begin();
+ char* end();
+ int* begin() const;
+ int* end() const;
+};
+
+struct NonConstView : std::ranges::view_base {
+ char* begin();
+ char* end();
+};
+
+template <class T>
+concept HasBegin = requires(T t) { t.begin(); };
+
+static_assert(HasBegin<std::ranges::as_rvalue_view<SimpleView>>);
+static_assert(HasBegin<const std::ranges::as_rvalue_view<SimpleView>>);
+static_assert(HasBegin<std::ranges::as_rvalue_view<NonSimpleView>>);
+static_assert(HasBegin<const std::ranges::as_rvalue_view<NonSimpleView>>);
+static_assert(HasBegin<std::ranges::as_rvalue_view<NonConstView>>);
+static_assert(!HasBegin<const std::ranges::as_rvalue_view<NonConstView>>);
+
+template <class Iter, class Sent>
+constexpr void test_range() {
+ int a[] = {1, 2};
+ std::ranges::subrange range(Iter(std::begin(a)), Sent(Iter(std::end(a))));
+ std::ranges::as_rvalue_view view(std::move(range));
+ std::same_as<std::move_iterator<Iter>> decltype(auto) iter = view.begin();
+ assert(base(iter.base()) == std::begin(a));
+}
+
+template <class Iter, class Sent>
+class WrapRange {
+ Iter iter_;
+ Sent sent_;
+
+public:
+ constexpr WrapRange(Iter iter, Sent sent) : iter_(std::move(iter)), sent_(std::move(sent)) {}
+
+ constexpr Iter begin() const { return iter_; }
+ constexpr Sent end() const { return sent_; }
+};
+
+template <class Iter, class Sent>
+WrapRange(Iter, Sent) -> WrapRange<Iter, Sent>;
+
+template <class Iter, class Sent>
+constexpr void test_const_range() {
+ int a[] = {1, 2};
+ auto range = WrapRange{Iter(a), Sent(Iter(a + 2))};
+ const std::ranges::as_rvalue_view view(std::views::all(range));
+ std::same_as<std::move_iterator<Iter>> decltype(auto) iter = view.begin();
+ assert(base(iter.base()) == std::begin(a));
+}
+
+struct move_iterator_view : std::ranges::view_base {
+ constexpr std::move_iterator<int*> begin() const { return {}; }
+ constexpr std::move_iterator<int*> end() const { return {}; }
+};
+
+constexpr bool test() {
+ meta::for_each(meta::cpp20_input_iterator_list<int*>{}, []<class Iter> {
+ if constexpr (std::sentinel_for<Iter, Iter>)
+ test_range<Iter, Iter>();
+ test_range<Iter, sentinel_wrapper<Iter>>();
+ test_range<Iter, sized_sentinel<Iter>>();
+ });
+
+ meta::for_each(meta::forward_iterator_list<const int*>{}, []<class Iter> {
+ test_const_range<Iter, Iter>();
+ test_const_range<Iter, sentinel_wrapper<Iter>>();
+ test_const_range<Iter, sized_sentinel<Iter>>();
+ });
+
+ { // check that with a std::move_iterator begin() doesn't return move_iterator<move_iterator<T>>
+ std::ranges::as_rvalue_view view{move_iterator_view{}};
+ std::same_as<std::move_iterator<int*>> decltype(auto) it = view.begin();
+ assert(it == std::move_iterator<int*>{});
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/ctad.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/ctad.compile.pass.cpp
new file mode 100644
index 0000000..5149b71
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/ctad.compile.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include <ranges>
+#include <vector>
+#include <utility>
+
+static_assert(std::is_same_v<decltype(std::ranges::as_rvalue_view(std::vector<int>{})),
+ std::ranges::as_rvalue_view<std::views::all_t<std::vector<int>>>>);
+
+static_assert(std::is_same_v<decltype(std::ranges::as_rvalue_view(std::declval<std::vector<int>&>())),
+ std::ranges::as_rvalue_view<std::views::all_t<std::vector<int>&>>>);
+
+static_assert(std::is_same_v<decltype(std::ranges::as_rvalue_view(std::ranges::empty_view<int>{})),
+ std::ranges::as_rvalue_view<std::ranges::empty_view<int>>>);
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/ctor.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/ctor.pass.cpp
new file mode 100644
index 0000000..4832139
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/ctor.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// std::ranges::as_rvalue_view::as_rvalue_view(...)
+
+#include <cassert>
+#include <ranges>
+#include <vector>
+
+struct DefaultConstructibleView : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+
+ int i_ = 23;
+};
+
+struct NonDefaultConstructibleView : std::ranges::view_base {
+ NonDefaultConstructibleView(int i) : i_(i) {}
+
+ int* begin() const;
+ int* end() const;
+
+ int i_ = 23;
+};
+
+static_assert(!std::is_constructible_v<std::ranges::as_rvalue_view<NonDefaultConstructibleView>>);
+static_assert(std::is_constructible_v<std::ranges::as_rvalue_view<NonDefaultConstructibleView>, int>);
+static_assert(std::is_nothrow_constructible_v<std::ranges::as_rvalue_view<DefaultConstructibleView>>);
+
+template <class T, class... Args>
+concept IsImplicitlyConstructible = requires(T val, Args... args) { val = {std::forward<Args>(args)...}; };
+
+static_assert(IsImplicitlyConstructible<std::ranges::as_rvalue_view<DefaultConstructibleView>>);
+static_assert(!IsImplicitlyConstructible<std::ranges::as_rvalue_view<NonDefaultConstructibleView>, int>);
+
+constexpr bool test() {
+ std::ranges::as_rvalue_view<DefaultConstructibleView> view = {};
+ assert(view.base().i_ == 23);
+
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(test());
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp
new file mode 100644
index 0000000..48d1d96
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp
@@ -0,0 +1,16 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include <ranges>
+#include <vector>
+
+static_assert(std::ranges::enable_borrowed_range<std::ranges::as_rvalue_view<std::ranges::empty_view<int>>>);
+static_assert(std::ranges::enable_borrowed_range<std::ranges::as_rvalue_view<std::views::all_t<std::vector<int>&>>>);
+static_assert(!std::ranges::enable_borrowed_range<std::ranges::as_rvalue_view<std::views::all_t<std::vector<int>>>>);
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/end.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/end.pass.cpp
new file mode 100644
index 0000000..eb79e14
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/end.pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// constexpr auto end()
+// constexpr auto end() const
+
+#include <array>
+#include <cassert>
+#include <ranges>
+
+#include "test_iterators.h"
+
+struct DefaultConstructibleView : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+struct CVCallView : std::ranges::view_base {
+ mutable bool const_called = false;
+ mutable int i[1];
+ constexpr int* begin() {
+ const_called = false;
+ return i;
+ }
+
+ constexpr int* begin() const {
+ const_called = true;
+ return i;
+ }
+
+ constexpr int* end() {
+ const_called = false;
+ return i + 1;
+ }
+
+ constexpr int* end() const {
+ const_called = true;
+ return i + 1;
+ }
+};
+
+struct NonConstCommonRange : std::ranges::view_base {
+ int* begin();
+ int* end();
+
+ int* begin() const;
+ sentinel_wrapper<int*> end() const;
+};
+
+struct NonConstView : std::ranges::view_base {
+ int* begin();
+ int* end();
+};
+
+template <class T>
+concept HasEnd = requires(T t) { t.end(); };
+
+static_assert(HasEnd<std::ranges::as_rvalue_view<DefaultConstructibleView>>);
+static_assert(HasEnd<const std::ranges::as_rvalue_view<DefaultConstructibleView>>);
+static_assert(HasEnd<std::ranges::as_rvalue_view<NonConstView>>);
+static_assert(!HasEnd<const std::ranges::as_rvalue_view<NonConstView>>);
+
+static_assert(std::is_same_v<decltype(std::declval<std::ranges::as_rvalue_view<DefaultConstructibleView>>().end()),
+ std::move_iterator<int*>>);
+static_assert(std::is_same_v<decltype(std::declval<const std::ranges::as_rvalue_view<NonConstCommonRange>>().end()),
+ std::move_sentinel<sentinel_wrapper<int*>>>);
+
+template <class Iter, class Sent, bool is_common>
+constexpr void test_range() {
+ using Expected = std::conditional_t<is_common, std::move_iterator<Sent>, std::move_sentinel<Sent>>;
+ int a[] = {1, 2};
+ std::ranges::subrange range(Iter(std::begin(a)), Sent(Iter(std::end(a))));
+ std::ranges::as_rvalue_view view(std::move(range));
+ std::same_as<Expected> decltype(auto) iter = view.end();
+ assert(base(base(iter.base())) == std::end(a));
+}
+
+template <class Iter, class Sent>
+class WrapRange {
+ Iter iter_;
+ Sent sent_;
+
+public:
+ constexpr WrapRange(Iter iter, Sent sent) : iter_(std::move(iter)), sent_(std::move(sent)) {}
+
+ constexpr Iter begin() const { return iter_; }
+ constexpr Sent end() const { return sent_; }
+};
+
+template <class Iter, class Sent>
+WrapRange(Iter, Sent) -> WrapRange<Iter, Sent>;
+
+template <class Iter, class Sent, bool is_common>
+constexpr void test_const_range() {
+ using Expected = std::conditional_t<is_common, std::move_iterator<Sent>, std::move_sentinel<Sent>>;
+ int a[] = {1, 2};
+ auto range = WrapRange{Iter(a), Sent(Iter(a + 2))};
+ const std::ranges::as_rvalue_view view(std::move(range));
+ std::same_as<Expected> decltype(auto) iter = view.end();
+ assert(base(base(iter.base())) == std::end(a));
+}
+
+struct move_iterator_view : std::ranges::view_base {
+ constexpr std::move_iterator<int*> begin() const { return {}; }
+ constexpr std::move_iterator<int*> end() const { return {}; }
+};
+
+constexpr bool test() {
+ test_range<cpp17_input_iterator<int*>, sentinel_wrapper<cpp17_input_iterator<int*>>, false>();
+ test_range<cpp17_input_iterator<int*>, sized_sentinel<cpp17_input_iterator<int*>>, false>();
+ test_range<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>, false>();
+ test_range<cpp20_input_iterator<int*>, sized_sentinel<cpp20_input_iterator<int*>>, false>();
+
+ meta::for_each(meta::forward_iterator_list<int*>{}, []<class Iter> {
+ test_range<Iter, Iter, true>();
+ test_range<Iter, sentinel_wrapper<Iter>, false>();
+ test_range<Iter, sized_sentinel<Iter>, false>();
+ });
+
+ {
+ std::ranges::as_rvalue_view view(CVCallView{});
+ (void)view.end();
+ assert(view.base().const_called);
+ }
+
+ { // check that with a std::move_iterator begin() doesn't return move_iterator<move_iterator<T>>
+ std::ranges::as_rvalue_view view{move_iterator_view{}};
+ std::same_as<std::move_iterator<int*>> decltype(auto) it = view.end();
+ assert(it == std::move_iterator<int*>{});
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+
+// gcc cannot have mutable member in constant expression
+#if !defined(TEST_COMPILER_GCC)
+ static_assert(test());
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/size.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/size.pass.cpp
new file mode 100644
index 0000000..f330b41
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/size.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// constexpr auto size()
+// constexpr auto size() const
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include <cassert>
+#include <cstddef>
+#include <ranges>
+
+struct ConstSizedView : std::ranges::view_base {
+ bool* size_called;
+ int* begin() const;
+ int* end() const;
+
+ constexpr size_t size() const {
+ *size_called = true;
+ return 3;
+ }
+};
+
+struct SizedView : std::ranges::view_base {
+ bool* size_called;
+ int* begin() const;
+ int* end() const;
+
+ constexpr int size() {
+ *size_called = true;
+ return 5;
+ }
+};
+
+struct UnsizedView : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+template <class T>
+concept HasSize = requires(T v) { v.size(); };
+
+static_assert(HasSize<ConstSizedView>);
+static_assert(HasSize<const ConstSizedView>);
+static_assert(HasSize<SizedView>);
+static_assert(!HasSize<const SizedView>);
+static_assert(!HasSize<UnsizedView>);
+static_assert(!HasSize<const UnsizedView>);
+
+constexpr bool test() {
+ {
+ bool size_called = false;
+ std::ranges::as_rvalue_view view(ConstSizedView{{}, &size_called});
+ std::same_as<size_t> auto size = view.size();
+ assert(size == 3);
+ assert(size_called);
+ }
+
+ {
+ bool size_called = false;
+ std::ranges::as_rvalue_view view(SizedView{{}, &size_called});
+ std::same_as<int> auto size = view.size();
+ assert(size == 5);
+ assert(size_called);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h
index 6f4a0a8..b2ef5f0 100644
--- a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h
@@ -23,25 +23,27 @@
{13, 14, 15, 16},
};
-struct ChildView : std::ranges::view_base {
+template <template<class...> class Iter>
+struct ChildViewBase : std::ranges::view_base {
int* ptr_;
- using iterator = cpp20_input_iterator<int*>;
- using const_iterator = cpp20_input_iterator<const int*>;
+ using iterator = Iter<int*>;
+ using const_iterator = Iter<const int*>;
using sentinel = sentinel_wrapper<iterator>;
using const_sentinel = sentinel_wrapper<const_iterator>;
- constexpr ChildView(int* ptr = globalBuffer[0]) : ptr_(ptr) {}
- ChildView(const ChildView&) = delete;
- ChildView(ChildView&&) = default;
- ChildView& operator=(const ChildView&) = delete;
- ChildView& operator=(ChildView&&) = default;
+ constexpr ChildViewBase(int* ptr = globalBuffer[0]) : ptr_(ptr) {}
+ ChildViewBase(const ChildViewBase&) = delete;
+ ChildViewBase(ChildViewBase&&) = default;
+ ChildViewBase& operator=(const ChildViewBase&) = delete;
+ ChildViewBase& operator=(ChildViewBase&&) = default;
constexpr iterator begin() { return iterator(ptr_); }
constexpr const_iterator begin() const { return const_iterator(ptr_); }
constexpr sentinel end() { return sentinel(iterator(ptr_ + 4)); }
constexpr const_sentinel end() const { return const_sentinel(const_iterator(ptr_ + 4)); }
};
+using ChildView = ChildViewBase<cpp20_input_iterator>;
inline ChildView globalChildren[4] = {
ChildView(globalBuffer[0]),
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp
new file mode 100644
index 0000000..cd12011
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// std::views::split
+
+#include <ranges>
+
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <string_view>
+#include <utility>
+
+#include "test_iterators.h"
+
+template <class View, class T>
+concept CanBePiped = requires (View&& view, T&& t) {
+ { std::forward<View>(view) | std::forward<T>(t) };
+};
+
+struct SomeView : std::ranges::view_base {
+ const std::string_view* v_;
+ constexpr SomeView(const std::string_view& v) : v_(&v) {}
+ constexpr auto begin() const { return v_->begin(); }
+ constexpr auto end() const { return v_->end(); }
+};
+
+struct NotAView { };
+
+static_assert(!std::is_invocable_v<decltype(std::views::split)>);
+static_assert(!std::is_invocable_v<decltype(std::views::split), SomeView, NotAView>);
+static_assert(!std::is_invocable_v<decltype(std::views::split), NotAView, SomeView>);
+static_assert( std::is_invocable_v<decltype(std::views::split), SomeView, SomeView>);
+
+static_assert( CanBePiped<SomeView&, decltype(std::views::split)>);
+static_assert( CanBePiped<char(&)[10], decltype(std::views::split)>);
+static_assert(!CanBePiped<char(&&)[10], decltype(std::views::split)>);
+static_assert(!CanBePiped<NotAView, decltype(std::views::split)>);
+
+static_assert(std::same_as<decltype(std::views::split), decltype(std::ranges::views::split)>);
+
+constexpr bool test() {
+ std::string_view input = "abc";
+ std::string_view sep = "a";
+
+ // Test that `std::views::split` is a range adaptor.
+
+ // Test `views::split(input, sep)`.
+ {
+ SomeView view(input);
+
+ using Result = std::ranges::split_view<SomeView, std::string_view>;
+ std::same_as<Result> decltype(auto) result = std::views::split(view, sep);
+ assert(result.base().begin() == input.begin());
+ assert(result.base().end() == input.end());
+ }
+
+ // Test `views::split(sep)(input)`.
+ {
+ SomeView view(input);
+
+ using Result = std::ranges::split_view<SomeView, std::string_view>;
+ std::same_as<Result> decltype(auto) result = std::views::split(sep)(view);
+ assert(result.base().begin() == input.begin());
+ assert(result.base().end() == input.end());
+ }
+
+ // Test `view | views::split`.
+ {
+ SomeView view(input);
+
+ using Result = std::ranges::split_view<SomeView, std::string_view>;
+ std::same_as<Result> decltype(auto) result = view | std::views::split(sep);
+ assert(result.base().begin() == input.begin());
+ assert(result.base().end() == input.end());
+ }
+
+ // Test `adaptor | views::split`.
+ {
+ SomeView view(input);
+ auto f = [](char c) { return c; };
+ auto partial = std::views::transform(f) | std::views::split(sep);
+
+ using Result = std::ranges::split_view<std::ranges::transform_view<SomeView, decltype(f)>, std::string_view>;
+ std::same_as<Result> decltype(auto) result = partial(view);
+ assert(result.base().base().begin() == input.begin());
+ assert(result.base().base().end() == input.end());
+ }
+
+ // Test `views::split | adaptor`.
+ {
+ SomeView view(input);
+ auto f = [](auto v) { return v; };
+ auto partial = std::views::split(sep) | std::views::transform(f);
+
+ using Result = std::ranges::transform_view<std::ranges::split_view<SomeView, std::string_view>, decltype(f)>;
+ std::same_as<Result> decltype(auto) result = partial(view);
+ assert(result.base().base().begin() == input.begin());
+ assert(result.base().base().end() == input.end());
+ }
+
+ // Test that one can call `std::views::split` with arbitrary stuff, as long as we
+ // don't try to actually complete the call by passing it a range.
+ //
+ // That makes no sense and we can't do anything with the result, but it's valid.
+ {
+ struct X { };
+ [[maybe_unused]] auto partial = std::views::split(X{});
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/base.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/base.pass.cpp
new file mode 100644
index 0000000..56ac55c
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/base.pass.cpp
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr V base() const & requires copy_constructible<V> { return base_; }
+// constexpr V base() && { return std::move(base_); }
+
+#include <cassert>
+#include <ranges>
+#include <type_traits>
+#include <utility>
+
+#include "MoveOnly.h"
+
+struct View : std::ranges::view_base {
+ int i;
+ int* begin() const;
+ int* end() const;
+};
+
+struct MoveOnlyView : View {
+ MoveOnly mo;
+};
+
+template <class T>
+concept HasBase = requires(T&& t) { std::forward<T>(t).base(); };
+
+static_assert(HasBase<std::ranges::split_view<View, View> const&>);
+static_assert(HasBase<std::ranges::split_view<View, View>&&>);
+
+static_assert(!HasBase<std::ranges::split_view<MoveOnlyView, View> const&>);
+static_assert(HasBase<std::ranges::split_view<MoveOnlyView, View>&&>);
+
+constexpr bool test() {
+ // const &
+ {
+ const std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};
+ std::same_as<View> decltype(auto) v = sv.base();
+ assert(v.i == 5);
+ }
+
+ // &
+ {
+ std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};
+ std::same_as<View> decltype(auto) v = sv.base();
+ assert(v.i == 5);
+ }
+
+ // &&
+ {
+ std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};
+ std::same_as<View> decltype(auto) v = std::move(sv).base();
+ assert(v.i == 5);
+ }
+
+ // const &&
+ {
+ std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};
+ std::same_as<View> decltype(auto) v = std::move(sv).base();
+ assert(v.i == 5);
+ }
+
+ // move only
+ {
+ std::ranges::split_view<MoveOnlyView, View> sv{MoveOnlyView{{}, 5}, View{{}, 0}};
+ std::same_as<MoveOnlyView> decltype(auto) v = std::move(sv).base();
+ assert(v.mo.get() == 5);
+ }
+
+ // LWG 3590 split_view::base() const & is overconstrained
+ {
+ struct CopyCtorButNotAssignable : std::ranges::view_base {
+ int i;
+ constexpr CopyCtorButNotAssignable(int ii) : i(ii) {}
+ constexpr CopyCtorButNotAssignable(const CopyCtorButNotAssignable&) = default;
+ constexpr CopyCtorButNotAssignable(CopyCtorButNotAssignable&&) = default;
+ constexpr CopyCtorButNotAssignable& operator=(CopyCtorButNotAssignable&&) = default;
+ constexpr CopyCtorButNotAssignable& operator=(const CopyCtorButNotAssignable&) = delete;
+ constexpr int* begin() const { return nullptr; }
+ constexpr int* end() const { return nullptr; }
+ };
+ static_assert(std::copy_constructible<CopyCtorButNotAssignable>);
+ static_assert(!std::copyable<CopyCtorButNotAssignable>);
+ const std::ranges::split_view<CopyCtorButNotAssignable, CopyCtorButNotAssignable> sv{
+ CopyCtorButNotAssignable{5}, CopyCtorButNotAssignable{5}};
+ std::same_as<CopyCtorButNotAssignable> decltype(auto) v = sv.base();
+ assert(v.i == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/begin.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/begin.pass.cpp
new file mode 100644
index 0000000..15df4d0
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/begin.pass.cpp
@@ -0,0 +1,173 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr auto begin();
+
+#include <array>
+#include <cassert>
+#include <ranges>
+#include <type_traits>
+#include <utility>
+
+#include "test_iterators.h"
+
+struct View : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+// Test that begin is not const
+template <class T>
+concept HasBegin = requires(T t) { t.begin(); };
+
+static_assert(HasBegin<std::ranges::split_view<View, View>>);
+static_assert(!HasBegin<const std::ranges::split_view<View, View>>);
+
+template <template <class> class MakeIter>
+constexpr void testOne() {
+ constexpr auto make_subrange = []<class T, std::size_t N>(T(&buffer)[N]) {
+ using Iter = MakeIter<T*>;
+ using Sent = sentinel_wrapper<Iter>;
+ return std::ranges::subrange<Iter, Sent>{Iter{buffer}, Sent{Iter{buffer + N}}};
+ };
+
+ using Iter = MakeIter<int*>;
+ using Sent = sentinel_wrapper<Iter>;
+ using Range = std::ranges::subrange<Iter, Sent>;
+
+ // empty view
+ {
+ std::array<int, 0> a;
+ Range range{Iter{a.data()}, Sent{Iter{a.data() + a.size()}}};
+ std::ranges::split_view sv{std::move(range), 1};
+ auto it = sv.begin();
+ auto firstRange = *it;
+ assert(firstRange.begin() == range.begin());
+ assert(firstRange.end() == range.end());
+ }
+
+ // empty pattern
+ {
+ int buffer[] = {1, 2, 3};
+ auto range = make_subrange(buffer);
+ std::ranges::split_view sv{std::move(range), std::views::empty<int>};
+ auto it = sv.begin();
+ auto firstRange = *it;
+ assert(firstRange.begin() == range.begin());
+ assert(firstRange.end() == std::next(range.begin()));
+ }
+
+ // empty view and empty pattern
+ {
+ std::array<int, 0> a;
+ Range range{Iter{a.data()}, Sent{Iter{a.data() + a.size()}}};
+ std::ranges::split_view sv{std::move(range), std::views::empty<int>};
+ auto it = sv.begin();
+ auto firstRange = *it;
+ assert(firstRange.begin() == range.begin());
+ assert(firstRange.end() == range.end());
+ }
+
+ // pattern found at the beginning
+ {
+ int buffer[] = {1, 2, 3};
+ auto range = make_subrange(buffer);
+ int pattern[] = {1, 2};
+ std::ranges::split_view sv{range, pattern};
+
+ auto it = sv.begin();
+ auto firstRange = *it;
+ assert(firstRange.begin() == range.begin());
+ assert(firstRange.end() == range.begin());
+ }
+
+ // pattern found in the middle
+ {
+ int buffer[] = {1, 2, 3, 4};
+ auto range = make_subrange(buffer);
+ int pattern[] = {2, 3};
+ std::ranges::split_view sv{range, pattern};
+
+ auto it = sv.begin();
+ auto firstRange = *it;
+ assert(firstRange.begin() == range.begin());
+ assert(firstRange.end() == std::next(range.begin()));
+ }
+
+ // pattern found at the end
+ {
+ int buffer[] = {1, 2, 3};
+ auto range = make_subrange(buffer);
+ int pattern[] = {2, 3};
+ std::ranges::split_view sv{range, pattern};
+
+ auto it = sv.begin();
+ auto firstRange = *it;
+ assert(firstRange.begin() == range.begin());
+ assert(firstRange.end() == std::next(range.begin()));
+ }
+
+ // pattern not found
+ {
+ int buffer[] = {1, 2, 3};
+ auto range = make_subrange(buffer);
+ int pattern[] = {1, 3};
+ std::ranges::split_view sv{range, pattern};
+
+ auto it = sv.begin();
+ auto firstRange = *it;
+ assert(firstRange.begin() == range.begin());
+ assert(firstRange.end() == range.end());
+ }
+
+ // Make sure that we cache the result of begin() on subsequent calls
+ {
+ struct Foo {
+ int& equalsCalledTimes;
+
+ constexpr bool operator==(const Foo&) const {
+ ++equalsCalledTimes;
+ return true;
+ }
+ };
+
+ int equalsCalledTimes = 0;
+ Foo buffer[] = {Foo{equalsCalledTimes}, Foo{equalsCalledTimes}};
+ auto range = make_subrange(buffer);
+
+ std::ranges::split_view sv{range, Foo{equalsCalledTimes}};
+
+ assert(equalsCalledTimes == 0);
+
+ [[maybe_unused]] auto it1 = sv.begin();
+ auto calledTimesAfterFirstBegin = equalsCalledTimes;
+ assert(calledTimesAfterFirstBegin != 0);
+
+ for (int i = 0; i < 10; ++i) {
+ [[maybe_unused]] auto it2 = sv.begin();
+ assert(equalsCalledTimes == calledTimesAfterFirstBegin);
+ }
+ }
+}
+
+constexpr bool test() {
+ testOne<forward_iterator>();
+ testOne<bidirectional_iterator>();
+ testOne<random_access_iterator>();
+ testOne<contiguous_iterator>();
+ testOne<std::type_identity_t>();
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/constraints.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/constraints.compile.pass.cpp
new file mode 100644
index 0000000..66a491f
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/constraints.compile.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// template<forward_range V, forward_range Pattern>
+// requires view<V> && view<Pattern> &&
+// indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>
+// class split_view;
+
+#include <ranges>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+template <class It>
+using Range = std::ranges::subrange<It, sentinel_wrapper<It>>;
+
+template <class View, class Pattern>
+concept HasSplitView = requires { typename std::ranges::split_view<View, Pattern>; };
+
+static_assert(HasSplitView<Range<int*>, Range<int*>>);
+
+// !forward_range<V>
+static_assert(!HasSplitView<Range<cpp20_input_iterator<int*>>, Range<int*>>);
+
+// !forward_range<Pattern>
+static_assert(!HasSplitView<Range<int*>, Range<cpp20_input_iterator<int*>>>);
+
+struct NotAView {
+ int* begin() const;
+ int* end() const;
+};
+
+// !view<V>
+static_assert(!HasSplitView<NotAView, Range<int*>>);
+
+// !view<Pattern>
+static_assert(!HasSplitView<Range<int*>, NotAView>);
+
+// indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to
+struct Foo {};
+static_assert(!HasSplitView<Range<int*>, Range<Foo*>>);
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctad.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctad.compile.pass.cpp
new file mode 100644
index 0000000..90d49e4
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctad.compile.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// template <class R, class P>
+// split_view(R&&, P&&) -> split_view<views::all_t<R>, views::all_t<P>>;
+//
+// template <input_range R>
+// split_view(R&&, range_value_t<R>) -> split_view<views::all_t<R>, single_view<range_value_t<R>>>;
+
+#include <concepts>
+#include <ranges>
+#include <type_traits>
+#include <utility>
+
+struct Container {
+ int* begin() const;
+ int* end() const;
+};
+
+struct View : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+template <class I1, class I2, class ExpectedView, class ExpectedPattern>
+constexpr void test() {
+ static_assert(std::is_same_v<decltype(std::ranges::split_view(std::declval<I1>(), std::declval<I2>())),
+ std::ranges::split_view<ExpectedView, ExpectedPattern>>);
+}
+
+constexpr void testCtad() {
+ // (Range, Pattern)
+ test<View, View, View, View>();
+ test<Container&, Container&, std::ranges::ref_view<Container>, std::ranges::ref_view<Container>>();
+ test<Container&&, Container&&, std::ranges::owning_view<Container>, std::ranges::owning_view<Container>>();
+
+ // (Range, RangeElement)
+ test<Container&, int, std::ranges::ref_view<Container>, std::ranges::single_view<int>>();
+ test<View, int, View, std::ranges::single_view<int>>();
+
+ // (Range, RangeElement) with implicit conversion.
+ test<Container&, bool, std::ranges::ref_view<Container>, std::ranges::single_view<int>>();
+ test<View, bool, View, std::ranges::single_view<int>>();
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.default.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.default.pass.cpp
new file mode 100644
index 0000000..aff0740
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.default.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr split_view() requires
+// default_initializable<V> && default_initializable<Pattern> = default;
+
+#include <cassert>
+#include <ranges>
+#include <type_traits>
+
+template <bool DefaultInitializable>
+struct View : std::ranges::view_base {
+ int i = 42;
+ constexpr explicit View()
+ requires DefaultInitializable
+ = default;
+ int* begin() const;
+ int* end() const;
+};
+
+// clang-format off
+static_assert( std::is_default_constructible_v<std::ranges::split_view<View<true >, View<true >>>);
+static_assert(!std::is_default_constructible_v<std::ranges::split_view<View<false>, View<true >>>);
+static_assert(!std::is_default_constructible_v<std::ranges::split_view<View<true >, View<false>>>);
+static_assert(!std::is_default_constructible_v<std::ranges::split_view<View<false>, View<false>>>);
+// clang-format on
+
+constexpr bool test() {
+ {
+ std::ranges::split_view<View<true>, View<true>> sv = {};
+ assert(sv.base().i == 42);
+ }
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.range.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.range.pass.cpp
new file mode 100644
index 0000000..605e3d5
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.range.pass.cpp
@@ -0,0 +1,139 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// template <input_range Range>
+// requires constructible_from<View, views::all_t<Range>> &&
+// constructible_from<Pattern, single_view<range_value_t<Range>>>
+// constexpr split_view(Range&& r, range_value_t<Range> e);
+
+#include <algorithm>
+#include <cassert>
+#include <ranges>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+
+struct Counting {
+ int* times_copied = nullptr;
+ int* times_moved = nullptr;
+
+ constexpr Counting(int& copies_ctr, int& moves_ctr) : times_copied(&copies_ctr), times_moved(&moves_ctr) {}
+
+ constexpr Counting(const Counting& rhs) : times_copied(rhs.times_copied), times_moved(rhs.times_moved) {
+ ++(*times_copied);
+ }
+ constexpr Counting(Counting&& rhs) : times_copied(rhs.times_copied), times_moved(rhs.times_moved) {
+ ++(*times_moved);
+ }
+
+ constexpr Counting& operator=(const Counting&) = default;
+ constexpr Counting& operator=(Counting&&) = default;
+};
+
+struct ElementWithCounting : Counting {
+ using Counting::Counting;
+
+ constexpr bool operator==(const ElementWithCounting&) const { return true; }
+};
+
+struct RangeWithCounting : Counting {
+ using Counting::Counting;
+
+ constexpr const ElementWithCounting* begin() const { return nullptr; }
+ constexpr const ElementWithCounting* end() const { return nullptr; }
+
+ constexpr bool operator==(const RangeWithCounting&) const { return true; }
+};
+static_assert(std::ranges::forward_range<RangeWithCounting>);
+static_assert(!std::ranges::view<RangeWithCounting>);
+
+struct StrView : std::ranges::view_base {
+ std::string buffer_;
+
+ template <std::ranges::range R>
+ constexpr StrView(R&& r) : buffer_(std::ranges::begin(r), std::ranges::end(r)) {}
+ constexpr const char* begin() const { return buffer_.data(); }
+ constexpr const char* end() const { return buffer_.data() + buffer_.size(); }
+ constexpr bool operator==(const StrView& rhs) const { return buffer_ == rhs.buffer_; }
+};
+static_assert(std::ranges::random_access_range<StrView>);
+static_assert(std::ranges::view<StrView>);
+static_assert(std::is_copy_constructible_v<StrView>);
+
+constexpr bool test() {
+ {
+ using V = std::ranges::split_view<StrView, StrView>;
+
+ // Calling the constructor with `(std::string, range_value_t)`.
+ {
+ std::string input("abc def");
+ V v(input, ' ');
+ assert(v.base() == input);
+ assert(std::ranges::equal(*v.begin(), std::string_view("abc")));
+ }
+
+ // Calling the constructor with `(StrView, range_value_t)`.
+ {
+ StrView input("abc def");
+ V v(input, ' ');
+ assert(v.base() == input);
+ assert(std::ranges::equal(*v.begin(), std::string_view("abc")));
+ }
+
+ struct Empty {};
+ static_assert(!std::is_constructible_v<V, Empty, std::string_view>);
+ static_assert(!std::is_constructible_v<V, std::string_view, Empty>);
+ }
+
+ // Make sure the arguments are moved, not copied.
+ {
+ using Range = RangeWithCounting;
+ using Element = ElementWithCounting;
+ using Pattern = std::ranges::single_view<Element>;
+
+ // Arguments are lvalues.
+ {
+ using View = std::ranges::ref_view<Range>;
+
+ int range_copied = 0, range_moved = 0, element_copied = 0, element_moved = 0;
+ Range range(range_copied, range_moved);
+ Element element(element_copied, element_moved);
+
+ std::ranges::split_view<View, Pattern> v(range, element);
+ assert(range_copied == 0); // `ref_view` does neither copy...
+ assert(range_moved == 0); // ...nor move the element.
+ assert(element_copied == 1); // The element is copied into the argument...
+ assert(element_moved == 1); // ...and moved into the member variable.
+ }
+
+ // Arguments are rvalues.
+ {
+ using View = std::ranges::owning_view<Range>;
+
+ int range_copied = 0, range_moved = 0, element_copied = 0, element_moved = 0;
+ std::ranges::split_view<View, Pattern> v(
+ Range(range_copied, range_moved), Element(element_copied, element_moved));
+ assert(range_copied == 0);
+ assert(range_moved == 1); // `owning_view` moves the given argument.
+ assert(element_copied == 0);
+ assert(element_moved == 1);
+ }
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.view.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.view.pass.cpp
new file mode 100644
index 0000000..ad206ee
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/ctor.view.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr split_view(View base, Pattern pattern);
+
+#include <algorithm>
+#include <cassert>
+#include <ranges>
+#include <string_view>
+#include <utility>
+
+struct ViewWithCounting : std::ranges::view_base {
+ int* times_copied = nullptr;
+ int* times_moved = nullptr;
+
+ constexpr ViewWithCounting(int& copies_ctr, int& moves_ctr) : times_copied(&copies_ctr), times_moved(&moves_ctr) {}
+
+ constexpr ViewWithCounting(const ViewWithCounting& rhs)
+ : times_copied(rhs.times_copied), times_moved(rhs.times_moved) {
+ ++(*times_copied);
+ }
+ constexpr ViewWithCounting(ViewWithCounting&& rhs) : times_copied(rhs.times_copied), times_moved(rhs.times_moved) {
+ ++(*times_moved);
+ }
+
+ constexpr const char* begin() const { return nullptr; }
+ constexpr const char* end() const { return nullptr; }
+
+ constexpr ViewWithCounting& operator=(const ViewWithCounting&) = default;
+ constexpr ViewWithCounting& operator=(ViewWithCounting&&) = default;
+ constexpr bool operator==(const ViewWithCounting&) const { return true; }
+};
+
+constexpr bool test() {
+ {
+ std::string_view input = "abc def";
+ std::ranges::lazy_split_view<std::string_view, std::string_view> v(input, " ");
+ assert(v.base() == input);
+ assert(std::ranges::equal(*v.begin(), std::string_view{"abc"}));
+ }
+
+ // Make sure the arguments are moved, not copied.
+ {
+ using View = ViewWithCounting;
+ using Pattern = ViewWithCounting;
+
+ // Arguments are lvalues.
+ {
+ int view_copied = 0, view_moved = 0, pattern_copied = 0, pattern_moved = 0;
+ View view(view_copied, view_moved);
+ Pattern pattern(pattern_copied, pattern_moved);
+
+ std::ranges::split_view<View, Pattern> v(view, pattern);
+ assert(view_copied == 1); // The local variable is copied into the argument.
+ assert(view_moved == 1);
+ assert(pattern_copied == 1);
+ assert(pattern_moved == 1);
+ }
+
+ // Arguments are rvalues.
+ {
+ int view_copied = 0, view_moved = 0, pattern_copied = 0, pattern_moved = 0;
+ std::ranges::split_view<View, Pattern> v(View(view_copied, view_moved), Pattern(pattern_copied, pattern_moved));
+ assert(view_copied == 0);
+ assert(view_moved == 1);
+ assert(pattern_copied == 0);
+ assert(pattern_moved == 1);
+ }
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/end.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/end.pass.cpp
new file mode 100644
index 0000000..6c8aece
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/end.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr auto end();
+
+#include <cassert>
+#include <ranges>
+#include <type_traits>
+#include <utility>
+
+#include "test_iterators.h"
+
+struct View : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+// Test that end is not const
+template <class T>
+concept HasEnd = requires(T t) { t.end(); };
+
+static_assert(HasEnd<std::ranges::split_view<View, View>>);
+static_assert(!HasEnd<const std::ranges::split_view<View, View>>);
+
+constexpr bool test() {
+ // return iterator
+ {
+ int buffer[] = {1, 2, -1, 4, 5, 6, 5, 4, -1, 2, 1};
+ auto inputView = std::views::all(buffer);
+ static_assert(std::ranges::common_range<decltype(inputView)>);
+
+ std::ranges::split_view sv(buffer, -1);
+ using SplitIter = std::ranges::iterator_t<decltype(sv)>;
+ std::same_as<SplitIter> decltype(auto) sentinel = sv.end();
+ assert(sentinel.base() == buffer + 11);
+ }
+
+ // return sentinel
+ {
+ using Iter = int*;
+ using Sent = sentinel_wrapper<Iter>;
+ using Range = std::ranges::subrange<Iter, Sent>;
+ int buffer[] = {1, 2, -1, 4, 5, 6, 5, 4, -1, 2, 1};
+ Range range = {buffer, Sent{buffer + 11}};
+ static_assert(!std::ranges::common_range<Range>);
+
+ std::ranges::split_view sv(range, -1);
+ auto sentinel = sv.end();
+
+ using SplitIter = std::ranges::iterator_t<decltype(sv)>;
+ static_assert(!std::same_as<decltype(sentinel), SplitIter>);
+
+ assert(std::next(sv.begin(), 3) == sentinel);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/general.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/general.pass.cpp
new file mode 100644
index 0000000..8684e3b
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/general.pass.cpp
@@ -0,0 +1,395 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Some basic examples of how split_view might be used in the wild. This is a general
+// collection of sample algorithms and functions that try to mock general usage of
+// this view.
+
+// These test check the output `split_view` produces for a variety of inputs, including many corner cases, with no
+// restrictions on which member functions can be called.
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <map>
+#include <ranges>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "test_macros.h"
+
+template <std::ranges::view View, std::ranges::range Expected>
+constexpr bool is_equal(View& view, const Expected& expected) {
+ return std::ranges::equal(view, expected, std::ranges::equal);
+}
+
+template <class T, class Separator, class U, size_t M>
+constexpr bool test_function_call(T&& input, Separator&& separator, std::array<U, M> expected) {
+ std::ranges::split_view v(input, separator);
+ return is_equal(v, expected);
+}
+
+template <class T, class Separator, class U, size_t M>
+constexpr bool test_with_piping(T&& input, Separator&& separator, std::array<U, M> expected) {
+ auto expected_it = expected.begin();
+ for (auto e : input | std::ranges::views::split(separator)) {
+ if (expected_it == expected.end())
+ return false;
+ if (!std::ranges::equal(e, *expected_it))
+ return false;
+
+ ++expected_it;
+ }
+
+ return expected_it == expected.end();
+}
+
+constexpr bool test_l_r_values() {
+ using namespace std::string_view_literals;
+
+ // Both lvalues and rvalues can be used as input.
+ {
+ // Lvalues.
+ {
+ auto input = "abc"sv;
+ auto sep = " "sv;
+ [[maybe_unused]] std::ranges::split_view v(input, sep);
+ }
+
+ // Const lvalues.
+ {
+ const auto input = "abc"sv;
+ const auto sep = " "sv;
+ [[maybe_unused]] std::ranges::split_view v(input, sep);
+ }
+
+ // Rvalues.
+ {
+ auto input = "abc"sv;
+ auto sep = " "sv;
+ [[maybe_unused]] std::ranges::split_view v(std::move(input), std::move(sep));
+ }
+
+ // Const rvalues.
+ {
+ const auto input = "abc"sv;
+ const auto sep = " "sv;
+ [[maybe_unused]] std::ranges::split_view v(std::move(input), std::move(sep));
+ }
+ }
+
+ return true;
+}
+
+constexpr bool test_string_literal_separator() {
+ using namespace std::string_view_literals;
+
+ // Splitting works as expected when the separator is a single character literal.
+ {
+ std::ranges::split_view v("abc def"sv, ' ');
+ assert(is_equal(v, std::array{"abc"sv, "def"sv}));
+ }
+
+ // Counterintuitively, a seemingly equivalent separator expressed as a string literal doesn't match anything. This is
+ // because of the implicit terminating null in the literal.
+ {
+ std::ranges::split_view v("abc def"sv, " ");
+ assert(is_equal(v, std::array{"abc def"sv}));
+ }
+
+ // To illustrate the previous point further, the separator is actually a two-character string literal: `{' ', '\0'}`.
+ // Should the input string contain that two-character sequence, the separator would match.
+ {
+ std::ranges::split_view v("abc \0def"sv, " ");
+ assert(is_equal(v, std::array{"abc"sv, "def"sv}));
+ }
+
+ return true;
+}
+
+// Make sure that a string literal and a `string_view` produce the same results (which isn't always the case, see
+// below).
+template <class T>
+constexpr std::string_view sv(T&& str) {
+ return std::string_view(str);
+};
+
+template <class T, class Separator, class U, size_t M>
+constexpr void test_one(T&& input, Separator&& separator, std::array<U, M> expected) {
+ assert(test_function_call(input, separator, expected));
+ assert(test_with_piping(input, separator, expected));
+}
+
+constexpr bool test_string_literals() {
+ // These tests show characteristic examples of how using string literals with `split_view` produces unexpected
+ // results due to the implicit terminating null that is treated as part of the range.
+
+ using namespace std::string_view_literals;
+
+ char short_sep = ' ';
+ auto long_sep = "12"sv;
+
+ // When splitting a string literal, only the last segment will be null-terminated (getting the terminating null from
+ // the original range).
+ {
+ std::array expected = {"abc"sv, std::string_view("def", sizeof("def"))};
+
+ assert(test_function_call("abc def", short_sep, expected));
+ assert(test_with_piping("abc def", short_sep, expected));
+ assert(test_function_call("abc12def", long_sep, expected));
+ assert(test_with_piping("abc12def", long_sep, expected));
+ }
+
+ // Empty string.
+ {
+ // Because an empty string literal contains an implicit terminating null, the output will contain one segment.
+ std::array expected = {std::string_view("", 1)};
+
+ assert(test_function_call("", short_sep, expected));
+ assert(test_with_piping("", short_sep, expected));
+ assert(test_function_call("", long_sep, expected));
+ assert(test_with_piping("", long_sep, expected));
+ }
+
+ // Terminating null in the separator -- the character literal `' '` and the seemingly equivalent string literal `" "`
+ // are treated differently due to the presence of an implicit `\0` in the latter.
+ {
+ const char input[] = "abc def";
+ std::array expected_unsplit = {std::string_view(input, sizeof(input))};
+ std::array expected_split = {"abc"sv, std::string_view("def", sizeof("def"))};
+
+ assert(test_function_call(input, " ", expected_unsplit));
+ assert(test_function_call("abc \0def", " ", expected_split));
+ // Note: string literals don't work with piping because arrays decay to pointers, and pointers don't model `range`.
+ }
+
+ // Empty separator.
+ {
+ auto empty_sep = ""sv;
+ std::array expected = {"a"sv, "b"sv, "c"sv, "\0"sv};
+
+ assert(test_function_call("abc", empty_sep, expected));
+ assert(test_with_piping("abc", empty_sep, expected));
+ }
+
+ return true;
+}
+
+bool test_nontrivial_characters() {
+ // Try a deliberately heavyweight "character" type to see if it triggers any corner cases.
+
+ using Map = std::map<std::string, int>;
+ using Vec = std::vector<Map>;
+
+ Map sep = {{"yyy", 999}};
+ Map m1 = {
+ {"a", 1},
+ {"bc", 2},
+ };
+ Map m2 = {
+ {"def", 3},
+ };
+ Map m3 = {
+ {"g", 4},
+ {"hijk", 5},
+ };
+
+ Vec expected1 = {m1, m2};
+ Vec expected2 = {m3};
+
+ std::ranges::split_view v(Vec{m1, m2, sep, m3}, sep);
+
+ // Segment 1: {m1, m2}
+ auto outer = v.begin();
+ assert(outer != v.end());
+ auto inner = (*outer).begin();
+ assert(*inner++ == m1);
+ assert(*inner++ == m2);
+ assert(inner == (*outer).end());
+
+ // Segment 2: {m3}
+ ++outer;
+ assert(outer != v.end());
+ inner = (*outer).begin();
+ assert(*inner++ == m3);
+ assert(inner == (*outer).end());
+
+ ++outer;
+ assert(outer == v.end());
+
+ return true;
+}
+
+constexpr bool main_test() {
+ using namespace std::string_view_literals;
+
+ char short_sep = ' ';
+ auto long_sep = "12"sv;
+
+ // One separator.
+ {
+ std::array expected = {"abc"sv, "def"sv};
+ test_one("abc def"sv, short_sep, expected);
+ test_one("abc12def"sv, long_sep, expected);
+ }
+
+ // Several separators in a row.
+ {
+ std::array expected = {"abc"sv, ""sv, ""sv, ""sv, "def"sv};
+ test_one("abc def"sv, short_sep, expected);
+ test_one("abc12121212def"sv, long_sep, expected);
+ }
+
+ // Trailing separator.
+ {
+ std::array expected = {"abc"sv, "def"sv, ""sv};
+ test_one("abc def "sv, short_sep, expected);
+ test_one("abc12def12"sv, long_sep, expected);
+ }
+
+ // Leading separator.
+ {
+ std::array expected = {""sv, "abc"sv, "def"sv};
+ test_one(" abc def"sv, short_sep, expected);
+ test_one("12abc12def"sv, long_sep, expected);
+ }
+
+ // No separator.
+ {
+ std::array expected = {"abc"sv};
+ test_one("abc"sv, short_sep, expected);
+ test_one("abc"sv, long_sep, expected);
+ }
+
+ // Input consisting of a single separator.
+ {
+ std::array expected = {""sv, ""sv};
+ test_one(" "sv, short_sep, expected);
+ test_one("12"sv, long_sep, expected);
+ }
+
+ // Input consisting of only separators.
+ {
+ std::array expected = {""sv, ""sv, ""sv, ""sv};
+ test_one(" "sv, short_sep, expected);
+ test_one("121212"sv, long_sep, expected);
+ }
+
+ // The separator and the string use the same character only.
+ {
+ auto overlapping_sep = "aaa"sv;
+ std::array expected = {""sv, "aa"sv};
+ test_one("aaaaa"sv, overlapping_sep, expected);
+ }
+
+ // Many redundant separators.
+ {
+ std::array expected = {""sv, ""sv, "abc"sv, ""sv, ""sv, "def"sv, ""sv, ""sv};
+ test_one(" abc def "sv, short_sep, expected);
+ test_one("1212abc121212def1212"sv, long_sep, expected);
+ }
+
+ // Separators after every character.
+ {
+ std::array expected = {""sv, "a"sv, "b"sv, "c"sv, ""sv};
+ test_one(" a b c "sv, short_sep, expected);
+ test_one("12a12b12c12"sv, long_sep, expected);
+ }
+
+ // Overlap between the separator and the string (see https://wg21.link/lwg3505).
+ {
+ auto overlapping_sep = "ab"sv;
+ std::array expected = {"a"sv, "aa"sv, ""sv, "b"sv};
+ test_one("aabaaababb"sv, overlapping_sep, expected);
+ }
+
+ // Empty input.
+ {
+ std::array<std::string_view, 0> expected = {};
+ test_one(""sv, short_sep, expected);
+ test_one(""sv, long_sep, expected);
+ }
+
+ // Empty separator.
+ {
+ auto empty_sep = ""sv;
+ std::array expected = {"a"sv, "b"sv, "c"sv};
+ test_one("abc"sv, empty_sep, expected);
+ test_one("abc"sv, empty_sep, expected);
+ }
+
+ // Terminating null as a separator.
+ {
+ std::array expected = {"abc"sv, "def"sv};
+ test_one("abc\0def"sv, '\0', expected);
+ test_one("abc\0\0def"sv, "\0\0"sv, expected);
+ }
+
+ // Different character types.
+ {
+ // `char`.
+ test_function_call("abc def", ' ', std::array{"abc"sv, "def"sv});
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ // `wchar_t`.
+ test_function_call(L"abc def", L' ', std::array{L"abc"sv, L"def"sv});
+#endif
+ // `char8_t`.
+ test_function_call(u8"abc def", u8' ', std::array{u8"abc"sv, u8"def"sv});
+ // `char16_t`.
+ test_function_call(u"abc def", u' ', std::array{u"abc"sv, u"def"sv});
+ // `char32_t`.
+ test_function_call(U"abc def", U' ', std::array{U"abc"sv, U"def"sv});
+ }
+
+ // Non-character input.
+ {
+ std::array expected = {std::array{1, 2, 3}, std::array{4, 5, 6}};
+ test_one(std::array{1, 2, 3, 0, 4, 5, 6}, 0, expected);
+ test_one(std::array{1, 2, 3, 0, 0, 0, 4, 5, 6}, std::array{0, 0, 0}, expected);
+ }
+
+ return true;
+}
+
+constexpr bool example_test() {
+ // example code in the spec
+ std::string str{"the quick brown fox"};
+ std::vector<std::string_view> result;
+ for (auto r : std::views::split(str, ' ')) {
+ result.emplace_back(r.begin(), r.end());
+ }
+ using namespace std::string_view_literals;
+ auto expected = {"the"sv, "quick"sv, "brown"sv, "fox"sv};
+ assert(std::ranges::equal(result, expected));
+
+ return true;
+}
+
+int main(int, char**) {
+ example_test();
+ static_assert(example_test());
+
+ test_string_literals();
+ static_assert(test_string_literals());
+
+ test_l_r_values();
+ static_assert(test_l_r_values());
+
+ test_string_literal_separator();
+ static_assert(test_string_literal_separator());
+
+ // Note: map is not `constexpr`, so this test is runtime-only.
+ test_nontrivial_characters();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
new file mode 100644
index 0000000..325189a
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/base.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr iterator_t<V> base() const;
+
+#include <cassert>
+#include <ranges>
+
+#include "../types.h"
+
+struct Iter : ForwardIterBase<Iter> {
+ int i;
+ constexpr Iter() = default;
+ constexpr Iter(int ii) : i(ii) {}
+};
+
+constexpr bool test() {
+ // base only has one const overload
+ using SplitView = std::ranges::split_view<std::ranges::subrange<Iter>, std::ranges::subrange<Iter>>;
+ using SplitIter = std::ranges::iterator_t<SplitView>;
+
+ // const &
+ {
+ SplitView sv;
+ const SplitIter it{sv, Iter{5}, {}};
+ std::same_as<Iter> decltype(auto) base = it.base();
+ assert(base.i == 5);
+ }
+
+ // &
+ {
+ SplitView sv;
+ SplitIter it{sv, Iter{5}, {}};
+ std::same_as<Iter> decltype(auto) base = it.base();
+ assert(base.i == 5);
+ }
+
+ // &&
+ {
+ SplitView sv;
+ SplitIter it{sv, Iter{5}, {}};
+ std::same_as<Iter> decltype(auto) base = std::move(it).base();
+ assert(base.i == 5);
+ }
+
+ // const &&
+ {
+ SplitView sv;
+ const SplitIter it{sv, Iter{5}, {}};
+ std::same_as<Iter> decltype(auto) base = std::move(it).base();
+ assert(base.i == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp
new file mode 100644
index 0000000..20b3c19
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.base.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next);
+
+#include <cassert>
+#include <ranges>
+
+#include "../types.h"
+
+struct TracedMoveIter : ForwardIterBase<TracedMoveIter> {
+ bool moved = false;
+
+ constexpr TracedMoveIter() = default;
+ constexpr TracedMoveIter(const TracedMoveIter&) = default;
+ constexpr TracedMoveIter(TracedMoveIter&&) : moved{true} {}
+ constexpr TracedMoveIter& operator=(TracedMoveIter&&) = default;
+ constexpr TracedMoveIter& operator=(const TracedMoveIter&) = default;
+};
+
+struct TracedMoveView : std::ranges::view_base {
+ constexpr TracedMoveIter begin() const { return {}; }
+ constexpr TracedMoveIter end() const { return {}; }
+};
+
+constexpr bool test() {
+ using SplitView = std::ranges::split_view<TracedMoveView, TracedMoveView>;
+ using SplitIter = std::ranges::iterator_t<SplitView>;
+
+ SplitView sv{TracedMoveView{}, TracedMoveView{}};
+ SplitIter iter = {sv, sv.base().begin(), std::ranges::subrange<TracedMoveIter>{sv.base().begin(), sv.base().end()}};
+ assert(iter.base().moved);
+
+ auto subRange = *iter;
+ assert(subRange.begin().moved);
+ assert(subRange.end().moved);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.default.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.default.pass.cpp
new file mode 100644
index 0000000..72a6fe5
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/ctor.default.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// iterator() = default;
+
+#include <cassert>
+#include <ranges>
+
+#include "../types.h"
+
+struct PODIter : ForwardIterBase<PODIter> {
+ int i;
+};
+
+constexpr bool test() {
+ using SplitView = std::ranges::split_view<std::ranges::subrange<PODIter>, std::ranges::subrange<PODIter>>;
+ using SplitIter = std::ranges::iterator_t<SplitView>;
+ {
+ SplitIter iter;
+ assert(iter.base().i == 0); // PODIter has to be initialised to have value 0
+ }
+
+ {
+ SplitIter iter = {}; // explicit(false)
+ assert(iter.base().i == 0); // PODIter has to be initialised to have value 0
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
new file mode 100644
index 0000000..721a1cc
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/deref.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr value_type operator*() const;
+// Effects: Equivalent to return {cur_, next_.begin()};
+
+#include <cassert>
+#include <ranges>
+
+#include "../types.h"
+
+struct Iter : ForwardIterBase<Iter> {
+ int i;
+ constexpr Iter() = default;
+ constexpr Iter(int ii) : i(ii) {}
+};
+
+constexpr bool test() {
+ using SplitView = std::ranges::split_view<std::ranges::subrange<Iter>, std::ranges::subrange<Iter>>;
+ using SplitIter = std::ranges::iterator_t<SplitView>;
+
+ {
+ SplitView sv;
+ Iter current{5};
+ std::ranges::subrange next{Iter{6}, Iter{7}};
+ const SplitIter it{sv, current, next};
+ std::same_as<std::ranges::subrange<Iter>> decltype(auto) value = *it;
+ assert(value.begin().i == 5);
+ assert(value.end().i == 6);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/equal.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/equal.pass.cpp
new file mode 100644
index 0000000..30888d1
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/equal.pass.cpp
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// friend constexpr bool operator==(const iterator& x, const iterator& y);
+
+#include <algorithm>
+#include <cassert>
+#include <concepts>
+#include <ranges>
+
+#include "test_iterators.h"
+
+template <class Iter>
+constexpr void testOne() {
+ using Range = std::ranges::subrange<Iter>;
+ using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
+ static_assert(std::ranges::common_range<SplitView>);
+
+ {
+ // simple test
+ {
+ int buffer[] = {0, 1, 2, -1, 4, 5, 6};
+ Range input(Iter{buffer}, Iter{buffer + 7});
+ SplitView sv(input, -1);
+ auto b = sv.begin(), e = sv.end();
+
+ assert(b == b);
+ assert(!(b != b));
+
+ assert(e == e);
+ assert(!(e != e));
+
+ assert(!(b == e));
+ assert(b != e);
+
+ std::advance(b, 2);
+ assert(b == b);
+ assert(!(b != b));
+
+ assert(e == e);
+ assert(!(e != e));
+
+ assert(b == e);
+ assert(!(b != e));
+ }
+
+ // iterator at trailing empty position should not equal to end
+ {
+ int buffer[] = {0, 1, 2, -1};
+ Range input(Iter{buffer}, Iter{buffer + 4});
+ SplitView sv(input, -1);
+ auto b = sv.begin(), e = sv.end();
+
+ ++b; // cur points to end but trailing_empty is true
+
+ assert(b != e);
+ assert(!(b == e));
+
+ ++b;
+ assert(b == e);
+ assert(!(b != e));
+ }
+
+ // Default-constructed iterators compare equal.
+ {
+ int buffer[] = {0, 1, 2, -1, 4, 5, 6};
+ Range input(Iter{buffer}, Iter{buffer + 7});
+ std::ranges::split_view sv(buffer, -1);
+ using SplitIter = decltype(sv.begin());
+ SplitIter i1, i2;
+ assert(i1 == i2);
+ assert(!(i1 != i2));
+ }
+ }
+}
+
+constexpr bool test() {
+ testOne<forward_iterator<int*>>();
+ testOne<bidirectional_iterator<int*>>();
+ testOne<random_access_iterator<int*>>();
+ testOne<contiguous_iterator<int*>>();
+ testOne<int*>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/increment.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/increment.pass.cpp
new file mode 100644
index 0000000..56036dc
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/increment.pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr iterator& operator++();
+// constexpr iterator operator++(int);
+
+#include <cassert>
+#include <ranges>
+
+#include "test_iterators.h"
+
+template <class Iter>
+constexpr void testOne() {
+ constexpr auto make_subrange = []<std::size_t N>(int(&buffer)[N]) {
+ return std::ranges::subrange<Iter>{Iter{buffer}, Iter{buffer + N}};
+ };
+
+ // next subrange does not reach the end
+ {
+ int buffer[] = {0, 1, 2, -1, 4, 5, -1, 7};
+ auto input = make_subrange(buffer);
+ std::ranges::split_view sv(input, -1);
+ using SplitIter = std::ranges::iterator_t<decltype(sv)>;
+
+ // ++it
+ {
+ auto it = sv.begin();
+
+ decltype(auto) it1 = ++it;
+ static_assert(std::is_same_v<decltype(it1), SplitIter&>);
+ assert(&it1 == &it);
+
+ assert(base((*it).begin()) == buffer + 4);
+ assert(base((*it).end()) == buffer + 6);
+
+ ++it;
+ assert(base((*it).begin()) == buffer + 7);
+ assert(base((*it).end()) == buffer + 8);
+ }
+
+ // it++
+ {
+ auto it = sv.begin();
+ auto original = it;
+
+ decltype(auto) it1 = it++;
+ static_assert(std::is_same_v<decltype(it1), SplitIter>);
+ assert(it1 == original);
+
+ assert(base((*it).begin()) == buffer + 4);
+ assert(base((*it).end()) == buffer + 6);
+
+ it++;
+ assert(base((*it).begin()) == buffer + 7);
+ assert(base((*it).end()) == buffer + 8);
+ }
+ }
+
+ // next's begin is the end
+ {
+ int buffer[] = {0, 1, 2};
+ auto input = make_subrange(buffer);
+ std::ranges::split_view sv(input, -1);
+ using SplitIter = std::ranges::iterator_t<decltype(sv)>;
+
+ // ++it
+ {
+ auto it = sv.begin();
+
+ decltype(auto) it1 = ++it; // trailing_empty is false
+ static_assert(std::is_same_v<decltype(it1), SplitIter&>);
+ assert(&it1 == &it);
+
+ assert(it == sv.end());
+ }
+
+ // it++
+ {
+ auto it = sv.begin();
+ auto original = it;
+
+ decltype(auto) it1 = it++; // trailing_empty is false
+ static_assert(std::is_same_v<decltype(it1), SplitIter>);
+ assert(it1 == original);
+
+ assert(it == sv.end());
+ }
+ }
+
+ // next's end is the end
+ {
+ int buffer[] = {0, 1, 2, -1};
+ auto input = make_subrange(buffer);
+ std::ranges::split_view sv(input, -1);
+ using SplitIter = std::ranges::iterator_t<decltype(sv)>;
+
+ // ++it
+ {
+ auto it = sv.begin();
+
+ decltype(auto) it1 = ++it; // trailing_empty is true
+ static_assert(std::is_same_v<decltype(it1), SplitIter&>);
+ assert(&it1 == &it);
+
+ assert(it != sv.end());
+ assert(base((*it).begin()) == buffer + 4);
+ assert(base((*it).begin()) == buffer + 4);
+
+ ++it;
+ assert(it == sv.end());
+ }
+
+ // it++
+ {
+ auto it = sv.begin();
+ auto original = it;
+
+ decltype(auto) it1 = it++; // trailing_empty is true
+ static_assert(std::is_same_v<decltype(it1), SplitIter>);
+ assert(it1 == original);
+
+ assert(it != sv.end());
+
+ assert(base((*it).begin()) == buffer + 4);
+ assert(base((*it).begin()) == buffer + 4);
+
+ it++;
+ assert(it == sv.end());
+ }
+ }
+}
+
+constexpr bool test() {
+ testOne<forward_iterator<int*>>();
+ testOne<bidirectional_iterator<int*>>();
+ testOne<random_access_iterator<int*>>();
+ testOne<contiguous_iterator<int*>>();
+ testOne<int*>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/member_types.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/member_types.compile.pass.cpp
new file mode 100644
index 0000000..aa1a346
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/iterator/member_types.compile.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Member typedefs in split_view<V, P>::iterator.
+
+#include <concepts>
+#include <ranges>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+template <class Iter, class PatternIter>
+constexpr void testIteratorTypedef() {
+ using Range = std::ranges::subrange<Iter, sentinel_wrapper<Iter>>;
+ using Pattern = std::ranges::subrange<PatternIter, sentinel_wrapper<PatternIter>>;
+ using SplitIter = std::ranges::iterator_t<std::ranges::split_view<Range, Pattern>>;
+
+ static_assert(std::same_as<typename SplitIter::iterator_concept, //
+ std::forward_iterator_tag>);
+
+ static_assert(std::same_as<typename SplitIter::iterator_category, //
+ std::input_iterator_tag>);
+
+ static_assert(std::same_as<typename SplitIter::value_type, //
+ std::ranges::subrange<Iter>>);
+
+ static_assert(std::same_as<typename SplitIter::difference_type, //
+ std::iter_difference_t<Iter>>);
+}
+
+template <class Iter>
+void testIteratorTypedefPattern() {
+ testIteratorTypedef<Iter, forward_iterator<int*>>();
+ testIteratorTypedef<Iter, bidirectional_iterator<int*>>();
+ testIteratorTypedef<Iter, random_access_iterator<int*>>();
+ testIteratorTypedef<Iter, contiguous_iterator<int*>>();
+ testIteratorTypedef<Iter, int*>();
+}
+
+void test() {
+ testIteratorTypedefPattern<forward_iterator<int*>>();
+ testIteratorTypedefPattern<bidirectional_iterator<int*>>();
+ testIteratorTypedefPattern<random_access_iterator<int*>>();
+ testIteratorTypedefPattern<contiguous_iterator<int*>>();
+ testIteratorTypedefPattern<int*>();
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.default.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.default.pass.cpp
new file mode 100644
index 0000000..7914af9
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.default.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// sentinel() = default;
+
+#include <cassert>
+#include <ranges>
+
+struct PODSentinel {
+ int i;
+
+ friend constexpr bool operator==(int*, const PODSentinel& p) { return p.i == 0; }
+};
+
+struct Range : std::ranges::view_base {
+ int* begin() const;
+ PODSentinel end();
+};
+
+constexpr bool test() {
+ using SplitView = std::ranges::split_view<Range, Range>;
+ using SplitIter = std::ranges::iterator_t<SplitView>;
+ using SplitSent = std::ranges::sentinel_t<SplitView>;
+ static_assert(!std::is_same_v<SplitSent, SplitIter>);
+
+ {
+ SplitIter it;
+ SplitSent s;
+ assert(s == it); // to make sure that s.__end_.i is initialised to 0;
+ }
+
+ {
+ SplitIter it;
+ SplitSent s = {};
+ assert(s == it); // to make sure that s.__end_.i is initialised to 0;
+ }
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.pass.cpp
new file mode 100644
index 0000000..c89b1ee
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/ctor.parent.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr explicit sentinel(split_view& parent);
+
+#include <cassert>
+#include <ranges>
+#include <type_traits>
+
+#include "test_iterators.h"
+
+// test explicit
+using Range = std::ranges::subrange<int*, sentinel_wrapper<int*>>;
+using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
+using SplitSent = std::ranges::sentinel_t<SplitView>;
+
+static_assert(std::is_constructible_v<SplitSent, SplitView&>);
+static_assert(!std::is_convertible_v<SplitView&, SplitSent>);
+
+constexpr bool test() {
+ {
+ int buffer[] = {0, 1, 2};
+ Range input{buffer, sentinel_wrapper<int*>(buffer + 3)};
+ SplitView sv(input, -1);
+ auto it = sv.begin();
+
+ SplitSent sent(sv);
+ assert(sent != it);
+
+ ++it;
+ assert(sent == it);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/equal.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/equal.pass.cpp
new file mode 100644
index 0000000..7b33a6b
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/sentinel/equal.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// friend constexpr bool operator==(const iterator& x, const sentinel& y);
+
+#include <algorithm>
+#include <cassert>
+#include <concepts>
+#include <ranges>
+
+#include "test_iterators.h"
+
+template <class Iter>
+constexpr void testOne() {
+ using Sent = sentinel_wrapper<Iter>;
+ using Range = std::ranges::subrange<Iter, Sent>;
+ using SplitView = std::ranges::split_view<Range, std::ranges::single_view<int>>;
+ static_assert(!std::ranges::common_range<SplitView>);
+
+ {
+ // simple test
+ {
+ int buffer[] = {0, 1, 2, -1, 4, 5, 6};
+ Range input(Iter{buffer}, Sent{Iter{buffer + 7}});
+ SplitView sv(input, -1);
+ auto b = sv.begin();
+ auto e = sv.end();
+
+ assert(!(b == e));
+ assert(b != e);
+
+ std::advance(b, 2);
+ assert(b == e);
+ assert(!(b != e));
+ }
+
+ // iterator at trailing empty position should not equal to end
+ {
+ int buffer[] = {0, 1, 2, -1};
+ Range input(Iter{buffer}, Sent{Iter{buffer + 4}});
+ SplitView sv(input, -1);
+ auto b = sv.begin();
+ auto e = sv.end();
+
+ ++b; // cur points to end but trailing_empty is true
+
+ assert(b != e);
+ assert(!(b == e));
+
+ ++b;
+ assert(b == e);
+ assert(!(b != e));
+ }
+ }
+}
+
+constexpr bool test() {
+ testOne<forward_iterator<int*>>();
+ testOne<bidirectional_iterator<int*>>();
+ testOne<random_access_iterator<int*>>();
+ testOne<contiguous_iterator<int*>>();
+ testOne<int*>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/types.h b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/types.h
new file mode 100644
index 0000000..ff2ce38
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.adaptors/range.split/types.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_SPLIT_TYPES_H
+#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_SPLIT_TYPES_H
+
+#include <functional>
+#include <ranges>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "test_range.h"
+
+template <class Derived>
+struct ForwardIterBase {
+ using iterator_concept = std::forward_iterator_tag;
+ using value_type = int;
+ using difference_type = intptr_t;
+
+ constexpr int operator*() const { return 5; }
+
+ constexpr Derived& operator++() { return static_cast<Derived&>(*this); }
+ constexpr Derived operator++(int) { return {}; }
+
+ friend constexpr bool operator==(const ForwardIterBase&, const ForwardIterBase&) { return true; };
+};
+
+#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_SPLIT_TYPES_H
diff --git a/third_party/llvm-project/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp b/third_party/llvm-project/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp
index 95388cc..570c74e 100644
--- a/third_party/llvm-project/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/ranges/range.factories/range.iota.view/iterator/star.pass.cpp
@@ -26,7 +26,7 @@
int value_;
constexpr explicit NotNoexceptCopy(int value = 0) : value_(value) {}
- NotNoexceptCopy(const NotNoexceptCopy&) noexcept(false) = default;
+ constexpr NotNoexceptCopy(const NotNoexceptCopy& other) noexcept(false) : value_(other.value_) {}
bool operator==(const NotNoexceptCopy&) const = default;
diff --git a/third_party/llvm-project/libcxx/test/std/re/re.traits/lookup_collatename.pass.cpp b/third_party/llvm-project/libcxx/test/std/re/re.traits/lookup_collatename.pass.cpp
index a9598b1..178979d 100644
--- a/third_party/llvm-project/libcxx/test/std/re/re.traits/lookup_collatename.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/re/re.traits/lookup_collatename.pass.cpp
@@ -8,7 +8,9 @@
//
// NetBSD does not support LC_COLLATE at the moment
// XFAIL: netbsd
+
// XFAIL: LIBCXX-AIX-FIXME
+// XFAIL: LIBCXX-FREEBSD-FIXME
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/third_party/llvm-project/libcxx/test/std/re/re.traits/transform_primary.pass.cpp b/third_party/llvm-project/libcxx/test/std/re/re.traits/transform_primary.pass.cpp
index 9a8b289..422e3a5 100644
--- a/third_party/llvm-project/libcxx/test/std/re/re.traits/transform_primary.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/re/re.traits/transform_primary.pass.cpp
@@ -8,7 +8,9 @@
//
// NetBSD does not support LC_COLLATE at the moment
// XFAIL: netbsd
+
// XFAIL: LIBCXX-AIX-FIXME
+// XFAIL: LIBCXX-FREEBSD-FIXME
// REQUIRES: locale.cs_CZ.ISO8859-2
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp
index e6475f8..491d30b 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mdlast/ostream.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.month/time.cal.month.nonmembers/ostream.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.month/time.cal.month.nonmembers/ostream.pass.cpp
index 4d62217..2efc023 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.month/time.cal.month.nonmembers/ostream.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.month/time.cal.month.nonmembers/ostream.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp
index 2c0e692..006df5e 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwd/time.cal.mwd.nonmembers/ostream.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp
index ca3d71e..0a76fbd 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.mwdlast/time.cal.mwdlast.nonmembers/ostream.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp
index 45ce90c..13257cc 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/ostream.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp
index df75711..9ded734 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/ostream.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.day.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.day.pass.cpp
index 75a0e1e..373db72 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.day.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.day.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
index 7d4ac7b..1a2fcca 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month.pass.cpp
index a6d458d..324887f 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp
index 36550e7..f86476f 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp
index d7f3fc6..7c78271 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_day_last.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp
index 3c6a7b9..f34b22c 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.month_weekday.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday.pass.cpp
index 6e9dd50..1b3fbe9 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp
index 8923147..5493034 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_index.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp
index 9c2ec9c..e3fa9ae 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.weekday_last.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year.pass.cpp
index cbb2dcd..beb4732 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp
index 9edca55..344967d 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp
index a795511..25d5a58 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp
index 0df6919..35ce599 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_day_last.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp
index 7189789..617f183 100644
--- a/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_weekday.pass.cpp
@@ -5,6 +5,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: no-localization
// UNSUPPORTED: libcpp-has-no-incomplete-format
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
index 4e9e526..b0abc2c 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp
@@ -38,6 +38,7 @@
#include <variant>
#include "test_macros.h"
+#include "min_allocator.h"
#ifndef TEST_HAS_NO_FILESYSTEM_LIBRARY
# include <filesystem>
@@ -194,38 +195,45 @@
assert_is_not_formattable<std::unique_ptr<int>, CharT>();
}
+template <class CharT, class Vector>
+void test_P2286_vector_bool() {
+ assert_is_formattable<Vector, CharT>();
+ assert_is_formattable<typename Vector::reference, CharT>();
+}
+
// Tests for P2286 Formatting ranges
-//
-// The paper hasn't been voted in so currently all formatters are disabled.
-// TODO validate whether the test is correct after the paper has been accepted.
template <class CharT>
void test_P2286() {
- assert_is_not_formattable<std::array<int, 42>, CharT>();
- assert_is_not_formattable<std::vector<int>, CharT>();
- assert_is_not_formattable<std::deque<int>, CharT>();
- assert_is_not_formattable<std::forward_list<int>, CharT>();
- assert_is_not_formattable<std::list<int>, CharT>();
+ assert_is_formattable<std::array<int, 42>, CharT>();
+ assert_is_formattable<std::vector<int>, CharT>();
+ assert_is_formattable<std::deque<int>, CharT>();
+ assert_is_formattable<std::forward_list<int>, CharT>();
+ assert_is_formattable<std::list<int>, CharT>();
- assert_is_not_formattable<std::set<int>, CharT>();
- assert_is_not_formattable<std::map<int, int>, CharT>();
- assert_is_not_formattable<std::multiset<int>, CharT>();
- assert_is_not_formattable<std::multimap<int, int>, CharT>();
+ assert_is_formattable<std::set<int>, CharT>();
+ assert_is_formattable<std::map<int, int>, CharT>();
+ assert_is_formattable<std::multiset<int>, CharT>();
+ assert_is_formattable<std::multimap<int, int>, CharT>();
- assert_is_not_formattable<std::unordered_set<int>, CharT>();
- assert_is_not_formattable<std::unordered_map<int, int>, CharT>();
- assert_is_not_formattable<std::unordered_multiset<int>, CharT>();
- assert_is_not_formattable<std::unordered_multimap<int, int>, CharT>();
+ assert_is_formattable<std::unordered_set<int>, CharT>();
+ assert_is_formattable<std::unordered_map<int, int>, CharT>();
+ assert_is_formattable<std::unordered_multiset<int>, CharT>();
+ assert_is_formattable<std::unordered_multimap<int, int>, CharT>();
- assert_is_not_formattable<std::stack<int>, CharT>();
- assert_is_not_formattable<std::queue<int>, CharT>();
- assert_is_not_formattable<std::priority_queue<int>, CharT>();
+ assert_is_formattable<std::stack<int>, CharT>();
+ assert_is_formattable<std::queue<int>, CharT>();
+ assert_is_formattable<std::priority_queue<int>, CharT>();
- assert_is_not_formattable<std::span<int>, CharT>();
+ assert_is_formattable<std::span<int>, CharT>();
- assert_is_not_formattable<std::valarray<int>, CharT>();
+ assert_is_formattable<std::valarray<int>, CharT>();
assert_is_formattable<std::pair<int, int>, CharT>();
assert_is_formattable<std::tuple<int>, CharT>();
+
+ test_P2286_vector_bool<CharT, std::vector<bool>>();
+ test_P2286_vector_bool<CharT, std::vector<bool, std::allocator<bool>>>();
+ test_P2286_vector_bool<CharT, std::vector<bool, min_allocator<bool>>>();
}
class c {
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.ascii.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.ascii.pass.cpp
index 4145385..329124f 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.ascii.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.ascii.pass.cpp
@@ -24,6 +24,7 @@
#include "test_macros.h"
#include "make_string.h"
#include "test_format_string.h"
+#include "assert_macros.h"
#ifndef TEST_HAS_NO_LOCALIZATION
# include <iostream>
@@ -35,19 +36,9 @@
std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
{
std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
-#ifndef TEST_HAS_NO_LOCALIZATION
- if (out != expected) {
- if constexpr (std::same_as<CharT, char>)
- std::cerr << "\nFormat string " << fmt.get() << "\nExpected output " << expected << "\nActual output "
- << out << '\n';
-# ifndef TEST_HAS_NO_WIDE_CHARACTERS
- else
- std::wcerr << L"\nFormat string " << fmt.get() << L"\nExpected output " << expected << L"\nActual output "
- << out << L'\n';
-# endif // TEST_HAS_NO_WIDE_CHARACTERS
- }
-#endif // TEST_HAS_NO_LOCALIZATION
- assert(out == expected);
+ TEST_REQUIRE(out == expected,
+ test_concat_message(
+ "\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
}
#ifndef TEST_HAS_NO_LOCALIZATION
{
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.unicode.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.unicode.pass.cpp
index 3514919..c940bcb 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.unicode.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/escaped_output.unicode.pass.cpp
@@ -30,6 +30,7 @@
#include "test_macros.h"
#include "make_string.h"
#include "test_format_string.h"
+#include "assert_macros.h"
#ifndef TEST_HAS_NO_LOCALIZATION
# include <iostream>
@@ -41,19 +42,9 @@
std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
{
std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
-#ifndef TEST_HAS_NO_LOCALIZATION
- if (out != expected) {
- if constexpr (std::same_as<CharT, char>)
- std::cerr << "\nFormat string " << fmt.get() << "\nExpected output " << expected << "\nActual output "
- << out << '\n';
-# ifndef TEST_HAS_NO_WIDE_CHARACTERS
- else
- std::wcerr << L"\nFormat string " << fmt.get() << L"\nExpected output " << expected << L"\nActual output "
- << out << L'\n';
-# endif // TEST_HAS_NO_WIDE_CHARACTERS
- }
-#endif // TEST_HAS_NO_LOCALIZATION
- assert(out == expected);
+ TEST_REQUIRE(out == expected,
+ test_concat_message(
+ "\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
}
#ifndef TEST_HAS_NO_LOCALIZATION
{
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.locale.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.locale.pass.cpp
index 76d4b35..ab34558 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.locale.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.locale.pass.cpp
@@ -27,16 +27,16 @@
#include "format_tests.h"
#include "string_literal.h"
#include "test_format_string.h"
+#include "assert_macros.h"
auto test =
[]<class CharT, class... Args>(
std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) constexpr {
std::basic_string<CharT> out = std::format(std::locale(), fmt, std::forward<Args>(args)...);
- if constexpr (std::same_as<CharT, char>)
- if (out != expected)
- std::cerr << "\nFormat string " << fmt.get() << "\nExpected output " << expected << "\nActual output "
- << out << '\n';
- assert(out == expected);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message(
+ "\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
};
auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.pass.cpp
index 2710078..ca9d1d9 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/format.pass.cpp
@@ -29,23 +29,16 @@
#include "format_tests.h"
#include "string_literal.h"
#include "test_format_string.h"
-
-#ifndef TEST_HAS_NO_LOCALIZATION
-# include <iostream>
-# include <type_traits>
-#endif
+#include "assert_macros.h"
auto test =
[]<class CharT, class... Args>(
std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) constexpr {
std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
-#ifndef TEST_HAS_NO_LOCALIZATION
- if constexpr (std::same_as<CharT, char>)
- if (out != expected)
- std::cerr << "\nFormat string " << fmt.get() << "\nExpected output " << expected << "\nActual output "
- << out << '\n';
-#endif
- assert(out == expected);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message(
+ "\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
};
auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp
index 7f3f195..86d56da 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp
@@ -93,6 +93,7 @@
#include "format_tests.h"
#include "string_literal.h"
#include "test_format_string.h"
+#include "assert_macros.h"
#define STR(S) MAKE_STRING(CharT, S)
#define SV(S) MAKE_STRING_VIEW(CharT, S)
@@ -127,11 +128,9 @@
// *** format ***
{
std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
- if constexpr (std::same_as<CharT, char>)
- if (out != expected)
- std::cerr << "\nFormat string " << fmt.get() << "\nExpected output " << expected << "\nActual output "
- << out << '\n';
- assert(out == expected);
+ TEST_REQUIRE(out == expected,
+ test_concat_message(
+ "\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
}
// *** vformat ***
{
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.locale.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.locale.pass.cpp
index 11bf67f..90c56df 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.locale.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.locale.pass.cpp
@@ -23,11 +23,14 @@
#include "test_macros.h"
#include "format_tests.h"
#include "string_literal.h"
+#include "assert_macros.h"
auto test = []<class CharT, class... Args>(
std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) constexpr {
std::basic_string<CharT> out = std::vformat(std::locale(), fmt, std::make_format_args<context_t<CharT>>(args...));
- assert(out == expected);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
};
auto test_exception =
@@ -37,10 +40,13 @@
[[maybe_unused]] Args&&... args) {
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
- (void)std::vformat(std::locale(), fmt, std::make_format_args<context_t<CharT>>(args...));
- assert(false);
+ TEST_IGNORE_NODISCARD std::vformat(std::locale(), fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
} catch ([[maybe_unused]] const std::format_error& e) {
- LIBCPP_ASSERT(e.what() == what);
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
return;
}
assert(false);
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp
index d115615..236d83e 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp
@@ -22,11 +22,14 @@
#include "test_macros.h"
#include "format_tests.h"
#include "string_literal.h"
+#include "assert_macros.h"
auto test = []<class CharT, class... Args>(
std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) constexpr {
std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
- assert(out == expected);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
};
auto test_exception =
@@ -37,9 +40,13 @@
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
- assert(false);
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
} catch ([[maybe_unused]] const std::format_error& e) {
- LIBCPP_ASSERT(e.what() == what);
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+
return;
}
assert(false);
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.format.pass.cpp
new file mode 100644
index 0000000..b2e65ec
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.format.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::map, R, charT>
+//
+// template<class... Args>
+// string format(format_string<Args...> fmt, Args&&... args);
+// template<class... Args>
+// wstring format(wformat_string<Args...> fmt, Args&&... args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_format_string.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
+ // After P2216 most exceptions thrown by std::format become ill-formed.
+ // Therefore this tests does nothing.
+};
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.tests.h b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.tests.h
new file mode 100644
index 0000000..005a2bd
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.tests.h
@@ -0,0 +1,841 @@
+//===----------------------------------------------------------------------===//
+// 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 TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FMTMAP_FORMAT_FUNCTIONS_TESTS_H
+#define TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FMTMAP_FORMAT_FUNCTIONS_TESTS_H
+
+#include <algorithm>
+#include <format>
+#include <map>
+#include <unordered_map>
+
+#include "format.functions.common.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+//
+// Char
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char(TestFunction check, ExceptionTest check_exception) {
+ std::map<CharT, CharT> input{{CharT('a'), CharT('A')}, {CharT('c'), CharT('C')}, {CharT('b'), CharT('B')}};
+
+ check(SV("{a: A, b: B, c: C}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{a: A, b: B, c: C} "), SV("{:23}"), input);
+ check(SV("{a: A, b: B, c: C}*****"), SV("{:*<23}"), input);
+ check(SV("__{a: A, b: B, c: C}___"), SV("{:_^23}"), input);
+ check(SV("#####{a: A, b: B, c: C}"), SV("{:#>23}"), input);
+
+ check(SV("{a: A, b: B, c: C} "), SV("{:{}}"), input, 23);
+ check(SV("{a: A, b: B, c: C}*****"), SV("{:*<{}}"), input, 23);
+ check(SV("__{a: A, b: B, c: C}___"), SV("{:_^{}}"), input, 23);
+ check(SV("#####{a: A, b: B, c: C}"), SV("{:#>{}}"), input, 23);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__a: A, b: B, c: C___"), SV("{:_^21n}"), input);
+
+ // *** type ***
+ check(SV("__{a: A, b: B, c: C}___"), SV("{:_^23m}"), input); // the m type does the same as the default.
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+
+ check(SV("{'a': 'A' , 'b': 'B' , 'c': 'C' }"), SV("{::13}"), input);
+ check(SV("{'a': 'A'*****, 'b': 'B'*****, 'c': 'C'*****}"), SV("{::*<13}"), input);
+ check(SV("{__'a': 'A'___, __'b': 'B'___, __'c': 'C'___}"), SV("{::_^13}"), input);
+ check(SV("{#####'a': 'A', #####'b': 'B', #####'c': 'C'}"), SV("{::#>13}"), input);
+
+ check(SV("{'a': 'A' , 'b': 'B' , 'c': 'C' }"), SV("{::{}}"), input, 13);
+ check(SV("{'a': 'A'*****, 'b': 'B'*****, 'c': 'C'*****}"), SV("{::*<{}}"), input, 13);
+ check(SV("{__'a': 'A'___, __'b': 'B'___, __'c': 'C'___}"), SV("{::_^{}}"), input, 13);
+ check(SV("{#####'a': 'A', #####'b': 'B', #####'c': 'C'}"), SV("{::#>{}}"), input, 13);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("{'a': 'A', 'b': 'B', 'c': 'C'}"), SV("{::m}"), input);
+ check(SV("{'a': 'A', 'b': 'B', 'c': 'C'}"), SV("{::n}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{###'a': 'A', ###'b': 'B', ###'c': 'C'}^^^"), SV("{:^^44:#>11}"), input);
+ check(SV("^^{###'a': 'A', ###'b': 'B', ###'c': 'C'}^^^"), SV("{:^^{}:#>11}"), input, 44);
+ check(SV("^^{###'a': 'A', ###'b': 'B', ###'c': 'C'}^^^"), SV("{:^^{}:#>{}}"), input, 44, 11);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>11}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 44);
+}
+
+//
+// char -> wchar_t
+//
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class TestFunction, class ExceptionTest>
+void test_char_to_wchar(TestFunction check, ExceptionTest check_exception) {
+ std::map<char, char> input{{'a', 'A'}, {'c', 'C'}, {'b', 'B'}};
+
+ using CharT = wchar_t;
+ check(SV("{a: A, b: B, c: C}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{a: A, b: B, c: C} "), SV("{:23}"), input);
+ check(SV("{a: A, b: B, c: C}*****"), SV("{:*<23}"), input);
+ check(SV("__{a: A, b: B, c: C}___"), SV("{:_^23}"), input);
+ check(SV("#####{a: A, b: B, c: C}"), SV("{:#>23}"), input);
+
+ check(SV("{a: A, b: B, c: C} "), SV("{:{}}"), input, 23);
+ check(SV("{a: A, b: B, c: C}*****"), SV("{:*<{}}"), input, 23);
+ check(SV("__{a: A, b: B, c: C}___"), SV("{:_^{}}"), input, 23);
+ check(SV("#####{a: A, b: B, c: C}"), SV("{:#>{}}"), input, 23);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__a: A, b: B, c: C___"), SV("{:_^21n}"), input);
+
+ // *** type ***
+ check(SV("__{a: A, b: B, c: C}___"), SV("{:_^23m}"), input); // the m type does the same as the default.
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{'a': 'A' , 'b': 'B' , 'c': 'C' }"), SV("{::13}"), input);
+ check(SV("{'a': 'A'*****, 'b': 'B'*****, 'c': 'C'*****}"), SV("{::*<13}"), input);
+ check(SV("{__'a': 'A'___, __'b': 'B'___, __'c': 'C'___}"), SV("{::_^13}"), input);
+ check(SV("{#####'a': 'A', #####'b': 'B', #####'c': 'C'}"), SV("{::#>13}"), input);
+
+ check(SV("{'a': 'A' , 'b': 'B' , 'c': 'C' }"), SV("{::{}}"), input, 13);
+ check(SV("{'a': 'A'*****, 'b': 'B'*****, 'c': 'C'*****}"), SV("{::*<{}}"), input, 13);
+ check(SV("{__'a': 'A'___, __'b': 'B'___, __'c': 'C'___}"), SV("{::_^{}}"), input, 13);
+ check(SV("{#####'a': 'A', #####'b': 'B', #####'c': 'C'}"), SV("{::#>{}}"), input, 13);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("{'a': 'A', 'b': 'B', 'c': 'C'}"), SV("{::m}"), input);
+ check(SV("{'a': 'A', 'b': 'B', 'c': 'C'}"), SV("{::n}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{###'a': 'A', ###'b': 'B', ###'c': 'C'}^^^"), SV("{:^^44:#>11}"), input);
+ check(SV("^^{###'a': 'A', ###'b': 'B', ###'c': 'C'}^^^"), SV("{:^^{}:#>11}"), input, 44);
+ check(SV("^^{###'a': 'A', ###'b': 'B', ###'c': 'C'}^^^"), SV("{:^^{}:#>{}}"), input, 44, 11);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>11}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 44);
+}
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+//
+// Bool
+//
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_bool(TestFunction check, ExceptionTest check_exception) {
+ // duplicates are stored in order of insertion
+ std::multimap<bool, int> input{{true, 42}, {false, 0}, {true, 1}};
+
+ check(SV("{false: 0, true: 42, true: 1}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{false: 0, true: 42, true: 1} "), SV("{:34}"), input);
+ check(SV("{false: 0, true: 42, true: 1}*****"), SV("{:*<34}"), input);
+ check(SV("__{false: 0, true: 42, true: 1}___"), SV("{:_^34}"), input);
+ check(SV("#####{false: 0, true: 42, true: 1}"), SV("{:#>34}"), input);
+
+ check(SV("{false: 0, true: 42, true: 1} "), SV("{:{}}"), input, 34);
+ check(SV("{false: 0, true: 42, true: 1}*****"), SV("{:*<{}}"), input, 34);
+ check(SV("__{false: 0, true: 42, true: 1}___"), SV("{:_^{}}"), input, 34);
+ check(SV("#####{false: 0, true: 42, true: 1}"), SV("{:#>{}}"), input, 34);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__false: 0, true: 42, true: 1___"), SV("{:_^32n}"), input);
+
+ // *** type ***
+ check(SV("__{false: 0, true: 42, true: 1}___"), SV("{:_^34m}"), input); // the m type does the same as the default.
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{false: 0 , true: 42 , true: 1 }"), SV("{::10}"), input);
+ check(SV("{false: 0**, true: 42**, true: 1***}"), SV("{::*<10}"), input);
+ check(SV("{_false: 0_, _true: 42_, _true: 1__}"), SV("{::_^10}"), input);
+ check(SV("{##false: 0, ##true: 42, ###true: 1}"), SV("{::#>10}"), input);
+
+ check(SV("{false: 0 , true: 42 , true: 1 }"), SV("{::{}}"), input, 10);
+ check(SV("{false: 0**, true: 42**, true: 1***}"), SV("{::*<{}}"), input, 10);
+ check(SV("{_false: 0_, _true: 42_, _true: 1__}"), SV("{::_^{}}"), input, 10);
+ check(SV("{##false: 0, ##true: 42, ###true: 1}"), SV("{::#>{}}"), input, 10);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{##false: 0, ##true: 42, ###true: 1}^^^"), SV("{:^^41:#>10}"), input);
+ check(SV("^^{##false: 0, ##true: 42, ###true: 1}^^^"), SV("{:^^{}:#>10}"), input, 41);
+ check(SV("^^{##false: 0, ##true: 42, ###true: 1}^^^"), SV("{:^^{}:#>{}}"), input, 41, 10);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>10}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 41);
+}
+
+//
+// Integral
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("{-42: 42, 1: -1, 42: -42}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{-42: 42, 1: -1, 42: -42} "), SV("{:30}"), input);
+ check(SV("{-42: 42, 1: -1, 42: -42}*****"), SV("{:*<30}"), input);
+ check(SV("__{-42: 42, 1: -1, 42: -42}___"), SV("{:_^30}"), input);
+ check(SV("#####{-42: 42, 1: -1, 42: -42}"), SV("{:#>30}"), input);
+
+ check(SV("{-42: 42, 1: -1, 42: -42} "), SV("{:{}}"), input, 30);
+ check(SV("{-42: 42, 1: -1, 42: -42}*****"), SV("{:*<{}}"), input, 30);
+ check(SV("__{-42: 42, 1: -1, 42: -42}___"), SV("{:_^{}}"), input, 30);
+ check(SV("#####{-42: 42, 1: -1, 42: -42}"), SV("{:#>{}}"), input, 30);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__-42: 42, 1: -1, 42: -42___"), SV("{:_^28n}"), input);
+
+ // *** type ***
+ check(SV("__{-42: 42, 1: -1, 42: -42}___"), SV("{:_^30m}"), input); // the m type does the same as the default.
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{-42: 42 , 1: -1 , 42: -42 }"), SV("{::10}"), input);
+ check(SV("{-42: 42***, 1: -1*****, 42: -42***}"), SV("{::*<10}"), input);
+ check(SV("{_-42: 42__, __1: -1___, _42: -42__}"), SV("{::_^10}"), input);
+ check(SV("{###-42: 42, #####1: -1, ###42: -42}"), SV("{::#>10}"), input);
+
+ check(SV("{-42: 42 , 1: -1 , 42: -42 }"), SV("{::{}}"), input, 10);
+ check(SV("{-42: 42***, 1: -1*****, 42: -42***}"), SV("{::*<{}}"), input, 10);
+ check(SV("{_-42: 42__, __1: -1___, _42: -42__}"), SV("{::_^{}}"), input, 10);
+ check(SV("{###-42: 42, #####1: -1, ###42: -42}"), SV("{::#>{}}"), input, 10);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{###-42: 42, #####1: -1, ###42: -42}^^^"), SV("{:^^41:#>10}"), input);
+ check(SV("^^{###-42: 42, #####1: -1, ###42: -42}^^^"), SV("{:^^{}:#>10}"), input, 41);
+ check(SV("^^{###-42: 42, #####1: -1, ###42: -42}^^^"), SV("{:^^{}:#>{}}"), input, 41, 10);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>10}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 41);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception) {
+ test_int<CharT>(check, check_exception, std::map<int, int>{{1, -1}, {42, -42}, {-42, 42}});
+}
+
+//
+// Floating point
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_floating_point(TestFunction check, ExceptionTest check_exception) {
+ std::map<double, double> input{{1.0, -1.0}, {-42, 42}};
+
+ check(SV("{-42: 42, 1: -1}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{-42: 42, 1: -1} "), SV("{:21}"), input);
+ check(SV("{-42: 42, 1: -1}*****"), SV("{:*<21}"), input);
+ check(SV("__{-42: 42, 1: -1}___"), SV("{:_^21}"), input);
+ check(SV("#####{-42: 42, 1: -1}"), SV("{:#>21}"), input);
+
+ check(SV("{-42: 42, 1: -1} "), SV("{:{}}"), input, 21);
+ check(SV("{-42: 42, 1: -1}*****"), SV("{:*<{}}"), input, 21);
+ check(SV("__{-42: 42, 1: -1}___"), SV("{:_^{}}"), input, 21);
+ check(SV("#####{-42: 42, 1: -1}"), SV("{:#>{}}"), input, 21);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__-42: 42, 1: -1___"), SV("{:_^19n}"), input);
+
+ // *** type ***
+ check(SV("__{-42: 42, 1: -1}___"), SV("{:_^21m}"), input); // the m type does the same as the default.
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{-42: 42 , 1: -1 }"), SV("{::10}"), input);
+ check(SV("{-42: 42***, 1: -1*****}"), SV("{::*<10}"), input);
+ check(SV("{_-42: 42__, __1: -1___}"), SV("{::_^10}"), input);
+ check(SV("{###-42: 42, #####1: -1}"), SV("{::#>10}"), input);
+
+ check(SV("{-42: 42 , 1: -1 }"), SV("{::{}}"), input, 10);
+ check(SV("{-42: 42***, 1: -1*****}"), SV("{::*<{}}"), input, 10);
+ check(SV("{_-42: 42__, __1: -1___}"), SV("{::_^{}}"), input, 10);
+ check(SV("{###-42: 42, #####1: -1}"), SV("{::#>{}}"), input, 10);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{###-42: 42, #####1: -1}^^^"), SV("{:^^29:#>10}"), input);
+ check(SV("^^{###-42: 42, #####1: -1}^^^"), SV("{:^^{}:#>10}"), input, 29);
+ check(SV("^^{###-42: 42, #####1: -1}^^^"), SV("{:^^{}:#>{}}"), input, 29, 10);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>10}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 29);
+}
+
+//
+// Pointer
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pointer(TestFunction check, ExceptionTest check_exception) {
+ std::unordered_map<const void*, std::nullptr_t> input{{0, 0}};
+
+ check(SV("{0x0: 0x0}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{0x0: 0x0} "), SV("{:15}"), input);
+ check(SV("{0x0: 0x0}*****"), SV("{:*<15}"), input);
+ check(SV("__{0x0: 0x0}___"), SV("{:_^15}"), input);
+ check(SV("#####{0x0: 0x0}"), SV("{:#>15}"), input);
+
+ check(SV("{0x0: 0x0} "), SV("{:{}}"), input, 15);
+ check(SV("{0x0: 0x0}*****"), SV("{:*<{}}"), input, 15);
+ check(SV("__{0x0: 0x0}___"), SV("{:_^{}}"), input, 15);
+ check(SV("#####{0x0: 0x0}"), SV("{:#>{}}"), input, 15);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__0x0: 0x0___"), SV("{:_^13n}"), input);
+
+ // *** type ***
+ check(SV("__{0x0: 0x0}___"), SV("{:_^15m}"), input); // the m type does the same as the default.
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{0x0: 0x0 }"), SV("{::13}"), input);
+ check(SV("{0x0: 0x0*****}"), SV("{::*<13}"), input);
+ check(SV("{__0x0: 0x0___}"), SV("{::_^13}"), input);
+ check(SV("{#####0x0: 0x0}"), SV("{::#>13}"), input);
+
+ check(SV("{0x0: 0x0 }"), SV("{::{}}"), input, 13);
+ check(SV("{0x0: 0x0*****}"), SV("{::*<{}}"), input, 13);
+ check(SV("{__0x0: 0x0___}"), SV("{::_^{}}"), input, 13);
+ check(SV("{#####0x0: 0x0}"), SV("{::#>{}}"), input, 13);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{###0x0: 0x0}^^^"), SV("{:^^18:#>11}"), input);
+ check(SV("^^{###0x0: 0x0}^^^"), SV("{:^^{}:#>11}"), input, 18);
+ check(SV("^^{###0x0: 0x0}^^^"), SV("{:^^{}:#>{}}"), input, 18, 11);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>11}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 18);
+}
+
+//
+// String
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_string(TestFunction check, ExceptionTest check_exception) {
+ std::map<std::basic_string<CharT>, std::basic_string<CharT>> input{
+ {STR("hello"), STR("HELLO")}, {STR("world"), STR("WORLD")}};
+
+ check(SV(R"({hello: HELLO, world: WORLD})"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV(R"({hello: HELLO, world: WORLD} )"), SV("{:33}"), input);
+ check(SV(R"({hello: HELLO, world: WORLD}*****)"), SV("{:*<33}"), input);
+ check(SV(R"(__{hello: HELLO, world: WORLD}___)"), SV("{:_^33}"), input);
+ check(SV(R"(#####{hello: HELLO, world: WORLD})"), SV("{:#>33}"), input);
+
+ check(SV(R"({hello: HELLO, world: WORLD} )"), SV("{:{}}"), input, 33);
+ check(SV(R"({hello: HELLO, world: WORLD}*****)"), SV("{:*<{}}"), input, 33);
+ check(SV(R"(__{hello: HELLO, world: WORLD}___)"), SV("{:_^{}}"), input, 33);
+ check(SV(R"(#####{hello: HELLO, world: WORLD})"), SV("{:#>{}}"), input, 33);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV(R"(__hello: HELLO, world: WORLD___)"), SV("{:_^31n}"), input);
+
+ // *** type ***
+ check(SV(R"(__{hello: HELLO, world: WORLD}___)"), SV("{:_^33m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV(R"({"hello": "HELLO" , "world": "WORLD" })"), SV("{::21}"), input);
+ check(SV(R"({"hello": "HELLO"*****, "world": "WORLD"*****})"), SV("{::*<21}"), input);
+ check(SV(R"({__"hello": "HELLO"___, __"world": "WORLD"___})"), SV("{::_^21}"), input);
+ check(SV(R"({#####"hello": "HELLO", #####"world": "WORLD"})"), SV("{::#>21}"), input);
+
+ check(SV(R"({"hello": "HELLO" , "world": "WORLD" })"), SV("{::{}}"), input, 21);
+ check(SV(R"({"hello": "HELLO"*****, "world": "WORLD"*****})"), SV("{::*<{}}"), input, 21);
+ check(SV(R"({__"hello": "HELLO"___, __"world": "WORLD"___})"), SV("{::_^{}}"), input, 21);
+ check(SV(R"({#####"hello": "HELLO", #####"world": "WORLD"})"), SV("{::#>{}}"), input, 21);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+
+ check(SV(R"(^^{#####"hello": "HELLO", #####"world": "WORLD"}^^^)"), SV("{:^^51:#>21}"), input);
+ check(SV(R"(^^{#####"hello": "HELLO", #####"world": "WORLD"}^^^)"), SV("{:^^{}:#>21}"), input, 51);
+ check(SV(R"(^^{#####"hello": "HELLO", #####"world": "WORLD"}^^^)"), SV("{:^^{}:#>{}}"), input, 51, 21);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>21}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 51);
+}
+
+//
+// Handle
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_status(TestFunction check, ExceptionTest check_exception) {
+ std::unordered_multimap<status, status> input{{status::foobar, status::foo}, {status::foobar, status::bar}};
+
+ check(SV("{0xaa55: 0xaaaa, 0xaa55: 0x5555}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{0xaa55: 0xaaaa, 0xaa55: 0x5555} "), SV("{:37}"), input);
+ check(SV("{0xaa55: 0xaaaa, 0xaa55: 0x5555}*****"), SV("{:*<37}"), input);
+ check(SV("__{0xaa55: 0xaaaa, 0xaa55: 0x5555}___"), SV("{:_^37}"), input);
+ check(SV("#####{0xaa55: 0xaaaa, 0xaa55: 0x5555}"), SV("{:#>37}"), input);
+
+ check(SV("{0xaa55: 0xaaaa, 0xaa55: 0x5555} "), SV("{:{}}"), input, 37);
+ check(SV("{0xaa55: 0xaaaa, 0xaa55: 0x5555}*****"), SV("{:*<{}}"), input, 37);
+ check(SV("__{0xaa55: 0xaaaa, 0xaa55: 0x5555}___"), SV("{:_^{}}"), input, 37);
+ check(SV("#####{0xaa55: 0xaaaa, 0xaa55: 0x5555}"), SV("{:#>{}}"), input, 37);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__0xaa55: 0xaaaa, 0xaa55: 0x5555___"), SV("{:_^35n}"), input);
+
+ // *** type ***
+ check(SV("__{0xaa55: 0xaaaa, 0xaa55: 0x5555}___"), SV("{:_^37}"), input); // the m type does the same as the default.
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ // Underlying can't have a format-spec
+}
+
+//
+// Adaptor
+//
+
+class adaptor {
+ using adaptee = std::map<int, int>;
+
+public:
+ using key_type = typename adaptee::key_type;
+ using mapped_type = typename adaptee::mapped_type;
+ using iterator = typename adaptee::iterator;
+
+ iterator begin() { return data_.begin(); }
+ iterator end() { return data_.end(); }
+
+ explicit adaptor(std::map<int, int>&& data) : data_(std::move(data)) {}
+
+private:
+ adaptee data_;
+};
+
+static_assert(std::format_kind<adaptor> == std::range_format::map);
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_adaptor(TestFunction check, ExceptionTest check_exception) {
+ test_int<CharT>(check, check_exception, adaptor{std::map<int, int>{{1, -1}, {42, -42}, {-42, 42}}});
+}
+
+//
+// Driver
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void format_tests(TestFunction check, ExceptionTest check_exception) {
+ test_char<CharT>(check, check_exception);
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ if (std::same_as<CharT, wchar_t>) // avoid testing twice
+ test_char_to_wchar(check, check_exception);
+#endif
+ test_bool<CharT>(check, check_exception);
+ test_int<CharT>(check, check_exception);
+ test_floating_point<CharT>(check, check_exception);
+ test_pointer<CharT>(check, check_exception);
+ test_string<CharT>(check, check_exception);
+
+ test_status<CharT>(check, check_exception);
+
+ test_adaptor<CharT>(check, check_exception);
+}
+
+#endif // TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FMTMAP_FORMAT_FUNCTIONS_TESTS_H
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.vformat.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.vformat.pass.cpp
new file mode 100644
index 0000000..27b8805
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.functions.vformat.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::map, R, charT>
+//
+// string vformat(string_view fmt, format_args args);
+// wstring vformat(wstring_view fmt, wformat_args args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception =
+ []<class CharT, class... Args>(
+ [[maybe_unused]] std::string_view what,
+ [[maybe_unused]] std::basic_string_view<CharT> fmt,
+ [[maybe_unused]] Args&&... args) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
+ } catch (const std::format_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+
+ return;
+ }
+ assert(false);
+#endif
+ };
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.pass.cpp
new file mode 100644
index 0000000..0001618
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/format.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::map, R, charT>
+
+// template<class FormatContext>
+// typename FormatContext::iterator
+// format(const T& ref, FormatContext& ctx) const;
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format.functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <map>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+void test_format(StringViewT expected, std::map<int, int> arg) {
+ using CharT = typename StringViewT::value_type;
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ std::formatter<std::map<int, int>, CharT> formatter;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
+ formatter.format(arg, format_ctx);
+ assert(result == expected);
+}
+
+template <class CharT>
+void test_fmt() {
+ test_format(SV("{1: 42}"), std::map<int, int>{{1, 42}});
+ test_format(SV("{0: 99}"), std::map<int, int>{{0, 99}});
+}
+
+void test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/parse.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/parse.pass.cpp
new file mode 100644
index 0000000..92763be
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtmap/parse.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::map, R, charT>
+
+// template<class ParseContext>
+// constexpr typename ParseContext::iterator
+// parse(ParseContext& ctx);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format.functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <map>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+constexpr void test_parse(StringViewT fmt) {
+ using CharT = typename StringViewT::value_type;
+ auto parse_ctx = std::basic_format_parse_context<CharT>(fmt);
+ std::formatter<std::map<int, int>, CharT> formatter;
+ static_assert(std::semiregular<decltype(formatter)>);
+
+ std::same_as<typename StringViewT::iterator> auto it = formatter.parse(parse_ctx);
+ assert(it == fmt.end() - (!fmt.empty() && fmt.back() == '}'));
+}
+
+template <class CharT>
+constexpr void test_fmt() {
+ test_parse(SV(""));
+ test_parse(SV(":5"));
+
+ test_parse(SV("}"));
+ test_parse(SV(":5}"));
+}
+
+constexpr bool test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.format.pass.cpp
new file mode 100644
index 0000000..1361626
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.format.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::set, R, charT>
+//
+// template<class... Args>
+// string format(format_string<Args...> fmt, Args&&... args);
+// template<class... Args>
+// wstring format(wformat_string<Args...> fmt, Args&&... args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_format_string.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
+ // After P2216 most exceptions thrown by std::format become ill-formed.
+ // Therefore this tests does nothing.
+};
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.tests.h b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.tests.h
new file mode 100644
index 0000000..a884ba7
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.tests.h
@@ -0,0 +1,1482 @@
+//===----------------------------------------------------------------------===//
+// 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 TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FMTSET_FORMAT_FUNCTIONS_TESTS_H
+#define TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FMTSET_FORMAT_FUNCTIONS_TESTS_H
+
+#include <algorithm>
+#include <format>
+#include <set>
+#include <tuple>
+#include <unordered_set>
+#include <utility>
+
+#include "format.functions.common.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+//
+// Char
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_default(TestFunction check, ExceptionTest check_exception) {
+ std::set input{CharT('a'), CharT('c'), CharT('b')}; // input not sorted.
+
+ // Note when no range-underlying-spec is present the char is escaped,
+ check(SV("{'a', 'b', 'c'}"), SV("{}"), input);
+ // when one is present there is no escaping,
+ check(SV("{a, b, c}"), SV("{::}"), input);
+ // unless forced by the type specifier.
+ check(SV("{'a', 'b', 'c'}"), SV("{::?}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{'a', 'b', 'c'} "), SV("{:20}"), input);
+ check(SV("{'a', 'b', 'c'}*****"), SV("{:*<20}"), input);
+ check(SV("__{'a', 'b', 'c'}___"), SV("{:_^20}"), input);
+ check(SV("#####{'a', 'b', 'c'}"), SV("{:#>20}"), input);
+
+ check(SV("{'a', 'b', 'c'} "), SV("{:{}}"), input, 20);
+ check(SV("{'a', 'b', 'c'}*****"), SV("{:*<{}}"), input, 20);
+ check(SV("__{'a', 'b', 'c'}___"), SV("{:_^{}}"), input, 20);
+ check(SV("#####{'a', 'b', 'c'}"), SV("{:#>{}}"), input, 20);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__'a', 'b', 'c'___"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{a , b , c }"), SV("{::4}"), input);
+ check(SV("{a***, b***, c***}"), SV("{::*<4}"), input);
+ check(SV("{_a__, _b__, _c__}"), SV("{::_^4}"), input);
+ check(SV("{:::a, :::b, :::c}"), SV("{:::>4}"), input);
+
+ check(SV("{a , b , c }"), SV("{::{}}"), input, 4);
+ check(SV("{a***, b***, c***}"), SV("{::*<{}}"), input, 4);
+ check(SV("{_a__, _b__, _c__}"), SV("{::_^{}}"), input, 4);
+ check(SV("{:::a, :::b, :::c}"), SV("{:::>{}}"), input, 4);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("{97, 98, 99}"), SV("{::-d}"), input);
+ check(SV("{+97, +98, +99}"), SV("{::+d}"), input);
+ check(SV("{ 97, 98, 99}"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("{0x61, 0x62, 0x63}"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("{00141, 00142, 00143}"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("{a, b, c}"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
+ check_exception("The format-spec type has a type not supported for a char argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{:a, :b, :c}^^^"), SV("{:^^17::>2}"), input);
+ check(SV("^^{:a, :b, :c}^^^"), SV("{:^^{}::>2}"), input, 17);
+ check(SV("^^{:a, :b, :c}^^^"), SV("{:^^{}::>{}}"), input, 17, 2);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>2}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 17);
+}
+
+// A set can be written as a string, based on
+// [tab:formatter.range.type]
+// s T shall be charT. ...
+// This does not seem very useful, but it is allowed.
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_string(TestFunction check, [[maybe_unused]] ExceptionTest check_exception) {
+ std::set input{CharT('a'), CharT('c'), CharT('b')}; // input not sorted.
+
+ check(SV("abc"), SV("{:s}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("abc "), SV("{:6s}"), input);
+ check(SV("abc***"), SV("{:*<6s}"), input);
+ check(SV("_abc__"), SV("{:_^6s}"), input);
+ check(SV("###abc"), SV("{:#>6s}"), input);
+
+ check(SV("abc "), SV("{:{}s}"), input, 6);
+ check(SV("abc***"), SV("{:*<{}s}"), input, 6);
+ check(SV("_abc__"), SV("{:_^{}s}"), input, 6);
+ check(SV("###abc"), SV("{:#>{}s}"), input, 6);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<s}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: s}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#s}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0s}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.s}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:Ls}"), input);
+
+ // *** n
+ check_exception("The n option and type s can't be used together", SV("{:ns}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("Type s and an underlying format specification can't be used together", SV("{:s:}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
+ check_exception("The format-spec type has a type not supported for a char argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check_exception("Type s and an underlying format specification can't be used together", SV("{:5s:5}"), input);
+}
+
+// A set can be written as a debug_string, based on
+// [tab:formatter.range.type]
+// ?s T shall be charT. ...
+// This does not seem very useful, but it is allowed.
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_escaped_string(TestFunction check, [[maybe_unused]] ExceptionTest check_exception) {
+ std::set input{CharT('a'), CharT('c'), CharT('b')}; // input not sorted.
+
+ check(SV("\"abc\""), SV("{:?s}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV(R"("abc" )"), SV("{:8?s}"), input);
+ check(SV(R"("abc"***)"), SV("{:*<8?s}"), input);
+ check(SV(R"(_"abc"__)"), SV("{:_^8?s}"), input);
+ check(SV(R"(###"abc")"), SV("{:#>8?s}"), input);
+
+ check(SV(R"("abc" )"), SV("{:{}?s}"), input, 8);
+ check(SV(R"("abc"***)"), SV("{:*<{}?s}"), input, 8);
+ check(SV(R"(_"abc"__)"), SV("{:_^{}?s}"), input, 8);
+ check(SV(R"(###"abc")"), SV("{:#>{}?s}"), input, 8);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<?s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<?s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<?s}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-?s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+?s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: ?s}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#?s}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0?s}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.?s}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L?s}"), input);
+
+ // *** n
+ check_exception("The n option and type ?s can't be used together", SV("{:n?s}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("Type ?s and an underlying format specification can't be used together", SV("{:?s:}"), input);
+
+ // ***** Both have a format-spec
+ check_exception("Type ?s and an underlying format specification can't be used together", SV("{:5?s:5}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char(TestFunction check, ExceptionTest check_exception) {
+ test_char_default<CharT>(check, check_exception);
+ test_char_string<CharT>(check, check_exception);
+ test_char_escaped_string<CharT>(check, check_exception);
+}
+
+//
+// char -> wchar_t
+//
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class TestFunction, class ExceptionTest>
+void test_char_to_wchar(TestFunction check, ExceptionTest check_exception) {
+ std::set input{'a', 'c', 'b'}; // input not sorted.
+
+ using CharT = wchar_t;
+
+ // Note when no range-underlying-spec is present the char is escaped,
+ check(SV("{'a', 'b', 'c'}"), SV("{}"), input);
+ // when one is present there is no escaping,
+ check(SV("{a, b, c}"), SV("{::}"), input);
+ // unless forced by the type specifier.
+ check(SV("{'a', 'b', 'c'}"), SV("{::?}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{'a', 'b', 'c'} "), SV("{:20}"), input);
+ check(SV("{'a', 'b', 'c'}*****"), SV("{:*<20}"), input);
+ check(SV("__{'a', 'b', 'c'}___"), SV("{:_^20}"), input);
+ check(SV("#####{'a', 'b', 'c'}"), SV("{:#>20}"), input);
+
+ check(SV("{'a', 'b', 'c'} "), SV("{:{}}"), input, 20);
+ check(SV("{'a', 'b', 'c'}*****"), SV("{:*<{}}"), input, 20);
+ check(SV("__{'a', 'b', 'c'}___"), SV("{:_^{}}"), input, 20);
+ check(SV("#####{'a', 'b', 'c'}"), SV("{:#>{}}"), input, 20);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__'a', 'b', 'c'___"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{a , b , c }"), SV("{::4}"), input);
+ check(SV("{a***, b***, c***}"), SV("{::*<4}"), input);
+ check(SV("{_a__, _b__, _c__}"), SV("{::_^4}"), input);
+ check(SV("{:::a, :::b, :::c}"), SV("{:::>4}"), input);
+
+ check(SV("{a , b , c }"), SV("{::{}}"), input, 4);
+ check(SV("{a***, b***, c***}"), SV("{::*<{}}"), input, 4);
+ check(SV("{_a__, _b__, _c__}"), SV("{::_^{}}"), input, 4);
+ check(SV("{:::a, :::b, :::c}"), SV("{:::>{}}"), input, 4);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("{97, 98, 99}"), SV("{::-d}"), input);
+ check(SV("{+97, +98, +99}"), SV("{::+d}"), input);
+ check(SV("{ 97, 98, 99}"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("{0x61, 0x62, 0x63}"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("{00141, 00142, 00143}"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("{a, b, c}"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
+ check_exception("The format-spec type has a type not supported for a char argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{:a, :b, :c}^^^"), SV("{:^^17::>2}"), input);
+ check(SV("^^{:a, :b, :c}^^^"), SV("{:^^{}::>2}"), input, 17);
+ check(SV("^^{:a, :b, :c}^^^"), SV("{:^^{}::>{}}"), input, 17, 2);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>2}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 17);
+
+ // The types s and ?s may only be used when using range_formatter<T, charT>
+ // where the types T and charT are the same. This means this can't be used for
+ // range_formatter<wchar_t, char> even when formatter<wchar_t, char> has a
+ // debug-enabled specialization.
+
+ using CharT = wchar_t;
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+}
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+//
+// Bool
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_bool(TestFunction check, ExceptionTest check_exception) {
+ std::set input{true, false};
+
+ check(SV("{false, true}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{false, true} "), SV("{:18}"), input);
+ check(SV("{false, true}*****"), SV("{:*<18}"), input);
+ check(SV("__{false, true}___"), SV("{:_^18}"), input);
+ check(SV("#####{false, true}"), SV("{:#>18}"), input);
+
+ check(SV("{false, true} "), SV("{:{}}"), input, 18);
+ check(SV("{false, true}*****"), SV("{:*<{}}"), input, 18);
+ check(SV("__{false, true}___"), SV("{:_^{}}"), input, 18);
+ check(SV("#####{false, true}"), SV("{:#>{}}"), input, 18);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__false, true___"), SV("{:_^16n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{false , true }"), SV("{::7}"), input);
+ check(SV("{false**, true***}"), SV("{::*<7}"), input);
+ check(SV("{_false_, _true__}"), SV("{::_^7}"), input);
+ check(SV("{::false, :::true}"), SV("{:::>7}"), input);
+
+ check(SV("{false , true }"), SV("{::{}}"), input, 7);
+ check(SV("{false**, true***}"), SV("{::*<{}}"), input, 7);
+ check(SV("{_false_, _true__}"), SV("{::_^{}}"), input, 7);
+ check(SV("{::false, :::true}"), SV("{:::>{}}"), input, 7);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("{0, 1}"), SV("{::-d}"), input);
+ check(SV("{+0, +1}"), SV("{::+d}"), input);
+ check(SV("{ 0, 1}"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("{0x0, 0x1}"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("{00000, 00001}"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("{false, true}"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX"))
+ check_exception("The format-spec type has a type not supported for a bool argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{::false, :::true}^^^"), SV("{:^^23::>7}"), input);
+ check(SV("^^{::false, :::true}^^^"), SV("{:^^{}::>7}"), input, 23);
+ check(SV("^^{::false, :::true}^^^"), SV("{:^^{}::>{}}"), input, 23, 7);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 23);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_bool_multiset(TestFunction check, ExceptionTest check_exception) {
+ std::multiset<bool, std::greater<bool>> input{true, false, true}; // unordered
+
+ check(SV("{true, true, false}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{true, true, false} "), SV("{:24}"), input);
+ check(SV("{true, true, false}*****"), SV("{:*<24}"), input);
+ check(SV("__{true, true, false}___"), SV("{:_^24}"), input);
+ check(SV("#####{true, true, false}"), SV("{:#>24}"), input);
+
+ check(SV("{true, true, false} "), SV("{:{}}"), input, 24);
+ check(SV("{true, true, false}*****"), SV("{:*<{}}"), input, 24);
+ check(SV("__{true, true, false}___"), SV("{:_^{}}"), input, 24);
+ check(SV("#####{true, true, false}"), SV("{:#>{}}"), input, 24);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__true, true, false___"), SV("{:_^22n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{true , true , false }"), SV("{::7}"), input);
+ check(SV("{true***, true***, false**}"), SV("{::*<7}"), input);
+ check(SV("{_true__, _true__, _false_}"), SV("{::_^7}"), input);
+ check(SV("{:::true, :::true, ::false}"), SV("{:::>7}"), input);
+
+ check(SV("{true , true , false }"), SV("{::{}}"), input, 7);
+ check(SV("{true***, true***, false**}"), SV("{::*<{}}"), input, 7);
+ check(SV("{_true__, _true__, _false_}"), SV("{::_^{}}"), input, 7);
+ check(SV("{:::true, :::true, ::false}"), SV("{:::>{}}"), input, 7);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("{1, 1, 0}"), SV("{::-d}"), input);
+ check(SV("{+1, +1, +0}"), SV("{::+d}"), input);
+ check(SV("{ 1, 1, 0}"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("{0x1, 0x1, 0x0}"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("{00001, 00001, 00000}"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("{true, true, false}"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX"))
+ check_exception("The format-spec type has a type not supported for a bool argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{:::true, :::true, ::false}^^^"), SV("{:^^32::>7}"), input);
+ check(SV("^^{:::true, :::true, ::false}^^^"), SV("{:^^{}::>7}"), input, 32);
+ check(SV("^^{:::true, :::true, ::false}^^^"), SV("{:^^{}::>{}}"), input, 32, 7);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 32);
+}
+
+//
+// Integral
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("{-42, 1, 2, 42}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{-42, 1, 2, 42} "), SV("{:20}"), input);
+ check(SV("{-42, 1, 2, 42}*****"), SV("{:*<20}"), input);
+ check(SV("__{-42, 1, 2, 42}___"), SV("{:_^20}"), input);
+ check(SV("#####{-42, 1, 2, 42}"), SV("{:#>20}"), input);
+
+ check(SV("{-42, 1, 2, 42} "), SV("{:{}}"), input, 20);
+ check(SV("{-42, 1, 2, 42}*****"), SV("{:*<{}}"), input, 20);
+ check(SV("__{-42, 1, 2, 42}___"), SV("{:_^{}}"), input, 20);
+ check(SV("#####{-42, 1, 2, 42}"), SV("{:#>{}}"), input, 20);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__-42, 1, 2, 42___"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{ -42, 1, 2, 42}"), SV("{::5}"), input);
+ check(SV("{-42**, 1****, 2****, 42***}"), SV("{::*<5}"), input);
+ check(SV("{_-42_, __1__, __2__, _42__}"), SV("{::_^5}"), input);
+ check(SV("{::-42, ::::1, ::::2, :::42}"), SV("{:::>5}"), input);
+
+ check(SV("{ -42, 1, 2, 42}"), SV("{::{}}"), input, 5);
+ check(SV("{-42**, 1****, 2****, 42***}"), SV("{::*<{}}"), input, 5);
+ check(SV("{_-42_, __1__, __2__, _42__}"), SV("{::_^{}}"), input, 5);
+ check(SV("{::-42, ::::1, ::::2, :::42}"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check(SV("{-42, 1, 2, 42}"), SV("{::-}"), input);
+ check(SV("{-42, +1, +2, +42}"), SV("{::+}"), input);
+ check(SV("{-42, 1, 2, 42}"), SV("{:: }"), input);
+
+ // *** alternate form ***
+ check(SV("{-0x2a, 0x1, 0x2, 0x2a}"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check(SV("{-0042, 00001, 00002, 00042}"), SV("{::05}"), input);
+ check(SV("{-002a, 00001, 00002, 0002a}"), SV("{::05x}"), input);
+ check(SV("{-0x2a, 0x001, 0x002, 0x02a}"), SV("{::#05x}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("{-42, 1, 2, 42}"), SV("{::L}"), input); // does nothing in this test, but is accepted.
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX"))
+ check_exception("The format-spec type has a type not supported for an integer argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{::-42, ::::1, ::::2, :::42}^^^"), SV("{:^^33::>5}"), input);
+ check(SV("^^{::-42, ::::1, ::::2, :::42}^^^"), SV("{:^^{}::>5}"), input, 33);
+ check(SV("^^{::-42, ::::1, ::::2, :::42}^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 33);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception) {
+ test_int<CharT>(check, check_exception, std::set{1, 42, 2, -42}); // unsorted
+ test_int<CharT>(check, check_exception, std::multiset{1, 42, 2, -42}); // unsorted
+}
+
+//
+// Floating point
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_floating_point(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("{-42.5, 0, 1.25, 42.5}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{-42.5, 0, 1.25, 42.5} "), SV("{:27}"), input);
+ check(SV("{-42.5, 0, 1.25, 42.5}*****"), SV("{:*<27}"), input);
+ check(SV("__{-42.5, 0, 1.25, 42.5}___"), SV("{:_^27}"), input);
+ check(SV("#####{-42.5, 0, 1.25, 42.5}"), SV("{:#>27}"), input);
+
+ check(SV("{-42.5, 0, 1.25, 42.5} "), SV("{:{}}"), input, 27);
+ check(SV("{-42.5, 0, 1.25, 42.5}*****"), SV("{:*<{}}"), input, 27);
+ check(SV("__{-42.5, 0, 1.25, 42.5}___"), SV("{:_^{}}"), input, 27);
+ check(SV("#####{-42.5, 0, 1.25, 42.5}"), SV("{:#>{}}"), input, 27);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__-42.5, 0, 1.25, 42.5___"), SV("{:_^25n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{-42.5, 0, 1.25, 42.5}"), SV("{::5}"), input);
+ check(SV("{-42.5, 0****, 1.25*, 42.5*}"), SV("{::*<5}"), input);
+ check(SV("{-42.5, __0__, 1.25_, 42.5_}"), SV("{::_^5}"), input);
+ check(SV("{-42.5, ::::0, :1.25, :42.5}"), SV("{:::>5}"), input);
+
+ check(SV("{-42.5, 0, 1.25, 42.5}"), SV("{::{}}"), input, 5);
+ check(SV("{-42.5, 0****, 1.25*, 42.5*}"), SV("{::*<{}}"), input, 5);
+ check(SV("{-42.5, __0__, 1.25_, 42.5_}"), SV("{::_^{}}"), input, 5);
+ check(SV("{-42.5, ::::0, :1.25, :42.5}"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check(SV("{-42.5, 0, 1.25, 42.5}"), SV("{::-}"), input);
+ check(SV("{-42.5, +0, +1.25, +42.5}"), SV("{::+}"), input);
+ check(SV("{-42.5, 0, 1.25, 42.5}"), SV("{:: }"), input);
+
+ // *** alternate form ***
+ check(SV("{-42.5, 0., 1.25, 42.5}"), SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check(SV("{-42.5, 00000, 01.25, 042.5}"), SV("{::05}"), input);
+ check(SV("{-42.5, 0000., 01.25, 042.5}"), SV("{::#05}"), input);
+
+ // *** precision ***
+ check(SV("{-42, 0, 1.2, 42}"), SV("{::.2}"), input);
+ check(SV("{-42.500, 0.000, 1.250, 42.500}"), SV("{::.3f}"), input);
+
+ check(SV("{-42, 0, 1.2, 42}"), SV("{::.{}}"), input, 2);
+ check(SV("{-42.500, 0.000, 1.250, 42.500}"), SV("{::.{}f}"), input, 3);
+
+ check_exception("The format-spec precision field doesn't contain a value or arg-id", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("{-42.5, 0, 1.25, 42.5}"), SV("{::L}"), input); // does not require locales present
+#ifndef TEST_HAS_NO_LOCALIZATION
+// TODO FMT Enable with locale testing active
+# if 0
+ std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+ check(SV("{-42,5, 0, 1,25, 42,5}"), SV("{::L}"), input);
+
+ std::locale::global(std::locale(LOCALE_en_US_UTF_8));
+ check(SV("{-42.5, 0, 1.25, 42.5}"), SV("{::L}"), input);
+
+ std::locale::global(std::locale::classic());
+# endif
+#endif // TEST_HAS_NO_LOCALIZATION
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("aAeEfFgG"))
+ check_exception("The format-spec type has a type not supported for a floating-point argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{-42.5, ::::0, :1.25, :42.5}^^^"), SV("{:^^33::>5}"), input);
+ check(SV("^^{-42.5, ::::0, :1.25, :42.5}^^^"), SV("{:^^{}::>5}"), input, 33);
+ check(SV("^^{-42.5, ::::0, :1.25, :42.5}^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
+
+ check(SV("^^{::-42, ::::0, ::1.2, :::42}^^^"), SV("{:^^33::>5.2}"), input);
+ check(SV("^^{::-42, ::::0, ::1.2, :::42}^^^"), SV("{:^^{}::>5.2}"), input, 33);
+ check(SV("^^{::-42, ::::0, ::1.2, :::42}^^^"), SV("{:^^{}::>{}.2}"), input, 33, 5);
+ check(SV("^^{::-42, ::::0, ::1.2, :::42}^^^"), SV("{:^^{}::>{}.{}}"), input, 33, 5, 2);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5.2}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}.2}"), input, 33);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}.{}}"), input, 33, 5);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_floating_point(TestFunction check, ExceptionTest check_exception) {
+ test_floating_point<CharT>(check, check_exception, std::set{-42.5f, 0.0f, 1.25f, 42.5f});
+ test_floating_point<CharT>(check, check_exception, std::multiset{-42.5, 0.0, 1.25, 42.5});
+ test_floating_point<CharT>(check, check_exception, std::set{-42.5l, 0.0l, 1.25l, 42.5l});
+}
+
+//
+// Pointer
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pointer(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("{0x0}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{0x0} "), SV("{:10}"), input);
+ check(SV("{0x0}*****"), SV("{:*<10}"), input);
+ check(SV("__{0x0}___"), SV("{:_^10}"), input);
+ check(SV("#####{0x0}"), SV("{:#>10}"), input);
+
+ check(SV("{0x0} "), SV("{:{}}"), input, 10);
+ check(SV("{0x0}*****"), SV("{:*<{}}"), input, 10);
+ check(SV("__{0x0}___"), SV("{:_^{}}"), input, 10);
+ check(SV("#####{0x0}"), SV("{:#>{}}"), input, 10);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("_0x0_"), SV("{:_^5n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{ 0x0}"), SV("{::5}"), input);
+ check(SV("{0x0**}"), SV("{::*<5}"), input);
+ check(SV("{_0x0_}"), SV("{::_^5}"), input);
+ check(SV("{::0x0}"), SV("{:::>5}"), input);
+
+ check(SV("{ 0x0}"), SV("{::{}}"), input, 5);
+ check(SV("{0x0**}"), SV("{::*<{}}"), input, 5);
+ check(SV("{_0x0_}"), SV("{::_^{}}"), input, 5);
+ check(SV("{::0x0}"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("p"))
+ check_exception("The format-spec type has a type not supported for a pointer argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{::0x0}^^^"), SV("{:^^12::>5}"), input);
+ check(SV("^^{::0x0}^^^"), SV("{:^^{}::>5}"), input, 12);
+ check(SV("^^{::0x0}^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
+
+ check(SV("^^{::0x0}^^^"), SV("{:^^12::>5}"), input);
+ check(SV("^^{::0x0}^^^"), SV("{:^^{}::>5}"), input, 12);
+ check(SV("^^{::0x0}^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 12);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pointer(TestFunction check, ExceptionTest check_exception) {
+ // Note nullptr_t can only be equality compared so not used in a set.
+ test_pointer<CharT>(check, check_exception, std::unordered_set{static_cast<const void*>(0)});
+ test_pointer<CharT>(check, check_exception, std::unordered_multiset{static_cast<void*>(0)});
+}
+
+//
+// String
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV(R"({"Hello", "world"})"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV(R"({"Hello", "world"} )"), SV("{:23}"), input);
+ check(SV(R"({"Hello", "world"}*****)"), SV("{:*<23}"), input);
+ check(SV(R"(__{"Hello", "world"}___)"), SV("{:_^23}"), input);
+ check(SV(R"(#####{"Hello", "world"})"), SV("{:#>23}"), input);
+
+ check(SV(R"({"Hello", "world"} )"), SV("{:{}}"), input, 23);
+ check(SV(R"({"Hello", "world"}*****)"), SV("{:*<{}}"), input, 23);
+ check(SV(R"(__{"Hello", "world"}___)"), SV("{:_^{}}"), input, 23);
+ check(SV(R"(#####{"Hello", "world"})"), SV("{:#>{}}"), input, 23);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV(R"(_"Hello", "world"_)"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV(R"({Hello , world })"), SV("{::8}"), input);
+ check(SV(R"({Hello***, world***})"), SV("{::*<8}"), input);
+ check(SV(R"({_Hello__, _world__})"), SV("{::_^8}"), input);
+ check(SV(R"({:::Hello, :::world})"), SV("{:::>8}"), input);
+
+ check(SV(R"({Hello , world })"), SV("{::{}}"), input, 8);
+ check(SV(R"({Hello***, world***})"), SV("{::*<{}}"), input, 8);
+ check(SV(R"({_Hello__, _world__})"), SV("{::_^{}}"), input, 8);
+ check(SV(R"({:::Hello, :::world})"), SV("{:::>{}}"), input, 8);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check(SV(R"({Hel, wor})"), SV("{::.3}"), input);
+
+ check(SV(R"({Hel, wor})"), SV("{::.{}}"), input, 3);
+
+ check_exception("The format-spec precision field doesn't contain a value or arg-id", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s?"))
+ check_exception("The format-spec type has a type not supported for a string argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV(R"(^^{:::Hello, :::world}^^^)"), SV("{:^^25::>8}"), input);
+ check(SV(R"(^^{:::Hello, :::world}^^^)"), SV("{:^^{}::>8}"), input, 25);
+ check(SV(R"(^^{:::Hello, :::world}^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
+
+ check(SV(R"(^^{:::Hello, :::world}^^^)"), SV("{:^^25::>8}"), input);
+ check(SV(R"(^^{:::Hello, :::world}^^^)"), SV("{:^^{}::>8}"), input, 25);
+ check(SV(R"(^^{:::Hello, :::world}^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>8}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 25);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_string(TestFunction check, ExceptionTest check_exception) {
+ test_string<CharT>(check, check_exception, std::set{STR("Hello"), STR("world")});
+ test_string<CharT>(check, check_exception, std::set{SV("Hello"), SV("world")});
+}
+
+//
+// Handle
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_status(TestFunction check, ExceptionTest check_exception) {
+ std::set input{status::foo, status::bar, status::foobar}; // unordered input
+
+ check(SV("{0x5555, 0xaa55, 0xaaaa}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{0x5555, 0xaa55, 0xaaaa} "), SV("{:29}"), input);
+ check(SV("{0x5555, 0xaa55, 0xaaaa}*****"), SV("{:*<29}"), input);
+ check(SV("__{0x5555, 0xaa55, 0xaaaa}___"), SV("{:_^29}"), input);
+ check(SV("#####{0x5555, 0xaa55, 0xaaaa}"), SV("{:#>29}"), input);
+
+ check(SV("{0x5555, 0xaa55, 0xaaaa} "), SV("{:{}}"), input, 29);
+ check(SV("{0x5555, 0xaa55, 0xaaaa}*****"), SV("{:*<{}}"), input, 29);
+ check(SV("__{0x5555, 0xaa55, 0xaaaa}___"), SV("{:_^{}}"), input, 29);
+ check(SV("#####{0x5555, 0xaa55, 0xaaaa}"), SV("{:#>{}}"), input, 29);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__0x5555, 0xaa55, 0xaaaa___"), SV("{:_^27n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("The format-spec type has a type not supported for a status argument", SV("{::*<7}"), input);
+
+ check(SV("{0x5555, 0xaa55, 0xaaaa}"), SV("{::x}"), input);
+ check(SV("{0X5555, 0XAA55, 0XAAAA}"), SV("{::X}"), input);
+ check(SV("{bar, foobar, foo}"), SV("{::s}"), input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{0X5555, 0XAA55, 0XAAAA}^^^"), SV("{:^^29:X}"), input);
+ check(SV("^^{0X5555, 0XAA55, 0XAAAA}^^^"), SV("{:^^{}:X}"), input, 29);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:X}"), input);
+}
+
+//
+// Pair
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pair_tuple(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("{(1, a), (42, *)}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{(1, a), (42, *)} "), SV("{:22}"), input);
+ check(SV("{(1, a), (42, *)}*****"), SV("{:*<22}"), input);
+ check(SV("__{(1, a), (42, *)}___"), SV("{:_^22}"), input);
+ check(SV("#####{(1, a), (42, *)}"), SV("{:#>22}"), input);
+
+ check(SV("{(1, a), (42, *)} "), SV("{:{}}"), input, 22);
+ check(SV("{(1, a), (42, *)}*****"), SV("{:*<{}}"), input, 22);
+ check(SV("__{(1, a), (42, *)}___"), SV("{:_^{}}"), input, 22);
+ check(SV("#####{(1, a), (42, *)}"), SV("{:#>{}}"), input, 22);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__(1, a), (42, *)___"), SV("{:_^20n}"), input);
+ check(SV("__(1, a), (42, *)___"), SV("{:_^20nm}"), input); // m should have no effect
+
+ // *** type ***
+ check(SV("__{(1, a), (42, *)}___"), SV("{:_^22m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{(1, 'a') , (42, '*') }"), SV("{::11}"), input);
+ check(SV("{(1, 'a')***, (42, '*')**}"), SV("{::*<11}"), input);
+ check(SV("{_(1, 'a')__, _(42, '*')_}"), SV("{::_^11}"), input);
+ check(SV("{###(1, 'a'), ##(42, '*')}"), SV("{::#>11}"), input);
+
+ check(SV("{(1, 'a') , (42, '*') }"), SV("{::{}}"), input, 11);
+ check(SV("{(1, 'a')***, (42, '*')**}"), SV("{::*<{}}"), input, 11);
+ check(SV("{_(1, 'a')__, _(42, '*')_}"), SV("{::_^{}}"), input, 11);
+ check(SV("{###(1, 'a'), ##(42, '*')}"), SV("{::#>{}}"), input, 11);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("{1: 'a', 42: '*'}"), SV("{::m}"), input);
+ check(SV("{1, 'a', 42, '*'}"), SV("{::n}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{###(1, 'a'), ##(42, '*')}^^^"), SV("{:^^31:#>11}"), input);
+ check(SV("^^{###(1, 'a'), ##(42, '*')}^^^"), SV("{:^^31:#>11}"), input);
+ check(SV("^^{###(1, 'a'), ##(42, '*')}^^^"), SV("{:^^{}:#>11}"), input, 31);
+ check(SV("^^{###(1, 'a'), ##(42, '*')}^^^"), SV("{:^^{}:#>{}}"), input, 31, 11);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 31);
+
+ check(SV("1: 'a', 42: '*'"), SV("{:n:m}"), input);
+ check(SV("1, 'a', 42, '*'"), SV("{:n:n}"), input);
+ check(SV("{1: 'a', 42: '*'}"), SV("{:m:m}"), input);
+ check(SV("{1, 'a', 42, '*'}"), SV("{:m:n}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pair_tuple(TestFunction check, ExceptionTest check_exception) {
+ test_pair_tuple<CharT>(
+ check, check_exception, std::set{std::make_pair(1, CharT('a')), std::make_pair(42, CharT('*'))});
+ test_pair_tuple<CharT>(
+ check, check_exception, std::set{std::make_tuple(1, CharT('a')), std::make_tuple(42, CharT('*'))});
+}
+
+//
+// Tuple 1
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_tuple_int(TestFunction check, ExceptionTest check_exception) {
+ std::set input{std::make_tuple(42), std::make_tuple(99)};
+
+ check(SV("{(42), (99)}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{(42), (99)} "), SV("{:17}"), input);
+ check(SV("{(42), (99)}*****"), SV("{:*<17}"), input);
+ check(SV("__{(42), (99)}___"), SV("{:_^17}"), input);
+ check(SV("#####{(42), (99)}"), SV("{:#>17}"), input);
+
+ check(SV("{(42), (99)} "), SV("{:{}}"), input, 17);
+ check(SV("{(42), (99)}*****"), SV("{:*<{}}"), input, 17);
+ check(SV("__{(42), (99)}___"), SV("{:_^{}}"), input, 17);
+ check(SV("#####{(42), (99)}"), SV("{:#>{}}"), input, 17);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__(42), (99)___"), SV("{:_^15n}"), input);
+
+ // *** type ***
+ check(SV("__{(42), (99)}___"), SV("{:_^17m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{(42) , (99) }"), SV("{::7}"), input);
+ check(SV("{(42)***, (99)***}"), SV("{::*<7}"), input);
+ check(SV("{_(42)__, _(99)__}"), SV("{::_^7}"), input);
+ check(SV("{###(42), ###(99)}"), SV("{::#>7}"), input);
+
+ check(SV("{(42) , (99) }"), SV("{::{}}"), input, 7);
+ check(SV("{(42)***, (99)***}"), SV("{::*<{}}"), input, 7);
+ check(SV("{_(42)__, _(99)__}"), SV("{::_^{}}"), input, 7);
+ check(SV("{###(42), ###(99)}"), SV("{::#>{}}"), input, 7);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("{42, 99}"), SV("{::n}"), input);
+ check_exception("The format specifier m requires a pair or a two-element tuple", SV("{::m}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{###(42), ###(99)}^^^"), SV("{:^^23:#>7}"), input);
+ check(SV("^^{###(42), ###(99)}^^^"), SV("{:^^23:#>7}"), input);
+ check(SV("^^{###(42), ###(99)}^^^"), SV("{:^^{}:#>7}"), input, 23);
+ check(SV("^^{###(42), ###(99)}^^^"), SV("{:^^{}:#>{}}"), input, 23, 7);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 23);
+}
+
+//
+// Tuple 3
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_tuple_int_int_int(TestFunction check, ExceptionTest check_exception) {
+ std::set input{std::make_tuple(42, 99, 0), std::make_tuple(1, 10, 100)}; // unordered
+
+ check(SV("{(1, 10, 100), (42, 99, 0)}"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("{(1, 10, 100), (42, 99, 0)} "), SV("{:32}"), input);
+ check(SV("{(1, 10, 100), (42, 99, 0)}*****"), SV("{:*<32}"), input);
+ check(SV("__{(1, 10, 100), (42, 99, 0)}___"), SV("{:_^32}"), input);
+ check(SV("#####{(1, 10, 100), (42, 99, 0)}"), SV("{:#>32}"), input);
+
+ check(SV("{(1, 10, 100), (42, 99, 0)} "), SV("{:{}}"), input, 32);
+ check(SV("{(1, 10, 100), (42, 99, 0)}*****"), SV("{:*<{}}"), input, 32);
+ check(SV("__{(1, 10, 100), (42, 99, 0)}___"), SV("{:_^{}}"), input, 32);
+ check(SV("#####{(1, 10, 100), (42, 99, 0)}"), SV("{:#>{}}"), input, 32);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__(1, 10, 100), (42, 99, 0)___"), SV("{:_^30n}"), input);
+
+ // *** type ***
+ check(SV("__{(1, 10, 100), (42, 99, 0)}___"), SV("{:_^32m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("{(1, 10, 100) , (42, 99, 0) }"), SV("{::14}"), input);
+ check(SV("{(1, 10, 100)**, (42, 99, 0)***}"), SV("{::*<14}"), input);
+ check(SV("{_(1, 10, 100)_, _(42, 99, 0)__}"), SV("{::_^14}"), input);
+ check(SV("{##(1, 10, 100), ###(42, 99, 0)}"), SV("{::#>14}"), input);
+
+ check(SV("{(1, 10, 100) , (42, 99, 0) }"), SV("{::{}}"), input, 14);
+ check(SV("{(1, 10, 100)**, (42, 99, 0)***}"), SV("{::*<{}}"), input, 14);
+ check(SV("{_(1, 10, 100)_, _(42, 99, 0)__}"), SV("{::_^{}}"), input, 14);
+ check(SV("{##(1, 10, 100), ###(42, 99, 0)}"), SV("{::#>{}}"), input, 14);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("{1, 10, 100, 42, 99, 0}"), SV("{::n}"), input);
+ check_exception("The format specifier m requires a pair or a two-element tuple", SV("{::m}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::?s}"), input);
+
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^{##(1, 10, 100), ###(42, 99, 0)}^^^"), SV("{:^^37:#>14}"), input);
+ check(SV("^^{##(1, 10, 100), ###(42, 99, 0)}^^^"), SV("{:^^37:#>14}"), input);
+ check(SV("^^{##(1, 10, 100), ###(42, 99, 0)}^^^"), SV("{:^^{}:#>14}"), input, 37);
+ check(SV("^^{##(1, 10, 100), ###(42, 99, 0)}^^^"), SV("{:^^{}:#>{}}"), input, 37, 14);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 37);
+}
+
+//
+// Adaptor
+//
+
+class adaptor {
+ using adaptee = std::set<int>;
+
+public:
+ using key_type = typename adaptee::key_type;
+ using iterator = typename adaptee::iterator;
+
+ iterator begin() { return data_.begin(); }
+ iterator end() { return data_.end(); }
+
+ explicit adaptor(std::set<int>&& data) : data_(std::move(data)) {}
+
+private:
+ adaptee data_;
+};
+
+static_assert(std::format_kind<adaptor> == std::range_format::set);
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_adaptor(TestFunction check, ExceptionTest check_exception) {
+ test_int<CharT>(check, check_exception, adaptor{std::set{1, 42, 2, -42}});
+}
+
+//
+// Driver
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void format_tests(TestFunction check, ExceptionTest check_exception) {
+ test_char<CharT>(check, check_exception);
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ if (std::same_as<CharT, wchar_t>) // avoid testing twice
+ test_char_to_wchar(check, check_exception);
+#endif
+ test_bool<CharT>(check, check_exception);
+ test_bool_multiset<CharT>(check, check_exception);
+ test_int<CharT>(check, check_exception);
+ test_floating_point<CharT>(check, check_exception);
+ test_pointer<CharT>(check, check_exception);
+ test_string<CharT>(check, check_exception);
+
+ test_status<CharT>(check, check_exception); // Has its own handler with its own parser
+
+ test_pair_tuple<CharT>(check, check_exception);
+ test_tuple_int<CharT>(check, check_exception);
+ test_tuple_int_int_int<CharT>(check, check_exception);
+
+ test_adaptor<CharT>(check, check_exception);
+}
+
+#endif // TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FMTSET_FORMAT_FUNCTIONS_TESTS_H
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.vformat.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.vformat.pass.cpp
new file mode 100644
index 0000000..4a8ee4c
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.functions.vformat.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::set, R, charT>
+//
+// string vformat(string_view fmt, format_args args);
+// wstring vformat(wstring_view fmt, wformat_args args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception =
+ []<class CharT, class... Args>(
+ [[maybe_unused]] std::string_view what,
+ [[maybe_unused]] std::basic_string_view<CharT> fmt,
+ [[maybe_unused]] Args&&... args) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
+ } catch (const std::format_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+
+ return;
+ }
+ assert(false);
+#endif
+ };
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.pass.cpp
new file mode 100644
index 0000000..651ae86
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/format.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::set, R, charT>
+
+// template<class FormatContext>
+// typename FormatContext::iterator
+// format(const T& ref, FormatContext& ctx) const;
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format.functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <set>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+void test_format(StringViewT expected, std::set<int> arg) {
+ using CharT = typename StringViewT::value_type;
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ std::formatter<std::set<int>, CharT> formatter;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
+ formatter.format(arg, format_ctx);
+ assert(result == expected);
+}
+
+template <class CharT>
+void test_fmt() {
+ test_format(SV("{42}"), std::set<int>{42});
+}
+
+void test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/parse.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/parse.pass.cpp
new file mode 100644
index 0000000..753a975
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.fmtset/parse.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<ranges::input_range R, class charT>
+// struct range-default-formatter<range_format::set, R, charT>
+
+// template<class ParseContext>
+// constexpr typename ParseContext::iterator
+// parse(ParseContext& ctx);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format.functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <set>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+constexpr void test_parse(StringViewT fmt) {
+ using CharT = typename StringViewT::value_type;
+ auto parse_ctx = std::basic_format_parse_context<CharT>(fmt);
+ std::formatter<std::set<int>, CharT> formatter;
+ static_assert(std::semiregular<decltype(formatter)>);
+
+ std::same_as<typename StringViewT::iterator> auto it = formatter.parse(parse_ctx);
+ assert(it == fmt.end() - (!fmt.empty() && fmt.back() == '}'));
+}
+
+template <class CharT>
+constexpr void test_fmt() {
+ test_parse(SV(""));
+ test_parse(SV(":5"));
+
+ test_parse(SV("}"));
+ test_parse(SV(":5}"));
+}
+
+constexpr bool test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.format.pass.cpp
new file mode 100644
index 0000000..78e04fe
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.format.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<class T, class charT = char>
+// requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+// class range_formatter;
+
+// template<class... Args>
+// string format(format_string<Args...> fmt, Args&&... args);
+// template<class... Args>
+// wstring format(wformat_string<Args...> fmt, Args&&... args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_format_string.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
+ // After P2216 most exceptions thrown by std::format become ill-formed.
+ // Therefore this tests does nothing.
+};
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.tests.h b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.tests.h
new file mode 100644
index 0000000..a465916
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.tests.h
@@ -0,0 +1,1353 @@
+//===----------------------------------------------------------------------===//
+// 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 TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FORMATTER_FORMAT_FUNCTIONS_TESTS_H
+#define TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FORMATTER_FORMAT_FUNCTIONS_TESTS_H
+
+#include <algorithm>
+#include <array>
+#include <charconv>
+#include <concepts>
+#include <deque>
+#include <format>
+#include <list>
+#include <ranges>
+#include <span>
+#include <vector>
+
+#include "format.functions.common.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_iterators.h"
+#include "test_macros.h"
+
+//
+// Char
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_default(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ // Note when no range-underlying-spec is present the char is escaped,
+ check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{}"), input);
+
+ // when one is present there is no escaping,
+ check(SV("[H, e, l, l, o]"), SV("{::}"), input);
+ // unless forced by the type specifier.
+ check(SV("['H', 'e', 'l', 'l', 'o']"), SV("{::?}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("['H', 'e', 'l', 'l', 'o'] "), SV("{:30}"), input);
+ check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<30}"), input);
+ check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^30}"), input);
+ check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>30}"), input);
+
+ check(SV("['H', 'e', 'l', 'l', 'o'] "), SV("{:{}}"), input, 30);
+ check(SV("['H', 'e', 'l', 'l', 'o']*****"), SV("{:*<{}}"), input, 30);
+ check(SV("__['H', 'e', 'l', 'l', 'o']___"), SV("{:_^{}}"), input, 30);
+ check(SV("#####['H', 'e', 'l', 'l', 'o']"), SV("{:#>{}}"), input, 30);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__'H', 'e', 'l', 'l', 'o'___"), SV("{:_^28n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[H , e , l , l , o ]"), SV("{::4}"), input);
+ check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<4}"), input);
+ check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^4}"), input);
+ check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>4}"), input);
+
+ check(SV("[H , e , l , l , o ]"), SV("{::{}}"), input, 4);
+ check(SV("[H***, e***, l***, l***, o***]"), SV("{::*<{}}"), input, 4);
+ check(SV("[_H__, _e__, _l__, _l__, _o__]"), SV("{::_^{}}"), input, 4);
+ check(SV("[:::H, :::e, :::l, :::l, :::o]"), SV("{:::>{}}"), input, 4);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("[72, 101, 108, 108, 111]"), SV("{::-d}"), input);
+ check(SV("[+72, +101, +108, +108, +111]"), SV("{::+d}"), input);
+ check(SV("[ 72, 101, 108, 108, 111]"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("[0x48, 0x65, 0x6c, 0x6c, 0x6f]"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("[00110, 00145, 00154, 00154, 00157]"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[H, e, l, l, o]"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
+ check_exception("The format-spec type has a type not supported for a char argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^25::>2}"), input);
+ check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>2}"), input, 25);
+ check(SV("^^[:H, :e, :l, :l, :o]^^^"), SV("{:^^{}::>{}}"), input, 25, 2);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>2}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 25);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("Hello"), SV("{:s}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("Hello "), SV("{:8s}"), input);
+ check(SV("Hello***"), SV("{:*<8s}"), input);
+ check(SV("_Hello__"), SV("{:_^8s}"), input);
+ check(SV("###Hello"), SV("{:#>8s}"), input);
+
+ check(SV("Hello "), SV("{:{}s}"), input, 8);
+ check(SV("Hello***"), SV("{:*<{}s}"), input, 8);
+ check(SV("_Hello__"), SV("{:_^{}s}"), input, 8);
+ check(SV("###Hello"), SV("{:#>{}s}"), input, 8);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<s}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: s}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#s}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0s}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.s}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:Ls}"), input);
+
+ // *** n
+ check_exception("The n option and type s can't be used together", SV("{:ns}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("Type s and an underlying format specification can't be used together", SV("{:s:}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX?"))
+ check_exception("The format-spec type has a type not supported for a char argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check_exception("Type s and an underlying format specification can't be used together", SV("{:5s:5}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char_escaped_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV(R"("\"Hello'")"), SV("{:?s}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV(R"("\"Hello'" )"), SV("{:13?s}"), input);
+ check(SV(R"("\"Hello'"***)"), SV("{:*<13?s}"), input);
+ check(SV(R"(_"\"Hello'"__)"), SV("{:_^13?s}"), input);
+ check(SV(R"(###"\"Hello'")"), SV("{:#>13?s}"), input);
+
+ check(SV(R"("\"Hello'" )"), SV("{:{}?s}"), input, 13);
+ check(SV(R"("\"Hello'"***)"), SV("{:*<{}?s}"), input, 13);
+ check(SV(R"(_"\"Hello'"__)"), SV("{:_^{}?s}"), input, 13);
+ check(SV(R"(###"\"Hello'")"), SV("{:#>{}?s}"), input, 13);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<?s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<?s}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<?s}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-?s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+?s}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: ?s}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#?s}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0?s}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.?s}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L?s}"), input);
+
+ // *** n
+ check_exception("The n option and type ?s can't be used together", SV("{:n?s}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("Type ?s and an underlying format specification can't be used together", SV("{:?s:}"), input);
+
+ // ***** Both have a format-spec
+ check_exception("Type ?s and an underlying format specification can't be used together", SV("{:5?s:5}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_char(TestFunction check, ExceptionTest check_exception) {
+ test_char_default<CharT>(
+ check, check_exception, std::array{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')});
+
+ // This tests two different implementations in libc++. A basic_string_view
+ // formatter if the range is contiguous, a basic_string otherwise.
+ test_char_escaped_string<CharT>(
+ check,
+ check_exception,
+ std::array{CharT('"'), CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o'), CharT('\'')});
+ test_char_escaped_string<CharT>(
+ check,
+ check_exception,
+ std::list{CharT('"'), CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o'), CharT('\'')});
+
+ // This tests two different implementations in libc++. A basic_string_view
+ // formatter if the range is contiguous, a basic_string otherwise.
+ test_char_string<CharT>(
+ check, check_exception, std::array{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')});
+ test_char_string<CharT>(
+ check, check_exception, std::list{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')});
+}
+
+//
+// char -> wchar_t
+//
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class TestFunction, class ExceptionTest>
+void test_char_to_wchar(TestFunction check, ExceptionTest check_exception) {
+ test_char_default<wchar_t>(check, check_exception, std::array{'H', 'e', 'l', 'l', 'o'});
+
+ // The types s and ?s may only be used when using range_formatter<T, charT>
+ // where the types T and charT are the same. This means this can't be used for
+ // range_formatter<wchar_t, char> even when formatter<wchar_t, char> has a
+ // debug-enabled specialization.
+
+ using CharT = wchar_t;
+ check_exception("The range-format-spec type s requires formatting a character type",
+ SV("{:s}"),
+ std::array{'H', 'e', 'l', 'l', 'o'});
+ check_exception("The range-format-spec type ?s requires formatting a character type",
+ SV("{:?s}"),
+ std::array{'H', 'e', 'l', 'l', 'o'});
+}
+#endif
+
+//
+// Bool
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_bool(TestFunction check, ExceptionTest check_exception) {
+ std::array input{true, true, false};
+
+ check(SV("[true, true, false]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[true, true, false] "), SV("{:24}"), input);
+ check(SV("[true, true, false]*****"), SV("{:*<24}"), input);
+ check(SV("__[true, true, false]___"), SV("{:_^24}"), input);
+ check(SV("#####[true, true, false]"), SV("{:#>24}"), input);
+
+ check(SV("[true, true, false] "), SV("{:{}}"), input, 24);
+ check(SV("[true, true, false]*****"), SV("{:*<{}}"), input, 24);
+ check(SV("__[true, true, false]___"), SV("{:_^{}}"), input, 24);
+ check(SV("#####[true, true, false]"), SV("{:#>{}}"), input, 24);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__true, true, false___"), SV("{:_^22n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[true , true , false ]"), SV("{::7}"), input);
+ check(SV("[true***, true***, false**]"), SV("{::*<7}"), input);
+ check(SV("[_true__, _true__, _false_]"), SV("{::_^7}"), input);
+ check(SV("[:::true, :::true, ::false]"), SV("{:::>7}"), input);
+
+ check(SV("[true , true , false ]"), SV("{::{}}"), input, 7);
+ check(SV("[true***, true***, false**]"), SV("{::*<{}}"), input, 7);
+ check(SV("[_true__, _true__, _false_]"), SV("{::_^{}}"), input, 7);
+ check(SV("[:::true, :::true, ::false]"), SV("{:::>{}}"), input, 7);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::-}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{::+}"), input);
+ check_exception("A sign field isn't allowed in this format-spec", SV("{:: }"), input);
+
+ check(SV("[1, 1, 0]"), SV("{::-d}"), input);
+ check(SV("[+1, +1, +0]"), SV("{::+d}"), input);
+ check(SV("[ 1, 1, 0]"), SV("{:: d}"), input);
+
+ // *** alternate form ***
+ check_exception("An alternate form field isn't allowed in this format-spec", SV("{::#}"), input);
+
+ check(SV("[0x1, 0x1, 0x0]"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check_exception("A zero-padding field isn't allowed in this format-spec", SV("{::05}"), input);
+
+ check(SV("[00001, 00001, 00000]"), SV("{::05o}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[true, true, false]"), SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX"))
+ check_exception("The format-spec type has a type not supported for a bool argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^32::>7}"), input);
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>7}"), input, 32);
+ check(SV("^^[:::true, :::true, ::false]^^^"), SV("{:^^{}::>{}}"), input, 32, 7);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 32);
+}
+
+//
+// Integral
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[1, 2, 42, -42]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[1, 2, 42, -42] "), SV("{:20}"), input);
+ check(SV("[1, 2, 42, -42]*****"), SV("{:*<20}"), input);
+ check(SV("__[1, 2, 42, -42]___"), SV("{:_^20}"), input);
+ check(SV("#####[1, 2, 42, -42]"), SV("{:#>20}"), input);
+
+ check(SV("[1, 2, 42, -42] "), SV("{:{}}"), input, 20);
+ check(SV("[1, 2, 42, -42]*****"), SV("{:*<{}}"), input, 20);
+ check(SV("__[1, 2, 42, -42]___"), SV("{:_^{}}"), input, 20);
+ check(SV("#####[1, 2, 42, -42]"), SV("{:#>{}}"), input, 20);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__1, 2, 42, -42___"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[ 1, 2, 42, -42]"), SV("{::5}"), input);
+ check(SV("[1****, 2****, 42***, -42**]"), SV("{::*<5}"), input);
+ check(SV("[__1__, __2__, _42__, _-42_]"), SV("{::_^5}"), input);
+ check(SV("[::::1, ::::2, :::42, ::-42]"), SV("{:::>5}"), input);
+
+ check(SV("[ 1, 2, 42, -42]"), SV("{::{}}"), input, 5);
+ check(SV("[1****, 2****, 42***, -42**]"), SV("{::*<{}}"), input, 5);
+ check(SV("[__1__, __2__, _42__, _-42_]"), SV("{::_^{}}"), input, 5);
+ check(SV("[::::1, ::::2, :::42, ::-42]"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check(SV("[1, 2, 42, -42]"), SV("{::-}"), input);
+ check(SV("[+1, +2, +42, -42]"), SV("{::+}"), input);
+ check(SV("[ 1, 2, 42, -42]"), SV("{:: }"), input);
+
+ // *** alternate form ***
+ check(SV("[0x1, 0x2, 0x2a, -0x2a]"), SV("{::#x}"), input);
+
+ // *** zero-padding ***
+ check(SV("[00001, 00002, 00042, -0042]"), SV("{::05}"), input);
+ check(SV("[00001, 00002, 0002a, -002a]"), SV("{::05x}"), input);
+ check(SV("[0x001, 0x002, 0x02a, -0x2a]"), SV("{::#05x}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[1, 2, 42, -42]"), SV("{::L}"), input); // does nothing in this test, but is accepted.
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBcdoxX"))
+ check_exception("The format-spec type has a type not supported for an integer argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[::::1, ::::2, :::42, ::-42]^^^"), SV("{:^^33::>5}"), input);
+ check(SV("^^[::::1, ::::2, :::42, ::-42]^^^"), SV("{:^^{}::>5}"), input, 33);
+ check(SV("^^[::::1, ::::2, :::42, ::-42]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 33);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_int(TestFunction check, ExceptionTest check_exception) {
+ test_int<CharT>(check, check_exception, std::array{1, 2, 42, -42});
+ test_int<CharT>(check, check_exception, std::list{1, 2, 42, -42});
+ test_int<CharT>(check, check_exception, std::vector{1, 2, 42, -42});
+ std::array input{1, 2, 42, -42};
+ test_int<CharT>(check, check_exception, std::span{input});
+}
+
+//
+// Floating point
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_floating_point(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[-42.5, 0, 1.25, 42.5] "), SV("{:27}"), input);
+ check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<27}"), input);
+ check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^27}"), input);
+ check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>27}"), input);
+
+ check(SV("[-42.5, 0, 1.25, 42.5] "), SV("{:{}}"), input, 27);
+ check(SV("[-42.5, 0, 1.25, 42.5]*****"), SV("{:*<{}}"), input, 27);
+ check(SV("__[-42.5, 0, 1.25, 42.5]___"), SV("{:_^{}}"), input, 27);
+ check(SV("#####[-42.5, 0, 1.25, 42.5]"), SV("{:#>{}}"), input, 27);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__-42.5, 0, 1.25, 42.5___"), SV("{:_^25n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::5}"), input);
+ check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<5}"), input);
+ check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^5}"), input);
+ check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>5}"), input);
+
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::{}}"), input, 5);
+ check(SV("[-42.5, 0****, 1.25*, 42.5*]"), SV("{::*<{}}"), input, 5);
+ check(SV("[-42.5, __0__, 1.25_, 42.5_]"), SV("{::_^{}}"), input, 5);
+ check(SV("[-42.5, ::::0, :1.25, :42.5]"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::-}"), input);
+ check(SV("[-42.5, +0, +1.25, +42.5]"), SV("{::+}"), input);
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{:: }"), input);
+
+ // *** alternate form ***
+ check(SV("[-42.5, 0., 1.25, 42.5]"), SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check(SV("[-42.5, 00000, 01.25, 042.5]"), SV("{::05}"), input);
+ check(SV("[-42.5, 0000., 01.25, 042.5]"), SV("{::#05}"), input);
+
+ // *** precision ***
+ check(SV("[-42, 0, 1.2, 42]"), SV("{::.2}"), input);
+ check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.3f}"), input);
+
+ check(SV("[-42, 0, 1.2, 42]"), SV("{::.{}}"), input, 2);
+ check(SV("[-42.500, 0.000, 1.250, 42.500]"), SV("{::.{}f}"), input, 3);
+
+ check_exception("The format-spec precision field doesn't contain a value or arg-id", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input); // does not require locales present
+#ifndef TEST_HAS_NO_LOCALIZATION
+// TODO FMT Enable with locale testing active
+# if 0
+ std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+ check(SV("[-42,5, 0, 1,25, 42,5]"), SV("{::L}"), input);
+
+ std::locale::global(std::locale(LOCALE_en_US_UTF_8));
+ check(SV("[-42.5, 0, 1.25, 42.5]"), SV("{::L}"), input);
+
+ std::locale::global(std::locale::classic());
+# endif
+#endif // TEST_HAS_NO_LOCALIZATION
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("aAeEfFgG"))
+ check_exception("The format-spec type has a type not supported for a floating-point argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^33::>5}"), input);
+ check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>5}"), input, 33);
+ check(SV("^^[-42.5, ::::0, :1.25, :42.5]^^^"), SV("{:^^{}::>{}}"), input, 33, 5);
+
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^33::>5.2}"), input);
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>5.2}"), input, 33);
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.2}"), input, 33, 5);
+ check(SV("^^[::-42, ::::0, ::1.2, :::42]^^^"), SV("{:^^{}::>{}.{}}"), input, 33, 5, 2);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5.2}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}.2}"), input, 33);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}.{}}"), input, 33, 5);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_floating_point(TestFunction check, ExceptionTest check_exception) {
+ test_floating_point<CharT>(check, check_exception, std::array{-42.5f, 0.0f, 1.25f, 42.5f});
+ test_floating_point<CharT>(check, check_exception, std::vector{-42.5, 0.0, 1.25, 42.5});
+
+ std::array input{-42.5l, 0.0l, 1.25l, 42.5l};
+ test_floating_point<CharT>(check, check_exception, std::span{input});
+}
+
+//
+// Pointer
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pointer(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV("[0x0]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[0x0] "), SV("{:10}"), input);
+ check(SV("[0x0]*****"), SV("{:*<10}"), input);
+ check(SV("__[0x0]___"), SV("{:_^10}"), input);
+ check(SV("#####[0x0]"), SV("{:#>10}"), input);
+
+ check(SV("[0x0] "), SV("{:{}}"), input, 10);
+ check(SV("[0x0]*****"), SV("{:*<{}}"), input, 10);
+ check(SV("__[0x0]___"), SV("{:_^{}}"), input, 10);
+ check(SV("#####[0x0]"), SV("{:#>{}}"), input, 10);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("_0x0_"), SV("{:_^5n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[ 0x0]"), SV("{::5}"), input);
+ check(SV("[0x0**]"), SV("{::*<5}"), input);
+ check(SV("[_0x0_]"), SV("{::_^5}"), input);
+ check(SV("[::0x0]"), SV("{:::>5}"), input);
+
+ check(SV("[ 0x0]"), SV("{::{}}"), input, 5);
+ check(SV("[0x0**]"), SV("{::*<{}}"), input, 5);
+ check(SV("[_0x0_]"), SV("{::_^{}}"), input, 5);
+ check(SV("[::0x0]"), SV("{:::>{}}"), input, 5);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("p"))
+ check_exception("The format-spec type has a type not supported for a pointer argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
+
+ check(SV("^^[::0x0]^^^"), SV("{:^^12::>5}"), input);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>5}"), input, 12);
+ check(SV("^^[::0x0]^^^"), SV("{:^^{}::>{}}"), input, 12, 5);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 12);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pointer(TestFunction check, ExceptionTest check_exception) {
+ test_pointer<CharT>(check, check_exception, std::array{nullptr});
+ test_pointer<CharT>(check, check_exception, std::array{static_cast<const void*>(0)});
+ test_pointer<CharT>(check, check_exception, std::array{static_cast<void*>(0)});
+}
+
+//
+// String
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_string(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ check(SV(R"(["Hello", "world"])"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV(R"(["Hello", "world"] )"), SV("{:23}"), input);
+ check(SV(R"(["Hello", "world"]*****)"), SV("{:*<23}"), input);
+ check(SV(R"(__["Hello", "world"]___)"), SV("{:_^23}"), input);
+ check(SV(R"(#####["Hello", "world"])"), SV("{:#>23}"), input);
+
+ check(SV(R"(["Hello", "world"] )"), SV("{:{}}"), input, 23);
+ check(SV(R"(["Hello", "world"]*****)"), SV("{:*<{}}"), input, 23);
+ check(SV(R"(__["Hello", "world"]___)"), SV("{:_^{}}"), input, 23);
+ check(SV(R"(#####["Hello", "world"])"), SV("{:#>{}}"), input, 23);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV(R"(_"Hello", "world"_)"), SV("{:_^18n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV(R"([Hello , world ])"), SV("{::8}"), input);
+ check(SV(R"([Hello***, world***])"), SV("{::*<8}"), input);
+ check(SV(R"([_Hello__, _world__])"), SV("{::_^8}"), input);
+ check(SV(R"([:::Hello, :::world])"), SV("{:::>8}"), input);
+
+ check(SV(R"([Hello , world ])"), SV("{::{}}"), input, 8);
+ check(SV(R"([Hello***, world***])"), SV("{::*<{}}"), input, 8);
+ check(SV(R"([_Hello__, _world__])"), SV("{::_^{}}"), input, 8);
+ check(SV(R"([:::Hello, :::world])"), SV("{:::>{}}"), input, 8);
+
+ check_exception("The format-spec fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check(SV(R"([Hel, wor])"), SV("{::.3}"), input);
+
+ check(SV(R"([Hel, wor])"), SV("{::.{}}"), input, 3);
+
+ check_exception("The format-spec precision field doesn't contain a value or arg-id", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s?"))
+ check_exception("The format-spec type has a type not supported for a string argument", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
+
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^25::>8}"), input);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>8}"), input, 25);
+ check(SV(R"(^^[:::Hello, :::world]^^^)"), SV("{:^^{}::>{}}"), input, 25, 8);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}::>8}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}::>{}}"), input, 25);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_string(TestFunction check, ExceptionTest check_exception) {
+ test_string<CharT>(check, check_exception, std::array{CSTR("Hello"), CSTR("world")});
+ test_string<CharT>(check, check_exception, std::array{STR("Hello"), STR("world")});
+ test_string<CharT>(check, check_exception, std::array{SV("Hello"), SV("world")});
+}
+
+//
+// Handle
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_status(TestFunction check, ExceptionTest check_exception) {
+ std::array input{status::foo, status::bar, status::foobar};
+
+ check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[0xaaaa, 0x5555, 0xaa55] "), SV("{:29}"), input);
+ check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<29}"), input);
+ check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^29}"), input);
+ check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>29}"), input);
+
+ check(SV("[0xaaaa, 0x5555, 0xaa55] "), SV("{:{}}"), input, 29);
+ check(SV("[0xaaaa, 0x5555, 0xaa55]*****"), SV("{:*<{}}"), input, 29);
+ check(SV("__[0xaaaa, 0x5555, 0xaa55]___"), SV("{:_^{}}"), input, 29);
+ check(SV("#####[0xaaaa, 0x5555, 0xaa55]"), SV("{:#>{}}"), input, 29);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__0xaaaa, 0x5555, 0xaa55___"), SV("{:_^27n}"), input);
+
+ // *** type ***
+ check_exception("The range-format-spec type m requires two elements for a pair or tuple", SV("{:m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check_exception("The format-spec type has a type not supported for a status argument", SV("{::*<7}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("sxX"))
+ check_exception("The format-spec type has a type not supported for a status argument", fmt, input);
+
+ check(SV("[0xaaaa, 0x5555, 0xaa55]"), SV("{::x}"), input);
+ check(SV("[0XAAAA, 0X5555, 0XAA55]"), SV("{::X}"), input);
+ check(SV("[foo, bar, foobar]"), SV("{::s}"), input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^29:X}"), input);
+ check(SV("^^[0XAAAA, 0X5555, 0XAA55]^^^"), SV("{:^^{}:X}"), input, 29);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:X}"), input);
+}
+
+//
+// Pair
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pair_tuple(TestFunction check, ExceptionTest check_exception, auto&& input) {
+ // [format.range.formatter]/3
+ // For range_formatter<T, charT>, the format-spec in a
+ // range-underlying-spec, if any, is interpreted by formatter<T, charT>.
+ //
+ // template<class ParseContext>
+ // constexpr typename ParseContext::iterator
+ // parse(ParseContext& ctx);
+ // [format.tuple]/7
+ // ... if e.set_debug_format() is a valid expression, calls
+ // e.set_debug_format().
+ // So when there is no range-underlying-spec, there is no need to call parse
+ // thus the char element is not escaped.
+ // TODO FMT P2733 addresses this issue.
+ check(SV("[(1, a), (42, *)]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[(1, a), (42, *)] "), SV("{:22}"), input);
+ check(SV("[(1, a), (42, *)]*****"), SV("{:*<22}"), input);
+ check(SV("__[(1, a), (42, *)]___"), SV("{:_^22}"), input);
+ check(SV("#####[(1, a), (42, *)]"), SV("{:#>22}"), input);
+
+ check(SV("[(1, a), (42, *)] "), SV("{:{}}"), input, 22);
+ check(SV("[(1, a), (42, *)]*****"), SV("{:*<{}}"), input, 22);
+ check(SV("__[(1, a), (42, *)]___"), SV("{:_^{}}"), input, 22);
+ check(SV("#####[(1, a), (42, *)]"), SV("{:#>{}}"), input, 22);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__(1, a), (42, *)___"), SV("{:_^20n}"), input);
+ check(SV("__(1, a), (42, *)___"), SV("{:_^20nm}"), input); // m should have no effect
+
+ // *** type ***
+ check(SV("__{(1, a), (42, *)}___"), SV("{:_^22m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[(1, 'a') , (42, '*') ]"), SV("{::11}"), input);
+ check(SV("[(1, 'a')***, (42, '*')**]"), SV("{::*<11}"), input);
+ check(SV("[_(1, 'a')__, _(42, '*')_]"), SV("{::_^11}"), input);
+ check(SV("[###(1, 'a'), ##(42, '*')]"), SV("{::#>11}"), input);
+
+ check(SV("[(1, 'a') , (42, '*') ]"), SV("{::{}}"), input, 11);
+ check(SV("[(1, 'a')***, (42, '*')**]"), SV("{::*<{}}"), input, 11);
+ check(SV("[_(1, 'a')__, _(42, '*')_]"), SV("{::_^{}}"), input, 11);
+ check(SV("[###(1, 'a'), ##(42, '*')]"), SV("{::#>{}}"), input, 11);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("[1: 'a', 42: '*']"), SV("{::m}"), input);
+ check(SV("[1, 'a', 42, '*']"), SV("{::n}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^31:#>11}"), input);
+ check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^31:#>11}"), input);
+ check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^{}:#>11}"), input, 31);
+ check(SV("^^[###(1, 'a'), ##(42, '*')]^^^"), SV("{:^^{}:#>{}}"), input, 31, 11);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 31);
+
+ check(SV("1: 'a', 42: '*'"), SV("{:n:m}"), input);
+ check(SV("1, 'a', 42, '*'"), SV("{:n:n}"), input);
+ check(SV("{1: 'a', 42: '*'}"), SV("{:m:m}"), input);
+ check(SV("{1, 'a', 42, '*'}"), SV("{:m:n}"), input);
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_pair_tuple(TestFunction check, ExceptionTest check_exception) {
+ test_pair_tuple<CharT>(
+ check, check_exception, std::array{std::make_pair(1, CharT('a')), std::make_pair(42, CharT('*'))});
+ test_pair_tuple<CharT>(
+ check, check_exception, std::array{std::make_tuple(1, CharT('a')), std::make_tuple(42, CharT('*'))});
+}
+
+//
+// Tuple 1
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_tuple_int(TestFunction check, ExceptionTest check_exception) {
+ std::array input{std::make_tuple(42), std::make_tuple(99)};
+
+ check(SV("[(42), (99)]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[(42), (99)] "), SV("{:17}"), input);
+ check(SV("[(42), (99)]*****"), SV("{:*<17}"), input);
+ check(SV("__[(42), (99)]___"), SV("{:_^17}"), input);
+ check(SV("#####[(42), (99)]"), SV("{:#>17}"), input);
+
+ check(SV("[(42), (99)] "), SV("{:{}}"), input, 17);
+ check(SV("[(42), (99)]*****"), SV("{:*<{}}"), input, 17);
+ check(SV("__[(42), (99)]___"), SV("{:_^{}}"), input, 17);
+ check(SV("#####[(42), (99)]"), SV("{:#>{}}"), input, 17);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__(42), (99)___"), SV("{:_^15n}"), input);
+
+ // *** type ***
+ check(SV("__{(42), (99)}___"), SV("{:_^17m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[(42) , (99) ]"), SV("{::7}"), input);
+ check(SV("[(42)***, (99)***]"), SV("{::*<7}"), input);
+ check(SV("[_(42)__, _(99)__]"), SV("{::_^7}"), input);
+ check(SV("[###(42), ###(99)]"), SV("{::#>7}"), input);
+
+ check(SV("[(42) , (99) ]"), SV("{::{}}"), input, 7);
+ check(SV("[(42)***, (99)***]"), SV("{::*<{}}"), input, 7);
+ check(SV("[_(42)__, _(99)__]"), SV("{::_^{}}"), input, 7);
+ check(SV("[###(42), ###(99)]"), SV("{::#>{}}"), input, 7);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("[42, 99]"), SV("{::n}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>(""))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^23:#>7}"), input);
+ check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^23:#>7}"), input);
+ check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^{}:#>7}"), input, 23);
+ check(SV("^^[###(42), ###(99)]^^^"), SV("{:^^{}:#>{}}"), input, 23, 7);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 23);
+}
+
+//
+// Tuple 3
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_tuple_int_int_int(TestFunction check, ExceptionTest check_exception) {
+ std::array input{std::make_tuple(42, 99, 0), std::make_tuple(1, 10, 100)};
+
+ check(SV("[(42, 99, 0), (1, 10, 100)]"), SV("{}"), input);
+
+ // ***** underlying has no format-spec
+
+ // *** align-fill & width ***
+ check(SV("[(42, 99, 0), (1, 10, 100)] "), SV("{:32}"), input);
+ check(SV("[(42, 99, 0), (1, 10, 100)]*****"), SV("{:*<32}"), input);
+ check(SV("__[(42, 99, 0), (1, 10, 100)]___"), SV("{:_^32}"), input);
+ check(SV("#####[(42, 99, 0), (1, 10, 100)]"), SV("{:#>32}"), input);
+
+ check(SV("[(42, 99, 0), (1, 10, 100)] "), SV("{:{}}"), input, 32);
+ check(SV("[(42, 99, 0), (1, 10, 100)]*****"), SV("{:*<{}}"), input, 32);
+ check(SV("__[(42, 99, 0), (1, 10, 100)]___"), SV("{:_^{}}"), input, 32);
+ check(SV("#####[(42, 99, 0), (1, 10, 100)]"), SV("{:#>{}}"), input, 32);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:{<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{:0}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:L}"), input);
+
+ // *** n
+ check(SV("__(42, 99, 0), (1, 10, 100)___"), SV("{:_^30n}"), input);
+
+ // *** type ***
+ check(SV("__{(42, 99, 0), (1, 10, 100)}___"), SV("{:_^32m}"), input);
+ check_exception("The range-format-spec type s requires formatting a character type", SV("{:s}"), input);
+ check_exception("The range-format-spec type ?s requires formatting a character type", SV("{:?s}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Only underlying has a format-spec
+ check(SV("[(42, 99, 0) , (1, 10, 100) ]"), SV("{::14}"), input);
+ check(SV("[(42, 99, 0)***, (1, 10, 100)**]"), SV("{::*<14}"), input);
+ check(SV("[_(42, 99, 0)__, _(1, 10, 100)_]"), SV("{::_^14}"), input);
+ check(SV("[###(42, 99, 0), ##(1, 10, 100)]"), SV("{::#>14}"), input);
+
+ check(SV("[(42, 99, 0) , (1, 10, 100) ]"), SV("{::{}}"), input, 14);
+ check(SV("[(42, 99, 0)***, (1, 10, 100)**]"), SV("{::*<{}}"), input, 14);
+ check(SV("[_(42, 99, 0)__, _(1, 10, 100)_]"), SV("{::_^{}}"), input, 14);
+ check(SV("[###(42, 99, 0), ##(1, 10, 100)]"), SV("{::#>{}}"), input, 14);
+
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{:::<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::}<}"), input);
+ check_exception("The format-spec range-fill field contains an invalid character", SV("{::{<}"), input);
+
+ // *** sign ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::-}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::+}"), input);
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{:: }"), input);
+
+ // *** alternate form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::#}"), input);
+
+ // *** zero-padding ***
+ check_exception("A format-spec width field shouldn't have a leading zero", SV("{::05}"), input);
+
+ // *** precision ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::.}"), input);
+
+ // *** locale-specific form ***
+ check_exception("The format-spec should consume the input or end with a '}'", SV("{::L}"), input);
+
+ // *** type ***
+ check(SV("[42, 99, 0, 1, 10, 100]"), SV("{::n}"), input);
+ for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("s"))
+ check_exception("The format-spec should consume the input or end with a '}'", fmt, input);
+
+ // ***** Both have a format-spec
+ check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^37:#>14}"), input);
+ check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^37:#>14}"), input);
+ check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^{}:#>14}"), input, 37);
+ check(SV("^^[###(42, 99, 0), ##(1, 10, 100)]^^^"), SV("{:^^{}:#>{}}"), input, 37, 14);
+
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>5}"), input);
+ check_exception("Argument index out of bounds", SV("{:^^{}:#>{}}"), input, 37);
+}
+
+//
+// Ranges
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_with_ranges(TestFunction check, ExceptionTest check_exception, auto&& iter) {
+ std::ranges::subrange range{std::move(iter), std::default_sentinel};
+ test_int<CharT>(check, check_exception, std::move(range));
+}
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_with_ranges(TestFunction check, ExceptionTest check_exception) {
+ std::array input{1, 2, 42, -42};
+ test_with_ranges<CharT>(
+ check, check_exception, std::counted_iterator{cpp20_input_iterator<int*>(input.data()), input.size()});
+ test_with_ranges<CharT>(
+ check, check_exception, std::counted_iterator{forward_iterator<int*>(input.data()), input.size()});
+ test_with_ranges<CharT>(
+ check, check_exception, std::counted_iterator{bidirectional_iterator<int*>(input.data()), input.size()});
+ test_with_ranges<CharT>(
+ check, check_exception, std::counted_iterator{random_access_iterator<int*>(input.data()), input.size()});
+ test_with_ranges<CharT>(
+ check, check_exception, std::counted_iterator{contiguous_iterator<int*>(input.data()), input.size()});
+}
+
+//
+// Adaptor
+//
+
+template <class CharT>
+class non_contiguous {
+ // A deque iterator is random access, but not contiguous.
+ using adaptee = std::deque<CharT>;
+
+public:
+ using iterator = typename adaptee::iterator;
+ using pointer = typename adaptee::pointer;
+
+ iterator begin() { return data_.begin(); }
+ iterator end() { return data_.end(); }
+
+ explicit non_contiguous(adaptee&& data) : data_(std::move(data)) {}
+
+private:
+ adaptee data_;
+};
+
+template <class CharT>
+class contiguous {
+ // A vector iterator is contiguous.
+ using adaptee = std::vector<CharT>;
+
+public:
+ using iterator = typename adaptee::iterator;
+ using pointer = typename adaptee::pointer;
+
+ iterator begin() { return data_.begin(); }
+ iterator end() { return data_.end(); }
+
+ explicit contiguous(adaptee&& data) : data_(std::move(data)) {}
+
+private:
+ adaptee data_;
+};
+
+// This tests two different implementations in libc++. A basic_string_view
+// formatter if the range is contiguous, a basic_string otherwise.
+template <class CharT, class TestFunction, class ExceptionTest>
+void test_adaptor(TestFunction check, ExceptionTest check_exception) {
+ static_assert(std::format_kind<non_contiguous<CharT>> == std::range_format::sequence);
+ static_assert(std::ranges::sized_range<non_contiguous<CharT>>);
+ static_assert(!std::ranges::contiguous_range<non_contiguous<CharT>>);
+ test_char_string<CharT>(
+ check,
+ check_exception,
+ non_contiguous<CharT>{std::deque{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')}});
+
+ static_assert(std::format_kind<contiguous<CharT>> == std::range_format::sequence);
+ static_assert(std::ranges::sized_range<contiguous<CharT>>);
+ static_assert(std::ranges::contiguous_range<contiguous<CharT>>);
+ test_char_string<CharT>(check,
+ check_exception,
+ contiguous<CharT>{std::vector{CharT('H'), CharT('e'), CharT('l'), CharT('l'), CharT('o')}});
+}
+
+//
+// Driver
+//
+
+template <class CharT, class TestFunction, class ExceptionTest>
+void format_tests(TestFunction check, ExceptionTest check_exception) {
+ test_char<CharT>(check, check_exception);
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ if (std::same_as<CharT, wchar_t>) // avoid testing twice
+ test_char_to_wchar(check, check_exception);
+#endif
+ test_bool<CharT>(check, check_exception);
+ test_int<CharT>(check, check_exception);
+ test_floating_point<CharT>(check, check_exception);
+ test_pointer<CharT>(check, check_exception);
+ test_string<CharT>(check, check_exception);
+
+ test_status<CharT>(check, check_exception); // Has its own handler with its own parser
+
+ test_pair_tuple<CharT>(check, check_exception);
+ test_tuple_int<CharT>(check, check_exception);
+ test_tuple_int_int_int<CharT>(check, check_exception);
+
+ test_with_ranges<CharT>(check, check_exception);
+
+ test_adaptor<CharT>(check, check_exception);
+}
+
+#endif // TEST_STD_UTILITIES_FORMAT_FORMAT_RANGE_FORMAT_RANGE_FORMATTER_FORMAT_FUNCTIONS_TESTS_H
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.vformat.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.vformat.pass.cpp
new file mode 100644
index 0000000..c473893
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.functions.vformat.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<class T, class charT = char>
+// requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+// class range_formatter;
+
+// string vformat(string_view fmt, format_args args);
+// wstring vformat(wstring_view fmt, wformat_args args);
+
+#include <format>
+#include <cassert>
+
+#include "format.functions.tests.h"
+#include "test_macros.h"
+#include "assert_macros.h"
+
+auto test = []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) {
+ std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
+auto test_exception =
+ []<class CharT, class... Args>(
+ [[maybe_unused]] std::string_view what,
+ [[maybe_unused]] std::basic_string_view<CharT> fmt,
+ [[maybe_unused]] Args&&... args) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ try {
+ TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
+ } catch (const std::format_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+
+ return;
+ }
+ assert(false);
+#endif
+ };
+
+int main(int, char**) {
+ format_tests<char>(test, test_exception);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ format_tests<wchar_t>(test, test_exception);
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.pass.cpp
new file mode 100644
index 0000000..acfe8cc
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/format.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<class T, class charT = char>
+// requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+// class range_formatter
+
+// template<class FormatContext>
+// typename FormatContext::iterator
+// format(const T& ref, FormatContext& ctx) const;
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+#include <vector>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+void test_format(StringViewT expected, std::vector<int> arg) {
+ using CharT = typename StringViewT::value_type;
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ const std::range_formatter<int, CharT> formatter;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>(arg));
+ formatter.format(arg, format_ctx);
+ assert(result == expected);
+}
+
+template <class CharT>
+void test_fmt() {
+ test_format(SV("[1]"), std::vector<int>{1});
+ test_format(SV("[0]"), std::vector<int>{0});
+}
+
+void test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/parse.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/parse.pass.cpp
new file mode 100644
index 0000000..ce1c0c9
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/parse.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<class T, class charT = char>
+// requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+// class range_formatter
+
+// template<class ParseContext>
+// constexpr typename ParseContext::iterator
+// parse(ParseContext& ctx);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <cassert>
+#include <concepts>
+#include <format>
+
+#include "test_format_context.h"
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class StringViewT>
+constexpr void test_parse(StringViewT fmt) {
+ using CharT = typename StringViewT::value_type;
+ auto parse_ctx = std::basic_format_parse_context<CharT>(fmt);
+ std::range_formatter<int, CharT> formatter;
+ static_assert(std::semiregular<decltype(formatter)>);
+
+ std::same_as<typename StringViewT::iterator> auto it = formatter.parse(parse_ctx);
+ assert(it == fmt.end() - (!fmt.empty() && fmt.back() == '}'));
+}
+
+template <class CharT>
+constexpr void test_fmt() {
+ test_parse(SV(""));
+ test_parse(SV(":d"));
+
+ test_parse(SV("}"));
+ test_parse(SV(":d}"));
+}
+
+constexpr bool test() {
+ test_fmt<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_fmt<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/set_brackets.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/set_brackets.pass.cpp
new file mode 100644
index 0000000..fe2d72c
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/set_brackets.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<class T, class charT = char>
+// requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+// class range_formatter
+
+// constexpr void constexpr void set_brackets(basic_string_view<charT> opening,
+// basic_string_view<charT> closing);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <format>
+#include <cassert>
+#include <type_traits>
+#include <vector>
+
+#include "make_string.h"
+#include "test_format_context.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+constexpr void test_setter() {
+ std::range_formatter<int, CharT> formatter;
+ formatter.set_brackets(SV("open"), SV("close"));
+
+ // Note there is no direct way to validate this function modified the object.
+ if (!std::is_constant_evaluated()) {
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>());
+ formatter.format(std::vector<int>{0, 42, 99}, format_ctx);
+ assert(result == SV("open0, 42, 99close"));
+ }
+}
+
+constexpr bool test() {
+ test_setter<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_setter<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/set_separator.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/set_separator.pass.cpp
new file mode 100644
index 0000000..413f5b4
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/set_separator.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<class T, class charT = char>
+// requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+// class range_formatter
+
+// constexpr void set_separator(basic_string_view<charT> sep);
+
+// Note this tests the basics of this function. It's tested in more detail in
+// the format functions test.
+
+#include <format>
+#include <cassert>
+#include <type_traits>
+#include <vector>
+
+#include "make_string.h"
+#include "test_format_context.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+constexpr void test_setter() {
+ std::range_formatter<int, CharT> formatter;
+ formatter.set_separator(SV("sep"));
+
+ // Note there is no direct way to validate this function modified the object.
+ if (!std::is_constant_evaluated()) {
+ using String = std::basic_string<CharT>;
+ using OutIt = std::back_insert_iterator<String>;
+ using FormatCtxT = std::basic_format_context<OutIt, CharT>;
+
+ String result;
+ OutIt out = std::back_inserter(result);
+ FormatCtxT format_ctx = test_format_context_create<OutIt, CharT>(out, std::make_format_args<FormatCtxT>());
+ formatter.format(std::vector<int>{0, 42, 99}, format_ctx);
+ assert(result == SV("[0sep42sep99]"));
+ }
+}
+
+constexpr bool test() {
+ test_setter<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_setter<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/underlying.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/underlying.pass.cpp
new file mode 100644
index 0000000..7d819d4
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.range/format.range.formatter/underlying.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
+// This test requires the dylib support introduced in D92214.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
+
+// <format>
+
+// template<class T, class charT = char>
+// requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
+// class range_formatter
+
+// constexpr formatter<T, charT>& underlying();
+// constexpr const formatter<T, charT>& underlying() const;
+
+#include <concepts>
+#include <format>
+
+#include "test_macros.h"
+
+template <class CharT>
+constexpr void test_underlying() {
+ {
+ std::range_formatter<int, CharT> formatter;
+ [[maybe_unused]] std::same_as<std::formatter<int, CharT>&> decltype(auto) underlying = formatter.underlying();
+ }
+ {
+ const std::range_formatter<int, CharT> formatter;
+ [[maybe_unused]] std::same_as<const std::formatter<int, CharT>&> decltype(auto) underlying = formatter.underlying();
+ }
+}
+
+constexpr bool test() {
+ test_underlying<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_underlying<wchar_t>();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.format.pass.cpp
index 72f8430..6f64016 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.format.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.format.pass.cpp
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// UNSUPPORTED: libcpp-has-no-incomplete-format
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
// This test requires the dylib support introduced in D92214.
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
@@ -30,22 +33,14 @@
#include "format.functions.tests.h"
#include "test_format_string.h"
#include "test_macros.h"
-
-#ifndef TEST_HAS_NO_LOCALIZATION
-# include <iostream>
-# include <concepts>
-#endif
+#include "assert_macros.h"
auto test = []<class CharT, class... Args>(
std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
-#ifndef TEST_HAS_NO_LOCALIZATION
- if constexpr (std::same_as<CharT, char>)
- if (out != expected)
- std::cerr << "\nFormat string " << fmt.get() << "\nExpected output " << expected << "\nActual output " << out
- << '\n';
-#endif // TEST_HAS_NO_LOCALIZATION
- assert(out == expected);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
};
auto test_exception = []<class CharT, class... Args>(std::string_view, std::basic_string_view<CharT>, Args&&...) {
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.tests.h b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.tests.h
index 2ad2d87..3f7a1fa 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.tests.h
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.tests.h
@@ -279,7 +279,7 @@
void test_nested(TestFunction check, ExceptionTest check_exception, Nested&& input) {
// [format.formatter.spec]/2
// A debug-enabled specialization of formatter additionally provides a
- // public, constexpr, non-static member function set_Âdebug_Âformat()
+ // public, constexpr, non-static member function set_debug_format()
// which modifies the state of the formatter to be as if the type of the
// std-format-spec parsed by the last call to parse were ?.
// pair and tuple are not debug-enabled specializations to the
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.vformat.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.vformat.pass.cpp
index 7c9540c..6853134 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.vformat.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.functions.vformat.pass.cpp
@@ -29,22 +29,14 @@
#include "test_macros.h"
#include "format.functions.tests.h"
-
-#ifndef TEST_HAS_NO_LOCALIZATION
-# include <iostream>
-# include <concepts>
-#endif
+#include "assert_macros.h"
auto test = []<class CharT, class... Args>(
std::basic_string_view<CharT> expected, std::basic_string_view<CharT> fmt, Args&&... args) {
std::basic_string<CharT> out = std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
-#ifndef TEST_HAS_NO_LOCALIZATION
- if constexpr (std::same_as<CharT, char>)
- if (out != expected)
- std::cerr << "\nFormat string " << fmt << "\nExpected output " << expected << "\nActual output " << out
- << '\n';
-#endif // TEST_HAS_NO_LOCALIZATION
- assert(out == expected);
+ TEST_REQUIRE(
+ out == expected,
+ test_concat_message("\nFormat string ", fmt, "\nExpected output ", expected, "\nActual output ", out, '\n'));
};
auto test_exception =
@@ -55,22 +47,13 @@
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...));
-# if !defined(TEST_HAS_NO_LOCALIZATION)
- if constexpr (std::same_as<CharT, char>)
- std::cerr << "\nFormat string " << fmt << "\nDidn't throw an exception.\n";
-# endif // !defined(TEST_HAS_NO_LOCALIZATION
- assert(false);
+ TEST_FAIL(test_concat_message("\nFormat string ", fmt, "\nDidn't throw an exception.\n"));
} catch ([[maybe_unused]] const std::format_error& e) {
-# if defined(_LIBCPP_VERSION)
-# if !defined(TEST_HAS_NO_LOCALIZATION)
- if constexpr (std::same_as<CharT, char>) {
- if (e.what() != what)
- std::cerr << "\nFormat string " << fmt << "\nExpected exception " << what << "\nActual exception "
- << e.what() << '\n';
- }
-# endif // !defined(TEST_HAS_NO_LOCALIZATION
- assert(e.what() == what);
-# endif // defined(_LIBCPP_VERSION)
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ test_concat_message(
+ "\nFormat string ", fmt, "\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+
return;
}
assert(false);
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.pass.cpp
index aa56e2d..442df5d 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/format.pass.cpp
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// UNSUPPORTED: libcpp-has-no-incomplete-format
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
// This test requires the dylib support introduced in D92214.
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/parse.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/parse.pass.cpp
index 7800895..05c9055 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/parse.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/parse.pass.cpp
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// UNSUPPORTED: libcpp-has-no-incomplete-format
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
// This test requires the dylib support introduced in D92214.
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_brackets.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_brackets.pass.cpp
index bb32611..86c9845 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_brackets.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_brackets.pass.cpp
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// UNSUPPORTED: libcpp-has-no-incomplete-format
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
// This test requires the dylib support introduced in D92214.
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_separator.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_separator.pass.cpp
index dfa6561..fd2c827 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_separator.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/format/format.tuple/set_separator.pass.cpp
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// UNSUPPORTED: libcpp-has-no-incomplete-format
+// TODO FMT Fix this test using GCC, it currently times out.
+// UNSUPPORTED: gcc-12
+
// This test requires the dylib support introduced in D92214.
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{.+}}
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx11.{{.+}}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp
new file mode 100644
index 0000000..e69adee
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp
@@ -0,0 +1,190 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// template<class T, class A>
+// shared_ptr<T> make_shared_for_overwrite(const A& a); // T is not U[]
+//
+// template<class T, class A>
+// shared_ptr<T> make_shared_for_overwrite(const A& a, size_t N); // T is U[]
+
+#include <cassert>
+#include <concepts>
+#include <cstring>
+#include <memory>
+#include <utility>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T, class... Args>
+concept HasAllocateSharedForOverwrite =
+ requires(Args&&... args) { std::allocate_shared_for_overwrite<T>(std::forward<Args>(args)...); };
+
+struct Foo {
+ int i;
+};
+
+// non array
+static_assert(!HasAllocateSharedForOverwrite<int>);
+static_assert(!HasAllocateSharedForOverwrite<Foo>);
+static_assert(HasAllocateSharedForOverwrite<int, bare_allocator<void>>);
+static_assert(HasAllocateSharedForOverwrite<Foo, bare_allocator<void>>);
+static_assert(!HasAllocateSharedForOverwrite<int, bare_allocator<void>, std::size_t>);
+static_assert(!HasAllocateSharedForOverwrite<Foo, bare_allocator<void>, std::size_t>);
+
+// bounded array
+static_assert(!HasAllocateSharedForOverwrite<int[2]>);
+static_assert(!HasAllocateSharedForOverwrite<Foo[2]>);
+static_assert(HasAllocateSharedForOverwrite<int[2], bare_allocator<void>>);
+static_assert(HasAllocateSharedForOverwrite<Foo[2], bare_allocator<void>>);
+static_assert(!HasAllocateSharedForOverwrite<int[2], bare_allocator<void>, std::size_t>);
+static_assert(!HasAllocateSharedForOverwrite<Foo[2], bare_allocator<void>, std::size_t>);
+
+// unbounded array
+static_assert(!HasAllocateSharedForOverwrite<int[]>);
+static_assert(!HasAllocateSharedForOverwrite<Foo[]>);
+static_assert(!HasAllocateSharedForOverwrite<int[], bare_allocator<void>>);
+static_assert(!HasAllocateSharedForOverwrite<Foo[], bare_allocator<void>>);
+static_assert(HasAllocateSharedForOverwrite<int[], bare_allocator<void>, std::size_t>);
+static_assert(HasAllocateSharedForOverwrite<Foo[], bare_allocator<void>, std::size_t>);
+
+struct WithDefaultCtor {
+ int i;
+ WithDefaultCtor() : i(42) {}
+};
+
+template <class Alloc>
+void testDefaultConstructor() {
+ // single
+ {
+ std::same_as<std::shared_ptr<WithDefaultCtor>> auto ptr =
+ std::allocate_shared_for_overwrite<WithDefaultCtor>(Alloc{});
+ assert(ptr->i == 42);
+ }
+
+ // bounded array
+ {
+ std::same_as<std::shared_ptr<WithDefaultCtor[2]>> auto ptr =
+ std::allocate_shared_for_overwrite<WithDefaultCtor[2]>(Alloc{});
+ assert(ptr[0].i == 42);
+ assert(ptr[1].i == 42);
+ }
+
+ // unbounded array
+ {
+ std::same_as<std::shared_ptr<WithDefaultCtor[]>> auto ptr =
+ std::allocate_shared_for_overwrite<WithDefaultCtor[]>(Alloc{}, 3);
+ assert(ptr[0].i == 42);
+ assert(ptr[1].i == 42);
+ assert(ptr[2].i == 42);
+ }
+}
+
+void testTypeWithDefaultCtor() {
+ testDefaultConstructor<test_allocator<WithDefaultCtor>>();
+ testDefaultConstructor<min_allocator<WithDefaultCtor>>();
+ testDefaultConstructor<bare_allocator<WithDefaultCtor>>();
+}
+
+void testAllocatorOperationsCalled() {
+ // single
+ {
+ test_allocator_statistics alloc_stats;
+ {
+ [[maybe_unused]] std::same_as<std::shared_ptr<int>> auto ptr =
+ std::allocate_shared_for_overwrite<int>(test_allocator<void>{&alloc_stats});
+ assert(alloc_stats.alloc_count == 1);
+ }
+ assert(alloc_stats.alloc_count == 0);
+ }
+
+ // bounded array
+ {
+ test_allocator_statistics alloc_stats;
+ {
+ [[maybe_unused]] std::same_as<std::shared_ptr<int[2]>> auto ptr =
+ std::allocate_shared_for_overwrite<int[2]>(test_allocator<void>{&alloc_stats});
+ assert(alloc_stats.alloc_count == 1);
+ }
+ assert(alloc_stats.alloc_count == 0);
+ }
+
+ // unbounded array
+ {
+ test_allocator_statistics alloc_stats;
+ {
+ [[maybe_unused]] std::same_as<std::shared_ptr<int[]>> auto ptr =
+ std::allocate_shared_for_overwrite<int[]>(test_allocator<void>{&alloc_stats}, 3);
+ assert(alloc_stats.alloc_count == 1);
+ }
+ assert(alloc_stats.alloc_count == 0);
+ }
+}
+
+template <class T>
+struct AllocatorWithPattern {
+ constexpr static char pattern = 0xDE;
+
+ using value_type = T;
+
+ AllocatorWithPattern() = default;
+
+ template <class U>
+ AllocatorWithPattern(AllocatorWithPattern<U>) noexcept {}
+
+ T* allocate(std::size_t n) {
+ void* ptr = ::operator new(n * sizeof(T));
+ for (std::size_t i = 0; i < n * sizeof(T); ++i) {
+ *(reinterpret_cast<char*>(ptr) + i) = pattern;
+ }
+ return static_cast<T*>(ptr);
+ }
+
+ void deallocate(T* p, std::size_t) { return ::operator delete(static_cast<void*>(p)); }
+};
+
+void testNotValueInitialized() {
+ // single int
+ {
+ std::same_as<std::shared_ptr<int>> decltype(auto) ptr =
+ std::allocate_shared_for_overwrite<int>(AllocatorWithPattern<int>{});
+ assert(*(reinterpret_cast<char*>(ptr.get())) == AllocatorWithPattern<int>::pattern);
+ }
+
+ // bounded array int[N]
+ {
+ std::same_as<std::shared_ptr<int[2]>> decltype(auto) ptr =
+ std::allocate_shared_for_overwrite<int[2]>(AllocatorWithPattern<int>{});
+ assert(*(reinterpret_cast<char*>(&ptr[0])) == AllocatorWithPattern<int>::pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[1])) == AllocatorWithPattern<int>::pattern);
+ }
+
+ // unbounded array int[]
+ {
+ std::same_as<std::shared_ptr<int[]>> decltype(auto) ptr =
+ std::allocate_shared_for_overwrite<int[]>(AllocatorWithPattern<int>{}, 3);
+ assert(*(reinterpret_cast<char*>(&ptr[0])) == AllocatorWithPattern<int>::pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[1])) == AllocatorWithPattern<int>::pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[2])) == AllocatorWithPattern<int>::pattern);
+ }
+}
+
+void test() {
+ testTypeWithDefaultCtor();
+ testAllocatorOperationsCalled();
+ testNotValueInitialized();
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp
new file mode 100644
index 0000000..690a334
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp
@@ -0,0 +1,133 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: sanitizer-new-delete
+
+// template<class T>
+// shared_ptr<T> make_shared_for_overwrite(); // T is not U[]
+//
+// template<class T>
+// shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]
+
+#include <cassert>
+#include <concepts>
+#include <cstring>
+#include <memory>
+#include <stdlib.h>
+#include <utility>
+
+#include "test_macros.h"
+
+template <class T, class... Args>
+concept HasMakeSharedForOverwrite =
+ requires(Args&&... args) { std::make_shared_for_overwrite<T>(std::forward<Args>(args)...); };
+
+struct Foo {
+ int i;
+};
+
+// non array
+static_assert(HasMakeSharedForOverwrite<int>);
+static_assert(HasMakeSharedForOverwrite<Foo>);
+static_assert(!HasMakeSharedForOverwrite<int, int>);
+static_assert(!HasMakeSharedForOverwrite<Foo, Foo>);
+
+// bounded array
+static_assert(HasMakeSharedForOverwrite<int[2]>);
+static_assert(!HasMakeSharedForOverwrite<int[2], size_t>);
+static_assert(!HasMakeSharedForOverwrite<int[2], int>);
+static_assert(!HasMakeSharedForOverwrite<int[2], int, int>);
+static_assert(HasMakeSharedForOverwrite<Foo[2]>);
+static_assert(!HasMakeSharedForOverwrite<Foo[2], size_t>);
+static_assert(!HasMakeSharedForOverwrite<Foo[2], int>);
+static_assert(!HasMakeSharedForOverwrite<Foo[2], int, int>);
+
+// unbounded array
+static_assert(HasMakeSharedForOverwrite<int[], size_t>);
+static_assert(HasMakeSharedForOverwrite<Foo[], size_t>);
+static_assert(!HasMakeSharedForOverwrite<int[]>);
+static_assert(!HasMakeSharedForOverwrite<Foo[]>);
+static_assert(!HasMakeSharedForOverwrite<int[], size_t, int>);
+static_assert(!HasMakeSharedForOverwrite<Foo[], size_t, int>);
+
+constexpr char pattern = 0xDE;
+
+void* operator new(std::size_t count) {
+ void* ptr = malloc(count);
+ for (std::size_t i = 0; i < count; ++i) {
+ *(reinterpret_cast<char*>(ptr) + i) = pattern;
+ }
+ return ptr;
+}
+
+void* operator new[](std::size_t count) { return ::operator new(count); }
+
+void operator delete(void* ptr) noexcept { free(ptr); }
+
+void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
+
+struct WithDefaultConstructor {
+ int i;
+ constexpr WithDefaultConstructor() : i(5) {}
+};
+
+bool test() {
+ // single int
+ {
+ std::same_as<std::shared_ptr<int>> decltype(auto) ptr = std::make_shared_for_overwrite<int>();
+ assert(*(reinterpret_cast<char*>(ptr.get())) == pattern);
+ }
+
+ // bounded array int[N]
+ {
+ std::same_as<std::shared_ptr<int[2]>> decltype(auto) ptr = std::make_shared_for_overwrite<int[2]>();
+ assert(*(reinterpret_cast<char*>(&ptr[0])) == pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[1])) == pattern);
+ }
+
+ // unbounded array int[]
+ {
+ std::same_as<std::shared_ptr<int[]>> decltype(auto) ptr = std::make_shared_for_overwrite<int[]>(3);
+ assert(*(reinterpret_cast<char*>(&ptr[0])) == pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[1])) == pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[2])) == pattern);
+ }
+
+ // single with default constructor
+ {
+ std::same_as<std::shared_ptr<WithDefaultConstructor>> decltype(auto) ptr =
+ std::make_shared_for_overwrite<WithDefaultConstructor>();
+ assert(ptr->i == 5);
+ }
+
+ // bounded array with default constructor
+ {
+ std::same_as<std::shared_ptr<WithDefaultConstructor[2]>> decltype(auto) ptr =
+ std::make_shared_for_overwrite<WithDefaultConstructor[2]>();
+ assert(ptr[0].i == 5);
+ assert(ptr[1].i == 5);
+ }
+
+ // unbounded array with default constructor
+ {
+ std::same_as<std::shared_ptr<WithDefaultConstructor[]>> decltype(auto) ptrs =
+ std::make_shared_for_overwrite<WithDefaultConstructor[]>(3);
+ assert(ptrs[0].i == 5);
+ assert(ptrs[1].i == 5);
+ assert(ptrs[2].i == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.depr.verify.cpp b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.depr.verify.cpp
new file mode 100644
index 0000000..d8fa38a
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.depr.verify.cpp
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include <type_traits>
+
+std::aligned_storage<1, 1>::type s2; // expected-warning {{'aligned_storage<1, 1>' is deprecated}}
+std::aligned_storage<3, 1>::type s3; // expected-warning {{'aligned_storage<3, 1>' is deprecated}}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
index 890d0d68..35d1160 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp
@@ -13,6 +13,8 @@
// Issue 3034 added:
// The member typedef type shall be a trivial standard-layout type.
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
#include <type_traits>
#include <cstddef> // for std::max_align_t
#include "test_macros.h"
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.depr.verify.cpp b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.depr.verify.cpp
new file mode 100644
index 0000000..f3445ef
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.depr.verify.cpp
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include <type_traits>
+
+std::aligned_union<1, int>::type s2; // expected-warning {{'aligned_union<1, int>' is deprecated}}
+std::aligned_union<3, char, char>::type s3; // expected-warning {{'aligned_union<3, char, char>' is deprecated}}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp
index ff62845..73ca065 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_union.pass.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
// type_traits
// aligned_union<size_t Len, class ...Types>
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp
new file mode 100644
index 0000000..5f4fbd4
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: sanitizer-new-delete
+
+// template<class T>
+// constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not array
+//
+// template<class T>
+// constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[]
+
+// Test the object is not value initialized
+
+#include <cassert>
+#include <concepts>
+#include <cstddef>
+#include <memory>
+#include <stdlib.h>
+
+constexpr char pattern = 0xDE;
+
+void* operator new(std::size_t count) {
+ void* ptr = malloc(count);
+ for (std::size_t i = 0; i < count; ++i) {
+ *(reinterpret_cast<char*>(ptr) + i) = pattern;
+ }
+ return ptr;
+}
+
+void* operator new[](std::size_t count) { return ::operator new(count); }
+
+void operator delete(void* ptr) noexcept { free(ptr); }
+
+void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
+
+void test() {
+ {
+ std::same_as<std::unique_ptr<int>> auto ptr = std::make_unique_for_overwrite<int>();
+ assert(*(reinterpret_cast<char*>(ptr.get())) == pattern);
+ }
+ {
+ std::same_as<std::unique_ptr<int[]>> auto ptr = std::make_unique_for_overwrite<int[]>(3);
+ assert(*(reinterpret_cast<char*>(&ptr[0])) == pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[1])) == pattern);
+ assert(*(reinterpret_cast<char*>(&ptr[2])) == pattern);
+ }
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.pass.cpp
new file mode 100644
index 0000000..3f86904
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.pass.cpp
@@ -0,0 +1,149 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// template<class T>
+// constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not array
+//
+// template<class T>
+// constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[]
+//
+// template<class T, class... Args>
+// unspecified make_unique_for_overwrite(Args&&...) = delete; // T is U[N]
+
+#include <cassert>
+#include <concepts>
+#include <cstring>
+#include <memory>
+#include <utility>
+
+#include "test_macros.h"
+
+template <class T, class... Args>
+concept HasMakeUniqueForOverwrite =
+ requires(Args&&... args) { std::make_unique_for_overwrite<T>(std::forward<Args>(args)...); };
+
+struct Foo {
+ int i;
+};
+
+// template<class T>
+// constexpr unique_ptr<T> make_unique_for_overwrite();
+static_assert(HasMakeUniqueForOverwrite<int>);
+static_assert(HasMakeUniqueForOverwrite<Foo>);
+static_assert(!HasMakeUniqueForOverwrite<int, int>);
+static_assert(!HasMakeUniqueForOverwrite<Foo, Foo>);
+
+// template<class T>
+// constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);
+static_assert(HasMakeUniqueForOverwrite<int[], size_t>);
+static_assert(HasMakeUniqueForOverwrite<Foo[], size_t>);
+static_assert(!HasMakeUniqueForOverwrite<int[]>);
+static_assert(!HasMakeUniqueForOverwrite<Foo[]>);
+static_assert(!HasMakeUniqueForOverwrite<int[], size_t, int>);
+static_assert(!HasMakeUniqueForOverwrite<Foo[], size_t, int>);
+
+// template<class T, class... Args>
+// unspecified make_unique_for_overwrite(Args&&...) = delete;
+static_assert(!HasMakeUniqueForOverwrite<int[2]>);
+static_assert(!HasMakeUniqueForOverwrite<int[2], size_t>);
+static_assert(!HasMakeUniqueForOverwrite<int[2], int>);
+static_assert(!HasMakeUniqueForOverwrite<int[2], int, int>);
+static_assert(!HasMakeUniqueForOverwrite<Foo[2]>);
+static_assert(!HasMakeUniqueForOverwrite<Foo[2], size_t>);
+static_assert(!HasMakeUniqueForOverwrite<Foo[2], int>);
+static_assert(!HasMakeUniqueForOverwrite<Foo[2], int, int>);
+
+struct WithDefaultConstructor {
+ int i;
+ constexpr WithDefaultConstructor() : i(5) {}
+};
+
+TEST_CONSTEXPR_CXX23 bool test() {
+ // single int
+ {
+ std::same_as<std::unique_ptr<int>> decltype(auto) ptr = std::make_unique_for_overwrite<int>();
+ // memory is available for write, otherwise constexpr test would fail
+ *ptr = 5;
+ }
+
+ // unbounded array int[]
+ {
+ std::same_as<std::unique_ptr<int[]>> decltype(auto) ptrs = std::make_unique_for_overwrite<int[]>(3);
+
+ // memory is available for write, otherwise constexpr test would fail
+ ptrs[0] = 3;
+ ptrs[1] = 4;
+ ptrs[2] = 5;
+ }
+
+ // single with default constructor
+ {
+ std::same_as<std::unique_ptr<WithDefaultConstructor>> decltype(auto) ptr =
+ std::make_unique_for_overwrite<WithDefaultConstructor>();
+ assert(ptr->i == 5);
+ }
+
+ // unbounded array with default constructor
+ {
+ std::same_as<std::unique_ptr<WithDefaultConstructor[]>> decltype(auto) ptrs =
+ std::make_unique_for_overwrite<WithDefaultConstructor[]>(3);
+ assert(ptrs[0].i == 5);
+ assert(ptrs[1].i == 5);
+ assert(ptrs[2].i == 5);
+ }
+
+ return true;
+}
+
+// The standard specifically says to use `new (p) T`, which means that we should pick up any
+// custom in-class operator new if there is one.
+struct WithCustomNew {
+ inline static bool customNewCalled = false;
+ inline static bool customNewArrCalled = false;
+
+ static void* operator new(size_t n) {
+ customNewCalled = true;
+ return ::operator new(n);
+ ;
+ }
+
+ static void* operator new[](size_t n) {
+ customNewArrCalled = true;
+ return ::operator new[](n);
+ }
+};
+
+void testCustomNew() {
+ // single with custom operator new
+ {
+ [[maybe_unused]] std::same_as<std::unique_ptr<WithCustomNew>> decltype(auto) ptr =
+ std::make_unique_for_overwrite<WithCustomNew>();
+
+ assert(WithCustomNew::customNewCalled);
+ }
+
+ // unbounded array with custom operator new
+ {
+ [[maybe_unused]] std::same_as<std::unique_ptr<WithCustomNew[]>> decltype(auto) ptr =
+ std::make_unique_for_overwrite<WithCustomNew[]>(3);
+
+ assert(WithCustomNew::customNewArrCalled);
+ }
+}
+
+int main(int, char**) {
+ test();
+ testCustomNew();
+#if TEST_STD_VER >= 23
+ static_assert(test());
+#endif
+
+ return 0;
+}
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp
index f044e7a..ece7594 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate.pass.cpp
@@ -31,7 +31,10 @@
template <size_t S, size_t Align>
void testForSizeAndAlign() {
- using T = typename std::aligned_storage<S, Align>::type;
+ struct T {
+ alignas(Align) std::byte buf[S];
+ };
+
TestResource R;
std::pmr::polymorphic_allocator<T> a(&R);
@@ -47,7 +50,10 @@
#ifndef TEST_HAS_NO_EXCEPTIONS
template <size_t S>
void testAllocForSizeThrows() {
- using T = typename std::aligned_storage<S>::type;
+ struct T {
+ std::byte buf[S];
+ };
+
using Alloc = std::pmr::polymorphic_allocator<T>;
using Traits = std::allocator_traits<Alloc>;
NullResource R;
diff --git a/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp b/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp
index 7068c75..e7884c9 100644
--- a/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp
+++ b/third_party/llvm-project/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/deallocate.pass.cpp
@@ -28,7 +28,9 @@
template <size_t S, size_t Align>
void testForSizeAndAlign() {
- using T = typename std::aligned_storage<S, Align>::type;
+ struct T {
+ alignas(Align) std::byte buf[S];
+ };
TestResource R;
std::pmr::polymorphic_allocator<T> a(&R);
diff --git a/third_party/llvm-project/libcxx/test/support/assert_macros.h b/third_party/llvm-project/libcxx/test/support/assert_macros.h
new file mode 100644
index 0000000..5d5d810
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/support/assert_macros.h
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 TEST_SUPPORT_ASSERT_MACROS_H
+#define TEST_SUPPORT_ASSERT_MACROS_H
+
+// Contains a set of validation macros.
+//
+// Note these test were added after C++20 was well supported by the compilers
+// used. To make the implementation simple the macros require C++20 or newer.
+// It's not expected that existing tests start to use these new macros.
+//
+// These macros are an alternative to using assert. The differences are:
+// - The assert message isn't localized.
+// - It's possible to log additional information. This is useful when the
+// function asserting is a helper function. In these cases the assertion
+// failure contains to little information to find the issue. For example, in
+// the format functions, the really useful information is the actual output,
+// the expected output, and the format string used. These macros allow
+// logging additional arguments.
+
+#include "test_macros.h"
+
+#include <cstdio>
+#include <cstdlib>
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+# include <sstream>
+#endif
+
+#if TEST_STD_VER > 17
+
+# ifndef TEST_HAS_NO_LOCALIZATION
+template <class T>
+concept test_char_streamable = requires(T&& value) { std::stringstream{} << std::forward<T>(value); };
+# endif
+
+// If possible concatenates message for the assertion function, else returns a
+// default message. Not being able to stream is not considered and error. For
+// example, streaming to std::wcerr doesn't work properly in the CI. Therefore
+// the formatting tests should only stream to std::string_string.
+template <class... Args>
+std::string test_concat_message([[maybe_unused]] Args&&... args) {
+# ifndef TEST_HAS_NO_LOCALIZATION
+ if constexpr ((test_char_streamable<Args> && ...)) {
+ std::stringstream sstr;
+ ((sstr << std::forward<Args>(args)), ...);
+ return sstr.str();
+ } else
+# endif
+ return "Message discarded since it can't be streamed to std::cerr.\n";
+}
+
+#endif // TEST_STD_VER > 17
+
+// Logs the error and calls exit.
+//
+// It shows a generic assert like message including a custom message. This
+// message should end with a newline.
+[[noreturn]] void test_log_error(const char* condition, const char* file, int line, std::string&& message) {
+ const char* msg = condition ? "Assertion failure: " : "Unconditional failure:";
+ std::fprintf(stderr, "%s%s %s %d\n%s", msg, condition, file, line, message.c_str());
+ exit(EXIT_FAILURE);
+}
+
+inline void test_fail(const char* file, int line, std::string&& message) {
+ test_log_error("", file, line, std::move(message));
+}
+
+inline void test_require(bool condition, const char* condition_str, const char* file, int line, std::string&& message) {
+ if (condition)
+ return;
+
+ test_log_error(condition_str, file, line, std::move(message));
+}
+
+inline void test_libcpp_require(
+ [[maybe_unused]] bool condition,
+ [[maybe_unused]] const char* condition_str,
+ [[maybe_unused]] const char* file,
+ [[maybe_unused]] int line,
+ [[maybe_unused]] std::string&& message) {
+#if defined(_LIBCPP_VERSION)
+ test_require(condition, condition_str, file, line, std::move(message));
+#endif
+}
+
+// assert(false) replacement
+#define TEST_FAIL(MSG) ::test_fail(__FILE__, __LINE__, MSG)
+
+// assert replacement.
+#define TEST_REQUIRE(CONDITION, MSG) ::test_require(CONDITION, #CONDITION, __FILE__, __LINE__, MSG)
+
+// LIBCPP_ASSERT replacement
+//
+// This requirement is only tested when the test suite is used for libc++.
+// This allows checking libc++ specific requirements, for example the error
+// messages of exceptions.
+#define TEST_LIBCPP_REQUIRE(CONDITION, MSG) ::test_libcpp_require(CONDITION, #CONDITION, __FILE__, __LINE__, MSG)
+
+#endif // TEST_SUPPORT_ASSERT_MACROS_H
diff --git a/third_party/llvm-project/libcxx/test/support/format.functions.common.h b/third_party/llvm-project/libcxx/test/support/format.functions.common.h
index 14faf3a..769b1af 100644
--- a/third_party/llvm-project/libcxx/test/support/format.functions.common.h
+++ b/third_party/llvm-project/libcxx/test/support/format.functions.common.h
@@ -13,6 +13,10 @@
#include <algorithm>
#include <charconv>
#include <format>
+#include <ranges>
+#include <string>
+#include <string_view>
+#include <vector>
#include "make_string.h"
@@ -129,4 +133,57 @@
}
};
+// Creates format string for the invalid types.
+//
+// valid contains a list of types that are valid.
+// - The type ?s is the only type requiring 2 characters, use S for that type.
+// - Whether n is a type or not depends on the context, is is always used.
+//
+// The return value is a collection of basic_strings, instead of
+// basic_string_views since the values are temporaries.
+namespace detail {
+template <class CharT, size_t N>
+std::basic_string<CharT> get_colons() {
+ static std::basic_string<CharT> result(N, CharT(':'));
+ return result;
+}
+
+constexpr std::string_view get_format_types() {
+ return "aAbBcdeEfFgGopsxX"
+#if TEST_STD_VER > 20
+ "?"
+#endif
+ ;
+}
+
+template <class CharT, /*format_types types,*/ size_t N>
+std::vector<std::basic_string<CharT>> fmt_invalid_types(std::string_view valid) {
+ // std::ranges::to is not available in C++20.
+ std::vector<std::basic_string<CharT>> result;
+ std::ranges::copy(
+ get_format_types() | std::views::filter([&](char type) { return valid.find(type) == std::string_view::npos; }) |
+ std::views::transform([&](char type) { return std::format(SV("{{{}{}}}"), get_colons<CharT, N>(), type); }),
+ std::back_inserter(result));
+ return result;
+}
+
+} // namespace detail
+
+// Creates format string for the invalid types.
+//
+// valid contains a list of types that are valid.
+//
+// The return value is a collection of basic_strings, instead of
+// basic_string_views since the values are temporaries.
+template <class CharT>
+std::vector<std::basic_string<CharT>> fmt_invalid_types(std::string_view valid) {
+ return detail::fmt_invalid_types<CharT, 1>(valid);
+}
+
+// Like fmt_invalid_types but when the format spec is for an underlying formatter.
+template <class CharT>
+std::vector<std::basic_string<CharT>> fmt_invalid_nested_types(std::string_view valid) {
+ return detail::fmt_invalid_types<CharT, 2>(valid);
+}
+
#endif // TEST_SUPPORT_FORMAT_FUNCTIONS_COMMON_H
diff --git a/third_party/llvm-project/libcxx/test/support/test_iterators.h b/third_party/llvm-project/libcxx/test/support/test_iterators.h
index bc197e6..588a24f 100644
--- a/third_party/llvm-project/libcxx/test/support/test_iterators.h
+++ b/third_party/llvm-project/libcxx/test/support/test_iterators.h
@@ -1005,6 +1005,84 @@
} // namespace adl
+template <class T>
+class rvalue_iterator {
+public:
+ using iterator_category = std::input_iterator_tag;
+ using iterator_concept = std::random_access_iterator_tag;
+ using difference_type = std::ptrdiff_t;
+ using reference = T&&;
+ using value_type = T;
+
+ rvalue_iterator() = default;
+ constexpr rvalue_iterator(T* it) : it_(it) {}
+
+ constexpr reference operator*() const { return std::move(*it_); }
+
+ constexpr rvalue_iterator& operator++() {
+ ++it_;
+ return *this;
+ }
+
+ constexpr rvalue_iterator operator++(int) {
+ auto tmp = *this;
+ ++it_;
+ return tmp;
+ }
+
+ constexpr rvalue_iterator& operator--() {
+ --it_;
+ return *this;
+ }
+
+ constexpr rvalue_iterator operator--(int) {
+ auto tmp = *this;
+ --it_;
+ return tmp;
+ }
+
+ constexpr rvalue_iterator operator+(difference_type n) const {
+ auto tmp = *this;
+ tmp.it += n;
+ return tmp;
+ }
+
+ constexpr friend rvalue_iterator operator+(difference_type n, rvalue_iterator iter) {
+ iter += n;
+ return iter;
+ }
+
+ constexpr rvalue_iterator operator-(difference_type n) const {
+ auto tmp = *this;
+ tmp.it -= n;
+ return tmp;
+ }
+
+ constexpr difference_type operator-(const rvalue_iterator& other) const { return it_ - other.it_; }
+
+ constexpr rvalue_iterator& operator+=(difference_type n) {
+ it_ += n;
+ return *this;
+ }
+
+ constexpr rvalue_iterator& operator-=(difference_type n) {
+ it_ -= n;
+ return *this;
+ }
+
+ constexpr reference operator[](difference_type n) const { return std::move(it_[n]); }
+
+ auto operator<=>(const rvalue_iterator&) const noexcept = default;
+
+private:
+ T* it_;
+};
+
+template <class T>
+rvalue_iterator(T*) -> rvalue_iterator<T>;
+
+static_assert(std::random_access_iterator<rvalue_iterator<int*>>);
+
// Proxy
// ======================================================================
// Proxy that can wrap a value or a reference. It simulates C++23's tuple
@@ -1285,6 +1363,21 @@
static_assert(std::indirectly_writable<ProxyIterator<int*>, Proxy<int>>);
static_assert(std::indirectly_writable<ProxyIterator<int*>, Proxy<int&>>);
+template <class Iter>
+using Cpp20InputProxyIterator = ProxyIterator<cpp20_input_iterator<Iter>>;
+
+template <class Iter>
+using ForwardProxyIterator = ProxyIterator<forward_iterator<Iter>>;
+
+template <class Iter>
+using BidirectionalProxyIterator = ProxyIterator<bidirectional_iterator<Iter>>;
+
+template <class Iter>
+using RandomAccessProxyIterator = ProxyIterator<random_access_iterator<Iter>>;
+
+template <class Iter>
+using ContiguousProxyIterator = ProxyIterator<contiguous_iterator<Iter>>;
+
template <class BaseSent>
struct ProxySentinel {
BaseSent base_;
diff --git a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
index f5539a9..adceee2 100644
--- a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
+++ b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
@@ -6,11 +6,13 @@
find_package(Clang 16)
set(SOURCES
+ abi_tag_on_virtual.cpp
+ hide_from_abi.cpp
robust_against_adl.cpp
- libcpp_module.cpp
qualify_declval.cpp
- )
+ libcpp_module.cpp
+ )
if(NOT Clang_FOUND)
message(STATUS "Could not find a suitable version of the Clang development package;
diff --git a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/abi_tag_on_virtual.cpp b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/abi_tag_on_virtual.cpp
new file mode 100644
index 0000000..f186617
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/abi_tag_on_virtual.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+#include "clang-tidy/ClangTidyModuleRegistry.h"
+
+#include "abi_tag_on_virtual.hpp"
+
+// This clang-tidy check ensures that we don't place an abi_tag attribute on
+// virtual functions. This can happen by mistakenly applying a macro like
+// _LIBCPP_HIDE_FROM_ABI on a virtual function.
+//
+// The problem is that arm64e pointer authentication extensions use the mangled
+// name of the function to sign the function pointer in the vtable, which means
+// that the ABI tag effectively influences how the pointers are signed.
+//
+// This can lead to PAC failures when passing an object that holds one of these
+// pointers in its vtable across an ABI boundary if the two sides have been compiled
+// with different versions of libc++: one side will sign the pointer using one function
+// mangling (with one ABI tag), and the other side will authenticate the pointer expecting
+// it to have a different mangled name due to the ABI tag being different, which will crash.
+//
+// This test ensures that we don't re-introduce this issue in the code base.
+
+namespace libcpp {
+abi_tag_on_virtual::abi_tag_on_virtual(llvm::StringRef name, clang::tidy::ClangTidyContext* context)
+ : clang::tidy::ClangTidyCheck(name, context) {}
+
+void abi_tag_on_virtual::registerMatchers(clang::ast_matchers::MatchFinder* finder) {
+ using namespace clang::ast_matchers;
+ finder->addMatcher(cxxMethodDecl(isVirtual(), hasAttr(clang::attr::AbiTag)).bind("abi_tag_on_virtual"), this);
+}
+
+void abi_tag_on_virtual::check(const clang::ast_matchers::MatchFinder::MatchResult& result) {
+ if (const auto* call = result.Nodes.getNodeAs<clang::CXXMethodDecl>("abi_tag_on_virtual"); call != nullptr) {
+ diag(call->getBeginLoc(),
+ "_LIBCPP_HIDE_FROM_ABI should not be used on virtual functions to avoid problems with pointer authentication. "
+ "Use _LIBCPP_HIDE_FROM_ABI_VIRTUAL instead.");
+ }
+}
+} // namespace libcpp
diff --git a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/abi_tag_on_virtual.hpp b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/abi_tag_on_virtual.hpp
new file mode 100644
index 0000000..9a8d821
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/abi_tag_on_virtual.hpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+
+namespace libcpp {
+class abi_tag_on_virtual : public clang::tidy::ClangTidyCheck {
+public:
+ abi_tag_on_virtual(llvm::StringRef, clang::tidy::ClangTidyContext*);
+ void registerMatchers(clang::ast_matchers::MatchFinder*) override;
+ void check(const clang::ast_matchers::MatchFinder::MatchResult&) override;
+};
+} // namespace libcpp
diff --git a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp
new file mode 100644
index 0000000..9ae2536
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/hide_from_abi.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+#include "clang-tidy/ClangTidyModuleRegistry.h"
+
+#include "hide_from_abi.hpp"
+
+namespace libcpp {
+hide_from_abi::hide_from_abi(llvm::StringRef name, clang::tidy::ClangTidyContext* context)
+ : clang::tidy::ClangTidyCheck(name, context) {}
+
+void hide_from_abi::registerMatchers(clang::ast_matchers::MatchFinder* finder) {
+ using namespace clang::ast_matchers;
+ finder->addMatcher(
+ functionDecl(
+ unless(anyOf(
+ // These functions can't be marked `[[gnu::always_inline]]` for various reasons,
+ // so we can't mark them `_LIBCPP_HIDE_FROM_ABI`. These functions are ignored in
+ // all namespaces. Checking the qualified name is a lot harder and these names
+ // should result in very few (if any) false-negatives. This is also just a
+ // temporary work-around until we can mark functions as HIDE_FROM_ABI without
+ // having to add `[[gnu::always_inline]]` with GCC.
+ hasAnyName("__introsort",
+ "__inplace_merge",
+ "__libcpp_snprintf_l",
+ "__libcpp_asprintf_l",
+ "__libcpp_sscanf_l",
+ "__tree_sub_invariant",
+ "__stable_sort_move",
+ "__stable_sort",
+ "__stable_partition",
+ "__lock_first",
+ "__stable_partition_impl"),
+ hasAttr(clang::attr::Visibility),
+ hasAttr(clang::attr::AbiTag),
+ cxxMethodDecl(), // We have explicitly instantiated classes and some of their methods don't have these attributes
+ isDeleted(),
+ isConsteval())),
+ isDefinition())
+ .bind("missing_hide_from_abi"),
+ this);
+}
+
+void hide_from_abi::check(const clang::ast_matchers::MatchFinder::MatchResult& result) {
+ if (const auto* call = result.Nodes.getNodeAs<clang::FunctionDecl>("missing_hide_from_abi"); call != nullptr) {
+ diag(call->getBeginLoc(), "_LIBCPP_HIDE_FROM_ABI is missing");
+ }
+}
+} // namespace libcpp
diff --git a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/hide_from_abi.hpp b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/hide_from_abi.hpp
new file mode 100644
index 0000000..d73b510
--- /dev/null
+++ b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/hide_from_abi.hpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+
+namespace libcpp {
+class hide_from_abi : public clang::tidy::ClangTidyCheck {
+public:
+ hide_from_abi(llvm::StringRef, clang::tidy::ClangTidyContext*);
+ void registerMatchers(clang::ast_matchers::MatchFinder*) override;
+ void check(const clang::ast_matchers::MatchFinder::MatchResult&) override;
+};
+} // namespace libcpp
diff --git a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
index 60d200c..f1dfbf5 100644
--- a/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
+++ b/third_party/llvm-project/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
@@ -8,6 +8,9 @@
#include "clang-tidy/ClangTidyModule.h"
#include "clang-tidy/ClangTidyModuleRegistry.h"
+
+#include "abi_tag_on_virtual.hpp"
+#include "hide_from_abi.hpp"
#include "robust_against_adl.hpp"
#include "qualify_declval.hpp"
@@ -15,6 +18,8 @@
class LibcxxTestModule : public clang::tidy::ClangTidyModule {
public:
void addCheckFactories(clang::tidy::ClangTidyCheckFactories& check_factories) override {
+ check_factories.registerCheck<libcpp::abi_tag_on_virtual>("libcpp-avoid-abi-tag-on-virtual");
+ check_factories.registerCheck<libcpp::hide_from_abi>("libcpp-hide-from-abi");
check_factories.registerCheck<libcpp::robust_against_adl_check>("libcpp-robust-against-adl");
check_factories.registerCheck<libcpp::qualify_declval>("libcpp-qualify-declval");
}
diff --git a/third_party/llvm-project/libcxx/utils/ci/Dockerfile b/third_party/llvm-project/libcxx/utils/ci/Dockerfile
index 67c94bd..2a2e8e5 100644
--- a/third_party/llvm-project/libcxx/utils/ci/Dockerfile
+++ b/third_party/llvm-project/libcxx/utils/ci/Dockerfile
@@ -91,9 +91,6 @@
# TODO LLVM16 Don't install llvm-16-dev explicitly
RUN apt-get update && apt-get install -y llvm-16-dev libclang-16-dev
-# Install clang-tools
-RUN apt-get update && apt-get install -y clang-tools-$(($LLVM_HEAD_VERSION - 1)) clang-tools-$LLVM_HEAD_VERSION
-
# Install the most recent GCC, like clang install the previous version as a transition.
ENV GCC_LATEST_VERSION=12
RUN apt-get update && apt install -y gcc-$((GCC_LATEST_VERSION - 1)) g++-$((GCC_LATEST_VERSION - 1))
diff --git a/third_party/llvm-project/libcxx/utils/ci/buildkite-pipeline.yml b/third_party/llvm-project/libcxx/utils/ci/buildkite-pipeline.yml
index b189343..c6339e4 100644
--- a/third_party/llvm-project/libcxx/utils/ci/buildkite-pipeline.yml
+++ b/third_party/llvm-project/libcxx/utils/ci/buildkite-pipeline.yml
@@ -107,6 +107,7 @@
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
+ ENABLE_CLANG_TIDY: "On"
agents:
queue: "libcxx-builders"
os: "linux"
@@ -141,6 +142,7 @@
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
+ ENABLE_CLANG_TIDY: "On"
agents:
queue: "libcxx-builders"
os: "linux"
@@ -158,6 +160,7 @@
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
+ ENABLE_CLANG_TIDY: "On"
agents:
queue: "libcxx-builders"
os: "linux"
@@ -180,6 +183,7 @@
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
+ ENABLE_CLANG_TIDY: "On"
agents:
queue: "libcxx-builders"
os: "linux"
@@ -197,6 +201,7 @@
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
+ ENABLE_CLANG_TIDY: "On"
agents:
queue: "libcxx-builders"
os: "linux"
@@ -214,6 +219,7 @@
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
+ ENABLE_CLANG_TIDY: "On"
agents:
queue: "libcxx-builders"
os: "linux"
@@ -436,23 +442,6 @@
limit: 2
timeout_in_minutes: 120
- - label: "No transitive includes"
- command: "libcxx/utils/ci/run-buildbot generic-no-transitive-includes"
- artifact_paths:
- - "**/test-results.xml"
- - "**/*.abilist"
- env:
- CC: "clang-${LLVM_HEAD_VERSION}"
- CXX: "clang++-${LLVM_HEAD_VERSION}"
- agents:
- queue: "libcxx-builders"
- os: "linux"
- retry:
- automatic:
- - exit_status: -1 # Agent was lost
- limit: 2
- timeout_in_minutes: 120
-
- label: "With LLVM's libunwind"
command: "libcxx/utils/ci/run-buildbot generic-with_llvm_unwinder"
artifact_paths:
diff --git a/third_party/llvm-project/libcxx/utils/ci/run-buildbot b/third_party/llvm-project/libcxx/utils/ci/run-buildbot
index 3ee025c..8ec401c 100755
--- a/third_party/llvm-project/libcxx/utils/ci/run-buildbot
+++ b/third_party/llvm-project/libcxx/utils/ci/run-buildbot
@@ -42,6 +42,9 @@
When the value is omitted, it defaults to
'git-clang-format'. This variable or its fallback must work
when running the 'format' builder.
+
+ENABLE_CLANG_TIDY Whether to compile and run clang-tidy checks. This variable
+ is optional
EOF
}
@@ -90,6 +93,10 @@
rm -rf "${BUILD_DIR}"
}
+if [ -z "${ENABLE_CLANG_TIDY}" ]; then
+ ENABLE_CLANG_TIDY=Off
+fi
+
function generate-cmake-base() {
echo "--- Generating CMake"
${CMAKE} \
@@ -101,6 +108,7 @@
-DLIBCXX_ENABLE_WERROR=YES \
-DLIBCXXABI_ENABLE_WERROR=YES \
-DLIBUNWIND_ENABLE_WERROR=YES \
+ -DLIBCXX_ENABLE_CLANG_TIDY=${ENABLE_CLANG_TIDY} \
-DLLVM_LIT_ARGS="-sv --show-unsupported --xunit-xml-output test-results.xml --timeout=1500 --time-tests" \
"${@}"
}
@@ -226,43 +234,37 @@
#
generic-cxx03)
clean
- generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx03.cmake" \
- -DLIBCXX_ENABLE_CLANG_TIDY=ON
+ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx03.cmake"
check-runtimes
check-abi-list
;;
generic-cxx11)
clean
- generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake" \
- -DLIBCXX_ENABLE_CLANG_TIDY=ON
+ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx11.cmake"
check-runtimes
check-abi-list
;;
generic-cxx14)
clean
- generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx14.cmake" \
- -DLIBCXX_ENABLE_CLANG_TIDY=ON
+ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx14.cmake"
check-runtimes
check-abi-list
;;
generic-cxx17)
clean
- generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx17.cmake" \
- -DLIBCXX_ENABLE_CLANG_TIDY=ON
+ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx17.cmake"
check-runtimes
check-abi-list
;;
generic-cxx20)
clean
- generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx20.cmake" \
- -DLIBCXX_ENABLE_CLANG_TIDY=ON
+ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx20.cmake"
check-runtimes
check-abi-list
;;
generic-cxx2b)
clean
- generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx2b.cmake" \
- -DLIBCXX_ENABLE_CLANG_TIDY=ON
+ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-cxx2b.cmake"
check-runtimes
check-abi-list
;;
@@ -358,11 +360,6 @@
check-runtimes
# We don't check the ABI lists because the debug mode ABI is not stable
;;
-generic-no-transitive-includes)
- clean
- generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-no-transitive-includes.cmake"
- check-runtimes
-;;
generic-with_llvm_unwinder)
clean
generate-cmake -DLIBCXXABI_USE_LLVM_UNWINDER=ON
diff --git a/third_party/llvm-project/libcxx/utils/generate_extended_grapheme_cluster_table.py b/third_party/llvm-project/libcxx/utils/generate_extended_grapheme_cluster_table.py
index 7dd2016..2762c01 100755
--- a/third_party/llvm-project/libcxx/utils/generate_extended_grapheme_cluster_table.py
+++ b/third_party/llvm-project/libcxx/utils/generate_extended_grapheme_cluster_table.py
@@ -99,7 +99,7 @@
/// - https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
///
/// The data has 3 values
-/// - bits [0, 3] The property. One of the values generated form the datafiles
+/// - bits [0, 3] The property. One of the values generated from the datafiles
/// of \\ref __property
/// - bits [4, 10] The size of the range.
/// - bits [11, 31] The lower bound code point of the range. The upper bound of
diff --git a/third_party/llvm-project/libcxx/utils/generate_feature_test_macro_components.py b/third_party/llvm-project/libcxx/utils/generate_feature_test_macro_components.py
index 05a02b0..69cb942 100755
--- a/third_party/llvm-project/libcxx/utils/generate_feature_test_macro_components.py
+++ b/third_party/llvm-project/libcxx/utils/generate_feature_test_macro_components.py
@@ -534,7 +534,7 @@
"headers": ["iomanip"],
}, {
"name": "__cpp_lib_ranges",
- "values": { "c++20": 201811 },
+ "values": { "c++20": 202106 },
"headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
}, {
"name": "__cpp_lib_ranges_chunk",
diff --git a/third_party/llvm-project/libcxx/utils/libcxx/test/features.py b/third_party/llvm-project/libcxx/utils/libcxx/test/features.py
index ad2089b..c2745b9 100644
--- a/third_party/llvm-project/libcxx/utils/libcxx/test/features.py
+++ b/third_party/llvm-project/libcxx/utils/libcxx/test/features.py
@@ -159,9 +159,6 @@
Feature(name='has-clang-tidy',
when=lambda cfg: _getSuitableClangTidy(cfg) is not None,
actions=[AddSubstitution('%{clang-tidy}', lambda cfg: _getSuitableClangTidy(cfg))]),
- Feature(name='has-clang-query',
- when=lambda cfg: runScriptExitCode(cfg, ['clang-query-15 --version']) == 0,
- actions=[AddSubstitution('%{clang-query}', 'clang-query-15')]),
Feature(name='apple-clang', when=_isAppleClang),
Feature(name=lambda cfg: 'apple-clang-{__clang_major__}'.format(**compilerMacros(cfg)), when=_isAppleClang),
@@ -277,7 +274,8 @@
"""), actions=[AddCompileFlag('-DTEST_WINDOWS_DLL')]),
Feature(name='linux', when=lambda cfg: '__linux__' in compilerMacros(cfg)),
Feature(name='netbsd', when=lambda cfg: '__NetBSD__' in compilerMacros(cfg)),
- Feature(name='freebsd', when=lambda cfg: '__FreeBSD__' in compilerMacros(cfg))
+ Feature(name='freebsd', when=lambda cfg: '__FreeBSD__' in compilerMacros(cfg)),
+ Feature(name='LIBCXX-FREEBSD-FIXME', when=lambda cfg: '__FreeBSD__' in compilerMacros(cfg)),
]
# Add features representing the build host platform name.
diff --git a/third_party/llvm-project/libcxxabi/METADATA b/third_party/llvm-project/libcxxabi/METADATA
index 869b0ad..e1baa1a 100644
--- a/third_party/llvm-project/libcxxabi/METADATA
+++ b/third_party/llvm-project/libcxxabi/METADATA
@@ -3,16 +3,16 @@
"Filtered subtree at third_party/llvm-project/libcxxabi."
third_party {
- url {
- type: LOCAL_SOURCE
- value: "https://cobalt.googlesource.com/third_party/llvm-project/libcxxabi_filtered_mirror"
+ identifier {
+ type: "ChromiumVersion"
+ value: "111.0.5563.150" # from https://chromereleases.googleblog.com/2023/03/stable-channel-update-for-chromeos_29.html
}
- url {
- type: GIT
- value: "https://github.com/llvm/llvm-project.git"
+ identifier {
+ type: "Git"
+ value: "https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git"
+ version: "d520d582aa710cc0a4635620c02c5dbc187deb4f"
+ # from https://chromium.googlesource.com/chromium/src/+/111.0.5563.150/DEPS#466
}
- # Closest commit hash to llvm-project's 39da55e8f548a11f7dadefa73ea73d809a5f1729.
- version: "ae56bdc07c05dc3920476eef7adad00fd2548782"
last_upgrade_date {
year: 2023
month: 1
diff --git a/third_party/llvm-project/libcxxabi/test/thread_local_destruction_order.pass.cpp b/third_party/llvm-project/libcxxabi/test/thread_local_destruction_order.pass.cpp
index e256360..9daf966 100644
--- a/third_party/llvm-project/libcxxabi/test/thread_local_destruction_order.pass.cpp
+++ b/third_party/llvm-project/libcxxabi/test/thread_local_destruction_order.pass.cpp
@@ -9,6 +9,8 @@
// UNSUPPORTED: c++03
// UNSUPPORTED: no-threads
+// XFAIL: LIBCXX-FREEBSD-FIXME
+
#include <cassert>
#include <thread>
diff --git a/third_party/llvm-project/libunwind/METADATA b/third_party/llvm-project/libunwind/METADATA
index d343e36..a6257bc 100644
--- a/third_party/llvm-project/libunwind/METADATA
+++ b/third_party/llvm-project/libunwind/METADATA
@@ -3,16 +3,16 @@
"Filtered subtree at third_party/llvm-project/libunwind."
third_party {
- url {
- type: LOCAL_SOURCE
- value: "https://cobalt.googlesource.com/third_party/llvm-project/libunwind_filtered_mirror"
+ identifier {
+ type: "ChromiumVersion"
+ value: "111.0.5563.150" # from https://chromereleases.googleblog.com/2023/03/stable-channel-update-for-chromeos_29.html
}
- url {
- type: GIT
- value: "https://github.com/llvm/llvm-project.git"
+ identifier {
+ type: "Git"
+ value: "https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git"
+ version: "e95b94b74d26f8387d4fb03a687a2fab0ed8e91c"
+ # from https://chromium.googlesource.com/chromium/src/+/111.0.5563.150/DEPS#470
}
- # Closest commit hash to llvm-project's 39da55e8f548a11f7dadefa73ea73d809a5f1729.
- version: "4cc5f231b5b0174cdd5b0f7fc3be5a595be0009d"
last_upgrade_date {
year: 2023
month: 1
diff --git a/third_party/llvm-project/libunwind/docs/conf.py b/third_party/llvm-project/libunwind/docs/conf.py
index 404bcb0..307ece6 100644
--- a/third_party/llvm-project/libunwind/docs/conf.py
+++ b/third_party/llvm-project/libunwind/docs/conf.py
@@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
-version = '16.0'
+version = '17.0'
# The full version, including alpha/beta/rc tags.
-release = '16.0'
+release = '17.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.