[libcxx-commits] [libcxx] [libc++][C++03] Split libc++-specific tests for the frozen headers (PR #144093)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jun 18 10:34:23 PDT 2025
https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/144093
>From 271c5135f04bd939f7205e2bfb6785a2f87b8c72 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 13 Jun 2025 17:24:09 +0200
Subject: [PATCH] [libc++] Split libc++-specific tests for the frozen headers
---
...modular_include_in_module.compile.pass.cpp | 21 +
.../random_shuffle.cxx1z.pass.cpp | 51 +
.../random_shuffle.depr_in_cxx14.verify.cpp | 43 +
.../copy_move_nontrivial.pass.cpp | 331 ++
.../copy_move_trivial.pass.cpp | 334 ++
.../copy_move_unwrap_reverse.pass.cpp | 141 +
.../make.heap/complexity.pass.cpp | 75 +
.../alg.sorting/assert.min.max.pass.cpp | 30 +
...ssert.sort.invalid_comparator.oob.pass.cpp | 72 +
.../assert.sort.invalid_comparator.pass.cpp | 195 +
.../bad_comparator_values.h | 3565 +++++++++++++++++
.../invalid_comparator_utilities.h | 85 +
.../alg.sorting/pstl.is_partitioned.pass.cpp | 31 +
.../algorithms/bad_iterator_traits.verify.cpp | 61 +
...lable-requirements-rvalue.compile.pass.cpp | 46 +
.../callable-requirements.verify.cpp | 118 +
.../cpp17_iterator_concepts.verify.cpp | 425 ++
.../debug_less.inconsistent.pass.cpp | 52 +
.../libcxx-03/algorithms/debug_less.pass.cpp | 260 ++
...debug_three_way_comp.inconsistent.pass.cpp | 56 +
.../algorithms/half_positive.pass.cpp | 59 +
.../algorithms/lifetimebound.verify.cpp | 81 +
.../algorithms/no_specializations.verify.cpp | 28 +
.../algorithms/nth_element_stability.pass.cpp | 101 +
.../partial_sort_stability.pass.cpp | 102 +
.../pstl.iterator-requirements.verify.cpp | 193 +
...pstl.libdispatch.chunk_partitions.pass.cpp | 41 +
...obust_against_copying_comparators.pass.cpp | 264 ++
...obust_against_copying_projections.pass.cpp | 278 ++
...obust_against_copying_comparators.pass.cpp | 323 ++
...t_cpp20_hostile_iterators.compile.pass.cpp | 225 ++
...using_non_transparent_comparators.pass.cpp | 80 +
.../algorithms/sort_stability.pass.cpp | 100 +
.../nothrow_forward_iterator.compile.pass.cpp | 27 +
.../nothrow_forward_range.compile.pass.cpp | 29 +
.../nothrow_input_iterator.compile.pass.cpp | 30 +
.../nothrow_input_range.compile.pass.cpp | 32 +
.../nothrow_sentinel_for.compile.pass.cpp | 35 +
.../algorithms/vectorization.compile.pass.cpp | 34 +
...tomize_verbose_abort.compile-time.pass.cpp | 27 +
...customize_verbose_abort.link-time.pass.cpp | 25 +
.../assertions/default_verbose_abort.pass.cpp | 28 +
.../libcxx-03/assertions/modes/debug.pass.cpp | 26 +
.../assertions/modes/extensive.pass.cpp | 26 +
.../libcxx-03/assertions/modes/fast.pass.cpp | 26 +
.../hardening_mode_incorrect_value.sh.cpp | 26 +
.../libcxx-03/assertions/modes/none.pass.cpp | 32 +
.../modes/override_with_debug_mode.pass.cpp | 27 +
.../override_with_extensive_mode.pass.cpp | 32 +
.../modes/override_with_fast_mode.pass.cpp | 31 +
.../override_with_unchecked_mode.pass.cpp | 24 +
.../assertions/single_expression.pass.cpp | 34 +
.../atomics/atomics.align/align.pass.cpp | 113 +
.../atomics/atomics.flag/init_bool.pass.cpp | 43 +
.../memory_order.underlying_type.pass.cpp | 34 +
.../assert.compare_exchange_strong.pass.cpp | 59 +
.../assert.compare_exchange_weak.pass.cpp | 59 +
.../atomics/atomics.ref/assert.ctor.pass.cpp | 41 +
.../atomics/atomics.ref/assert.load.pass.cpp | 56 +
.../atomics/atomics.ref/assert.store.pass.cpp | 64 +
.../atomics/atomics.ref/assert.wait.pass.cpp | 56 +
.../compare_exchange_strong.verify.cpp | 39 +
.../compare_exchange_weak.verify.cpp | 39 +
.../atomics/atomics.ref/load.verify.cpp | 34 +
.../atomics/atomics.ref/store.verify.cpp | 36 +
.../atomics/atomics.ref/wait.verify.cpp | 36 +
...compatible_with_stdatomic.compile.pass.cpp | 23 +
.../incompatible_with_stdatomic.verify.cpp | 25 +
.../atomics.syn/wait.issue_85107.pass.cpp | 54 +
.../atomics.types.float/lockfree.pass.cpp | 51 +
.../atomic_fetch_add.verify.cpp | 76 +
.../atomic_fetch_add_explicit.verify.cpp | 79 +
.../atomic_fetch_sub.verify.cpp | 76 +
.../atomic_fetch_sub_explicit.verify.cpp | 79 +
.../test/libcxx-03/atomics/bit-int.verify.cpp | 22 +
.../diagnose_invalid_memory_order.verify.cpp | 122 +
.../dont_hijack_header.compile.pass.cpp | 24 +
.../dont_hijack_header.cxx23.compile.pass.cpp | 28 +
.../libcxx-03/clang_modules_include.gen.py | 97 +
libcxx/test/libcxx-03/clang_tidy.gen.py | 40 +
libcxx/test/libcxx-03/clang_tidy.sh.py | 11 +
.../__libcpp_integer.compile.pass.cpp | 63 +
.../__libcpp_signed_integer.compile.pass.cpp | 63 +
...__libcpp_unsigned_integer.compile.pass.cpp | 63 +
.../associative/map/at.abort.pass.cpp | 33 +
.../associative/map/at.const.abort.pass.cpp | 33 +
.../map/find.modules.compile.pass.mm | 16 +
.../associative/map/scary.compile.pass.cpp | 26 +
...non_const_comparator.incomplete.verify.cpp | 56 +
.../non_const_comparator.verify.cpp | 48 +
.../reference_comparator_abi.compile.pass.cpp | 57 +
.../associative/set/scary.compile.pass.cpp | 26 +
.../tree_balance_after_insert.pass.cpp | 1612 ++++++++
.../tree_key_value_traits.pass.cpp | 56 +
.../associative/tree_left_rotate.pass.cpp | 100 +
.../associative/tree_remove.pass.cpp | 1646 ++++++++
.../associative/tree_right_rotate.pass.cpp | 100 +
.../unord.map/abi.compile.pass.cpp | 141 +
.../unord.map/scary.compile.pass.cpp | 28 +
.../unord.set/abi.compile.pass.cpp | 139 +
.../unord.set/scary.compile.pass.cpp | 28 +
.../flat.map/assert.input_range.pass.cpp | 66 +
.../flat.map/assert.sorted_unique.pass.cpp | 225 ++
.../flat.map/scary.compile.pass.cpp | 33 +
.../flat.multimap/assert.input_range.pass.cpp | 66 +
.../assert.sorted_equivalent.pass.cpp | 225 ++
.../assert.sorted_unique.pass.cpp | 131 +
.../flat.multiset/insert.temporary.pass.cpp | 48 +
.../flat.multiset/insert_range.pass.cpp | 46 +
.../flat.multiset/iterator.compile.pass.cpp | 42 +
.../flat.set/assert.sorted_unique.pass.cpp | 226 ++
.../flat.set/insert.temporary.pass.cpp | 48 +
.../flat.set/insert_range.pass.cpp | 46 +
.../flat.set/iterator.compile.pass.cpp | 42 +
.../flat.set/scary.compile.pass.cpp | 33 +
.../container.adaptors/flat_helpers.h | 48 +
.../container_traits.compile.pass.cpp | 165 +
.../containers/gnu_cxx/hash_map.pass.cpp | 36 +
.../gnu_cxx/hash_map_name_lookup.pass.cpp | 36 +
.../containers/gnu_cxx/hash_set.pass.cpp | 36 +
.../gnu_cxx/hash_set_name_lookup.pass.cpp | 36 +
.../sequences/array/triviality.pass.cpp | 51 +
.../sequences/deque/abi.compile.pass.cpp | 117 +
.../containers/sequences/deque/asan.pass.cpp | 68 +
.../sequences/deque/asan_caterpillar.pass.cpp | 53 +
.../sequences/deque/asan_turning_off.pass.cpp | 77 +
.../sequences/deque/assert.pass.cpp | 56 +
.../deque/assert.pop_back.empty.pass.cpp | 29 +
.../sequences/deque/incomplete.pass.cpp | 34 +
.../deque/segmented_iterator.compile.pass.cpp | 12 +
.../deque/spare_block_handling.pass.cpp | 288 ++
.../sequences/forwardlist/assert.pass.cpp | 47 +
.../forwardlist/bool-conversion.pass.cpp | 37 +
.../sequences/list/abi.compile.pass.cpp | 87 +
.../list/list.cons/debug.copy.pass.cpp | 30 +
.../assert.erase_iter.end.pass.cpp | 29 +
.../assert.pop_back.empty.pass.cpp | 35 +
.../list.modifiers/bool-conversion.pass.cpp | 37 +
.../list.modifiers/debug.emplace.pass.cpp | 34 +
.../list.modifiers/debug.erase.iter.pass.cpp | 28 +
.../debug.erase.iter_iter.pass.cpp | 57 +
.../debug.insert.iter_iter_iter.pass.cpp | 29 +
.../debug.insert.iter_rvalue.pass.cpp | 27 +
.../debug.insert.iter_size_value.pass.cpp | 27 +
.../debug.insert.iter_value.pass.cpp | 28 +
.../list.ops/debug.splice.pos_list.pass.cpp | 26 +
.../debug.splice.pos_list_iter.pass.cpp | 28 +
.../debug.splice.pos_list_iter_iter.pass.cpp | 28 +
.../vector.bool/abi.compile.pass.cpp | 69 +
.../sequences/vector.bool/assert.pass.cpp | 63 +
.../trivial_for_purposes_of_call.pass.cpp | 56 +
.../sequences/vector/abi.compile.pass.cpp | 95 +
.../containers/sequences/vector/asan.pass.cpp | 76 +
.../sequences/vector/asan_throw.pass.cpp | 233 ++
.../vector/asan_turning_off.pass.cpp | 77 +
.../vector/assert.back.empty.pass.cpp | 43 +
.../vector/assert.cback.empty.pass.cpp | 39 +
.../vector/assert.cfront.empty.pass.cpp | 39 +
.../vector/assert.cindex.oob.pass.cpp | 42 +
.../vector/assert.front.empty.pass.cpp | 44 +
.../vector/assert.index.oob.pass.cpp | 42 +
.../vector/assert.iterator.add.pass.cpp | 49 +
.../vector/assert.iterator.decrement.pass.cpp | 44 +
.../assert.iterator.dereference.pass.cpp | 42 +
.../vector/assert.iterator.increment.pass.cpp | 47 +
.../vector/assert.iterator.index.pass.cpp | 51 +
.../vector/assert.pop_back.empty.pass.cpp | 29 +
.../vector/debug.iterator.compare.pass.cpp | 39 +
.../vector/debug.iterator.subtract.pass.cpp | 39 +
.../vector/erase.modules.compile.pass.mm | 16 +
...eption_safety_exceptions_disabled.pass.cpp | 56 +
.../sequences/vector/fill_to_capacity.h | 24 +
.../vector/invalid_allocator.verify.cpp | 29 +
.../vector/robust_against_adl.pass.cpp | 54 +
.../vector.cons/construct_iter_iter.pass.cpp | 56 +
.../construct_iter_iter_alloc.pass.cpp | 59 +
.../strings/basic.string/asan.pass.cpp | 56 +
.../asan_deque_integration.pass.cpp | 182 +
.../strings/basic.string/asan_short.pass.cpp | 56 +
.../basic.string/asan_turning_off.pass.cpp | 102 +
.../asan_vector_integration.pass.cpp | 182 +
.../unord/key_value_traits.pass.cpp | 60 +
.../containers/unord/next_pow2.pass.cpp | 78 +
.../containers/unord/next_prime.pass.cpp | 51 +
...non_const_comparator.incomplete.verify.cpp | 58 +
.../unord/non_const_comparator.verify.cpp | 58 +
.../unord/unord.map/assert.bucket.pass.cpp | 29 +
.../unord.map/assert.bucket_size.pass.cpp | 33 +
.../assert.iterator.dereference.pass.cpp | 52 +
.../assert.iterator.increment.pass.cpp | 59 +
...assert.local_iterator.dereference.pass.cpp | 50 +
.../assert.local_iterator.increment.pass.cpp | 66 +
.../unord.map/assert.max_load_factor.pass.cpp | 34 +
.../unord/unord.map/at.abort.pass.cpp | 32 +
.../unord/unord.map/at.const.abort.pass.cpp | 32 +
.../debug.insert.hint_const_lvalue.pass.cpp | 41 +
.../debug.insert.hint_rvalue.pass.cpp | 35 +
.../unord/unord.map/debug.swap.pass.cpp | 38 +
.../debug.erase.iter.pass.cpp | 43 +
.../debug.erase.iter_iter.pass.cpp | 64 +
.../unord.multimap/assert.bucket.pass.cpp | 33 +
.../assert.bucket_size.pass.cpp | 33 +
.../assert.iterator.dereference.pass.cpp | 52 +
.../assert.iterator.increment.pass.cpp | 59 +
...assert.local_iterator.dereference.pass.cpp | 50 +
.../assert.local_iterator.increment.pass.cpp | 67 +
.../assert.max_load_factor.pass.cpp | 34 +
.../debug.insert.hint_const_lvalue.pass.cpp | 33 +
.../debug.insert.hint_rvalue.pass.cpp | 34 +
.../unord/unord.multimap/debug.swap.pass.cpp | 38 +
.../debug.erase.iter.pass.cpp | 43 +
.../debug.erase.iter_iter.pass.cpp | 64 +
.../unord.multiset/assert.bucket.pass.cpp | 32 +
.../assert.bucket_size.pass.cpp | 32 +
.../assert.iterator.dereference.pass.cpp | 46 +
.../assert.iterator.increment.pass.cpp | 58 +
...assert.local_iterator.dereference.pass.cpp | 48 +
.../assert.local_iterator.increment.pass.cpp | 64 +
.../assert.max_load_factor.pass.cpp | 33 +
.../unord.multiset/debug.erase.iter.pass.cpp | 41 +
.../debug.erase.iter_iter.pass.cpp | 60 +
.../debug.insert.hint_const_lvalue.pass.cpp | 33 +
.../unord/unord.multiset/debug.swap.pass.cpp | 37 +
.../unord/unord.set/assert.bucket.pass.cpp | 32 +
.../unord.set/assert.bucket_size.pass.cpp | 32 +
.../assert.iterator.dereference.pass.cpp | 46 +
.../assert.iterator.increment.pass.cpp | 58 +
...assert.local_iterator.dereference.pass.cpp | 48 +
.../assert.local_iterator.increment.pass.cpp | 64 +
.../unord.set/assert.max_load_factor.pass.cpp | 33 +
.../unord/unord.set/debug.erase.iter.pass.cpp | 41 +
.../unord.set/debug.erase.iter_iter.pass.cpp | 60 +
.../debug.insert.hint_const_lvalue.pass.cpp | 33 +
.../unord/unord.set/debug.swap.pass.cpp | 37 +
.../missing_hash_specialization.verify.cpp | 70 +
.../byte_alignment.verify.cpp | 29 +
.../aligned_accessor/element_type.verify.cpp | 32 +
.../mdspan/extents/assert.conversion.pass.cpp | 57 +
.../extents/assert.ctor_from_array.pass.cpp | 60 +
.../assert.ctor_from_integral.pass.cpp | 62 +
.../extents/assert.ctor_from_span.pass.cpp | 63 +
.../views/mdspan/extents/assert.obs.pass.cpp | 65 +
.../layout_left/assert.conversion.pass.cpp | 62 +
.../layout_left/assert.ctor.extents.pass.cpp | 38 +
.../assert.ctor.layout_right.pass.cpp | 59 +
.../assert.ctor.layout_stride.pass.cpp | 83 +
.../assert.index_operator.pass.cpp | 84 +
.../mdspan/layout_left/assert.stride.pass.cpp | 41 +
.../layout_right/assert.conversion.pass.cpp | 62 +
.../layout_right/assert.ctor.extents.pass.cpp | 40 +
.../assert.ctor.layout_left.pass.cpp | 58 +
.../assert.ctor.layout_stride.pass.cpp | 83 +
.../assert.index_operator.pass.cpp | 84 +
.../layout_right/assert.stride.pass.cpp | 41 +
.../layout_stride/assert.conversion.pass.cpp | 111 +
...ert.ctor.extents_array.non_unique.pass.cpp | 67 +
.../assert.ctor.extents_array.pass.cpp | 74 +
...sert.ctor.extents_span.non_unique.pass.cpp | 70 +
.../assert.ctor.extents_span.pass.cpp | 81 +
.../assert.index_operator.pass.cpp | 88 +
.../layout_stride/assert.stride.pass.cpp | 36 +
.../mdspan/mdspan/assert.conversion.pass.cpp | 66 +
.../mdspan/assert.index_operator.pass.cpp | 90 +
.../views/mdspan/mdspan/assert.size.pass.cpp | 50 +
.../assert.iterator-indexing.pass.cpp | 174 +
.../span.cons/assert.iter_sent.pass.cpp | 58 +
.../span.cons/assert.iter_size.pass.cpp | 72 +
.../span.cons/assert.other_span.pass.cpp | 36 +
.../span.cons/assert.range.pass.cpp | 38 +
.../views.span/span.elem/assert.back.pass.cpp | 39 +
.../span.elem/assert.front.pass.cpp | 39 +
.../span.elem/assert.op_idx.pass.cpp | 39 +
.../views.span/span.sub/assert.first.pass.cpp | 40 +
.../views.span/span.sub/assert.last.pass.cpp | 40 +
.../span.sub/assert.subspan.pass.cpp | 61 +
.../debug/containers.multithread.pass.cpp | 65 +
.../sequence_container_iterators.pass.cpp | 333 ++
.../debug/containers/string.pass.cpp | 92 +
.../containers/unord_containers.pass.cpp | 62 +
.../auto.ptr/auto_ptr.cxx1z.pass.cpp | 31 +
.../auto_ptr.depr_in_cxx11.verify.cpp | 30 +
.../depr/depr.c.headers/extern_c.pass.cpp | 53 +
.../depr.c.headers/math_h.compile.pass.cpp | 26 +
.../stdint_h.std_types_t.compile.pass.cpp | 263 ++
.../stdint_h.xopen_source.compile.pass.cpp | 263 ++
.../allocator.members/address.cxx20.pass.cpp | 44 +
.../address.cxx20.verify.cpp | 42 +
.../address.depr_in_cxx17.verify.cpp | 26 +
.../allocator.members/allocate.cxx20.pass.cpp | 92 +
.../allocate.cxx20.verify.cpp | 23 +
.../allocate.depr_in_cxx17.verify.cpp | 25 +
.../construct.cxx20.pass.cpp | 147 +
.../construct.cxx20.verify.cpp | 77 +
.../allocator.members/max_size.cxx20.pass.cpp | 34 +
.../max_size.cxx20.verify.cpp | 32 +
.../allocator_types.cxx20.pass.cpp | 53 +
.../typedefs.depr_in_cxx17.verify.cpp | 125 +
.../adaptors.depr_in_cxx11.verify.cpp | 51 +
.../depr.adaptors.cxx1z.pass.cpp | 68 +
.../rel_ops.depr_in_cxx20.verify.cpp | 35 +
.../get_unexpected.pass.cpp | 44 +
.../set_unexpected.pass.cpp | 40 +
.../exception.unexpected/unexpected.pass.cpp | 31 +
.../unexpected_disabled_cpp17.verify.cpp | 24 +
.../algorithm.nodiscard.verify.cpp | 396 ++
.../diagnostics/array.nodiscard.verify.cpp | 23 +
.../diagnostics/bit.nodiscard.verify.cpp | 33 +
.../diagnostics/chrono.nodiscard.verify.cpp | 127 +
.../diagnostics/cmath.nodiscard.verify.cpp | 167 +
.../diagnostics/cstddef.nodiscard.verify.cpp | 20 +
.../diagnostics/cstdlib.nodiscard.verify.cpp | 25 +
.../diagnostics/deque.nodiscard.verify.cpp | 18 +
.../filesystem.nodiscard.verify.cpp | 19 +
.../diagnostics/flat_map.nodiscard.verify.cpp | 20 +
.../flat_multimap.nodiscard.verify.cpp | 22 +
.../flat_multiset.nodiscard.verify.cpp | 20 +
.../diagnostics/flat_set.nodiscard.verify.cpp | 20 +
.../diagnostics/format.nodiscard.verify.cpp | 49 +
.../forward_list.nodiscard.verify.cpp | 18 +
.../functional.nodiscard.verify.cpp | 20 +
.../diagnostics/future.nodiscard.verify.cpp | 22 +
.../diagnostics/iterator.nodiscard.verify.cpp | 38 +
.../diagnostics/limits.nodiscard.verify.cpp | 70 +
.../diagnostics/list.nodiscard.verify.cpp | 18 +
.../diagnostics/map.nodiscard.verify.cpp | 23 +
.../diagnostics/memory.nodiscard.verify.cpp | 42 +
.../memory_resource.nodiscard.verify.cpp | 25 +
.../diagnostics/mutex.nodiscard.verify.cpp | 69 +
.../diagnostics/new.nodiscard.verify.cpp | 35 +
.../node_handle.nodiscard.verify.cpp | 18 +
.../diagnostics/pstl.nodiscard.verify.cpp | 28 +
.../diagnostics/queue.nodiscard.verify.cpp | 23 +
.../diagnostics/ranges.nodiscard.verify.cpp | 60 +
.../diagnostics/regex.nodiscard.verify.cpp | 20 +
.../scoped_allocator.nodiscard.verify.cpp | 22 +
.../diagnostics/set.nodiscard.verify.cpp | 23 +
.../diagnostics/stack.nodiscard.verify.cpp | 18 +
.../diagnostics/string.nodiscard.verify.cpp | 18 +
.../string_view.nodiscard.verify.cpp | 18 +
.../system_error_win_codes.pass.cpp | 25 +
.../unordered_map.nodiscard.verify.cpp | 25 +
.../unordered_set.nodiscard.verify.cpp | 25 +
.../diagnostics/utility.nodiscard.verify.cpp | 35 +
.../diagnostics/vector.nodiscard.verify.cpp | 23 +
libcxx/test/libcxx-03/double_include.gen.py | 42 +
.../fexperimental-library.compile.pass.cpp | 31 +
.../hash/specializations.compile.fail.cpp | 18 +
.../extensions/hash/specializations.pass.cpp | 36 +
.../hash_map/const_iterator.compile.fail.cpp | 19 +
.../feature_test_macro/ftm_metadata.sh.py | 82 +
.../generate_header_test.sh.py | 637 +++
.../feature_test_macro/implemented_ftms.sh.py | 68 +
.../feature_test_macro/invalid.sh.py | 108 +
.../feature_test_macro/is_implemented.sh.py | 39 +
.../feature_test_macro/standard_ftms.sh.py | 81 +
.../standard_library_headers.sh.py | 44 +
.../feature_test_macro/std_dialects.sh.py | 39 +
.../feature_test_macro/test_data.json | 213 +
.../feature_test_macro/version_header.sh.py | 84 +
.../version_header_implementation.sh.py | 163 +
.../libcxx-03/fuzzing/format_no_args.pass.cpp | 30 +
libcxx/test/libcxx-03/fuzzing/fuzz.h | 145 +
.../test/libcxx-03/fuzzing/make_heap.pass.cpp | 27 +
.../libcxx-03/fuzzing/nth_element.pass.cpp | 42 +
.../libcxx-03/fuzzing/partial_sort.pass.cpp | 40 +
.../fuzzing/partial_sort_copy.pass.cpp | 41 +
.../test/libcxx-03/fuzzing/partition.pass.cpp | 30 +
.../libcxx-03/fuzzing/partition_copy.pass.cpp | 65 +
.../test/libcxx-03/fuzzing/pop_heap.pass.cpp | 33 +
.../test/libcxx-03/fuzzing/push_heap.pass.cpp | 40 +
libcxx/test/libcxx-03/fuzzing/random.pass.cpp | 198 +
libcxx/test/libcxx-03/fuzzing/regex.pass.cpp | 46 +
libcxx/test/libcxx-03/fuzzing/search.pass.cpp | 35 +
libcxx/test/libcxx-03/fuzzing/sort.pass.cpp | 27 +
.../fuzzing/stable_partition.pass.cpp | 38 +
.../libcxx-03/fuzzing/stable_sort.pass.cpp | 39 +
libcxx/test/libcxx-03/fuzzing/unique.pass.cpp | 54 +
.../libcxx-03/fuzzing/unique_copy.pass.cpp | 56 +
.../libcxx-03/gdb/gdb_pretty_printer_test.py | 162 +
.../gdb/gdb_pretty_printer_test.sh.cpp | 722 ++++
.../test/libcxx-03/header_inclusions.gen.py | 57 +
.../test/libcxx-03/headers_in_modulemap.sh.py | 20 +
libcxx/test/libcxx-03/include_as_c.sh.cpp | 59 +
.../filebuf/traits_mismatch.verify.cpp | 22 +
.../fstreams/fstream.close.pass.cpp | 38 +
.../fstream.cons/wchar_pointer.pass.cpp | 52 +
.../open_wchar_pointer.pass.cpp | 58 +
.../fstreams/ifstream.cons/test.dat | 1 +
.../ifstream.cons/wchar_pointer.pass.cpp | 48 +
.../open_wchar_pointer.pass.cpp | 54 +
.../fstreams/ifstream.members/test.dat | 1 +
.../ofstream.cons/wchar_pointer.pass.cpp | 66 +
.../open_wchar_pointer.pass.cpp | 66 +
.../fstreams/traits_mismatch.verify.cpp | 29 +
.../input.output/file.streams/lit.local.cfg | 7 +
.../last_write_time.pass.cpp | 104 +
.../path.itr/assert.iterator.pass.cpp | 49 +
.../path.native.obs/string_alloc.pass.cpp | 173 +
.../class.path/path.req/is_pathable.pass.cpp | 107 +
.../filesystems/convert_file_time.pass.cpp | 309 ++
.../input.streams/traits_mismatch.verify.cpp | 25 +
.../iostream.format/lit.local.cfg | 7 +
.../vprint_unicode.pass.cpp | 171 +
.../ostream.syn/includes.compile.pass.cpp | 31 +
.../output.streams/traits_mismatch.verify.cpp | 25 +
.../print.fun/transcoding.pass.cpp | 91 +
.../print.fun/vprint_unicode_posix.pass.cpp | 79 +
.../print.fun/vprint_unicode_windows.pass.cpp | 135 +
.../iostream.objects/lit.local.cfg | 7 +
.../ios.base.cons/dtor.uninitialized.pass.cpp | 83 +
.../ios/iostate.flags/clear.abort.pass.cpp | 43 +
.../input.output/iostreams.base/lit.local.cfg | 7 +
.../input.output/stream.buffers/lit.local.cfg | 7 +
.../input.output/string.streams/lit.local.cfg | 7 +
.../stringbuf/const_sso_buffer.pass.cpp | 171 +
.../string.streams/traits_mismatch.verify.cpp | 25 +
.../iterators/aliasing_iterator.pass.cpp | 47 +
.../iterators/assert.advance.pass.cpp | 37 +
.../libcxx-03/iterators/assert.next.pass.cpp | 31 +
.../libcxx-03/iterators/assert.prev.pass.cpp | 37 +
.../bounded_iter/arithmetic.pass.cpp | 114 +
.../bounded_iter/comparison.pass.cpp | 89 +
.../bounded_iter/dereference.pass.cpp | 86 +
.../bounded_iter/pointer_traits.pass.cpp | 63 +
.../bounded_iter/types.compile.pass.cpp | 51 +
...contiguous_iterators.conv.compile.pass.cpp | 65 +
.../iterators/contiguous_iterators.pass.cpp | 265 ++
.../iterators/contiguous_iterators.verify.cpp | 27 +
.../subsumption.compile.pass.cpp | 29 +
.../iterator.operations/prev.verify.cpp | 21 +
...cy_bidirectional_iterator.compile.pass.cpp | 164 +
.../legacy_forward_iterator.compile.pass.cpp | 164 +
.../legacy_input_iterator.compile.pass.cpp | 164 +
.../legacy_iterator.compile.pass.cpp | 164 +
...cy_random_access_iterator.compile.pass.cpp | 164 +
.../locale_dependent.compile.pass.cpp | 50 +
.../cpp20_iter_concepts.compile.pass.cpp | 81 +
.../cpp20_iter_traits.compile.pass.cpp | 34 +
.../integer_like.compile.pass.cpp | 51 +
.../iterators/iterator_with_data.pass.cpp | 41 +
.../counted.iterator/assert.pass.cpp | 42 +
.../get_container.pass.cpp | 37 +
.../iterators.common/assert.pass.cpp | 58 +
.../bad_template_argument.verify.cpp | 22 +
.../ostreambuf.iter.ops/failed.pass.cpp | 36 +
.../libcxx-03/iterators/unwrap_iter.pass.cpp | 59 +
.../cxa_deleted_virtual.pass.cpp | 22 +
.../no_specializations.verify.cpp | 23 +
.../math.lerp.verify.cpp | 39 +
...new_not_overridden_fno_exceptions.pass.cpp | 58 +
.../support.dynamic/libcpp_deallocate.sh.cpp | 255 ++
.../new_dont_return_nullptr.pass.cpp | 37 +
...ype_info.comparison.apple.compile.pass.cpp | 30 +
.../type_info.comparison.merged.sh.cpp | 48 +
.../type_info.comparison.unmerged.sh.cpp | 45 +
.../support.types/cstddef.compile.pass.cpp | 26 +
.../timespec_get.xopen.compile.pass.cpp | 21 +
libcxx/test/libcxx-03/libcpp_alignof.pass.cpp | 36 +
.../test/libcxx-03/libcpp_freestanding.sh.cpp | 20 +
libcxx/test/libcxx-03/libcpp_version.gen.py | 34 +
.../test/libcxx-03/lint/lint_cmakelists.sh.py | 33 +
libcxx/test/libcxx-03/lint/lint_headers.sh.py | 63 +
libcxx/test/libcxx-03/lit.local.cfg | 9 +
.../test/libcxx-03/localization/lit.local.cfg | 7 +
.../locale.categories/__scan_keyword.pass.cpp | 121 +
.../locales/locale.abort.pass.cpp | 36 +
.../locales/locale.category.abort.pass.cpp | 36 +
.../conversions.string/ctor_move.pass.cpp | 42 +
.../locale.types/locale.facet/facet.pass.cpp | 56 +
.../locale.facet/no_allocation.pass.cpp | 23 +
.../locale/locale.types/locale.id/id.pass.cpp | 53 +
.../locales/use_facet.abort.pass.cpp | 39 +
.../mem/mem.res/nodiscard.verify.cpp | 25 +
.../aligned_allocation_macro.compile.pass.cpp | 17 +
.../memory/allocation_guard.pass.cpp | 194 +
.../allocator_void.trivial.compile.pass.cpp | 26 +
.../memory/allocator_volatile.verify.cpp | 14 +
.../libcxx-03/memory/is_allocator.pass.cpp | 43 +
.../memory/shared_ptr_array.pass.cpp | 33 +
.../libcxx-03/memory/swap_allocator.pass.cpp | 83 +
.../trivial_abi/shared_ptr_arg.pass.cpp | 51 +
.../trivial_abi/unique_ptr_arg.pass.cpp | 52 +
.../trivial_abi/unique_ptr_array.pass.cpp | 57 +
.../unique_ptr_destruction_order.pass.cpp | 68 +
.../trivial_abi/unique_ptr_ret.pass.cpp | 59 +
.../memory/trivial_abi/weak_ptr_ret.pass.cpp | 62 +
.../uninitialized_allocator_copy.pass.cpp | 67 +
.../minimal_cxx11_configuration.pass.cpp | 130 +
libcxx/test/libcxx-03/module_std.gen.py | 38 +
.../test/libcxx-03/module_std_compat.gen.py | 42 +
.../test/libcxx-03/no_assert_include.gen.py | 39 +
.../test/libcxx-03/numerics/bit.ops.pass.cpp | 45 +
.../c.math/constexpr-cxx23-clang.pass.cpp | 266 ++
.../c.math/constexpr-cxx23-gcc.pass.cpp | 256 ++
.../numerics/c.math/constexpr-fns.pass.cpp | 29 +
.../c.math/fdelayed-template-parsing.pass.cpp | 28 +
.../numerics/clamp_to_integral.pass.cpp | 94 +
.../numerics/complex.number/__sqr.pass.cpp | 84 +
.../complex.number/cmplx.over.pow.pass.cpp | 86 +
.../numerics/numarray/assert.pass.cpp | 42 +
.../class.gslice.array/assert.get.pass.cpp | 49 +
.../numarray/class.gslice.array/get.pass.cpp | 52 +
.../class.indirect.array/assert.get.pass.cpp | 49 +
.../class.indirect.array/get.pass.cpp | 44 +
.../class.mask.array/assert.get.pass.cpp | 48 +
.../numarray/class.mask.array/get.pass.cpp | 51 +
.../class.slice.array/assert.get.pass.cpp | 49 +
.../numarray/class.slice.array/get.pass.cpp | 46 +
.../numeric.ops/midpoint.integer.pass.cpp | 69 +
.../has-no-random-device.verify.cpp | 18 +
.../bad_engine.verify.cpp | 30 +
.../rand.dist.bern.bin/bad_engine.verify.cpp | 30 +
.../rand.dist.bern.geo/bad_engine.verify.cpp | 31 +
.../bad_engine.verify.cpp | 31 +
.../bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 30 +
.../rand.dist.norm.f/bad_engine.verify.cpp | 31 +
.../bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 30 +
.../rand.dist.norm.t/bad_engine.verify.cpp | 30 +
.../rand.dist.pois.exp/bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 31 +
.../bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 30 +
.../bad_engine.verify.cpp | 30 +
.../rand.dist.uni.int/bad_engine.verify.cpp | 31 +
.../rand.dist.uni.real/bad_engine.verify.cpp | 30 +
.../rand.req.urng/valid_int_type.verify.cpp | 51 +
.../rand.req.urng/valid_real_type.verify.cpp | 109 +
.../libcxx-03/odr_signature.exceptions.sh.cpp | 46 +
.../libcxx-03/odr_signature.hardening.sh.cpp | 67 +
.../ranges/no_specializations.verify.cpp | 25 +
.../range.access/end.incomplete_type.pass.cpp | 46 +
.../as-lvalue.lifetimebound.verify.cpp | 22 +
.../range.adaptor.helpers/as-lvalue.pass.cpp | 41 +
.../tuple-for-each.pass.cpp | 31 +
.../range.all/all.nodiscard.verify.cpp | 21 +
.../range.chunk.by/assert.begin.pass.cpp | 35 +
.../range.chunk.by/assert.find-next.pass.cpp | 38 +
.../range.chunk.by/assert.find-prev.pass.cpp | 49 +
.../no_unique_address.compile.pass.cpp | 46 +
.../range.chunk.by.iter/assert.deref.pass.cpp | 30 +
.../assert.increment.pass.cpp | 30 +
.../range.adaptors/range.chunk.by/types.h | 23 +
.../adaptor.nodiscard.verify.cpp | 21 +
.../adaptor.nodiscard.verify.cpp | 19 +
.../range.drop.while/assert.begin.pass.cpp | 49 +
...ts_view.no_unique_address.compile.pass.cpp | 33 +
...entinel.no_unique_address.compile.pass.cpp | 37 +
.../ctor.parent.outer.pass.cpp | 65 +
.../range.join.iterator/ctor.parent.pass.cpp | 36 +
.../range.join/range.join.iterator/types.h | 114 +
.../segmented_iterator.compile.pass.cpp | 17 +
.../no_unique_address.compile.pass.cpp | 116 +
.../assert.equal.pass.cpp | 37 +
.../assert.equal.pass.cpp | 37 +
.../range.adaptors/range.lazy.split/types.h | 73 +
.../range.move.wrap/arrow.pass.cpp | 54 +
.../range.move.wrap/assign.copy.pass.cpp | 168 +
.../range.move.wrap/assign.move.pass.cpp | 228 ++
.../range.move.wrap/ctor.default.pass.cpp | 65 +
.../range.move.wrap/ctor.in_place.pass.cpp | 69 +
.../range.move.wrap/deref.pass.cpp | 52 +
.../range.move.wrap/empty_object.pass.cpp | 56 +
.../range.move.wrap/has_value.pass.cpp | 48 +
.../no_unique_address.pass.cpp | 78 +
.../properties.compile.pass.cpp | 61 +
.../range.adaptors/range.move.wrap/types.h | 157 +
.../adaptor.nodiscard.verify.cpp | 21 +
.../no_unique_address.compile.pass.cpp | 26 +
.../adaptor.nodiscard.verify.cpp | 23 +
.../no_unique_address.compile.pass.cpp | 22 +
.../range.repeat.view/ctor.piecewise.pass.cpp | 32 +
.../ctor.value.bound.pass.cpp | 29 +
.../no_unique_address.compile.pass.cpp | 23 +
.../no_unique_address.compile.pass.cpp | 23 +
.../range.nonprop.cache/assign.copy.pass.cpp | 102 +
.../range.nonprop.cache/assign.move.pass.cpp | 98 +
.../constraints.compile.pass.cpp | 28 +
.../range.nonprop.cache/ctor.copy.pass.cpp | 73 +
.../range.nonprop.cache/ctor.default.pass.cpp | 41 +
.../range.nonprop.cache/ctor.move.pass.cpp | 64 +
.../ranges/range.nonprop.cache/deref.pass.cpp | 53 +
.../range.nonprop.cache/emplace.pass.cpp | 95 +
.../range.nonprop.cache/emplace_from.pass.cpp | 77 +
.../range.nonprop.cache/has_value.pass.cpp | 46 +
.../different_from.compile.pass.cpp | 27 +
.../has_arrow.compile.pass.cpp | 83 +
.../simple_view.compile.pass.cpp | 58 +
.../to.internal_constraints.verify.cpp | 94 +
.../to.static_assert.verify.cpp | 92 +
.../conditional-compile-flags.sh.cpp | 14 +
.../additional_compile_flags/lit.local.cfg | 2 +
.../substitutes-in-compile-flags.sh.cpp | 18 +
.../substitutes-in-run.sh.cpp | 15 +
.../compile-error.compile.fail.cpp | 14 +
.../compile-success.compile.fail.cpp | 13 +
.../compile-error.compile.pass.cpp | 16 +
.../compile-success.compile.pass.cpp | 11 +
.../link-error.compile.pass.cpp | 16 +
.../run-error.compile.pass.cpp | 13 +
.../compile-error.compile.pass.mm | 18 +
.../compile-success.compile.pass.mm | 16 +
.../link-error.compile.pass.mm | 21 +
.../compile.pass.mm/run-error.compile.pass.mm | 18 +
.../build_run.sh.cpp | 23 +
.../convenience_substitutions/verify.sh.cpp | 16 +
libcxx/test/libcxx-03/selftest/dsl/dsl.sh.py | 629 +++
.../test/libcxx-03/selftest/dsl/lit.local.cfg | 15 +
.../selftest/file_dependencies/a.txt | 0
.../absolute-and-relative-paths.sh.cpp | 15 +
.../selftest/file_dependencies/dir/b.txt | 0
.../substitute-in-dependencies.sh.cpp | 12 +
.../libcxx-03/selftest/gen.cpp/empty.gen.cpp | 11 +
.../libcxx-03/selftest/gen.cpp/one.gen.cpp | 11 +
.../libcxx-03/selftest/gen.cpp/two.gen.cpp | 12 +
.../link.fail.cpp/compile-error.link.fail.cpp | 16 +
.../link.fail.cpp/link-error.link.fail.cpp | 16 +
.../link.fail.cpp/link-success.link.fail.cpp | 13 +
.../link.pass.cpp/compile-error.link.pass.cpp | 16 +
.../link.pass.cpp/link-error.link.pass.cpp | 18 +
.../link.pass.cpp/link-success.link.pass.cpp | 11 +
.../link.pass.cpp/run-error.link.pass.cpp | 14 +
.../link.pass.mm/compile-error.link.pass.mm | 18 +
.../link.pass.mm/link-error.link.pass.mm | 20 +
.../link.pass.mm/link-success.link.pass.mm | 16 +
.../link.pass.mm/run-error.link.pass.mm | 19 +
.../selftest/modules/no-modules.sh.cpp | 14 +
.../modules/std-and-std.compat-module.sh.cpp | 22 +
.../selftest/modules/std-module.sh.cpp | 24 +
.../selftest/modules/std.compat-module.sh.cpp | 24 +
.../selftest/pass.cpp/compile-error.pass.cpp | 16 +
.../selftest/pass.cpp/link-error.pass.cpp | 18 +
.../selftest/pass.cpp/run-error.pass.cpp | 15 +
.../selftest/pass.cpp/run-success.pass.cpp | 13 +
.../selftest/pass.cpp/werror.pass.cpp | 22 +
.../selftest/pass.mm/compile-error.pass.mm | 18 +
.../selftest/pass.mm/link-error.pass.mm | 20 +
.../libcxx-03/selftest/pass.mm/no-arc.pass.mm | 19 +
.../selftest/pass.mm/run-error.pass.mm | 17 +
.../selftest/pass.mm/run-success.pass.mm | 15 +
.../pass.mm/use-objective-cxx.pass.mm | 18 +
.../selftest/remote-substitutions.sh.cpp | 32 +
.../selftest/sh.cpp/run-error.sh.cpp | 13 +
.../selftest/sh.cpp/run-success.sh.cpp | 11 +
.../selftest/sh.cpp/substitutions.sh.cpp | 24 +
.../libcxx-03/selftest/sh.cpp/werror.sh.cpp | 23 +
.../selftest/shell-no-escape-builtins.sh.cpp | 12 +
.../libcxx-03/selftest/stdin-is-piped.sh.cpp | 22 +
.../libcxx-03/selftest/test_macros.pass.cpp | 41 +
.../libcxx-03/selftest/tmpdir-exists.sh.cpp | 11 +
.../no-diagnostics-unmarked.verify.cpp | 17 +
.../verify.cpp/no-diagnostics.verify.cpp | 11 +
.../selftest/verify.cpp/no-werror.verify.cpp | 15 +
.../verify.cpp/right-diagnostic.verify.cpp | 12 +
.../verify.cpp/wrong-diagnostic.verify.cpp | 14 +
.../basic.string/alignof.compile.pass.cpp | 146 +
.../strings/basic.string/nonnull.verify.cpp | 41 +
.../basic.string/sizeof.compile.pass.cpp | 145 +
.../string.access/assert.back.pass.cpp | 34 +
.../string.access/assert.cback.pass.cpp | 34 +
.../string.access/assert.cfront.pass.cpp | 34 +
.../string.access/assert.cindex.pass.cpp | 36 +
.../string.access/assert.front.pass.cpp | 35 +
.../string.access/assert.index.pass.cpp | 36 +
.../string.capacity/PR53170.pass.cpp | 84 +
.../string.capacity/allocation_size.pass.cpp | 37 +
.../string.capacity/max_size.pass.cpp | 122 +
.../string.capacity/shrink_to_fit.pass.cpp | 87 +
.../constinit_sso_string.compile.pass.cpp | 25 +
.../string.cons/copy_shrunk_long.pass.cpp | 45 +
.../debug.iterator.substr.pass.cpp | 49 +
.../assert.iterator.add.pass.cpp | 37 +
.../assert.iterator.decrement.pass.cpp | 36 +
.../assert.iterator.dereference.pass.cpp | 33 +
.../assert.iterator.increment.pass.cpp | 36 +
.../assert.iterator.index.pass.cpp | 37 +
.../debug.iterator.compare.pass.cpp | 33 +
.../debug.iterator.subtract.pass.cpp | 33 +
.../assert.erase_iter.null.pass.cpp | 35 +
.../string.modifiers/assert.pop_back.pass.cpp | 32 +
.../debug.erase.iter.pass.cpp | 35 +
.../debug.erase.iter_iter.pass.cpp | 61 +
.../debug.insert.iter_char.pass.cpp | 39 +
.../debug.insert.iter_iter_iter.pass.cpp | 35 +
.../debug.insert.iter_size_char.pass.cpp | 32 +
.../resize_default_initialized.pass.cpp | 75 +
.../constexpr.cstring.compile.pass.cpp | 31 +
.../constexpr.cwchar.compile.pass.cpp | 26 +
.../c.strings/constexpr_memmove.pass.cpp | 157 +
.../string.view/assert.ctor.length.pass.cpp | 26 +
.../string.view/assert.ctor.pointer.pass.cpp | 41 +
.../assert.iterator-indexing.pass.cpp | 158 +
.../libcxx-03/system_reserved_names.gen.py | 206 +
.../thread/atomic.availability.verify.cpp | 77 +
.../thread/barrier.availability.verify.cpp | 41 +
.../assert.set_exception.pass.cpp | 40 +
...sert.set_exception_at_thread_exit.pass.cpp | 40 +
.../futures/futures.task/type.depr.verify.cpp | 28 +
.../futures/futures.task/types.pass.cpp | 34 +
.../thread/latch.availability.verify.cpp | 23 +
.../thread/semaphore.availability.verify.cpp | 48 +
.../thread.barrier/assert.arrive.pass.cpp | 40 +
.../thread.barrier/assert.ctor.pass.cpp | 48 +
...otify_from_pthread_created_thread.pass.cpp | 78 +
.../native_handle.pass.cpp | 36 +
.../assert.arrive_and_wait.pass.cpp | 37 +
.../thread.latch/assert.count_down.pass.cpp | 45 +
.../thread/thread.latch/assert.ctor.pass.cpp | 38 +
.../thread.mutex.class/native_handle.pass.cpp | 32 +
.../native_handle.pass.cpp | 32 +
...ad_safety_annotations_not_enabled.pass.cpp | 30 +
.../thread_safety_lock_guard.pass.cpp | 40 +
.../thread_safety_lock_unlock.pass.cpp | 33 +
.../thread_safety_missing_unlock.verify.cpp | 26 +
...thread_safety_requires_capability.pass.cpp | 37 +
.../thread.semaphore/assert.ctor.pass.cpp | 37 +
.../thread.semaphore/assert.release.pass.cpp | 41 +
.../thread_safety.verify.cpp | 64 +
.../thread_safety.verify.cpp | 95 +
.../atomic_unique_lock.pass.cpp | 95 +
.../intrusive_list_view.pass.cpp | 108 +
.../intrusive_shared_ptr.pass.cpp | 88 +
.../thread.threads/create_late.pass.cpp | 29 +
.../native_handle.pass.cpp | 59 +
.../thread.thread.class/types.pass.cpp | 31 +
.../thread.thread.this/sleep_for.pass.cpp | 35 +
.../sleep_for.signals.pass.cpp | 67 +
.../libcxx-03/time/convert_to_tm.pass.cpp | 63 +
.../assert.from_utc.pass.cpp | 73 +
.../assert.to_utc.pass.cpp | 73 +
.../assert.from_utc.pass.cpp | 73 +
.../assert.to_utc.pass.cpp | 73 +
.../get_leap_second_info.pass.cpp | 147 +
.../time.clock.utc.members/from_sys.pass.cpp | 108 +
.../time.clock.utc.members/to_sys.pass.cpp | 117 +
.../time.zone.db/leap_seconds.pass.cpp | 126 +
.../time.zone/time.zone.db/links.pass.cpp | 102 +
.../time.zone/time.zone.db/rules.pass.cpp | 594 +++
.../time.zone.db.list/erase_after.pass.cpp | 71 +
.../time.zone.db.remote/reload_tzdb.pass.cpp | 58 +
.../time.zone.db.tzdb/locate_zone.pass.cpp | 84 +
.../time.zone/time.zone.db/version.pass.cpp | 74 +
.../time.zone/time.zone.db/zones.pass.cpp | 380 ++
.../assert.ctor.pass.cpp | 53 +
.../assert.ctor.pass.cpp | 53 +
.../time.zone.info.local/ostream.pass.cpp | 114 +
.../time.zone.info.sys/ostream.pass.cpp | 74 +
.../time.zone.timezone/choose.pass.cpp | 37 +
.../assert.to_local.pass.cpp | 40 +
.../time.zone.members/assert.to_sys.pass.cpp | 39 +
.../assert.to_sys_choose.pass.cpp | 41 +
.../get_info.sys_time.pass.cpp | 204 +
.../get_info.sys_time.rule_selection.pass.cpp | 185 +
.../test/libcxx-03/transitive_includes.gen.py | 102 +
.../libcxx-03/transitive_includes/cxx03.csv | 2568 ++++++++++++
.../libcxx-03/transitive_includes/cxx11.csv | 2568 ++++++++++++
.../libcxx-03/transitive_includes/cxx14.csv | 2619 ++++++++++++
.../libcxx-03/transitive_includes/cxx17.csv | 2621 ++++++++++++
.../libcxx-03/transitive_includes/cxx20.csv | 2649 ++++++++++++
.../libcxx-03/transitive_includes/cxx23.csv | 1166 ++++++
.../libcxx-03/transitive_includes/cxx26.csv | 1167 ++++++
.../libcxx-03/transitive_includes/to_csv.py | 120 +
.../type_traits/convert_to_integral.pass.cpp | 123 +
.../type_traits/datasizeof.compile.pass.cpp | 62 +
.../type_traits/desugars_to.compile.pass.cpp | 42 +
.../is_always_bitcastable.compile.pass.cpp | 219 +
.../type_traits/is_callable.compile.pass.cpp | 31 +
.../is_constant_evaluated.pass.cpp | 36 +
..._implicitly_default_constructible.pass.cpp | 81 +
.../type_traits/is_pointer.arc.pass.mm | 75 +
.../is_replaceable.compile.pass.cpp | 313 ++
.../type_traits/is_scalar.objc.pass.mm | 38 +
.../is_specialization.compile.pass.cpp | 55 +
.../type_traits/is_specialization.verify.cpp | 21 +
.../is_trivially_comparable.compile.pass.cpp | 67 +
.../is_trivially_relocatable.compile.pass.cpp | 243 ++
.../type_traits/lazy_metafunctions.pass.cpp | 131 +
.../type_traits/no_specializations.verify.cpp | 197 +
.../utilities/any/allocator.pass.cpp | 127 +
.../utilities/any/size_and_alignment.pass.cpp | 25 +
.../utilities/any/small_type.pass.cpp | 115 +
...ert.exception_guard.no_exceptions.pass.cpp | 22 +
.../exception_guard.no_exceptions.pass.cpp | 22 +
.../utilities/exception_guard.odr.sh.cpp | 45 +
.../utilities/exception_guard.pass.cpp | 161 +
.../and_then.mandates.verify.cpp | 126 +
.../expected.expected/assert.arrow.pass.cpp | 30 +
.../expected.expected/assert.deref.pass.cpp | 34 +
.../expected.expected/assert.error.pass.cpp | 34 +
.../error_or.mandates.verify.cpp | 72 +
.../no_unique_address.compile.pass.cpp | 75 +
.../noexcept.extension.compile.pass.cpp | 125 +
.../or_else.mandates.verify.cpp | 125 +
.../transform_error.mandates.verify.cpp | 99 +
.../value.observers.verify.cpp | 131 +
.../value_or.mandates.verify.cpp | 66 +
.../class.mandates.verify.cpp | 25 +
.../noexcept.extension.compile.pass.cpp | 46 +
.../swap.mandates.verify.cpp | 26 +
.../and_then.mandates.verify.cpp | 125 +
.../expected.void/assert.deref.pass.cpp | 28 +
.../expected.void/assert.error.pass.cpp | 34 +
.../error_or.mandates.verify.cpp | 71 +
.../no_unique_address.compile.pass.cpp | 68 +
.../noexcept.extension.compile.pass.cpp | 81 +
.../expected.void/or_else.mandates.verify.cpp | 121 +
.../transform_error.mandates.verify.cpp | 102 +
.../expected.void/value.lwg3940.verify.cpp | 51 +
.../test/libcxx-03/utilities/expected/types.h | 51 +
.../utilities/expol/policies.compile.pass.cpp | 44 +
.../format/enable_insertable.compile.pass.cpp | 151 +
.../format.arg/arg_t.compile.pass.cpp | 39 +
.../format.arg/assert.array.pass.cpp | 33 +
.../format.context/types.compile.pass.cpp | 128 +
.../format/format.functions/ascii.pass.cpp | 161 +
.../escaped_output.ascii.pass.cpp | 352 ++
.../code_point_width_estimation.pass.cpp | 86 +
.../format.string.std/concepts_precision.h | 22 +
.../format.string.std/escaped_output.pass.cpp | 104 +
.../extended_grapheme_cluster.h | 3382 ++++++++++++++++
.../extended_grapheme_cluster.pass.cpp | 107 +
.../format.string.std/test_exception.h | 52 +
.../format/no_specializations.verify.cpp | 23 +
.../func.bind.partial/bind_back.pass.cpp | 416 ++
.../func.bind.partial/compose.pass.cpp | 81 +
.../function.objects/func.blocks.arc.pass.mm | 89 +
.../function.objects/func.blocks.pass.cpp | 147 +
.../func.not.fn/not_fn.nttp.compile.pass.cpp | 43 +
.../not_fn.nttp.nodiscard.verify.cpp | 24 +
.../func.require/bullet_1_2_3.pass.cpp | 405 ++
.../func.require/bullet_4_5_6.pass.cpp | 210 +
.../func.require/bullet_7.pass.cpp | 328 ++
.../func.require/invoke.pass.cpp | 46 +
.../func.require/invoke_helpers.h | 375 ++
.../move_reentrant.pass.cpp | 52 +
.../nullptr_t_assign_reentrant.pass.cpp | 52 +
.../function.objects/refwrap/binary.pass.cpp | 87 +
.../refwrap/desugars_to.compile.pass.cpp | 36 +
.../refwrap/layout.binary.compile.pass.cpp | 21 +
.../refwrap/layout.unary.compile.pass.cpp | 22 +
.../function.objects/refwrap/unary.pass.cpp | 85 +
...h_ubsan_unsigned_overflow_ignored.pass.cpp | 43 +
.../intseq/for_each_index_sequence.pass.cpp | 33 +
.../utilities/is_pointer_in_range.pass.cpp | 58 +
.../utilities/is_valid_range.pass.cpp | 70 +
.../pointer.conversion/to_address.pass.cpp | 159 +
.../to_address_on_funcptr.verify.cpp | 20 +
.../to_address_on_function.verify.cpp | 20 +
.../to_address_std_iterators.pass.cpp | 56 +
.../assume_aligned.const_eval.verify.cpp | 48 +
.../assume_aligned.power2.verify.cpp | 31 +
.../util.smartptr/race_condition.pass.cpp | 99 +
.../function_type_default_deleter.verify.cpp | 54 +
.../libcxx.control_block_layout.pass.cpp | 232 ++
...te_shared.array.zero_size.compile.fail.cpp | 22 +
...ke_shared.array.zero_size.compile.fail.cpp | 22 +
.../meta/is_referenceable.compile.pass.cpp | 192 +
.../utilities/meta/meta_base.pass.cpp | 92 +
.../stress_tests/stress_test_is_same.sh.cpp | 55 +
.../stress_test_metafunctions.sh.cpp | 65 +
.../stress_test_variant_overloads_impl.sh.cpp | 119 +
.../libcxx-03/utilities/no_destroy.pass.cpp | 33 +
.../utilities/optional/block.objc.pass.mm | 28 +
.../optional.object.assign/copy.pass.cpp | 78 +
.../optional.object.assign/move.pass.cpp | 75 +
.../optional.object.ctor/copy.pass.cpp | 62 +
.../optional.object.ctor/move.pass.cpp | 63 +
.../assert.dereference.pass.cpp | 51 +
.../assert.op_arrow.pass.cpp | 39 +
.../optional.object/optional_size.pass.cpp | 31 +
.../optional.object/triviality.abi.pass.cpp | 101 +
.../smartptr/unique.ptr/null.pass.cpp | 84 +
.../utilities/template.bitset/assert.pass.cpp | 42 +
.../template.bitset/includes.pass.cpp | 33 +
.../tuple/__tuple_like.compile.pass.cpp | 95 +
.../tuple/no_specializations.verify.cpp | 23 +
.../tuple/tuple.tuple/empty_member.pass.cpp | 49 +
.../tuple.assign/array.extension.pass.cpp | 104 +
.../tuple_array_template_depth.pass.cpp | 37 +
...5_tuple_ref_binding_diagnostics.verify.cpp | 74 +
.../utility/__is_inplace_index.pass.cpp | 37 +
.../utility/__is_inplace_type.pass.cpp | 37 +
.../__murmur2_or_cityhash.abi-v1.pass.cpp | 50 +
.../__murmur2_or_cityhash.abi-v2.pass.cpp | 47 +
.../utility/forward/lifetimebound.verify.cpp | 28 +
.../allocate_vocabulary.attributes.verify.cpp | 19 +
.../assert.deallocate.pass.cpp | 41 +
.../construct_piecewise_pair.pass.cpp | 170 +
...allocate_from_underaligned_buffer.pass.cpp | 61 +
...allocate_in_geometric_progression.pass.cpp | 34 +
.../unsynchronized_buffer.pass.cpp | 211 +
.../mem.res/pmr.availability.verify.cpp | 63 +
.../utility/pairs/pairs.pair/U_V.pass.cpp | 58 +
.../abi.non_trivial_copy_move.pass.cpp | 154 +
.../pairs.pair/abi.trivial_copy_move.pass.cpp | 182 +
.../abi.trivially_copyable.compile.pass.cpp | 68 +
.../pairs.pair/assign_tuple_like.pass.cpp | 100 +
.../const_first_const_second.pass.cpp | 63 +
.../pairs/pairs.pair/const_pair_U_V.pass.cpp | 68 +
.../utility/pairs/pairs.pair/default.pass.cpp | 39 +
.../pair.incomplete.compile.pass.cpp | 22 +
.../pairs.pair/pair.tuple_element.verify.cpp | 21 +
.../pairs/pairs.pair/piecewise.pass.cpp | 41 +
.../pairs/pairs.pair/rv_pair_U_V.pass.cpp | 66 +
.../private_constructor_tag.compile.pass.cpp | 22 +
.../utilities/utility/small_buffer.pass.cpp | 74 +
.../variant/no_specializations.verify.cpp | 23 +
.../variant_alternative.verify.cpp | 37 +
.../variant.variant/variant_size.pass.cpp | 88 +
...lity-with-pedantic-errors.compile.pass.cpp | 22 +
.../vendor/apple/disable-availability.sh.cpp | 49 +
.../apple/system-install-properties.sh.cpp | 46 +
.../vendor/clang-cl/static-lib-exports.sh.cpp | 16 +
.../vendor/ibm/bad_function_call.pass.cpp | 45 +
.../vendor/mingw/static-lib-exports.sh.cpp | 16 +
libcxx/test/libcxx-03/xopen_source.gen.py | 56 +
libcxx/test/libcxx/lit.local.cfg | 4 +
921 files changed, 84519 insertions(+)
create mode 100644 libcxx/test/libcxx-03/Wnon_modular_include_in_module.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.verify.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_nontrivial.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.sorting/assert.min.max.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.oob.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/bad_comparator_values.h
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/invalid_comparator_utilities.h
create mode 100644 libcxx/test/libcxx-03/algorithms/alg.sorting/pstl.is_partitioned.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/bad_iterator_traits.verify.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/callable-requirements-rvalue.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/callable-requirements.verify.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/cpp17_iterator_concepts.verify.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/debug_less.inconsistent.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/debug_less.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/debug_three_way_comp.inconsistent.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/lifetimebound.verify.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/no_specializations.verify.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/nth_element_stability.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/partial_sort_stability.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/pstl.iterator-requirements.verify.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_comparators.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_projections.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/robust_against_using_non_transparent_comparators.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/sort_stability.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/algorithms/vectorization.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/customize_verbose_abort.compile-time.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/default_verbose_abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/debug.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/extensive.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/fast.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/hardening_mode_incorrect_value.sh.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/none.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/override_with_debug_mode.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/override_with_extensive_mode.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/override_with_fast_mode.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/modes/override_with_unchecked_mode.pass.cpp
create mode 100644 libcxx/test/libcxx-03/assertions/single_expression.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.align/align.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.flag/init_bool.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.order/memory_order.underlying_type.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_strong.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_weak.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/assert.ctor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/assert.load.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/assert.store.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/assert.wait.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_strong.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_weak.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/load.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/store.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.ref/wait.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.syn/wait.issue_85107.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.types.generic/atomics.types.float/lockfree.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/bit-int.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/diagnose_invalid_memory_order.verify.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/clang_modules_include.gen.py
create mode 100644 libcxx/test/libcxx-03/clang_tidy.gen.py
create mode 100644 libcxx/test/libcxx-03/clang_tidy.sh.py
create mode 100644 libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/map/at.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/map/at.const.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/map/find.modules.compile.pass.mm
create mode 100644 libcxx/test/libcxx-03/containers/associative/map/scary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/non_const_comparator.incomplete.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/non_const_comparator.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/reference_comparator_abi.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/set/scary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/tree_balance_after_insert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/tree_key_value_traits.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/tree_left_rotate.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/tree_remove.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/tree_right_rotate.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/unord.map/abi.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/unord.map/scary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/unord.set/abi.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/associative/unord.set/scary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.input_range.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.sorted_unique.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.map/scary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.input_range.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.sorted_equivalent.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/assert.sorted_unique.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert.temporary.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert_range.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.set/assert.sorted_unique.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert.temporary.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert_range.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.set/iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat.set/scary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/container.adaptors/flat_helpers.h
create mode 100644 libcxx/test/libcxx-03/containers/container_traits.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/gnu_cxx/hash_map.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/gnu_cxx/hash_map_name_lookup.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/gnu_cxx/hash_set.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/gnu_cxx/hash_set_name_lookup.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/array/triviality.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/abi.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/asan.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/asan_caterpillar.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/asan_turning_off.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/assert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/assert.pop_back.empty.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/incomplete.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/segmented_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/deque/spare_block_handling.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/forwardlist/assert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/forwardlist/bool-conversion.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/abi.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.cons/debug.copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.erase_iter.end.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.emplace.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_rvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_size_value.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_value.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector.bool/abi.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector.bool/assert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector.bool/trivial_for_purposes_of_call.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/abi.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/asan_turning_off.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.back.empty.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.cback.empty.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.cfront.empty.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.cindex.oob.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.front.empty.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.index.oob.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.add.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.decrement.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.index.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/assert.pop_back.empty.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.compare.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.subtract.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/erase.modules.compile.pass.mm
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/exception_safety_exceptions_disabled.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/fill_to_capacity.h
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/invalid_allocator.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/robust_against_adl.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/strings/basic.string/asan.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/strings/basic.string/asan_deque_integration.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/strings/basic.string/asan_short.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/strings/basic.string/asan_turning_off.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/strings/basic.string/asan_vector_integration.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/key_value_traits.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/next_pow2.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/next_prime.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/non_const_comparator.incomplete.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/non_const_comparator.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/assert.max_load_factor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/at.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/at.const.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_const_lvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_rvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/debug.swap.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_const_lvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_rvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.swap.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.insert.hint_const_lvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.swap.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/assert.max_load_factor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/debug.insert.hint_const_lvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/debug.swap.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/unord/unord.set/missing_hash_specialization.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.conversion.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.obs.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_stride.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.stride.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_stride.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.stride.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.index_operator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.stride.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/assert.iterator-indexing.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_sent.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.other_span.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.range.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.back.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.front.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.op_idx.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.first.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.last.pass.cpp
create mode 100644 libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.subspan.pass.cpp
create mode 100644 libcxx/test/libcxx-03/debug/containers.multithread.pass.cpp
create mode 100644 libcxx/test/libcxx-03/debug/containers/sequence_container_iterators.pass.cpp
create mode 100644 libcxx/test/libcxx-03/debug/containers/string.pass.cpp
create mode 100644 libcxx/test/libcxx-03/debug/containers/unord_containers.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.cxx1z.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.c.headers/extern_c.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.c.headers/math_h.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.std_types_t.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.xopen_source.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.default.allocator/allocator_types.cxx20.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.func.adaptor.typedefs/typedefs.depr_in_cxx17.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.function.objects/adaptors.depr_in_cxx11.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/depr.rel_ops/rel_ops.depr_in_cxx20.verify.cpp
create mode 100644 libcxx/test/libcxx-03/depr/exception.unexpected/get_unexpected.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/exception.unexpected/set_unexpected.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/exception.unexpected/unexpected.pass.cpp
create mode 100644 libcxx/test/libcxx-03/depr/exception.unexpected/unexpected_disabled_cpp17.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/algorithm.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/array.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/bit.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/chrono.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/cmath.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/cstddef.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/cstdlib.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/deque.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/filesystem.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/flat_map.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/flat_multimap.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/flat_multiset.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/flat_set.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/format.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/forward_list.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/functional.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/future.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/iterator.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/limits.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/list.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/map.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/memory.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/memory_resource.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/mutex.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/new.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/node_handle.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/pstl.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/queue.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/ranges.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/regex.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/scoped_allocator.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/set.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/stack.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/string.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/string_view.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/system_error_win_codes.pass.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/unordered_map.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/unordered_set.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/utility.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/diagnostics/vector.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/double_include.gen.py
create mode 100644 libcxx/test/libcxx-03/experimental/fexperimental-library.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/extensions/hash/specializations.compile.fail.cpp
create mode 100644 libcxx/test/libcxx-03/extensions/hash/specializations.pass.cpp
create mode 100644 libcxx/test/libcxx-03/extensions/hash_map/const_iterator.compile.fail.cpp
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/ftm_metadata.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/generate_header_test.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/implemented_ftms.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/invalid.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/is_implemented.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/standard_ftms.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/standard_library_headers.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/std_dialects.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/test_data.json
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/version_header.sh.py
create mode 100644 libcxx/test/libcxx-03/feature_test_macro/version_header_implementation.sh.py
create mode 100644 libcxx/test/libcxx-03/fuzzing/format_no_args.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/fuzz.h
create mode 100644 libcxx/test/libcxx-03/fuzzing/make_heap.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/nth_element.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/partial_sort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/partial_sort_copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/partition.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/partition_copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/pop_heap.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/push_heap.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/random.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/regex.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/search.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/sort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/stable_partition.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/stable_sort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/unique.pass.cpp
create mode 100644 libcxx/test/libcxx-03/fuzzing/unique_copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.py
create mode 100644 libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.sh.cpp
create mode 100644 libcxx/test/libcxx-03/header_inclusions.gen.py
create mode 100644 libcxx/test/libcxx-03/headers_in_modulemap.sh.py
create mode 100644 libcxx/test/libcxx-03/include_as_c.sh.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.close.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.cons/wchar_pointer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.members/open_wchar_pointer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/test.dat
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/wchar_pointer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/open_wchar_pointer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/test.dat
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.members/open_wchar_pointer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/fstreams/traits_mismatch.verify.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/file.streams/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/input.output/filesystems/class.directory_entry/directory_entry.mods/last_write_time.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/filesystems/class.path/path.itr/assert.iterator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/filesystems/class.path/path.req/is_pathable.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/filesystems/convert_file_time.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/input.streams/traits_mismatch.verify.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.syn/includes.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/output.streams/traits_mismatch.verify.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/print.fun/transcoding.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_posix.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_windows.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostream.objects/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostreams.base/ios/iostate.flags/clear.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/iostreams.base/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/input.output/stream.buffers/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/input.output/string.streams/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/input.output/string.streams/traits_mismatch.verify.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/aliasing_iterator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/assert.advance.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/assert.next.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/assert.prev.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/bounded_iter/dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/contiguous_iterators.verify.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/integer_like.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/iterator_with_data.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/predef.iterators/counted.iterator/assert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/predef.iterators/iterators.common/assert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/predef.iterators/reverse.iterators/bad_template_argument.verify.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/stream.iterators/ostreambuf.iterator/ostreambuf.iter.ops/failed.pass.cpp
create mode 100644 libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/cxa_deleted_virtual.pass.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/no_specializations.verify.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.c.headers/support.c.headers.other/math.lerp.verify.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.dynamic/assert.nothrow_new_not_overridden_fno_exceptions.pass.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.dynamic/new_dont_return_nullptr.pass.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.apple.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.merged.sh.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.unmerged.sh.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/support.types/cstddef.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/language.support/timespec_get.xopen.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/libcpp_alignof.pass.cpp
create mode 100644 libcxx/test/libcxx-03/libcpp_freestanding.sh.cpp
create mode 100644 libcxx/test/libcxx-03/libcpp_version.gen.py
create mode 100644 libcxx/test/libcxx-03/lint/lint_cmakelists.sh.py
create mode 100644 libcxx/test/libcxx-03/lint/lint_headers.sh.py
create mode 100644 libcxx/test/libcxx-03/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/localization/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/localization/locale.categories/__scan_keyword.pass.cpp
create mode 100644 libcxx/test/libcxx-03/localization/locales/locale.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/localization/locales/locale.category.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp
create mode 100644 libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
create mode 100644 libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.id/id.pass.cpp
create mode 100644 libcxx/test/libcxx-03/localization/locales/use_facet.abort.pass.cpp
create mode 100644 libcxx/test/libcxx-03/mem/mem.res/nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/memory/aligned_allocation_macro.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/allocator_void.trivial.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/allocator_volatile.verify.cpp
create mode 100644 libcxx/test/libcxx-03/memory/is_allocator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/shared_ptr_array.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/trivial_abi/shared_ptr_arg.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_arg.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_array.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_destruction_order.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_ret.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/trivial_abi/weak_ptr_ret.pass.cpp
create mode 100644 libcxx/test/libcxx-03/memory/uninitialized_allocator_copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/minimal_cxx11_configuration.pass.cpp
create mode 100644 libcxx/test/libcxx-03/module_std.gen.py
create mode 100644 libcxx/test/libcxx-03/module_std_compat.gen.py
create mode 100644 libcxx/test/libcxx-03/no_assert_include.gen.py
create mode 100644 libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-clang.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-gcc.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/c.math/constexpr-fns.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/c.math/fdelayed-template-parsing.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/clamp_to_integral.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/complex.number/__sqr.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/complex.number/cmplx.over.pow.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/assert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/assert.get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/assert.get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.mask.array/assert.get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.mask.array/get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.slice.array/assert.get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numarray/class.slice.array/get.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/numeric.ops/midpoint.integer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.device/has-no-random-device.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bernoulli/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bin/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.geo/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.negbin/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.cauchy/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.chisq/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.f/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.lognormal/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.normal/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.t/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.exp/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.extreme/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.gamma/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.poisson/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.weibull/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.discrete/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.pconst/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.plinear/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.int/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.real/bad_engine.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_int_type.verify.cpp
create mode 100644 libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_real_type.verify.cpp
create mode 100644 libcxx/test/libcxx-03/odr_signature.exceptions.sh.cpp
create mode 100644 libcxx/test/libcxx-03/odr_signature.hardening.sh.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/no_specializations.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.access/end.incomplete_type.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.lifetimebound.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/tuple-for-each.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.begin.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-next.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-prev.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.deref.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/types.h
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.common.view/adaptor.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.counted/adaptor.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.drop.while/assert.begin.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/elements_view.no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/sentinel.no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.outer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/types.h
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.join/segmented_iterator.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/types.h
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/arrow.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.default.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.in_place.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/deref.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/empty_object.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/has_value.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/no_unique_address.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/properties.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/types.h
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.reverse/adaptor.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.split/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.adaptors/range.transform/adaptor.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.factories/range.istream.view/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.value.bound.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.factories/range.single.view/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/constraints.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.default.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/deref.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace_from.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.nonprop.cache/has_value.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.utility.helpers/different_from.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.utility.helpers/has_arrow.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.utility.helpers/simple_view.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.internal_constraints.verify.cpp
create mode 100644 libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.static_assert.verify.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/additional_compile_flags/conditional-compile-flags.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/additional_compile_flags/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-compile-flags.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-run.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-error.compile.fail.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-success.compile.fail.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-error.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-success.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.cpp/link-error.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.cpp/run-error.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-error.compile.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-success.compile.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.mm/link-error.compile.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/compile.pass.mm/run-error.compile.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/convenience_substitutions/build_run.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/convenience_substitutions/verify.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/dsl/dsl.sh.py
create mode 100644 libcxx/test/libcxx-03/selftest/dsl/lit.local.cfg
create mode 100644 libcxx/test/libcxx-03/selftest/file_dependencies/a.txt
create mode 100644 libcxx/test/libcxx-03/selftest/file_dependencies/absolute-and-relative-paths.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/file_dependencies/dir/b.txt
create mode 100644 libcxx/test/libcxx-03/selftest/file_dependencies/substitute-in-dependencies.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/gen.cpp/empty.gen.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/gen.cpp/one.gen.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/gen.cpp/two.gen.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.fail.cpp/compile-error.link.fail.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.fail.cpp/link-error.link.fail.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.fail.cpp/link-success.link.fail.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.cpp/compile-error.link.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.cpp/link-error.link.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.cpp/link-success.link.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.cpp/run-error.link.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.mm/compile-error.link.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.mm/link-error.link.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.mm/link-success.link.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/link.pass.mm/run-error.link.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/modules/no-modules.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/modules/std-and-std.compat-module.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/modules/std-module.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/modules/std.compat-module.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/pass.cpp/compile-error.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/pass.cpp/link-error.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/pass.cpp/run-error.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/pass.cpp/run-success.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/pass.cpp/werror.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/pass.mm/compile-error.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/pass.mm/link-error.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/pass.mm/no-arc.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/pass.mm/run-error.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/pass.mm/run-success.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/pass.mm/use-objective-cxx.pass.mm
create mode 100644 libcxx/test/libcxx-03/selftest/remote-substitutions.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/sh.cpp/run-error.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/sh.cpp/run-success.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/sh.cpp/substitutions.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/sh.cpp/werror.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/shell-no-escape-builtins.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/stdin-is-piped.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/test_macros.pass.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/tmpdir-exists.sh.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics-unmarked.verify.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics.verify.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/verify.cpp/no-werror.verify.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/verify.cpp/right-diagnostic.verify.cpp
create mode 100644 libcxx/test/libcxx-03/selftest/verify.cpp/wrong-diagnostic.verify.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/alignof.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/nonnull.verify.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/sizeof.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.access/assert.back.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cback.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cfront.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cindex.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.access/assert.front.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.access/assert.index.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.capacity/PR53170.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.cons/constinit_sso_string.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.cons/debug.iterator.substr.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/c.strings/constexpr.cstring.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/c.strings/constexpr.cwchar.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/string.view/assert.ctor.length.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/string.view/assert.ctor.pointer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp
create mode 100644 libcxx/test/libcxx-03/system_reserved_names.gen.py
create mode 100644 libcxx/test/libcxx-03/thread/atomic.availability.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/barrier.availability.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/futures/futures.task/type.depr.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/futures/futures.task/types.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/latch.availability.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/semaphore.availability.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.barrier/assert.arrive.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.barrier/assert.ctor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.condition/PR30202_notify_from_pthread_created_thread.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.latch/assert.arrive_and_wait.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.latch/assert.count_down.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.latch/assert.ctor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_requires_capability.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.semaphore/assert.ctor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.semaphore/assert.release.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.shared_mutex/thread_safety.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.shared_timed_mutex/thread_safety.verify.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.stoptoken/atomic_unique_lock.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_list_view.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_shared_ptr.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.threads/create_late.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/types.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
create mode 100644 libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.signals.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/convert_to_tm.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.from_utc.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.to_utc.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.from_utc.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.to_utc.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.clock/time.clock.utc/get_leap_second_info.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/from_sys.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/to_sys.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/leap_seconds.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/links.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/rules.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.list/erase_after.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/version.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.db/zones.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.local/ostream.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/choose.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.pass.cpp
create mode 100644 libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.rule_selection.pass.cpp
create mode 100644 libcxx/test/libcxx-03/transitive_includes.gen.py
create mode 100644 libcxx/test/libcxx-03/transitive_includes/cxx03.csv
create mode 100644 libcxx/test/libcxx-03/transitive_includes/cxx11.csv
create mode 100644 libcxx/test/libcxx-03/transitive_includes/cxx14.csv
create mode 100644 libcxx/test/libcxx-03/transitive_includes/cxx17.csv
create mode 100644 libcxx/test/libcxx-03/transitive_includes/cxx20.csv
create mode 100644 libcxx/test/libcxx-03/transitive_includes/cxx23.csv
create mode 100644 libcxx/test/libcxx-03/transitive_includes/cxx26.csv
create mode 100755 libcxx/test/libcxx-03/transitive_includes/to_csv.py
create mode 100644 libcxx/test/libcxx-03/type_traits/convert_to_integral.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/datasizeof.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/desugars_to.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_always_bitcastable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_callable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_constant_evaluated.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_implicitly_default_constructible.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_pointer.arc.pass.mm
create mode 100644 libcxx/test/libcxx-03/type_traits/is_replaceable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_scalar.objc.pass.mm
create mode 100644 libcxx/test/libcxx-03/type_traits/is_specialization.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_specialization.verify.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_trivially_comparable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/lazy_metafunctions.pass.cpp
create mode 100644 libcxx/test/libcxx-03/type_traits/no_specializations.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/any/allocator.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/any/size_and_alignment.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/any/small_type.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/assert.exception_guard.no_exceptions.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/exception_guard.no_exceptions.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/exception_guard.odr.sh.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/exception_guard.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/and_then.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.arrow.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.deref.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.error.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/error_or.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/or_else.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/transform_error.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/value.observers.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.expected/value_or.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.unexpected/class.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.unexpected/swap.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/and_then.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/assert.deref.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/assert.error.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/error_or.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/no_unique_address.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/noexcept.extension.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/or_else.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/transform_error.mandates.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/expected.void/value.lwg3940.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/expected/types.h
create mode 100644 libcxx/test/libcxx-03/utilities/expol/policies.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/enable_insertable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/assert.array.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.formatter/format.context/types.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.functions/ascii.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.functions/escaped_output.ascii.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/code_point_width_estimation.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/concepts_precision.h
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/escaped_output.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.h
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/test_exception.h
create mode 100644 libcxx/test/libcxx-03/utilities/format/no_specializations.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/bind_back.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/compose.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.blocks.arc.pass.mm
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.blocks.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.nodiscard.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/move_reentrant.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign_reentrant.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/refwrap/binary.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.binary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.unary.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/refwrap/unary.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/function.objects/unord.hash/murmur2_or_cityhash_ubsan_unsigned_overflow_ignored.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/intseq/for_each_index_sequence.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_funcptr.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_function.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.const_eval.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/util.smartptr/race_condition.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/libcxx.control_block_layout.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.zero_size.compile.fail.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.zero_size.compile.fail.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/meta/meta_base.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_is_same.sh.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_metafunctions.sh.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_variant_overloads_impl.sh.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/block.objc.pass.mm
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.dereference.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/optional_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/optional/optional.object/triviality.abi.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/smartptr/unique.ptr/null.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/template.bitset/assert.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/template.bitset/includes.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/tuple/__tuple_like.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/tuple/no_specializations.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/empty_member.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/array.extension.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/__is_inplace_index.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/__is_inplace_type.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v1.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v2.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/forward/lifetimebound.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate_vocabulary.attributes.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/assert.deallocate.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/mem.res/pmr.availability.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/U_V.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/assign_tuple_like.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/default.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.incomplete.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.tuple_element.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/private_constructor_tag.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/utility/small_buffer.pass.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/variant/no_specializations.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/variant/variant.variant/variant.helper/variant_alternative.verify.cpp
create mode 100644 libcxx/test/libcxx-03/utilities/variant/variant.variant/variant_size.pass.cpp
create mode 100644 libcxx/test/libcxx-03/vendor/apple/availability-with-pedantic-errors.compile.pass.cpp
create mode 100644 libcxx/test/libcxx-03/vendor/apple/disable-availability.sh.cpp
create mode 100644 libcxx/test/libcxx-03/vendor/apple/system-install-properties.sh.cpp
create mode 100644 libcxx/test/libcxx-03/vendor/clang-cl/static-lib-exports.sh.cpp
create mode 100644 libcxx/test/libcxx-03/vendor/ibm/bad_function_call.pass.cpp
create mode 100644 libcxx/test/libcxx-03/vendor/mingw/static-lib-exports.sh.cpp
create mode 100644 libcxx/test/libcxx-03/xopen_source.gen.py
diff --git a/libcxx/test/libcxx-03/Wnon_modular_include_in_module.compile.pass.cpp b/libcxx/test/libcxx-03/Wnon_modular_include_in_module.compile.pass.cpp
new file mode 100644
index 0000000000000..aa7a6d98d7d68
--- /dev/null
+++ b/libcxx/test/libcxx-03/Wnon_modular_include_in_module.compile.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: target={{.*}}-apple-{{.*}}
+// UNSUPPORTED: c++03
+
+// This test ensures that libc++ supports being compiled with modules enabled and with
+// -Wnon-modular-include-in-module. This effectively checks that we don't include any
+// non-modular header from the library.
+//
+// Since most underlying platforms are not modularized properly, this test currently only
+// works on Apple platforms.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wnon-modular-include-in-module -Wsystem-headers-in-module=std -fmodules -fcxx-modules
+
+#include <vector>
diff --git a/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.pass.cpp
new file mode 100644
index 0000000000000..4e51014f20b18
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.cxx1z.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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class RandomAccessIterator>
+// void
+// random_shuffle(RandomAccessIterator first, RandomAccessIterator last);
+//
+// template <class RandomAccessIterator, class RandomNumberGenerator>
+// void
+// random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+// RandomNumberGenerator& rand);
+
+//
+// In C++17, random_shuffle has been removed.
+// However, for backwards compatibility, if _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
+// is defined before including <algorithm>, then random_shuffle will be restored.
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <algorithm>
+#include <cstddef>
+#include <vector>
+
+#include "test_macros.h"
+
+struct gen
+{
+ std::ptrdiff_t operator()(std::ptrdiff_t n)
+ {
+ return n-1;
+ }
+};
+
+
+int main(int, char**)
+{
+ std::vector<int> v;
+ std::random_shuffle(v.begin(), v.end());
+ gen r;
+ std::random_shuffle(v.begin(), v.end(), r);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.verify.cpp b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.verify.cpp
new file mode 100644
index 0000000000000..057f126a93cfe
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/alg.random.shuffle/random_shuffle.depr_in_cxx14.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class RandomAccessIterator>
+// void
+// random_shuffle(RandomAccessIterator first, RandomAccessIterator last);
+//
+// template <class RandomAccessIterator, class RandomNumberGenerator>
+// void
+// random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+// RandomNumberGenerator& rand);
+
+// UNSUPPORTED: c++03, c++11
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
+
+#include <algorithm>
+#include <cstddef>
+
+#include "test_macros.h"
+
+struct gen
+{
+ std::ptrdiff_t operator()(std::ptrdiff_t n)
+ {
+ return n-1;
+ }
+};
+
+
+void f() {
+ int v[1] = {1};
+ std::random_shuffle(&v[0], &v[1]); // expected-warning {{'random_shuffle<int *>' is deprecated}}
+ gen r;
+ std::random_shuffle(&v[0], &v[1], r); // expected-warning {{'random_shuffle<int *, gen &>' is deprecated}}
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_nontrivial.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_nontrivial.pass.cpp
new file mode 100644
index 0000000000000..0c5ae84d97700
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_nontrivial.pass.cpp
@@ -0,0 +1,331 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// In the modules build, adding another overload of `memmove` doesn't work.
+// UNSUPPORTED: clang-modules-build
+// GCC complains about "ambiguating" `__builtin_memmove`.
+// UNSUPPORTED: gcc
+
+// <algorithm>
+
+#include <cassert>
+#include <cstddef>
+
+// These tests check that `std::copy` and `std::move` (including their variations like `copy_n`) don't forward to
+// `std::memmove` when doing so would be observable.
+
+// This template is a better match than the actual `builtin_memmove` (it can match the pointer type exactly, without an
+// implicit conversion to `void*`), so it should hijack the call inside `std::copy` and similar algorithms if it's made.
+template <class Dst, class Src>
+constexpr void* __builtin_memmove(Dst*, Src*, std::size_t) {
+ assert(false);
+ return nullptr;
+}
+
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <ranges>
+#include <type_traits>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+// S1 and S2 are simple structs that are convertible to each other and have the same bit representation.
+struct S1 {
+ int x;
+
+ constexpr S1() = default;
+ constexpr S1(int set_x) : x(set_x) {}
+
+ friend constexpr bool operator==(const S1& lhs, const S1& rhs) { return lhs.x == rhs.x; }
+};
+
+struct S2 {
+ int x;
+
+ constexpr S2() = default;
+ constexpr S2(int set_x) : x(set_x) {}
+ constexpr S2(S1 from) : x(from.x) {}
+
+ friend constexpr bool operator==(const S1& lhs, const S2& rhs) { return lhs.x == rhs.x; }
+ friend constexpr bool operator==(const S2& lhs, const S2& rhs) { return lhs.x == rhs.x; }
+};
+
+// U1 and U2 are simple unions that are convertible to each other and have the same bit representation.
+union U1 {
+ int x;
+
+ constexpr U1() = default;
+ constexpr U1(int set_x) : x(set_x) {}
+
+ friend constexpr bool operator==(const U1& lhs, const U1& rhs) { return lhs.x == rhs.x; }
+};
+
+union U2 {
+ int x;
+
+ constexpr U2() = default;
+ constexpr U2(int set_x) : x(set_x) {}
+ constexpr U2(U1 from) : x(from.x) {}
+
+ friend constexpr bool operator==(const U1& lhs, const U2& rhs) { return lhs.x == rhs.x; }
+ friend constexpr bool operator==(const U2& lhs, const U2& rhs) { return lhs.x == rhs.x; }
+};
+
+struct NonTrivialMoveAssignment {
+ int i;
+
+ constexpr NonTrivialMoveAssignment() = default;
+ constexpr NonTrivialMoveAssignment(int set_i) : i(set_i) {}
+
+ constexpr NonTrivialMoveAssignment(NonTrivialMoveAssignment&& rhs) = default;
+ constexpr NonTrivialMoveAssignment& operator=(NonTrivialMoveAssignment&& rhs) noexcept {
+ i = rhs.i;
+ return *this;
+ }
+
+ constexpr friend bool operator==(const NonTrivialMoveAssignment&, const NonTrivialMoveAssignment&) = default;
+};
+
+static_assert(!std::is_trivially_move_assignable_v<NonTrivialMoveAssignment>);
+static_assert(!std::is_trivially_assignable<NonTrivialMoveAssignment&, NonTrivialMoveAssignment&>::value);
+
+struct NonTrivialMoveCtr {
+ int i;
+
+ constexpr NonTrivialMoveCtr() = default;
+ constexpr NonTrivialMoveCtr(int set_i) : i(set_i) {}
+
+ constexpr NonTrivialMoveCtr(NonTrivialMoveCtr&& rhs) noexcept : i(rhs.i) {}
+ constexpr NonTrivialMoveCtr& operator=(NonTrivialMoveCtr&& rhs) = default;
+
+ constexpr friend bool operator==(const NonTrivialMoveCtr&, const NonTrivialMoveCtr&) = default;
+};
+
+static_assert(std::is_trivially_move_assignable_v<NonTrivialMoveCtr>);
+static_assert(!std::is_trivially_copyable_v<NonTrivialMoveCtr>);
+
+struct NonTrivialCopyAssignment {
+ int i;
+
+ constexpr NonTrivialCopyAssignment() = default;
+ constexpr NonTrivialCopyAssignment(int set_i) : i(set_i) {}
+
+ constexpr NonTrivialCopyAssignment(const NonTrivialCopyAssignment& rhs) = default;
+ constexpr NonTrivialCopyAssignment& operator=(const NonTrivialCopyAssignment& rhs) {
+ i = rhs.i;
+ return *this;
+ }
+
+ constexpr friend bool operator==(const NonTrivialCopyAssignment&, const NonTrivialCopyAssignment&) = default;
+};
+
+static_assert(!std::is_trivially_copy_assignable_v<NonTrivialCopyAssignment>);
+
+struct NonTrivialCopyCtr {
+ int i;
+
+ constexpr NonTrivialCopyCtr() = default;
+ constexpr NonTrivialCopyCtr(int set_i) : i(set_i) {}
+
+ constexpr NonTrivialCopyCtr(const NonTrivialCopyCtr& rhs) : i(rhs.i) {}
+ constexpr NonTrivialCopyCtr& operator=(const NonTrivialCopyCtr& rhs) = default;
+
+ constexpr friend bool operator==(const NonTrivialCopyCtr&, const NonTrivialCopyCtr&) = default;
+};
+
+static_assert(std::is_trivially_copy_assignable_v<NonTrivialCopyCtr>);
+static_assert(!std::is_trivially_copyable_v<NonTrivialCopyCtr>);
+
+template <class T>
+constexpr T make(int from) {
+ return T(from);
+}
+
+template <typename PtrT, typename T = std::remove_pointer_t<PtrT>>
+static T make_internal_array[5] = {T(), T(), T(), T(), T()};
+
+template <class T>
+requires std::is_pointer_v<T>
+constexpr T make(int i) {
+ if constexpr (!std::same_as<std::remove_pointer_t<T>, void>) {
+ return make_internal_array<T> + i;
+ } else {
+ return make_internal_array<int> + i;
+ }
+}
+
+template <class InIter, template <class> class SentWrapper, class OutIter, class Func>
+constexpr void test_one(Func func) {
+ using From = typename std::iterator_traits<InIter>::value_type;
+ using To = typename std::iterator_traits<OutIter>::value_type;
+
+ {
+ const std::size_t N = 5;
+
+ From input[N] = {make<From>(0), make<From>(1), make<From>(2), make<From>(3), make<From>(4)};
+ To output[N];
+
+ auto in = InIter(input);
+ auto in_end = InIter(input + N);
+ auto sent = SentWrapper<decltype(in_end)>(in_end);
+ auto out = OutIter(output);
+
+ func(in, sent, out, N);
+ if constexpr (!std::same_as<To, bool>) {
+ assert(std::equal(input, input + N, output));
+ } else {
+ bool expected[N] = {false, true, true, true, true};
+ assert(std::equal(output, output + N, expected));
+ }
+ }
+
+ {
+ const std::size_t N = 0;
+
+ From input[1] = {make<From>(1)};
+ To output[1] = {make<To>(2)};
+
+ auto in = InIter(input);
+ auto in_end = InIter(input + N);
+ auto sent = SentWrapper<decltype(in_end)>(in_end);
+ auto out = OutIter(output);
+
+ func(in, sent, out, N);
+ assert(output[0] == make<To>(2));
+ }
+}
+
+template <class InIter, template <class> class SentWrapper, class OutIter>
+constexpr void test_copy() {
+ // Classic.
+ if constexpr (std::same_as<InIter, SentWrapper<InIter>>) {
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::copy(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::copy_backward(first, last, out + n);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto, auto out, std::size_t n) {
+ std::copy_n(first, n, out);
+ });
+ }
+
+ // Ranges.
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::copy(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::copy_backward(first, last, out + n);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto, auto out, std::size_t n) {
+ std::ranges::copy_n(first, n, out);
+ });
+}
+
+template <class InIter, template <class> class SentWrapper, class OutIter>
+constexpr void test_move() {
+ if constexpr (std::same_as<InIter, SentWrapper<InIter>>) {
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::move(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::move_backward(first, last, out + n);
+ });
+ }
+
+ // Ranges.
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::move(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::move_backward(first, last, out + n);
+ });
+}
+
+template <class From, class To = From>
+constexpr void test_copy_with_type() {
+ using FromIter = contiguous_iterator<From*>;
+ using ToIter = contiguous_iterator<To*>;
+
+ test_copy<FromIter, std::type_identity_t, ToIter>();
+ test_copy<FromIter, sized_sentinel, ToIter>();
+ test_copy<FromIter, std::type_identity_t, To*>();
+ test_copy<From*, std::type_identity_t, To*>();
+ test_copy<From*, std::type_identity_t, ToIter>();
+}
+
+template <class From, class To = From>
+constexpr void test_move_with_type() {
+ using FromIter = contiguous_iterator<From*>;
+ using ToIter = contiguous_iterator<To*>;
+
+ test_move<FromIter, std::type_identity_t, ToIter>();
+ test_move<FromIter, sized_sentinel, ToIter>();
+ test_move<FromIter, std::type_identity_t, To*>();
+ test_move<From*, std::type_identity_t, To*>();
+ test_move<From*, std::type_identity_t, ToIter>();
+}
+
+template <class From, class To>
+constexpr void test_copy_and_move() {
+ test_copy_with_type<From, To>();
+ test_move_with_type<From, To>();
+}
+
+template <class From, class To>
+constexpr void test_both_directions() {
+ test_copy_and_move<From, To>();
+ if (!std::same_as<From, To>) {
+ test_copy_and_move<To, From>();
+ }
+}
+
+constexpr bool test() {
+ test_copy_with_type<NonTrivialCopyAssignment>();
+ test_move_with_type<NonTrivialMoveAssignment>();
+
+ // Copying from a smaller type into a larger type and vice versa.
+ test_both_directions<char, int>();
+ test_both_directions<std::int32_t, std::int64_t>();
+
+ // Copying between types with different representations.
+ test_both_directions<int, float>();
+ // Copying from `bool` to `char` will invoke the optimization, so only check one direction.
+ test_copy_and_move<char, bool>();
+
+ // Copying between different structs with the same representation (there is no way to guarantee the representation is
+ // the same).
+ test_copy_and_move<S1, S2>();
+ // Copying between different unions with the same representation.
+ test_copy_and_move<U1, U2>();
+
+ // Copying from a regular pointer to a void pointer (these are not considered trivially copyable).
+ test_copy_and_move<int*, void*>();
+ // Copying from a non-const pointer to a const pointer (these are not considered trivially copyable).
+ test_copy_and_move<int*, const int*>();
+
+ // `memmove` does not support volatile pointers.
+ // (See also https://github.com/llvm/llvm-project/issues/28901).
+ if (!std::is_constant_evaluated()) {
+ test_both_directions<volatile int, int>();
+ test_both_directions<volatile int, volatile int>();
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp
new file mode 100644
index 0000000000000..ff10c7919200d
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_trivial.pass.cpp
@@ -0,0 +1,334 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// In the modules build, adding another overload of `memmove` doesn't work.
+// UNSUPPORTED: clang-modules-build
+// GCC complains about "ambiguating" `__builtin_memmove`.
+// UNSUPPORTED: gcc
+
+// <algorithm>
+
+// These tests check that `std::copy` and `std::move` (including their variations like `copy_n`) forward to
+// `memmove` when possible.
+
+#include <cstddef>
+
+struct Foo {
+ int i = 0;
+
+ Foo() = default;
+ Foo(int set_i) : i(set_i) {}
+
+ friend bool operator==(const Foo&, const Foo&) = default;
+};
+
+static bool memmove_called = false;
+
+// This template is a better match than the actual `builtin_memmove` (it can match the pointer type exactly, without an
+// implicit conversion to `void*`), so it should hijack the call inside `std::copy` and similar algorithms if it's made.
+template <class Dst, class Src>
+constexpr void* __builtin_memmove(Dst* dst, Src* src, std::size_t count) {
+ memmove_called = true;
+ return __builtin_memmove(static_cast<void*>(dst), static_cast<const void*>(src), count);
+}
+
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <limits>
+#include <ranges>
+#include <type_traits>
+
+#include "test_iterators.h"
+
+static_assert(std::is_trivially_copyable_v<Foo>);
+
+// To test pointers to functions.
+void Func() {}
+using FuncPtr = decltype(&Func);
+
+// To test pointers to members.
+struct S {
+ int mem_obj = 0;
+ void MemFunc() {}
+};
+using MemObjPtr = decltype(&S::mem_obj);
+using MemFuncPtr = decltype(&S::MemFunc);
+
+// To test bitfields.
+struct BitfieldS {
+ unsigned char b1 : 3;
+ unsigned char : 2;
+ unsigned char b2 : 5;
+ friend bool operator==(const BitfieldS&, const BitfieldS&) = default;
+};
+
+// To test non-default alignment.
+struct AlignedS {
+ alignas(64) int x;
+ alignas(8) int y;
+ friend bool operator==(const AlignedS&, const AlignedS&) = default;
+};
+
+template <class T>
+T make(int from) {
+ return T(from);
+}
+
+template <class T>
+requires (std::is_pointer_v<T> && !std::is_function_v<std::remove_pointer_t<T>>)
+T make(int i) {
+ static std::remove_pointer_t<T> arr[8];
+ return arr + i;
+}
+
+template <class T>
+requires std::same_as<T, FuncPtr>
+FuncPtr make(int) {
+ return &Func;
+}
+
+template <class T>
+requires std::same_as<T, MemObjPtr>
+MemObjPtr make(int) {
+ return &S::mem_obj;
+}
+
+template <class T>
+requires std::same_as<T, MemFuncPtr>
+MemFuncPtr make(int) {
+ return &S::MemFunc;
+}
+
+template <class T>
+requires std::same_as<T, BitfieldS>
+BitfieldS make(int x) {
+ BitfieldS result = {};
+ result.b1 = x;
+ result.b2 = x;
+ return result;
+}
+
+template <class T>
+requires std::same_as<T, AlignedS>
+AlignedS make(int x) {
+ AlignedS result;
+ result.x = x;
+ result.y = x;
+ return result;
+}
+
+template <class InIter, template <class> class SentWrapper, class OutIter, class Func>
+void test_one(Func func) {
+ using From = std::iter_value_t<InIter>;
+ using To = std::iter_value_t<OutIter>;
+
+ // Normal case.
+ {
+ const std::size_t N = 4;
+
+ From input[N] = {make<From>(1), make<From>(2), make<From>(3), make<From>(4)};
+ To output[N];
+
+ auto in = InIter(input);
+ auto in_end = InIter(input + N);
+ auto sent = SentWrapper<decltype(in_end)>(in_end);
+ auto out = OutIter(output);
+
+ assert(!memmove_called);
+ func(in, sent, out, N);
+ assert(memmove_called);
+ memmove_called = false;
+
+ assert(std::equal(input, input + N, output, [](const From& lhs, const To& rhs) {
+ // Prevents warnings/errors due to mismatched signed-ness.
+ if constexpr (std::convertible_to<From, To>) {
+ return static_cast<To>(lhs) == rhs;
+ } else if constexpr (std::convertible_to<To, From>) {
+ return lhs == static_cast<From>(rhs);
+ }
+ }));
+ }
+}
+
+template <class InIter, template <class> class SentWrapper, class OutIter>
+void test_copy_and_move() {
+ // Classic.
+ if constexpr (std::same_as<InIter, SentWrapper<InIter>>) {
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::copy(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::copy_backward(first, last, out + n);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto, auto out, std::size_t n) {
+ std::copy_n(first, n, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::move(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::move_backward(first, last, out + n);
+ });
+ }
+
+ // Ranges.
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::copy(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::copy_backward(first, last, out + n);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto, auto out, std::size_t n) {
+ std::ranges::copy_n(first, n, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::move(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter>([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::move_backward(first, last, out + n);
+ });
+}
+
+template <class From, class To, template <class> class SentWrapper, bool BothDirections = !std::same_as<From, To>>
+void test_all_permutations_from_to_sent() {
+ test_copy_and_move<From*, SentWrapper, To*>();
+ test_copy_and_move<contiguous_iterator<From*>, SentWrapper, To*>();
+ test_copy_and_move<From*, SentWrapper, contiguous_iterator<To*>>();
+ test_copy_and_move<contiguous_iterator<From*>, SentWrapper, contiguous_iterator<To*>>();
+
+ if (BothDirections) {
+ test_copy_and_move<To*, SentWrapper, From*>();
+ test_copy_and_move<contiguous_iterator<To*>, SentWrapper, From*>();
+ test_copy_and_move<To*, SentWrapper, contiguous_iterator<From*>>();
+ test_copy_and_move<contiguous_iterator<To*>, SentWrapper, contiguous_iterator<From*>>();
+ }
+}
+
+void test_different_signedness() {
+ auto check = [](auto alg) {
+ // Signed -> unsigned.
+ {
+ constexpr int N = 3;
+ constexpr auto min_value = std::numeric_limits<int>::min();
+
+ int in[N] = {-1, min_value / 2, min_value};
+ unsigned int out[N];
+ unsigned int expected[N] = {
+ static_cast<unsigned int>(in[0]),
+ static_cast<unsigned int>(in[1]),
+ static_cast<unsigned int>(in[2]),
+ };
+
+ assert(!memmove_called);
+ alg(in, in + N, out, N);
+ assert(memmove_called);
+ memmove_called = false;
+
+ assert(std::equal(out, out + N, expected));
+ }
+
+ // Unsigned -> signed.
+ {
+ constexpr int N = 3;
+ constexpr auto max_signed = std::numeric_limits<int>::max();
+ constexpr auto max_unsigned = std::numeric_limits<unsigned int>::max();
+
+ unsigned int in[N] = {static_cast<unsigned int>(max_signed) + 1, max_unsigned / 2, max_unsigned};
+ int out[N];
+ int expected[N] = {
+ static_cast<int>(in[0]),
+ static_cast<int>(in[1]),
+ static_cast<int>(in[2]),
+ };
+
+ assert(!memmove_called);
+ alg(in, in + N, out, N);
+ assert(memmove_called);
+ memmove_called = false;
+
+ assert(std::equal(out, out + N, expected));
+ }
+ };
+
+ check([](auto first, auto last, auto out, std::size_t) {
+ std::copy(first, last, out);
+ });
+ check([](auto first, auto last, auto out, std::size_t n) {
+ std::copy_backward(first, last, out + n);
+ });
+ check([](auto first, auto, auto out, std::size_t n) {
+ std::copy_n(first, n, out);
+ });
+ check([](auto first, auto last, auto out, std::size_t) {
+ std::move(first, last, out);
+ });
+ check([](auto first, auto last, auto out, std::size_t n) {
+ std::move_backward(first, last, out + n);
+ });
+
+ // Ranges.
+ check([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::copy(first, last, out);
+ });
+ check([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::copy_backward(first, last, out + n);
+ });
+ check([](auto first, auto, auto out, std::size_t n) {
+ std::ranges::copy_n(first, n, out);
+ });
+ check([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::move(first, last, out);
+ });
+ check([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::move_backward(first, last, out + n);
+ });
+}
+
+void test() {
+ // Built-in.
+ test_all_permutations_from_to_sent<int, int, std::type_identity_t>();
+ // User-defined.
+ test_all_permutations_from_to_sent<Foo, Foo, std::type_identity_t>();
+
+ // Conversions.
+ test_all_permutations_from_to_sent<char32_t, std::int32_t, sized_sentinel>();
+ test_all_permutations_from_to_sent<std::int32_t, std::uint32_t, sized_sentinel>();
+ // Conversion from `bool` to `char` invokes the optimization (the set of values for `char` is a superset of the set of
+ // values for `bool`), but the other way round cannot.
+ test_all_permutations_from_to_sent<bool, char, sized_sentinel, /*BothDirections=*/false>();
+
+ // Copying between regular pointers.
+ test_copy_and_move<int**, std::type_identity_t, int**>();
+
+ // Copying between pointers to functions.
+ test_copy_and_move<FuncPtr*, std::type_identity_t, FuncPtr*>();
+
+ // Copying between pointers to members.
+ test_copy_and_move<MemObjPtr*, std::type_identity_t, MemObjPtr*>();
+ test_copy_and_move<MemFuncPtr*, std::type_identity_t, MemFuncPtr*>();
+
+ // Copying structs with bitfields.
+ test_copy_and_move<BitfieldS*, std::type_identity_t, BitfieldS*>();
+
+ // Copying objects with non-default alignment.
+ test_copy_and_move<AlignedS*, std::type_identity_t, AlignedS*>();
+
+ // Copying integers with different signedness produces the same results as built-in assignment.
+ test_different_signedness();
+}
+
+int main(int, char**) {
+ test();
+ // The test relies on a global variable, so it cannot be made `constexpr`; the `memmove` optimization is not used in
+ // `constexpr` mode anyway.
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp
new file mode 100644
index 0000000000000..2a85e7b5ddcc3
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.modifying.operations/copy_move_unwrap_reverse.pass.cpp
@@ -0,0 +1,141 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <algorithm>
+
+// These tests checks that `std::copy` and `std::move` (including their variations like `copy_n`) can unwrap multiple
+// layers of reverse iterators.
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <type_traits>
+
+#include "test_iterators.h"
+
+template <std::size_t N, class Iter>
+requires (N == 0)
+constexpr auto wrap_n_times(Iter i) {
+ return i;
+}
+
+template <std::size_t N, class Iter>
+requires (N != 0)
+constexpr auto wrap_n_times(Iter i) {
+ return std::make_reverse_iterator(wrap_n_times<N - 1>(i));
+}
+
+static_assert(std::is_same_v<decltype(wrap_n_times<2>(std::declval<int*>())),
+ std::reverse_iterator<std::reverse_iterator<int*>>>);
+
+template <class InIter, template <class> class SentWrapper, class OutIter, std::size_t W1, size_t W2, class Func>
+constexpr void test_one(Func func) {
+ using From = std::iter_value_t<InIter>;
+ using To = std::iter_value_t<OutIter>;
+
+ const std::size_t N = 4;
+
+ From input[N] = {{1}, {2}, {3}, {4}};
+ To output[N];
+
+ auto in = wrap_n_times<W1>(InIter(input));
+ auto in_end = wrap_n_times<W1>(InIter(input + N));
+ auto sent = SentWrapper<decltype(in_end)>(in_end);
+ auto out = wrap_n_times<W2>(OutIter(output));
+
+ func(in, sent, out, N);
+
+ assert(std::equal(input, input + N, output, [](const From& lhs, const To& rhs) {
+ // Prevents warnings/errors due to mismatched signed-ness.
+ return lhs == static_cast<From>(rhs);
+ }));
+}
+
+template <class InIter, template <class> class SentWrapper, class OutIter, std::size_t W1, size_t W2>
+constexpr void test_copy_and_move() {
+ // Classic.
+ if constexpr (std::same_as<InIter, SentWrapper<InIter>>) {
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t) {
+ std::copy(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t n) {
+ std::copy_backward(first, last, out + n);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto, auto out, std::size_t n) {
+ std::copy_n(first, n, out);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t) {
+ std::move(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t n) {
+ std::move_backward(first, last, out + n);
+ });
+ }
+
+ // Ranges.
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::copy(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::copy_backward(first, last, out + n);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto, auto out, std::size_t n) {
+ std::ranges::copy_n(first, n, out);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t) {
+ std::ranges::move(first, last, out);
+ });
+ test_one<InIter, SentWrapper, OutIter, W1, W2>([](auto first, auto last, auto out, std::size_t n) {
+ std::ranges::move_backward(first, last, out + n);
+ });
+}
+
+template <std::size_t W1, size_t W2, class From, class To, template <class> class SentWrapper>
+constexpr void test_all_permutations_with_counts_from_to_sent() {
+ test_copy_and_move<From*, SentWrapper, To*, W1, W2>();
+ test_copy_and_move<contiguous_iterator<From*>, SentWrapper, To*, W1, W2>();
+ test_copy_and_move<From*, SentWrapper, contiguous_iterator<To*>, W1, W2>();
+ test_copy_and_move<contiguous_iterator<From*>, SentWrapper, contiguous_iterator<To*>, W1, W2>();
+
+ if (!std::same_as<From, To>) {
+ test_copy_and_move<To*, SentWrapper, From*, W1, W2>();
+ test_copy_and_move<contiguous_iterator<To*>, SentWrapper, From*, W1, W2>();
+ test_copy_and_move<To*, SentWrapper, contiguous_iterator<From*>, W1, W2>();
+ test_copy_and_move<contiguous_iterator<To*>, SentWrapper, contiguous_iterator<From*>, W1, W2>();
+ }
+}
+
+template <std::size_t W1, size_t W2>
+constexpr void test_all_permutations_with_counts() {
+ test_all_permutations_with_counts_from_to_sent<W1, W2, int, int, std::type_identity_t>();
+ test_all_permutations_with_counts_from_to_sent<W1, W2, int, int, sized_sentinel>();
+ test_all_permutations_with_counts_from_to_sent<W1, W2, std::int32_t, std::uint32_t, std::type_identity_t>();
+ test_all_permutations_with_counts_from_to_sent<W1, W2, std::int32_t, std::uint32_t, sized_sentinel>();
+}
+
+constexpr bool test() {
+ test_all_permutations_with_counts<0, 0>();
+ test_all_permutations_with_counts<0, 2>();
+ test_all_permutations_with_counts<2, 0>();
+ test_all_permutations_with_counts<2, 2>();
+ test_all_permutations_with_counts<2, 4>();
+ test_all_permutations_with_counts<4, 4>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.pass.cpp
new file mode 100644
index 0000000000000..cc48a81194e36
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.sorting/alg.heap.operations/make.heap/complexity.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
+
+// <algorithm>
+
+// template<class Iter>
+// void make_heap(Iter first, Iter last);
+
+#include <algorithm>
+#include <cassert>
+#include <random>
+#include <vector>
+
+#include "test_macros.h"
+
+struct Stats {
+ int compared = 0;
+ int copied = 0;
+ int moved = 0;
+} stats;
+
+struct MyInt {
+ int value;
+ explicit MyInt(int xval) : value(xval) {}
+ MyInt(const MyInt& other) : value(other.value) { ++stats.copied; }
+ MyInt(MyInt&& other) : value(other.value) { ++stats.moved; }
+ MyInt& operator=(const MyInt& other) {
+ value = other.value;
+ ++stats.copied;
+ return *this;
+ }
+ MyInt& operator=(MyInt&& other) {
+ value = other.value;
+ ++stats.moved;
+ return *this;
+ }
+ friend bool operator<(const MyInt& a, const MyInt& b) {
+ ++stats.compared;
+ return a.value < b.value;
+ }
+};
+
+int main(int, char**)
+{
+ const int N = 100'000;
+ std::vector<MyInt> v;
+ v.reserve(N);
+ std::mt19937 g;
+ for (int i = 0; i < N; ++i)
+ v.emplace_back(g());
+
+ // The exact stats of our current implementation are recorded here.
+ // If something changes to make them go a bit up or down, that's probably fine,
+ // and we can just update this test.
+ // But if they suddenly leap upward, that's a bad thing.
+
+ stats = {};
+ std::make_heap(v.begin(), v.end());
+ assert(stats.copied == 0);
+ assert(stats.moved == 153'486);
+#if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG
+ assert(stats.compared == 188'285);
+#endif
+
+ assert(std::is_heap(v.begin(), v.end()));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.min.max.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.min.max.pass.cpp
new file mode 100644
index 0000000000000..7e765d7e84683
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.min.max.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <algorithm>
+#include <array>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::initializer_list<int> init_list{};
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::minmax(init_list),
+ "initializer_list has to contain at least one element");
+
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::minmax(std::array<int, 0>{}),
+ "range has to contain at least one element");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.oob.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.oob.pass.cpp
new file mode 100644
index 0000000000000..6ddee1b2aabe0
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.oob.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// In the debug mode, the comparator validations will notice that it doesn't satisfy strict weak ordering before the
+// algorithm actually runs and goes out of bounds, so the test will terminate before the tested assertions are
+// triggered.
+// UNSUPPORTED: libcpp-hardening-mode=none, libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "bad_comparator_values.h"
+#include "check_assertion.h"
+#include "invalid_comparator_utilities.h"
+
+void check_oob_sort_read() {
+ SortingFixture fixture(SORT_DATA);
+
+ // Check the classic sorting algorithms
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::sort(copy.begin(), copy.end(), fixture.checked_predicate()),
+ "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+ }
+
+ // Check the Ranges sorting algorithms
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::sort(copy, fixture.checked_predicate()),
+ "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+ }
+}
+
+void check_oob_nth_element_read() {
+ SortingFixture fixture(NTH_ELEMENT_DATA);
+
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::nth_element(copy.begin(), copy.begin(), copy.end(), fixture.checked_predicate()),
+ "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+ }
+
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::nth_element(copy, copy.begin(), fixture.checked_predicate()),
+ "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+ }
+}
+
+int main(int, char**) {
+ check_oob_sort_read();
+ check_oob_nth_element_read();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.pass.cpp
new file mode 100644
index 0000000000000..92671617eb032
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/assert.sort.invalid_comparator.pass.cpp
@@ -0,0 +1,195 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// This test uses a specific combination of an invalid comparator and sequence of values to
+// ensure that our sorting functions do not go out-of-bounds and satisfy strict weak ordering in that case.
+// Instead, we should fail loud with an assertion. The specific issue we're looking for here is when the comparator
+// does not satisfy the strict weak ordering:
+//
+// Irreflexivity: comp(a, a) is false
+// Antisymmetry: comp(a, b) implies that !comp(b, a)
+// Transitivity: comp(a, b), comp(b, c) imply comp(a, c)
+// Transitivity of equivalence: !comp(a, b), !comp(b, a), !comp(b, c), !comp(c, b) imply !comp(a, c), !comp(c, a)
+//
+// If this is not satisfied, we have seen issues in the past where the std::sort implementation
+// would proceed to do OOB reads. (rdar://106897934).
+// Other algorithms like std::stable_sort, std::sort_heap do not go out of bounds but can produce
+// incorrect results, we also want to assert on that.
+// Sometimes std::sort does not go out of bounds as well, for example, right now if transitivity
+// of equivalence is not met, std::sort can only produce incorrect result but would not fail.
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <limits>
+#include <map>
+#include <memory>
+#include <ranges>
+#include <random>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "bad_comparator_values.h"
+#include "check_assertion.h"
+#include "invalid_comparator_utilities.h"
+
+void check_oob_sort_read() {
+ SortingFixture fixture(SORT_DATA);
+
+ // Check the classic sorting algorithms
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::sort(copy.begin(), copy.end(), fixture.checked_predicate()),
+ "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(std::stable_sort(copy.begin(), copy.end(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(std::make_heap(copy.begin(), copy.end(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ TEST_LIBCPP_ASSERT_FAILURE(std::sort_heap(copy.begin(), copy.end(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(std::partial_sort(copy.begin(), copy.end(), copy.end(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ std::vector<std::size_t*> results(copy.size(), nullptr);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::partial_sort_copy(copy.begin(), copy.end(), results.begin(), results.end(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+
+ // Check the Ranges sorting algorithms
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::sort(copy, fixture.checked_predicate()),
+ "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::stable_sort(copy, fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::make_heap(copy, fixture.checked_predicate()), "Comparator does not induce a strict weak ordering");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::sort_heap(copy, fixture.checked_predicate()), "Comparator does not induce a strict weak ordering");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::partial_sort(copy, copy.end(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ std::vector<std::size_t*> results(copy.size(), nullptr);
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::partial_sort_copy(copy, results, fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+}
+
+void check_oob_nth_element_read() {
+ SortingFixture fixture(NTH_ELEMENT_DATA);
+
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(std::nth_element(copy.begin(), copy.begin(), copy.end(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+
+ {
+ std::vector<std::size_t*> copy = fixture.create_elements();
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::nth_element(copy, copy.begin(), fixture.checked_predicate()),
+ "Comparator does not induce a strict weak ordering");
+ }
+}
+
+struct FloatContainer {
+ float value;
+ bool operator<(const FloatContainer& other) const { return value < other.value; }
+};
+
+// Nans in floats do not satisfy strict weak ordering by breaking transitivity of equivalence.
+std::vector<FloatContainer> generate_float_data() {
+ std::vector<FloatContainer> floats(50);
+ for (int i = 0; i < 50; ++i) {
+ floats[i].value = static_cast<float>(i);
+ }
+ floats.push_back(FloatContainer{std::numeric_limits<float>::quiet_NaN()});
+ std::shuffle(floats.begin(), floats.end(), std::default_random_engine());
+ return floats;
+}
+
+void check_nan_floats() {
+ auto floats = generate_float_data();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::sort(floats.begin(), floats.end()), "Your comparator is not a valid strict-weak ordering");
+ floats = generate_float_data();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::stable_sort(floats.begin(), floats.end()), "Your comparator is not a valid strict-weak ordering");
+ floats = generate_float_data();
+ std::make_heap(floats.begin(), floats.end());
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::sort_heap(floats.begin(), floats.end()), "Your comparator is not a valid strict-weak ordering");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::sort(generate_float_data(), std::less()), "Your comparator is not a valid strict-weak ordering");
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::stable_sort(generate_float_data(), std::less()),
+ "Your comparator is not a valid strict-weak ordering");
+ floats = generate_float_data();
+ std::ranges::make_heap(floats, std::less());
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::sort_heap(floats, std::less()), "Your comparator is not a valid strict-weak ordering");
+}
+
+void check_irreflexive() {
+ std::vector<int> v(1);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::sort(v.begin(), v.end(), std::greater_equal<int>()), "Your comparator is not a valid strict-weak ordering");
+ TEST_LIBCPP_ASSERT_FAILURE(std::stable_sort(v.begin(), v.end(), std::greater_equal<int>()),
+ "Your comparator is not a valid strict-weak ordering");
+ std::make_heap(v.begin(), v.end(), std::greater_equal<int>());
+ TEST_LIBCPP_ASSERT_FAILURE(std::sort_heap(v.begin(), v.end(), std::greater_equal<int>()),
+ "Comparator does not induce a strict weak ordering");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::sort(v, std::greater_equal<int>()), "Your comparator is not a valid strict-weak ordering");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::stable_sort(v, std::greater_equal<int>()), "Your comparator is not a valid strict-weak ordering");
+ std::ranges::make_heap(v, std::greater_equal<int>());
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::sort_heap(v, std::greater_equal<int>()), "Comparator does not induce a strict weak ordering");
+}
+
+int main(int, char**) {
+ check_oob_sort_read();
+
+ check_oob_nth_element_read();
+
+ check_nan_floats();
+
+ check_irreflexive();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/bad_comparator_values.h b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/bad_comparator_values.h
new file mode 100644
index 0000000000000..1a5910cfcd937
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/bad_comparator_values.h
@@ -0,0 +1,3565 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_LIBCXX_ALGORITHMS_ALG_SORTING_ASSERT_SORT_INVALID_COMPARATOR_BAD_COMPARATOR_VALUES_H
+#define TEST_LIBCXX_ALGORITHMS_ALG_SORTING_ASSERT_SORT_INVALID_COMPARATOR_BAD_COMPARATOR_VALUES_H
+
+#include <string_view>
+
+inline constexpr std::string_view NTH_ELEMENT_DATA = R"(
+0 0 0
+0 1 0
+0 2 0
+0 3 0
+0 4 1
+0 5 0
+0 6 0
+0 7 0
+1 0 0
+1 1 0
+1 2 0
+1 3 1
+1 4 1
+1 5 1
+1 6 1
+1 7 1
+2 0 1
+2 1 1
+2 2 1
+2 3 1
+2 4 1
+2 5 1
+2 6 1
+2 7 1
+3 0 1
+3 1 1
+3 2 1
+3 3 1
+3 4 1
+3 5 1
+3 6 1
+3 7 1
+4 0 1
+4 1 1
+4 2 1
+4 3 1
+4 4 1
+4 5 1
+4 6 1
+4 7 1
+5 0 1
+5 1 1
+5 2 1
+5 3 1
+5 4 1
+5 5 1
+5 6 1
+5 7 1
+6 0 1
+6 1 1
+6 2 1
+6 3 1
+6 4 1
+6 5 1
+6 6 1
+6 7 1
+7 0 1
+7 1 1
+7 2 1
+7 3 1
+7 4 1
+7 5 1
+7 6 1
+7 7 1
+)";
+
+inline constexpr std::string_view SORT_DATA = R"(
+0 0 0
+0 1 1
+0 2 1
+0 3 1
+0 4 1
+0 5 1
+0 6 1
+0 7 1
+0 8 1
+0 9 1
+0 10 1
+0 11 1
+0 12 1
+0 13 1
+0 14 1
+0 15 1
+0 16 1
+0 17 1
+0 18 1
+0 19 1
+0 20 1
+0 21 1
+0 22 1
+0 23 1
+0 24 1
+0 25 1
+0 26 1
+0 27 1
+0 28 1
+0 29 1
+0 30 1
+0 31 1
+0 32 1
+0 33 1
+0 34 1
+0 35 1
+0 36 1
+0 37 1
+0 38 1
+0 39 1
+0 40 1
+0 41 1
+0 42 1
+0 43 1
+0 44 1
+0 45 1
+0 46 1
+0 47 1
+0 48 1
+0 49 1
+0 50 1
+0 51 1
+0 52 1
+0 53 1
+0 54 1
+0 55 1
+0 56 1
+0 57 1
+0 58 1
+1 0 0
+1 1 0
+1 2 1
+1 3 1
+1 4 1
+1 5 1
+1 6 1
+1 7 1
+1 8 1
+1 9 1
+1 10 1
+1 11 1
+1 12 1
+1 13 1
+1 14 1
+1 15 1
+1 16 1
+1 17 1
+1 18 1
+1 19 1
+1 20 1
+1 21 1
+1 22 1
+1 23 1
+1 24 1
+1 25 1
+1 26 1
+1 27 1
+1 28 1
+1 29 1
+1 30 1
+1 31 1
+1 32 1
+1 33 1
+1 34 1
+1 35 1
+1 36 1
+1 37 1
+1 38 1
+1 39 1
+1 40 1
+1 41 1
+1 42 1
+1 43 1
+1 44 1
+1 45 1
+1 46 1
+1 47 1
+1 48 1
+1 49 1
+1 50 1
+1 51 1
+1 52 1
+1 53 1
+1 54 1
+1 55 1
+1 56 1
+1 57 1
+1 58 1
+2 0 0
+2 1 0
+2 2 0
+2 3 1
+2 4 1
+2 5 1
+2 6 1
+2 7 1
+2 8 1
+2 9 1
+2 10 1
+2 11 1
+2 12 1
+2 13 1
+2 14 1
+2 15 1
+2 16 1
+2 17 1
+2 18 1
+2 19 1
+2 20 1
+2 21 1
+2 22 1
+2 23 1
+2 24 1
+2 25 1
+2 26 1
+2 27 1
+2 28 1
+2 29 1
+2 30 1
+2 31 1
+2 32 1
+2 33 1
+2 34 1
+2 35 1
+2 36 1
+2 37 1
+2 38 1
+2 39 1
+2 40 1
+2 41 1
+2 42 1
+2 43 1
+2 44 1
+2 45 1
+2 46 1
+2 47 1
+2 48 1
+2 49 1
+2 50 1
+2 51 1
+2 52 1
+2 53 1
+2 54 1
+2 55 1
+2 56 1
+2 57 1
+2 58 1
+3 0 0
+3 1 0
+3 2 0
+3 3 0
+3 4 1
+3 5 1
+3 6 1
+3 7 1
+3 8 1
+3 9 1
+3 10 1
+3 11 1
+3 12 1
+3 13 1
+3 14 1
+3 15 1
+3 16 1
+3 17 1
+3 18 1
+3 19 1
+3 20 1
+3 21 1
+3 22 1
+3 23 1
+3 24 1
+3 25 1
+3 26 1
+3 27 1
+3 28 1
+3 29 1
+3 30 1
+3 31 1
+3 32 1
+3 33 1
+3 34 1
+3 35 1
+3 36 1
+3 37 1
+3 38 1
+3 39 1
+3 40 1
+3 41 1
+3 42 1
+3 43 1
+3 44 1
+3 45 1
+3 46 1
+3 47 1
+3 48 1
+3 49 1
+3 50 1
+3 51 1
+3 52 1
+3 53 1
+3 54 1
+3 55 1
+3 56 1
+3 57 1
+3 58 1
+4 0 0
+4 1 0
+4 2 0
+4 3 0
+4 4 0
+4 5 1
+4 6 1
+4 7 1
+4 8 1
+4 9 1
+4 10 1
+4 11 1
+4 12 1
+4 13 1
+4 14 1
+4 15 1
+4 16 1
+4 17 1
+4 18 1
+4 19 1
+4 20 1
+4 21 1
+4 22 1
+4 23 1
+4 24 1
+4 25 1
+4 26 1
+4 27 1
+4 28 1
+4 29 1
+4 30 1
+4 31 1
+4 32 1
+4 33 1
+4 34 1
+4 35 1
+4 36 1
+4 37 1
+4 38 1
+4 39 1
+4 40 1
+4 41 1
+4 42 1
+4 43 1
+4 44 1
+4 45 1
+4 46 1
+4 47 1
+4 48 1
+4 49 1
+4 50 1
+4 51 1
+4 52 1
+4 53 1
+4 54 1
+4 55 1
+4 56 1
+4 57 1
+4 58 1
+5 0 0
+5 1 0
+5 2 0
+5 3 0
+5 4 0
+5 5 0
+5 6 1
+5 7 1
+5 8 1
+5 9 1
+5 10 1
+5 11 1
+5 12 1
+5 13 1
+5 14 1
+5 15 1
+5 16 1
+5 17 1
+5 18 1
+5 19 1
+5 20 1
+5 21 1
+5 22 1
+5 23 1
+5 24 1
+5 25 1
+5 26 1
+5 27 1
+5 28 1
+5 29 1
+5 30 1
+5 31 1
+5 32 1
+5 33 1
+5 34 1
+5 35 1
+5 36 1
+5 37 1
+5 38 1
+5 39 1
+5 40 1
+5 41 1
+5 42 1
+5 43 1
+5 44 1
+5 45 1
+5 46 1
+5 47 1
+5 48 1
+5 49 1
+5 50 1
+5 51 1
+5 52 1
+5 53 1
+5 54 1
+5 55 1
+5 56 1
+5 57 1
+5 58 1
+6 0 0
+6 1 0
+6 2 0
+6 3 0
+6 4 0
+6 5 0
+6 6 0
+6 7 1
+6 8 1
+6 9 1
+6 10 1
+6 11 1
+6 12 1
+6 13 1
+6 14 1
+6 15 1
+6 16 1
+6 17 1
+6 18 1
+6 19 1
+6 20 1
+6 21 1
+6 22 1
+6 23 1
+6 24 1
+6 25 1
+6 26 1
+6 27 1
+6 28 1
+6 29 1
+6 30 1
+6 31 1
+6 32 1
+6 33 1
+6 34 1
+6 35 1
+6 36 1
+6 37 1
+6 38 1
+6 39 1
+6 40 1
+6 41 1
+6 42 1
+6 43 1
+6 44 1
+6 45 1
+6 46 1
+6 47 1
+6 48 1
+6 49 1
+6 50 1
+6 51 1
+6 52 1
+6 53 1
+6 54 1
+6 55 1
+6 56 1
+6 57 1
+6 58 1
+7 0 0
+7 1 0
+7 2 0
+7 3 0
+7 4 0
+7 5 0
+7 6 0
+7 7 0
+7 8 1
+7 9 1
+7 10 1
+7 11 1
+7 12 1
+7 13 1
+7 14 1
+7 15 1
+7 16 1
+7 17 1
+7 18 1
+7 19 1
+7 20 1
+7 21 1
+7 22 1
+7 23 1
+7 24 1
+7 25 1
+7 26 1
+7 27 1
+7 28 1
+7 29 1
+7 30 1
+7 31 1
+7 32 1
+7 33 1
+7 34 1
+7 35 1
+7 36 1
+7 37 1
+7 38 1
+7 39 1
+7 40 1
+7 41 1
+7 42 1
+7 43 1
+7 44 1
+7 45 1
+7 46 1
+7 47 1
+7 48 1
+7 49 1
+7 50 1
+7 51 1
+7 52 1
+7 53 1
+7 54 1
+7 55 1
+7 56 1
+7 57 1
+7 58 1
+8 0 0
+8 1 0
+8 2 0
+8 3 0
+8 4 0
+8 5 0
+8 6 0
+8 7 0
+8 8 0
+8 9 1
+8 10 1
+8 11 1
+8 12 1
+8 13 1
+8 14 1
+8 15 1
+8 16 1
+8 17 1
+8 18 1
+8 19 1
+8 20 1
+8 21 1
+8 22 1
+8 23 1
+8 24 1
+8 25 1
+8 26 1
+8 27 1
+8 28 1
+8 29 1
+8 30 1
+8 31 1
+8 32 1
+8 33 1
+8 34 1
+8 35 1
+8 36 1
+8 37 1
+8 38 1
+8 39 1
+8 40 1
+8 41 1
+8 42 1
+8 43 1
+8 44 1
+8 45 1
+8 46 1
+8 47 1
+8 48 1
+8 49 1
+8 50 1
+8 51 1
+8 52 1
+8 53 1
+8 54 1
+8 55 1
+8 56 1
+8 57 1
+8 58 1
+9 0 0
+9 1 0
+9 2 0
+9 3 0
+9 4 0
+9 5 0
+9 6 0
+9 7 0
+9 8 0
+9 9 0
+9 10 1
+9 11 1
+9 12 1
+9 13 1
+9 14 1
+9 15 1
+9 16 1
+9 17 1
+9 18 1
+9 19 1
+9 20 1
+9 21 1
+9 22 1
+9 23 1
+9 24 1
+9 25 1
+9 26 1
+9 27 1
+9 28 1
+9 29 1
+9 30 1
+9 31 1
+9 32 1
+9 33 1
+9 34 1
+9 35 1
+9 36 1
+9 37 1
+9 38 1
+9 39 1
+9 40 1
+9 41 1
+9 42 1
+9 43 1
+9 44 1
+9 45 1
+9 46 1
+9 47 1
+9 48 1
+9 49 1
+9 50 1
+9 51 1
+9 52 1
+9 53 1
+9 54 1
+9 55 1
+9 56 1
+9 57 1
+9 58 1
+10 0 0
+10 1 0
+10 2 0
+10 3 0
+10 4 0
+10 5 0
+10 6 0
+10 7 0
+10 8 0
+10 9 0
+10 10 0
+10 11 1
+10 12 1
+10 13 1
+10 14 1
+10 15 1
+10 16 1
+10 17 1
+10 18 1
+10 19 1
+10 20 1
+10 21 1
+10 22 1
+10 23 1
+10 24 1
+10 25 1
+10 26 1
+10 27 1
+10 28 1
+10 29 1
+10 30 1
+10 31 1
+10 32 1
+10 33 1
+10 34 1
+10 35 1
+10 36 1
+10 37 1
+10 38 1
+10 39 1
+10 40 1
+10 41 1
+10 42 1
+10 43 1
+10 44 1
+10 45 1
+10 46 1
+10 47 1
+10 48 1
+10 49 1
+10 50 1
+10 51 1
+10 52 1
+10 53 1
+10 54 1
+10 55 1
+10 56 1
+10 57 1
+10 58 1
+11 0 0
+11 1 0
+11 2 0
+11 3 0
+11 4 0
+11 5 0
+11 6 0
+11 7 0
+11 8 0
+11 9 0
+11 10 0
+11 11 0
+11 12 1
+11 13 1
+11 14 1
+11 15 1
+11 16 1
+11 17 1
+11 18 1
+11 19 1
+11 20 1
+11 21 1
+11 22 1
+11 23 1
+11 24 1
+11 25 1
+11 26 1
+11 27 1
+11 28 1
+11 29 1
+11 30 1
+11 31 1
+11 32 1
+11 33 1
+11 34 1
+11 35 1
+11 36 1
+11 37 1
+11 38 1
+11 39 1
+11 40 1
+11 41 1
+11 42 1
+11 43 1
+11 44 1
+11 45 1
+11 46 1
+11 47 1
+11 48 1
+11 49 1
+11 50 1
+11 51 1
+11 52 1
+11 53 1
+11 54 1
+11 55 1
+11 56 1
+11 57 1
+11 58 1
+12 0 0
+12 1 0
+12 2 0
+12 3 0
+12 4 0
+12 5 0
+12 6 0
+12 7 0
+12 8 0
+12 9 0
+12 10 0
+12 11 0
+12 12 0
+12 13 1
+12 14 1
+12 15 1
+12 16 1
+12 17 1
+12 18 1
+12 19 1
+12 20 1
+12 21 1
+12 22 1
+12 23 1
+12 24 1
+12 25 1
+12 26 1
+12 27 1
+12 28 1
+12 29 1
+12 30 1
+12 31 1
+12 32 1
+12 33 1
+12 34 1
+12 35 1
+12 36 1
+12 37 1
+12 38 1
+12 39 1
+12 40 1
+12 41 1
+12 42 1
+12 43 1
+12 44 1
+12 45 1
+12 46 1
+12 47 1
+12 48 1
+12 49 1
+12 50 1
+12 51 1
+12 52 1
+12 53 1
+12 54 1
+12 55 1
+12 56 1
+12 57 1
+12 58 1
+13 0 0
+13 1 0
+13 2 0
+13 3 0
+13 4 0
+13 5 0
+13 6 0
+13 7 0
+13 8 0
+13 9 0
+13 10 0
+13 11 0
+13 12 0
+13 13 0
+13 14 1
+13 15 1
+13 16 1
+13 17 1
+13 18 1
+13 19 1
+13 20 1
+13 21 1
+13 22 1
+13 23 1
+13 24 1
+13 25 1
+13 26 1
+13 27 1
+13 28 1
+13 29 1
+13 30 1
+13 31 1
+13 32 1
+13 33 1
+13 34 1
+13 35 1
+13 36 1
+13 37 1
+13 38 1
+13 39 1
+13 40 1
+13 41 1
+13 42 1
+13 43 1
+13 44 1
+13 45 1
+13 46 1
+13 47 1
+13 48 1
+13 49 1
+13 50 1
+13 51 1
+13 52 1
+13 53 1
+13 54 1
+13 55 1
+13 56 1
+13 57 1
+13 58 1
+14 0 0
+14 1 0
+14 2 0
+14 3 0
+14 4 0
+14 5 0
+14 6 0
+14 7 0
+14 8 0
+14 9 0
+14 10 0
+14 11 0
+14 12 0
+14 13 0
+14 14 0
+14 15 1
+14 16 1
+14 17 1
+14 18 1
+14 19 1
+14 20 1
+14 21 1
+14 22 1
+14 23 1
+14 24 1
+14 25 1
+14 26 1
+14 27 1
+14 28 1
+14 29 1
+14 30 1
+14 31 1
+14 32 1
+14 33 1
+14 34 1
+14 35 1
+14 36 1
+14 37 1
+14 38 1
+14 39 1
+14 40 1
+14 41 1
+14 42 1
+14 43 1
+14 44 1
+14 45 1
+14 46 1
+14 47 1
+14 48 1
+14 49 1
+14 50 1
+14 51 1
+14 52 1
+14 53 1
+14 54 1
+14 55 1
+14 56 1
+14 57 1
+14 58 1
+15 0 0
+15 1 0
+15 2 0
+15 3 0
+15 4 0
+15 5 0
+15 6 0
+15 7 0
+15 8 0
+15 9 0
+15 10 0
+15 11 0
+15 12 0
+15 13 0
+15 14 0
+15 15 0
+15 16 1
+15 17 1
+15 18 1
+15 19 1
+15 20 1
+15 21 1
+15 22 1
+15 23 1
+15 24 1
+15 25 1
+15 26 1
+15 27 1
+15 28 1
+15 29 1
+15 30 1
+15 31 1
+15 32 1
+15 33 1
+15 34 1
+15 35 1
+15 36 1
+15 37 1
+15 38 1
+15 39 1
+15 40 1
+15 41 1
+15 42 1
+15 43 1
+15 44 1
+15 45 1
+15 46 1
+15 47 1
+15 48 1
+15 49 1
+15 50 1
+15 51 1
+15 52 1
+15 53 1
+15 54 1
+15 55 1
+15 56 1
+15 57 1
+15 58 1
+16 0 0
+16 1 0
+16 2 0
+16 3 0
+16 4 0
+16 5 0
+16 6 0
+16 7 0
+16 8 0
+16 9 0
+16 10 0
+16 11 0
+16 12 0
+16 13 0
+16 14 0
+16 15 0
+16 16 0
+16 17 1
+16 18 1
+16 19 1
+16 20 1
+16 21 1
+16 22 1
+16 23 1
+16 24 1
+16 25 1
+16 26 1
+16 27 1
+16 28 1
+16 29 1
+16 30 1
+16 31 1
+16 32 1
+16 33 1
+16 34 1
+16 35 1
+16 36 1
+16 37 1
+16 38 1
+16 39 1
+16 40 1
+16 41 1
+16 42 1
+16 43 1
+16 44 1
+16 45 1
+16 46 1
+16 47 1
+16 48 1
+16 49 1
+16 50 1
+16 51 1
+16 52 1
+16 53 1
+16 54 1
+16 55 1
+16 56 1
+16 57 1
+16 58 1
+17 0 0
+17 1 0
+17 2 0
+17 3 0
+17 4 0
+17 5 0
+17 6 0
+17 7 0
+17 8 0
+17 9 0
+17 10 0
+17 11 0
+17 12 0
+17 13 0
+17 14 0
+17 15 0
+17 16 0
+17 17 0
+17 18 1
+17 19 1
+17 20 1
+17 21 1
+17 22 1
+17 23 1
+17 24 1
+17 25 1
+17 26 1
+17 27 1
+17 28 1
+17 29 1
+17 30 1
+17 31 1
+17 32 1
+17 33 1
+17 34 1
+17 35 1
+17 36 1
+17 37 1
+17 38 1
+17 39 1
+17 40 1
+17 41 1
+17 42 1
+17 43 1
+17 44 1
+17 45 1
+17 46 1
+17 47 1
+17 48 1
+17 49 1
+17 50 1
+17 51 1
+17 52 1
+17 53 1
+17 54 1
+17 55 1
+17 56 1
+17 57 1
+17 58 1
+18 0 0
+18 1 0
+18 2 0
+18 3 0
+18 4 0
+18 5 0
+18 6 0
+18 7 0
+18 8 0
+18 9 0
+18 10 0
+18 11 0
+18 12 0
+18 13 0
+18 14 0
+18 15 0
+18 16 0
+18 17 0
+18 18 0
+18 19 1
+18 20 1
+18 21 1
+18 22 1
+18 23 1
+18 24 1
+18 25 1
+18 26 1
+18 27 1
+18 28 1
+18 29 1
+18 30 1
+18 31 1
+18 32 1
+18 33 1
+18 34 1
+18 35 1
+18 36 1
+18 37 1
+18 38 1
+18 39 1
+18 40 1
+18 41 1
+18 42 1
+18 43 1
+18 44 1
+18 45 1
+18 46 1
+18 47 1
+18 48 1
+18 49 1
+18 50 1
+18 51 1
+18 52 1
+18 53 1
+18 54 1
+18 55 1
+18 56 1
+18 57 1
+18 58 1
+19 0 0
+19 1 0
+19 2 0
+19 3 0
+19 4 0
+19 5 0
+19 6 0
+19 7 0
+19 8 0
+19 9 0
+19 10 0
+19 11 0
+19 12 0
+19 13 0
+19 14 0
+19 15 0
+19 16 0
+19 17 0
+19 18 0
+19 19 0
+19 20 1
+19 21 1
+19 22 1
+19 23 1
+19 24 1
+19 25 1
+19 26 1
+19 27 1
+19 28 1
+19 29 1
+19 30 1
+19 31 1
+19 32 1
+19 33 1
+19 34 1
+19 35 1
+19 36 1
+19 37 1
+19 38 1
+19 39 1
+19 40 1
+19 41 1
+19 42 1
+19 43 1
+19 44 1
+19 45 1
+19 46 1
+19 47 1
+19 48 1
+19 49 1
+19 50 1
+19 51 1
+19 52 1
+19 53 1
+19 54 1
+19 55 1
+19 56 1
+19 57 1
+19 58 1
+20 0 0
+20 1 0
+20 2 0
+20 3 0
+20 4 0
+20 5 0
+20 6 0
+20 7 0
+20 8 0
+20 9 0
+20 10 0
+20 11 0
+20 12 0
+20 13 0
+20 14 0
+20 15 0
+20 16 0
+20 17 0
+20 18 0
+20 19 0
+20 20 0
+20 21 1
+20 22 1
+20 23 1
+20 24 1
+20 25 1
+20 26 1
+20 27 1
+20 28 1
+20 29 1
+20 30 1
+20 31 1
+20 32 1
+20 33 1
+20 34 1
+20 35 1
+20 36 1
+20 37 1
+20 38 1
+20 39 1
+20 40 1
+20 41 1
+20 42 1
+20 43 1
+20 44 1
+20 45 1
+20 46 1
+20 47 1
+20 48 1
+20 49 1
+20 50 1
+20 51 1
+20 52 1
+20 53 1
+20 54 1
+20 55 1
+20 56 1
+20 57 1
+20 58 1
+21 0 0
+21 1 0
+21 2 0
+21 3 0
+21 4 0
+21 5 0
+21 6 0
+21 7 0
+21 8 0
+21 9 0
+21 10 0
+21 11 0
+21 12 0
+21 13 0
+21 14 0
+21 15 0
+21 16 0
+21 17 0
+21 18 0
+21 19 0
+21 20 0
+21 21 0
+21 22 1
+21 23 1
+21 24 1
+21 25 1
+21 26 1
+21 27 1
+21 28 1
+21 29 1
+21 30 1
+21 31 1
+21 32 1
+21 33 1
+21 34 1
+21 35 1
+21 36 1
+21 37 1
+21 38 1
+21 39 1
+21 40 1
+21 41 1
+21 42 1
+21 43 1
+21 44 1
+21 45 1
+21 46 1
+21 47 1
+21 48 1
+21 49 1
+21 50 1
+21 51 1
+21 52 1
+21 53 1
+21 54 1
+21 55 1
+21 56 1
+21 57 1
+21 58 1
+22 0 0
+22 1 0
+22 2 0
+22 3 0
+22 4 0
+22 5 0
+22 6 0
+22 7 0
+22 8 0
+22 9 0
+22 10 0
+22 11 0
+22 12 0
+22 13 0
+22 14 0
+22 15 0
+22 16 0
+22 17 0
+22 18 0
+22 19 0
+22 20 0
+22 21 0
+22 22 0
+22 23 1
+22 24 1
+22 25 1
+22 26 1
+22 27 1
+22 28 1
+22 29 1
+22 30 1
+22 31 1
+22 32 1
+22 33 1
+22 34 1
+22 35 1
+22 36 1
+22 37 1
+22 38 1
+22 39 1
+22 40 1
+22 41 1
+22 42 1
+22 43 1
+22 44 1
+22 45 1
+22 46 1
+22 47 1
+22 48 1
+22 49 1
+22 50 1
+22 51 1
+22 52 1
+22 53 1
+22 54 1
+22 55 1
+22 56 1
+22 57 1
+22 58 1
+23 0 0
+23 1 0
+23 2 0
+23 3 0
+23 4 0
+23 5 0
+23 6 0
+23 7 0
+23 8 0
+23 9 0
+23 10 0
+23 11 0
+23 12 0
+23 13 0
+23 14 0
+23 15 0
+23 16 0
+23 17 0
+23 18 0
+23 19 0
+23 20 0
+23 21 0
+23 22 0
+23 23 0
+23 24 1
+23 25 1
+23 26 1
+23 27 1
+23 28 1
+23 29 1
+23 30 1
+23 31 1
+23 32 1
+23 33 1
+23 34 1
+23 35 1
+23 36 1
+23 37 1
+23 38 1
+23 39 1
+23 40 1
+23 41 1
+23 42 1
+23 43 1
+23 44 1
+23 45 1
+23 46 1
+23 47 1
+23 48 1
+23 49 1
+23 50 1
+23 51 1
+23 52 1
+23 53 1
+23 54 1
+23 55 1
+23 56 1
+23 57 1
+23 58 1
+24 0 0
+24 1 0
+24 2 0
+24 3 0
+24 4 0
+24 5 0
+24 6 0
+24 7 0
+24 8 0
+24 9 0
+24 10 0
+24 11 0
+24 12 0
+24 13 0
+24 14 0
+24 15 0
+24 16 0
+24 17 0
+24 18 0
+24 19 0
+24 20 0
+24 21 0
+24 22 0
+24 23 0
+24 24 0
+24 25 1
+24 26 1
+24 27 1
+24 28 1
+24 29 1
+24 30 1
+24 31 1
+24 32 1
+24 33 1
+24 34 1
+24 35 1
+24 36 1
+24 37 1
+24 38 1
+24 39 1
+24 40 1
+24 41 1
+24 42 1
+24 43 1
+24 44 1
+24 45 1
+24 46 1
+24 47 1
+24 48 1
+24 49 1
+24 50 1
+24 51 1
+24 52 1
+24 53 1
+24 54 1
+24 55 1
+24 56 1
+24 57 1
+24 58 1
+25 0 0
+25 1 0
+25 2 0
+25 3 0
+25 4 0
+25 5 0
+25 6 0
+25 7 0
+25 8 0
+25 9 0
+25 10 0
+25 11 0
+25 12 0
+25 13 0
+25 14 0
+25 15 0
+25 16 0
+25 17 0
+25 18 0
+25 19 0
+25 20 0
+25 21 0
+25 22 0
+25 23 0
+25 24 0
+25 25 0
+25 26 1
+25 27 1
+25 28 1
+25 29 1
+25 30 1
+25 31 1
+25 32 1
+25 33 1
+25 34 1
+25 35 1
+25 36 1
+25 37 1
+25 38 1
+25 39 1
+25 40 1
+25 41 1
+25 42 1
+25 43 1
+25 44 1
+25 45 1
+25 46 1
+25 47 1
+25 48 1
+25 49 1
+25 50 1
+25 51 1
+25 52 1
+25 53 1
+25 54 1
+25 55 1
+25 56 1
+25 57 1
+25 58 1
+26 0 0
+26 1 0
+26 2 0
+26 3 0
+26 4 0
+26 5 0
+26 6 0
+26 7 0
+26 8 0
+26 9 0
+26 10 0
+26 11 0
+26 12 0
+26 13 0
+26 14 0
+26 15 0
+26 16 0
+26 17 0
+26 18 0
+26 19 0
+26 20 0
+26 21 0
+26 22 0
+26 23 0
+26 24 0
+26 25 0
+26 26 0
+26 27 1
+26 28 1
+26 29 1
+26 30 1
+26 31 1
+26 32 1
+26 33 1
+26 34 1
+26 35 1
+26 36 1
+26 37 1
+26 38 1
+26 39 1
+26 40 1
+26 41 1
+26 42 1
+26 43 1
+26 44 1
+26 45 1
+26 46 1
+26 47 1
+26 48 1
+26 49 1
+26 50 1
+26 51 1
+26 52 1
+26 53 1
+26 54 1
+26 55 1
+26 56 1
+26 57 1
+26 58 1
+27 0 0
+27 1 0
+27 2 0
+27 3 0
+27 4 0
+27 5 0
+27 6 0
+27 7 0
+27 8 0
+27 9 0
+27 10 0
+27 11 0
+27 12 0
+27 13 0
+27 14 0
+27 15 0
+27 16 0
+27 17 0
+27 18 0
+27 19 0
+27 20 0
+27 21 0
+27 22 0
+27 23 0
+27 24 0
+27 25 0
+27 26 0
+27 27 0
+27 28 1
+27 29 1
+27 30 1
+27 31 1
+27 32 1
+27 33 1
+27 34 1
+27 35 1
+27 36 1
+27 37 1
+27 38 1
+27 39 1
+27 40 1
+27 41 1
+27 42 1
+27 43 1
+27 44 1
+27 45 1
+27 46 1
+27 47 1
+27 48 1
+27 49 1
+27 50 1
+27 51 1
+27 52 1
+27 53 1
+27 54 1
+27 55 1
+27 56 1
+27 57 1
+27 58 1
+28 0 0
+28 1 0
+28 2 0
+28 3 0
+28 4 0
+28 5 0
+28 6 0
+28 7 0
+28 8 0
+28 9 0
+28 10 0
+28 11 0
+28 12 0
+28 13 0
+28 14 0
+28 15 0
+28 16 0
+28 17 0
+28 18 0
+28 19 0
+28 20 0
+28 21 0
+28 22 0
+28 23 0
+28 24 0
+28 25 0
+28 26 0
+28 27 0
+28 28 0
+28 29 1
+28 30 0
+28 31 0
+28 32 0
+28 33 0
+28 34 0
+28 35 0
+28 36 0
+28 37 0
+28 38 0
+28 39 0
+28 40 0
+28 41 0
+28 42 0
+28 43 0
+28 44 0
+28 45 0
+28 46 0
+28 47 0
+28 48 0
+28 49 0
+28 50 0
+28 51 0
+28 52 0
+28 53 0
+28 54 0
+28 55 0
+28 56 0
+28 57 0
+28 58 0
+29 0 0
+29 1 0
+29 2 0
+29 3 0
+29 4 0
+29 5 0
+29 6 0
+29 7 0
+29 8 0
+29 9 0
+29 10 0
+29 11 0
+29 12 0
+29 13 0
+29 14 0
+29 15 0
+29 16 0
+29 17 0
+29 18 0
+29 19 0
+29 20 0
+29 21 0
+29 22 0
+29 23 0
+29 24 0
+29 25 0
+29 26 0
+29 27 0
+29 28 1
+29 29 0
+29 30 1
+29 31 0
+29 32 0
+29 33 0
+29 34 0
+29 35 0
+29 36 0
+29 37 0
+29 38 0
+29 39 0
+29 40 0
+29 41 0
+29 42 0
+29 43 0
+29 44 0
+29 45 0
+29 46 0
+29 47 0
+29 48 0
+29 49 0
+29 50 0
+29 51 0
+29 52 0
+29 53 0
+29 54 0
+29 55 0
+29 56 0
+29 57 0
+29 58 0
+30 0 0
+30 1 0
+30 2 0
+30 3 0
+30 4 0
+30 5 0
+30 6 0
+30 7 0
+30 8 0
+30 9 0
+30 10 0
+30 11 0
+30 12 0
+30 13 0
+30 14 0
+30 15 0
+30 16 0
+30 17 0
+30 18 0
+30 19 0
+30 20 0
+30 21 0
+30 22 0
+30 23 0
+30 24 0
+30 25 0
+30 26 0
+30 27 0
+30 28 1
+30 29 1
+30 30 0
+30 31 1
+30 32 0
+30 33 0
+30 34 0
+30 35 0
+30 36 0
+30 37 0
+30 38 0
+30 39 0
+30 40 0
+30 41 0
+30 42 0
+30 43 0
+30 44 0
+30 45 0
+30 46 0
+30 47 0
+30 48 0
+30 49 0
+30 50 0
+30 51 0
+30 52 0
+30 53 0
+30 54 0
+30 55 0
+30 56 0
+30 57 0
+30 58 0
+31 0 0
+31 1 0
+31 2 0
+31 3 0
+31 4 0
+31 5 0
+31 6 0
+31 7 0
+31 8 0
+31 9 0
+31 10 0
+31 11 0
+31 12 0
+31 13 0
+31 14 0
+31 15 0
+31 16 0
+31 17 0
+31 18 0
+31 19 0
+31 20 0
+31 21 0
+31 22 0
+31 23 0
+31 24 0
+31 25 0
+31 26 0
+31 27 0
+31 28 1
+31 29 1
+31 30 1
+31 31 0
+31 32 1
+31 33 0
+31 34 0
+31 35 0
+31 36 0
+31 37 0
+31 38 0
+31 39 0
+31 40 0
+31 41 0
+31 42 0
+31 43 0
+31 44 0
+31 45 0
+31 46 0
+31 47 0
+31 48 0
+31 49 0
+31 50 0
+31 51 0
+31 52 0
+31 53 0
+31 54 0
+31 55 0
+31 56 0
+31 57 0
+31 58 0
+32 0 0
+32 1 0
+32 2 0
+32 3 0
+32 4 0
+32 5 0
+32 6 0
+32 7 0
+32 8 0
+32 9 0
+32 10 0
+32 11 0
+32 12 0
+32 13 0
+32 14 0
+32 15 0
+32 16 0
+32 17 0
+32 18 0
+32 19 0
+32 20 0
+32 21 0
+32 22 0
+32 23 0
+32 24 0
+32 25 0
+32 26 0
+32 27 0
+32 28 1
+32 29 1
+32 30 1
+32 31 1
+32 32 0
+32 33 1
+32 34 0
+32 35 0
+32 36 0
+32 37 0
+32 38 0
+32 39 0
+32 40 0
+32 41 0
+32 42 0
+32 43 0
+32 44 0
+32 45 0
+32 46 0
+32 47 0
+32 48 0
+32 49 0
+32 50 0
+32 51 0
+32 52 0
+32 53 0
+32 54 0
+32 55 0
+32 56 0
+32 57 0
+32 58 0
+33 0 0
+33 1 0
+33 2 0
+33 3 0
+33 4 0
+33 5 0
+33 6 0
+33 7 0
+33 8 0
+33 9 0
+33 10 0
+33 11 0
+33 12 0
+33 13 0
+33 14 0
+33 15 0
+33 16 0
+33 17 0
+33 18 0
+33 19 0
+33 20 0
+33 21 0
+33 22 0
+33 23 0
+33 24 0
+33 25 0
+33 26 0
+33 27 0
+33 28 1
+33 29 1
+33 30 1
+33 31 1
+33 32 1
+33 33 0
+33 34 1
+33 35 0
+33 36 0
+33 37 0
+33 38 0
+33 39 0
+33 40 0
+33 41 0
+33 42 0
+33 43 0
+33 44 0
+33 45 0
+33 46 0
+33 47 0
+33 48 0
+33 49 0
+33 50 0
+33 51 0
+33 52 0
+33 53 0
+33 54 0
+33 55 0
+33 56 0
+33 57 0
+33 58 0
+34 0 0
+34 1 0
+34 2 0
+34 3 0
+34 4 0
+34 5 0
+34 6 0
+34 7 0
+34 8 0
+34 9 0
+34 10 0
+34 11 0
+34 12 0
+34 13 0
+34 14 0
+34 15 0
+34 16 0
+34 17 0
+34 18 0
+34 19 0
+34 20 0
+34 21 0
+34 22 0
+34 23 0
+34 24 0
+34 25 0
+34 26 0
+34 27 0
+34 28 1
+34 29 1
+34 30 1
+34 31 1
+34 32 1
+34 33 1
+34 34 0
+34 35 1
+34 36 0
+34 37 0
+34 38 0
+34 39 0
+34 40 0
+34 41 0
+34 42 0
+34 43 0
+34 44 0
+34 45 0
+34 46 0
+34 47 0
+34 48 0
+34 49 0
+34 50 0
+34 51 0
+34 52 0
+34 53 0
+34 54 0
+34 55 0
+34 56 0
+34 57 0
+34 58 0
+35 0 0
+35 1 0
+35 2 0
+35 3 0
+35 4 0
+35 5 0
+35 6 0
+35 7 0
+35 8 0
+35 9 0
+35 10 0
+35 11 0
+35 12 0
+35 13 0
+35 14 0
+35 15 0
+35 16 0
+35 17 0
+35 18 0
+35 19 0
+35 20 0
+35 21 0
+35 22 0
+35 23 0
+35 24 0
+35 25 0
+35 26 0
+35 27 0
+35 28 1
+35 29 1
+35 30 1
+35 31 1
+35 32 1
+35 33 1
+35 34 1
+35 35 0
+35 36 1
+35 37 0
+35 38 0
+35 39 0
+35 40 0
+35 41 0
+35 42 0
+35 43 0
+35 44 0
+35 45 0
+35 46 0
+35 47 0
+35 48 0
+35 49 0
+35 50 0
+35 51 0
+35 52 0
+35 53 0
+35 54 0
+35 55 0
+35 56 0
+35 57 0
+35 58 0
+36 0 0
+36 1 0
+36 2 0
+36 3 0
+36 4 0
+36 5 0
+36 6 0
+36 7 0
+36 8 0
+36 9 0
+36 10 0
+36 11 0
+36 12 0
+36 13 0
+36 14 0
+36 15 0
+36 16 0
+36 17 0
+36 18 0
+36 19 0
+36 20 0
+36 21 0
+36 22 0
+36 23 0
+36 24 0
+36 25 0
+36 26 0
+36 27 0
+36 28 1
+36 29 1
+36 30 1
+36 31 1
+36 32 1
+36 33 1
+36 34 1
+36 35 1
+36 36 0
+36 37 1
+36 38 0
+36 39 0
+36 40 0
+36 41 0
+36 42 0
+36 43 0
+36 44 0
+36 45 0
+36 46 0
+36 47 0
+36 48 0
+36 49 0
+36 50 0
+36 51 0
+36 52 0
+36 53 0
+36 54 0
+36 55 0
+36 56 0
+36 57 0
+36 58 0
+37 0 0
+37 1 0
+37 2 0
+37 3 0
+37 4 0
+37 5 0
+37 6 0
+37 7 0
+37 8 0
+37 9 0
+37 10 0
+37 11 0
+37 12 0
+37 13 0
+37 14 0
+37 15 0
+37 16 0
+37 17 0
+37 18 0
+37 19 0
+37 20 0
+37 21 0
+37 22 0
+37 23 0
+37 24 0
+37 25 0
+37 26 0
+37 27 0
+37 28 1
+37 29 1
+37 30 1
+37 31 1
+37 32 1
+37 33 1
+37 34 1
+37 35 1
+37 36 1
+37 37 0
+37 38 1
+37 39 0
+37 40 0
+37 41 0
+37 42 0
+37 43 0
+37 44 0
+37 45 0
+37 46 0
+37 47 0
+37 48 0
+37 49 0
+37 50 0
+37 51 0
+37 52 0
+37 53 0
+37 54 0
+37 55 0
+37 56 0
+37 57 0
+37 58 0
+38 0 0
+38 1 0
+38 2 0
+38 3 0
+38 4 0
+38 5 0
+38 6 0
+38 7 0
+38 8 0
+38 9 0
+38 10 0
+38 11 0
+38 12 0
+38 13 0
+38 14 0
+38 15 0
+38 16 0
+38 17 0
+38 18 0
+38 19 0
+38 20 0
+38 21 0
+38 22 0
+38 23 0
+38 24 0
+38 25 0
+38 26 0
+38 27 0
+38 28 1
+38 29 1
+38 30 1
+38 31 1
+38 32 1
+38 33 1
+38 34 1
+38 35 1
+38 36 1
+38 37 1
+38 38 0
+38 39 1
+38 40 0
+38 41 0
+38 42 0
+38 43 0
+38 44 0
+38 45 0
+38 46 0
+38 47 0
+38 48 0
+38 49 0
+38 50 0
+38 51 0
+38 52 0
+38 53 0
+38 54 0
+38 55 0
+38 56 0
+38 57 0
+38 58 0
+39 0 0
+39 1 0
+39 2 0
+39 3 0
+39 4 0
+39 5 0
+39 6 0
+39 7 0
+39 8 0
+39 9 0
+39 10 0
+39 11 0
+39 12 0
+39 13 0
+39 14 0
+39 15 0
+39 16 0
+39 17 0
+39 18 0
+39 19 0
+39 20 0
+39 21 0
+39 22 0
+39 23 0
+39 24 0
+39 25 0
+39 26 0
+39 27 0
+39 28 1
+39 29 1
+39 30 1
+39 31 1
+39 32 1
+39 33 1
+39 34 1
+39 35 1
+39 36 1
+39 37 1
+39 38 1
+39 39 0
+39 40 1
+39 41 0
+39 42 0
+39 43 0
+39 44 0
+39 45 0
+39 46 0
+39 47 0
+39 48 0
+39 49 0
+39 50 0
+39 51 0
+39 52 0
+39 53 0
+39 54 0
+39 55 0
+39 56 0
+39 57 0
+39 58 0
+40 0 0
+40 1 0
+40 2 0
+40 3 0
+40 4 0
+40 5 0
+40 6 0
+40 7 0
+40 8 0
+40 9 0
+40 10 0
+40 11 0
+40 12 0
+40 13 0
+40 14 0
+40 15 0
+40 16 0
+40 17 0
+40 18 0
+40 19 0
+40 20 0
+40 21 0
+40 22 0
+40 23 0
+40 24 0
+40 25 0
+40 26 0
+40 27 0
+40 28 1
+40 29 1
+40 30 1
+40 31 1
+40 32 1
+40 33 1
+40 34 1
+40 35 1
+40 36 1
+40 37 1
+40 38 1
+40 39 1
+40 40 0
+40 41 1
+40 42 0
+40 43 0
+40 44 0
+40 45 0
+40 46 0
+40 47 0
+40 48 0
+40 49 0
+40 50 0
+40 51 0
+40 52 0
+40 53 0
+40 54 0
+40 55 0
+40 56 0
+40 57 0
+40 58 0
+41 0 0
+41 1 0
+41 2 0
+41 3 0
+41 4 0
+41 5 0
+41 6 0
+41 7 0
+41 8 0
+41 9 0
+41 10 0
+41 11 0
+41 12 0
+41 13 0
+41 14 0
+41 15 0
+41 16 0
+41 17 0
+41 18 0
+41 19 0
+41 20 0
+41 21 0
+41 22 0
+41 23 0
+41 24 0
+41 25 0
+41 26 0
+41 27 0
+41 28 1
+41 29 1
+41 30 1
+41 31 1
+41 32 1
+41 33 1
+41 34 1
+41 35 1
+41 36 1
+41 37 1
+41 38 1
+41 39 1
+41 40 1
+41 41 0
+41 42 1
+41 43 0
+41 44 0
+41 45 0
+41 46 0
+41 47 0
+41 48 0
+41 49 0
+41 50 0
+41 51 0
+41 52 0
+41 53 0
+41 54 0
+41 55 0
+41 56 0
+41 57 0
+41 58 0
+42 0 0
+42 1 0
+42 2 0
+42 3 0
+42 4 0
+42 5 0
+42 6 0
+42 7 0
+42 8 0
+42 9 0
+42 10 0
+42 11 0
+42 12 0
+42 13 0
+42 14 0
+42 15 0
+42 16 0
+42 17 0
+42 18 0
+42 19 0
+42 20 0
+42 21 0
+42 22 0
+42 23 0
+42 24 0
+42 25 0
+42 26 0
+42 27 0
+42 28 1
+42 29 1
+42 30 1
+42 31 1
+42 32 1
+42 33 1
+42 34 1
+42 35 1
+42 36 1
+42 37 1
+42 38 1
+42 39 1
+42 40 1
+42 41 1
+42 42 0
+42 43 1
+42 44 0
+42 45 0
+42 46 0
+42 47 0
+42 48 0
+42 49 0
+42 50 0
+42 51 0
+42 52 0
+42 53 0
+42 54 0
+42 55 0
+42 56 0
+42 57 0
+42 58 0
+43 0 0
+43 1 0
+43 2 0
+43 3 0
+43 4 0
+43 5 0
+43 6 0
+43 7 0
+43 8 0
+43 9 0
+43 10 0
+43 11 0
+43 12 0
+43 13 0
+43 14 0
+43 15 0
+43 16 0
+43 17 0
+43 18 0
+43 19 0
+43 20 0
+43 21 0
+43 22 0
+43 23 0
+43 24 0
+43 25 0
+43 26 0
+43 27 0
+43 28 1
+43 29 1
+43 30 1
+43 31 1
+43 32 1
+43 33 1
+43 34 1
+43 35 1
+43 36 1
+43 37 1
+43 38 1
+43 39 1
+43 40 1
+43 41 1
+43 42 1
+43 43 0
+43 44 1
+43 45 0
+43 46 0
+43 47 0
+43 48 0
+43 49 0
+43 50 0
+43 51 0
+43 52 0
+43 53 0
+43 54 0
+43 55 0
+43 56 0
+43 57 0
+43 58 0
+44 0 0
+44 1 0
+44 2 0
+44 3 0
+44 4 0
+44 5 0
+44 6 0
+44 7 0
+44 8 0
+44 9 0
+44 10 0
+44 11 0
+44 12 0
+44 13 0
+44 14 0
+44 15 0
+44 16 0
+44 17 0
+44 18 0
+44 19 0
+44 20 0
+44 21 0
+44 22 0
+44 23 0
+44 24 0
+44 25 0
+44 26 0
+44 27 0
+44 28 1
+44 29 1
+44 30 1
+44 31 1
+44 32 1
+44 33 1
+44 34 1
+44 35 1
+44 36 1
+44 37 1
+44 38 1
+44 39 1
+44 40 1
+44 41 1
+44 42 1
+44 43 1
+44 44 0
+44 45 1
+44 46 0
+44 47 0
+44 48 0
+44 49 0
+44 50 0
+44 51 0
+44 52 0
+44 53 0
+44 54 0
+44 55 0
+44 56 0
+44 57 0
+44 58 0
+45 0 0
+45 1 0
+45 2 0
+45 3 0
+45 4 0
+45 5 0
+45 6 0
+45 7 0
+45 8 0
+45 9 0
+45 10 0
+45 11 0
+45 12 0
+45 13 0
+45 14 0
+45 15 0
+45 16 0
+45 17 0
+45 18 0
+45 19 0
+45 20 0
+45 21 0
+45 22 0
+45 23 0
+45 24 0
+45 25 0
+45 26 0
+45 27 0
+45 28 1
+45 29 1
+45 30 1
+45 31 1
+45 32 1
+45 33 1
+45 34 1
+45 35 1
+45 36 1
+45 37 1
+45 38 1
+45 39 1
+45 40 1
+45 41 1
+45 42 1
+45 43 1
+45 44 1
+45 45 0
+45 46 1
+45 47 0
+45 48 0
+45 49 0
+45 50 0
+45 51 0
+45 52 0
+45 53 0
+45 54 0
+45 55 0
+45 56 0
+45 57 0
+45 58 0
+46 0 0
+46 1 0
+46 2 0
+46 3 0
+46 4 0
+46 5 0
+46 6 0
+46 7 0
+46 8 0
+46 9 0
+46 10 0
+46 11 0
+46 12 0
+46 13 0
+46 14 0
+46 15 0
+46 16 0
+46 17 0
+46 18 0
+46 19 0
+46 20 0
+46 21 0
+46 22 0
+46 23 0
+46 24 0
+46 25 0
+46 26 0
+46 27 0
+46 28 1
+46 29 1
+46 30 1
+46 31 1
+46 32 1
+46 33 1
+46 34 1
+46 35 1
+46 36 1
+46 37 1
+46 38 1
+46 39 1
+46 40 1
+46 41 1
+46 42 1
+46 43 1
+46 44 1
+46 45 1
+46 46 0
+46 47 1
+46 48 0
+46 49 0
+46 50 0
+46 51 0
+46 52 0
+46 53 0
+46 54 0
+46 55 0
+46 56 0
+46 57 0
+46 58 0
+47 0 0
+47 1 0
+47 2 0
+47 3 0
+47 4 0
+47 5 0
+47 6 0
+47 7 0
+47 8 0
+47 9 0
+47 10 0
+47 11 0
+47 12 0
+47 13 0
+47 14 0
+47 15 0
+47 16 0
+47 17 0
+47 18 0
+47 19 0
+47 20 0
+47 21 0
+47 22 0
+47 23 0
+47 24 0
+47 25 0
+47 26 0
+47 27 0
+47 28 1
+47 29 1
+47 30 1
+47 31 1
+47 32 1
+47 33 1
+47 34 1
+47 35 1
+47 36 1
+47 37 1
+47 38 1
+47 39 1
+47 40 1
+47 41 1
+47 42 1
+47 43 1
+47 44 1
+47 45 1
+47 46 1
+47 47 0
+47 48 1
+47 49 0
+47 50 0
+47 51 0
+47 52 0
+47 53 0
+47 54 0
+47 55 0
+47 56 0
+47 57 0
+47 58 0
+48 0 0
+48 1 0
+48 2 0
+48 3 0
+48 4 0
+48 5 0
+48 6 0
+48 7 0
+48 8 0
+48 9 0
+48 10 0
+48 11 0
+48 12 0
+48 13 0
+48 14 0
+48 15 0
+48 16 0
+48 17 0
+48 18 0
+48 19 0
+48 20 0
+48 21 0
+48 22 0
+48 23 0
+48 24 0
+48 25 0
+48 26 0
+48 27 0
+48 28 1
+48 29 1
+48 30 1
+48 31 1
+48 32 1
+48 33 1
+48 34 1
+48 35 1
+48 36 1
+48 37 1
+48 38 1
+48 39 1
+48 40 1
+48 41 1
+48 42 1
+48 43 1
+48 44 1
+48 45 1
+48 46 1
+48 47 1
+48 48 0
+48 49 1
+48 50 0
+48 51 0
+48 52 0
+48 53 0
+48 54 0
+48 55 0
+48 56 0
+48 57 0
+48 58 0
+49 0 0
+49 1 0
+49 2 0
+49 3 0
+49 4 0
+49 5 0
+49 6 0
+49 7 0
+49 8 0
+49 9 0
+49 10 0
+49 11 0
+49 12 0
+49 13 0
+49 14 0
+49 15 0
+49 16 0
+49 17 0
+49 18 0
+49 19 0
+49 20 0
+49 21 0
+49 22 0
+49 23 0
+49 24 0
+49 25 0
+49 26 0
+49 27 0
+49 28 1
+49 29 1
+49 30 1
+49 31 1
+49 32 1
+49 33 1
+49 34 1
+49 35 1
+49 36 1
+49 37 1
+49 38 1
+49 39 1
+49 40 1
+49 41 1
+49 42 1
+49 43 1
+49 44 1
+49 45 1
+49 46 1
+49 47 1
+49 48 1
+49 49 0
+49 50 1
+49 51 0
+49 52 0
+49 53 0
+49 54 0
+49 55 0
+49 56 0
+49 57 0
+49 58 0
+50 0 0
+50 1 0
+50 2 0
+50 3 0
+50 4 0
+50 5 0
+50 6 0
+50 7 0
+50 8 0
+50 9 0
+50 10 0
+50 11 0
+50 12 0
+50 13 0
+50 14 0
+50 15 0
+50 16 0
+50 17 0
+50 18 0
+50 19 0
+50 20 0
+50 21 0
+50 22 0
+50 23 0
+50 24 0
+50 25 0
+50 26 0
+50 27 0
+50 28 1
+50 29 1
+50 30 1
+50 31 1
+50 32 1
+50 33 1
+50 34 1
+50 35 1
+50 36 1
+50 37 1
+50 38 1
+50 39 1
+50 40 1
+50 41 1
+50 42 1
+50 43 1
+50 44 1
+50 45 1
+50 46 1
+50 47 1
+50 48 1
+50 49 1
+50 50 0
+50 51 1
+50 52 0
+50 53 0
+50 54 0
+50 55 0
+50 56 0
+50 57 0
+50 58 0
+51 0 0
+51 1 0
+51 2 0
+51 3 0
+51 4 0
+51 5 0
+51 6 0
+51 7 0
+51 8 0
+51 9 0
+51 10 0
+51 11 0
+51 12 0
+51 13 0
+51 14 0
+51 15 0
+51 16 0
+51 17 0
+51 18 0
+51 19 0
+51 20 0
+51 21 0
+51 22 0
+51 23 0
+51 24 0
+51 25 0
+51 26 0
+51 27 0
+51 28 1
+51 29 1
+51 30 1
+51 31 1
+51 32 1
+51 33 1
+51 34 1
+51 35 1
+51 36 1
+51 37 1
+51 38 1
+51 39 1
+51 40 1
+51 41 1
+51 42 1
+51 43 1
+51 44 1
+51 45 1
+51 46 1
+51 47 1
+51 48 1
+51 49 1
+51 50 1
+51 51 0
+51 52 1
+51 53 0
+51 54 0
+51 55 0
+51 56 0
+51 57 0
+51 58 0
+52 0 0
+52 1 0
+52 2 0
+52 3 0
+52 4 0
+52 5 0
+52 6 0
+52 7 0
+52 8 0
+52 9 0
+52 10 0
+52 11 0
+52 12 0
+52 13 0
+52 14 0
+52 15 0
+52 16 0
+52 17 0
+52 18 0
+52 19 0
+52 20 0
+52 21 0
+52 22 0
+52 23 0
+52 24 0
+52 25 0
+52 26 0
+52 27 0
+52 28 1
+52 29 1
+52 30 1
+52 31 1
+52 32 1
+52 33 1
+52 34 1
+52 35 1
+52 36 1
+52 37 1
+52 38 1
+52 39 1
+52 40 1
+52 41 1
+52 42 1
+52 43 1
+52 44 1
+52 45 1
+52 46 1
+52 47 1
+52 48 1
+52 49 1
+52 50 1
+52 51 1
+52 52 0
+52 53 1
+52 54 0
+52 55 0
+52 56 0
+52 57 0
+52 58 0
+53 0 0
+53 1 0
+53 2 0
+53 3 0
+53 4 0
+53 5 0
+53 6 0
+53 7 0
+53 8 0
+53 9 0
+53 10 0
+53 11 0
+53 12 0
+53 13 0
+53 14 0
+53 15 0
+53 16 0
+53 17 0
+53 18 0
+53 19 0
+53 20 0
+53 21 0
+53 22 0
+53 23 0
+53 24 0
+53 25 0
+53 26 0
+53 27 0
+53 28 1
+53 29 1
+53 30 1
+53 31 1
+53 32 1
+53 33 1
+53 34 1
+53 35 1
+53 36 1
+53 37 1
+53 38 1
+53 39 1
+53 40 1
+53 41 1
+53 42 1
+53 43 1
+53 44 1
+53 45 1
+53 46 1
+53 47 1
+53 48 1
+53 49 1
+53 50 1
+53 51 1
+53 52 1
+53 53 0
+53 54 1
+53 55 0
+53 56 0
+53 57 0
+53 58 0
+54 0 0
+54 1 0
+54 2 0
+54 3 0
+54 4 0
+54 5 0
+54 6 0
+54 7 0
+54 8 0
+54 9 0
+54 10 0
+54 11 0
+54 12 0
+54 13 0
+54 14 0
+54 15 0
+54 16 0
+54 17 0
+54 18 0
+54 19 0
+54 20 0
+54 21 0
+54 22 0
+54 23 0
+54 24 0
+54 25 0
+54 26 0
+54 27 0
+54 28 1
+54 29 1
+54 30 1
+54 31 1
+54 32 1
+54 33 1
+54 34 1
+54 35 1
+54 36 1
+54 37 1
+54 38 1
+54 39 1
+54 40 1
+54 41 1
+54 42 1
+54 43 1
+54 44 1
+54 45 1
+54 46 1
+54 47 1
+54 48 1
+54 49 1
+54 50 1
+54 51 1
+54 52 1
+54 53 1
+54 54 0
+54 55 1
+54 56 0
+54 57 0
+54 58 0
+55 0 0
+55 1 0
+55 2 0
+55 3 0
+55 4 0
+55 5 0
+55 6 0
+55 7 0
+55 8 0
+55 9 0
+55 10 0
+55 11 0
+55 12 0
+55 13 0
+55 14 0
+55 15 0
+55 16 0
+55 17 0
+55 18 0
+55 19 0
+55 20 0
+55 21 0
+55 22 0
+55 23 0
+55 24 0
+55 25 0
+55 26 0
+55 27 0
+55 28 1
+55 29 1
+55 30 1
+55 31 1
+55 32 1
+55 33 1
+55 34 1
+55 35 1
+55 36 1
+55 37 1
+55 38 1
+55 39 1
+55 40 1
+55 41 1
+55 42 1
+55 43 1
+55 44 1
+55 45 1
+55 46 1
+55 47 1
+55 48 1
+55 49 1
+55 50 1
+55 51 1
+55 52 1
+55 53 1
+55 54 1
+55 55 0
+55 56 1
+55 57 0
+55 58 0
+56 0 0
+56 1 0
+56 2 0
+56 3 0
+56 4 0
+56 5 0
+56 6 0
+56 7 0
+56 8 0
+56 9 0
+56 10 0
+56 11 0
+56 12 0
+56 13 0
+56 14 0
+56 15 0
+56 16 0
+56 17 0
+56 18 0
+56 19 0
+56 20 0
+56 21 0
+56 22 0
+56 23 0
+56 24 0
+56 25 0
+56 26 0
+56 27 0
+56 28 1
+56 29 1
+56 30 1
+56 31 1
+56 32 1
+56 33 1
+56 34 1
+56 35 1
+56 36 1
+56 37 1
+56 38 1
+56 39 1
+56 40 1
+56 41 1
+56 42 1
+56 43 1
+56 44 1
+56 45 1
+56 46 1
+56 47 1
+56 48 1
+56 49 1
+56 50 1
+56 51 1
+56 52 1
+56 53 1
+56 54 1
+56 55 1
+56 56 0
+56 57 1
+56 58 0
+57 0 0
+57 1 0
+57 2 0
+57 3 0
+57 4 0
+57 5 0
+57 6 0
+57 7 0
+57 8 0
+57 9 0
+57 10 0
+57 11 0
+57 12 0
+57 13 0
+57 14 0
+57 15 0
+57 16 0
+57 17 0
+57 18 0
+57 19 0
+57 20 0
+57 21 0
+57 22 0
+57 23 0
+57 24 0
+57 25 0
+57 26 0
+57 27 0
+57 28 1
+57 29 1
+57 30 1
+57 31 1
+57 32 1
+57 33 1
+57 34 1
+57 35 1
+57 36 1
+57 37 1
+57 38 1
+57 39 1
+57 40 1
+57 41 1
+57 42 1
+57 43 1
+57 44 1
+57 45 1
+57 46 1
+57 47 1
+57 48 1
+57 49 1
+57 50 1
+57 51 1
+57 52 1
+57 53 1
+57 54 1
+57 55 1
+57 56 1
+57 57 0
+57 58 1
+58 0 0
+58 1 0
+58 2 0
+58 3 0
+58 4 0
+58 5 0
+58 6 0
+58 7 0
+58 8 0
+58 9 0
+58 10 0
+58 11 0
+58 12 0
+58 13 0
+58 14 0
+58 15 0
+58 16 0
+58 17 0
+58 18 0
+58 19 0
+58 20 0
+58 21 0
+58 22 0
+58 23 0
+58 24 0
+58 25 0
+58 26 0
+58 27 0
+58 28 1
+58 29 1
+58 30 1
+58 31 1
+58 32 1
+58 33 1
+58 34 1
+58 35 1
+58 36 1
+58 37 1
+58 38 1
+58 39 1
+58 40 1
+58 41 1
+58 42 1
+58 43 1
+58 44 1
+58 45 1
+58 46 1
+58 47 1
+58 48 1
+58 49 1
+58 50 1
+58 51 1
+58 52 1
+58 53 1
+58 54 1
+58 55 1
+58 56 1
+58 57 1
+58 58 0
+)";
+
+#endif // TEST_LIBCXX_ALGORITHMS_ALG_SORTING_ASSERT_SORT_INVALID_COMPARATOR_BAD_COMPARATOR_VALUES_H
diff --git a/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/invalid_comparator_utilities.h b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/invalid_comparator_utilities.h
new file mode 100644
index 0000000000000..f5e602577cae2
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.sorting/assert.sort.invalid_comparator/invalid_comparator_utilities.h
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_LIBCXX_ALGORITHMS_ALG_SORTING_ASSERT_SORT_INVALID_COMPARATOR_INVALID_COMPARATOR_UTILITIES_H
+#define TEST_LIBCXX_ALGORITHMS_ALG_SORTING_ASSERT_SORT_INVALID_COMPARATOR_INVALID_COMPARATOR_UTILITIES_H
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <map>
+#include <ranges>
+#include <set>
+#include <string>
+#include <string_view>
+#include <vector>
+
+class ComparisonResults {
+public:
+ explicit ComparisonResults(std::string_view data) {
+ for (auto line :
+ std::views::split(data, '\n') | std::views::filter([](auto const& line) { return !line.empty(); })) {
+ auto values = std::views::split(line, ' ');
+ auto it = values.begin();
+ std::size_t left = std::stol(std::string((*it).data(), (*it).size()));
+ it = std::next(it);
+ std::size_t right = std::stol(std::string((*it).data(), (*it).size()));
+ it = std::next(it);
+ bool result = static_cast<bool>(std::stol(std::string((*it).data(), (*it).size())));
+ comparison_results[left][right] = result;
+ }
+ }
+
+ bool compare(size_t* left, size_t* right) const {
+ assert(left != nullptr && right != nullptr && "something is wrong with the test");
+ assert(comparison_results.contains(*left) && comparison_results.at(*left).contains(*right) &&
+ "malformed input data?");
+ return comparison_results.at(*left).at(*right);
+ }
+
+ size_t size() const { return comparison_results.size(); }
+
+private:
+ std::map<std::size_t, std::map<std::size_t, bool>>
+ comparison_results; // terrible for performance, but really convenient
+};
+
+class SortingFixture {
+public:
+ explicit SortingFixture(std::string_view data) : comparison_results_(data) {
+ for (std::size_t i = 0; i != comparison_results_.size(); ++i) {
+ elements_.push_back(std::make_unique<std::size_t>(i));
+ valid_ptrs_.insert(elements_.back().get());
+ }
+ }
+
+ std::vector<std::size_t*> create_elements() {
+ std::vector<std::size_t*> copy;
+ for (auto const& e : elements_)
+ copy.push_back(e.get());
+ return copy;
+ }
+
+ auto checked_predicate() {
+ return [this](size_t* left, size_t* right) {
+ // If the pointers passed to the comparator are not in the set of pointers we
+ // set up above, then we're being passed garbage values from the algorithm
+ // because we're reading OOB.
+ assert(valid_ptrs_.contains(left));
+ assert(valid_ptrs_.contains(right));
+ return comparison_results_.compare(left, right);
+ };
+ }
+
+private:
+ ComparisonResults comparison_results_;
+ std::vector<std::unique_ptr<std::size_t>> elements_;
+ std::set<std::size_t*> valid_ptrs_;
+};
+
+#endif // TEST_LIBCXX_ALGORITHMS_ALG_SORTING_ASSERT_SORT_INVALID_COMPARATOR_INVALID_COMPARATOR_UTILITIES_H
diff --git a/libcxx/test/libcxx-03/algorithms/alg.sorting/pstl.is_partitioned.pass.cpp b/libcxx/test/libcxx-03/algorithms/alg.sorting/pstl.is_partitioned.pass.cpp
new file mode 100644
index 0000000000000..86647ccfdef8e
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/alg.sorting/pstl.is_partitioned.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// Make sure that the predicate is called exactly N times in is_partitioned
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <execution>
+#include <iterator>
+
+int main(int, char**) {
+ std::size_t call_count = 0;
+ int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ assert(std::is_partitioned(std::execution::seq, std::begin(a), std::end(a), [&](int i) {
+ ++call_count;
+ return i < 5;
+ }));
+ assert(call_count == std::size(a));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/bad_iterator_traits.verify.cpp b/libcxx/test/libcxx-03/algorithms/bad_iterator_traits.verify.cpp
new file mode 100644
index 0000000000000..a0b5b88bb9f0e
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/bad_iterator_traits.verify.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// std::sort
+
+#include <algorithm>
+#include <iterator>
+#include <type_traits>
+#include <utility>
+
+struct BadIter {
+ struct Value {
+ friend bool operator==(const Value& x, const Value& y);
+ friend bool operator!=(const Value& x, const Value& y);
+ friend bool operator< (const Value& x, const Value& y);
+ friend bool operator<=(const Value& x, const Value& y);
+ friend bool operator> (const Value& x, const Value& y);
+ friend bool operator>=(const Value& x, const Value& y);
+ friend void swap(Value, Value);
+ };
+
+ using iterator_category = std::random_access_iterator_tag;
+ using value_type = Value;
+ using reference = Value&;
+ using difference_type = long;
+ using pointer = Value*;
+
+ Value operator*() const; // Not `Value&`.
+ reference operator[](difference_type n) const;
+
+ BadIter& operator++();
+ BadIter& operator--();
+ BadIter operator++(int);
+ BadIter operator--(int);
+
+ BadIter& operator+=(difference_type n);
+ BadIter& operator-=(difference_type n);
+ friend BadIter operator+(BadIter x, difference_type n);
+ friend BadIter operator+(difference_type n, BadIter x);
+ friend BadIter operator-(BadIter x, difference_type n);
+ friend difference_type operator-(BadIter x, BadIter y);
+
+ friend bool operator==(const BadIter& x, const BadIter& y);
+ friend bool operator!=(const BadIter& x, const BadIter& y);
+ friend bool operator< (const BadIter& x, const BadIter& y);
+ friend bool operator<=(const BadIter& x, const BadIter& y);
+ friend bool operator> (const BadIter& x, const BadIter& y);
+ friend bool operator>=(const BadIter& x, const BadIter& y);
+};
+
+// Verify that iterators with incorrect `iterator_traits` are rejected. This protects against potential undefined
+// behavior when these iterators are passed to standard algorithms.
+void test() {
+ std::sort(BadIter(), BadIter());
+ //expected-error-re@*:* {{static assertion failed {{.*}}It looks like your iterator's `iterator_traits<It>::reference` does not match the return type of dereferencing the iterator}}
+}
diff --git a/libcxx/test/libcxx-03/algorithms/callable-requirements-rvalue.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/callable-requirements-rvalue.compile.pass.cpp
new file mode 100644
index 0000000000000..4a5535e71ab96
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/callable-requirements-rvalue.compile.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <algorithm>
+
+// Make sure that we don't error out when passing a comparator that is lvalue callable
+// but not rvalue callable to algorithms. While it is technically ill-formed for users
+// to provide us such predicates, this test is useful for libc++ to ensure that we check
+// predicate requirements correctly (i.e. that we check them on lvalues and not on
+// rvalues). See https://github.com/llvm/llvm-project/issues/69554 for additional
+// context.
+
+#include <algorithm>
+
+#include "test_macros.h"
+
+struct NotRvalueCallable {
+ bool operator()(int a, int b) const& { return a < b; }
+ bool operator()(int, int) && = delete;
+};
+
+void f() {
+ int a[] = {1, 2, 3, 4};
+ (void)std::lower_bound(a, a + 4, 0, NotRvalueCallable{});
+ (void)std::upper_bound(a, a + 4, 0, NotRvalueCallable{});
+ (void)std::minmax({1, 2, 3}, NotRvalueCallable{});
+ (void)std::minmax_element(a, a + 4, NotRvalueCallable{});
+ (void)std::min_element(a, a + 4, NotRvalueCallable{});
+ (void)std::max_element(a, a + 4, NotRvalueCallable{});
+ (void)std::is_permutation(a, a + 4, a, NotRvalueCallable{});
+#if TEST_STD_VER >= 14
+ (void)std::is_permutation(a, a + 4, a, a + 4, NotRvalueCallable{});
+#endif
+ (void)std::includes(a, a + 4, a, a + 4, NotRvalueCallable{});
+ (void)std::equal_range(a, a + 4, 0, NotRvalueCallable{});
+ (void)std::partial_sort_copy(a, a + 4, a, a + 4, NotRvalueCallable{});
+ (void)std::search(a, a + 4, a, a + 4, NotRvalueCallable{});
+ (void)std::search_n(a, a + 4, 4, 0, NotRvalueCallable{});
+}
diff --git a/libcxx/test/libcxx-03/algorithms/callable-requirements.verify.cpp b/libcxx/test/libcxx-03/algorithms/callable-requirements.verify.cpp
new file mode 100644
index 0000000000000..7555d9815c60b
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/callable-requirements.verify.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Ignore spurious errors after the initial static_assert failure.
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
+
+// <algorithm>
+
+// Check that calling a classic STL algorithm with various non-callable comparators is diagnosed.
+
+#include <algorithm>
+
+#include "test_macros.h"
+
+struct NotCallable {
+ bool compare(int a, int b) const { return a < b; }
+};
+
+struct NotMutableCallable {
+ bool operator()(int a, int b) = delete;
+ bool operator()(int a, int b) const { return a < b; }
+};
+
+void f() {
+ int a[] = {1, 2, 3, 4};
+ {
+ (void)std::lower_bound(a, a + 4, 0, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::upper_bound(a, a + 4, 0, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::minmax({1, 2, 3}, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::minmax_element(a, a + 4, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::min_element(a, a + 4, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::max_element(a, a + 4, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::is_permutation(a, a + 4, a, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+#if TEST_STD_VER >= 14
+ (void)std::is_permutation(a, a + 4, a, a + 4, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+#endif
+
+ (void)std::includes(a, a + 4, a, a + 4, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::equal_range(a, a + 4, 0, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::partial_sort_copy(a, a + 4, a, a + 4, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::search(a, a + 4, a, a + 4, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::search_n(a, a + 4, 4, 0, &NotCallable::compare);
+ // expected-error@*:* {{The comparator has to be callable}}
+ }
+
+ {
+ (void)std::lower_bound(a, a + 4, 0, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::upper_bound(a, a + 4, 0, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::minmax({1, 2, 3}, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::minmax_element(a, a + 4, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::min_element(a, a + 4, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::max_element(a, a + 4, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::is_permutation(a, a + 4, a, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+#if TEST_STD_VER >= 14
+ (void)std::is_permutation(a, a + 4, a, a + 4, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+#endif
+
+ (void)std::includes(a, a + 4, a, a + 4, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::equal_range(a, a + 4, 0, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::partial_sort_copy(a, a + 4, a, a + 4, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::search(a, a + 4, a, a + 4, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+
+ (void)std::search_n(a, a + 4, 4, 0, NotMutableCallable{});
+ // expected-error@*:* {{The comparator has to be callable}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/algorithms/cpp17_iterator_concepts.verify.cpp b/libcxx/test/libcxx-03/algorithms/cpp17_iterator_concepts.verify.cpp
new file mode 100644
index 0000000000000..c4462b26f5c92
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/cpp17_iterator_concepts.verify.cpp
@@ -0,0 +1,425 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 __cpp17_*_iterator catch bad iterators
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <compare>
+#include <cstddef>
+
+struct missing_deref {
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::input_iterator_tag;
+ using value_type = int;
+ using reference = int&;
+
+ missing_deref& operator++();
+};
+
+struct missing_preincrement {
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::input_iterator_tag;
+ using value_type = int;
+ using reference = int&;
+
+ int& operator*();
+};
+
+template <class Derived>
+struct valid_iterator {
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::input_iterator_tag;
+ using value_type = int;
+ using reference = int&;
+
+ int& operator*() const;
+ Derived& operator++();
+
+ struct Proxy {
+ int operator*();
+ };
+
+ Proxy operator++(int);
+};
+
+struct not_move_constructible : valid_iterator<not_move_constructible> {
+ not_move_constructible(const not_move_constructible&) = default;
+ not_move_constructible(not_move_constructible&&) = delete;
+ not_move_constructible& operator=(not_move_constructible&&) = default;
+ not_move_constructible& operator=(const not_move_constructible&) = default;
+};
+
+struct not_copy_constructible : valid_iterator<not_copy_constructible> {
+ not_copy_constructible(const not_copy_constructible&) = delete;
+ not_copy_constructible(not_copy_constructible&&) = default;
+ not_copy_constructible& operator=(not_copy_constructible&&) = default;
+ not_copy_constructible& operator=(const not_copy_constructible&) = default;
+};
+
+struct not_move_assignable : valid_iterator<not_move_assignable> {
+ not_move_assignable(const not_move_assignable&) = default;
+ not_move_assignable(not_move_assignable&&) = default;
+ not_move_assignable& operator=(not_move_assignable&&) = delete;
+ not_move_assignable& operator=(const not_move_assignable&) = default;
+};
+
+struct not_copy_assignable : valid_iterator<not_copy_assignable> {
+ not_copy_assignable(const not_copy_assignable&) = default;
+ not_copy_assignable(not_copy_assignable&&) = default;
+ not_copy_assignable& operator=(not_copy_assignable&&) = default;
+ not_copy_assignable& operator=(const not_copy_assignable&) = delete;
+};
+
+struct diff_t_not_signed : valid_iterator<diff_t_not_signed> {
+ using difference_type = unsigned;
+};
+
+void check_iterator_requirements() {
+ static_assert(std::__cpp17_iterator<missing_deref>); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{indirection requires pointer operand}}
+
+ static_assert(std::__cpp17_iterator<missing_preincrement>); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{cannot increment value of type 'missing_preincrement'}}
+
+ static_assert(std::__cpp17_iterator<not_move_constructible>); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'not_move_constructible' does not satisfy '__cpp17_move_constructible'}}
+
+ static_assert(std::__cpp17_iterator<not_copy_constructible>); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'not_copy_constructible' does not satisfy '__cpp17_copy_constructible'}}
+
+ static_assert(std::__cpp17_iterator<not_move_assignable>); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'not_move_assignable' does not satisfy '__cpp17_copy_assignable'}}
+
+ static_assert(std::__cpp17_iterator<not_copy_assignable>); // expected-error {{static assertion failed}}
+ // expectted-note@*:* {{because 'not_copy_assignable' does not satisfy '__cpp17_copy_assignable'}}
+
+ static_assert(std::__cpp17_iterator<diff_t_not_signed>); // expected-error {{static assertion failed}}
+ // expectted-note@*:* {{'is_signed_v<__iter_diff_t<diff_t_not_signed> >' evaluated to false}}
+}
+
+struct not_equality_comparable : valid_iterator<not_equality_comparable> {};
+bool operator==(not_equality_comparable, not_equality_comparable) = delete;
+bool operator!=(not_equality_comparable, not_equality_comparable);
+
+struct not_unequality_comparable : valid_iterator<not_unequality_comparable> {};
+bool operator==(not_unequality_comparable, not_unequality_comparable);
+bool operator!=(not_unequality_comparable, not_unequality_comparable) = delete;
+
+void check_input_iterator_requirements() {
+ // clang-format off
+ _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_equality_comparable, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{'__lhs == __rhs' would be invalid: overload resolution selected deleted operator '=='}}
+
+ _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_unequality_comparable, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{'__lhs != __rhs' would be invalid: overload resolution selected deleted operator '!='}}
+ // clang-format on
+}
+
+template <class Derived>
+struct valid_forward_iterator : valid_iterator<Derived> {
+ Derived& operator++();
+ Derived operator++(int);
+
+ friend bool operator==(Derived, Derived);
+};
+
+struct not_default_constructible : valid_forward_iterator<not_default_constructible> {
+ not_default_constructible() = delete;
+};
+
+struct postincrement_not_ref : valid_iterator<postincrement_not_ref> {};
+bool operator==(postincrement_not_ref, postincrement_not_ref);
+
+void check_forward_iterator_requirements() {
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(not_default_constructible, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'not_default_constructible' does not satisfy '__cpp17_default_constructible'}}
+ _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(postincrement_not_ref, ""); // expected-error {{static assertion failed}}
+#ifndef _AIX
+ // expected-note-re@*:* {{because type constraint 'convertible_to<{{(valid_iterator<postincrement_not_ref>::)?}}Proxy, const postincrement_not_ref &>' was not satisfied}}
+#endif
+}
+
+struct missing_predecrement : valid_forward_iterator<missing_predecrement> {
+ missing_deref operator--(int);
+};
+
+struct missing_postdecrement : valid_forward_iterator<missing_postdecrement> {
+ missing_postdecrement& operator--();
+};
+
+struct not_returning_iter_reference : valid_forward_iterator<not_returning_iter_reference> {
+ struct Proxy {
+ operator const not_returning_iter_reference&();
+
+ int operator*();
+ };
+
+ not_returning_iter_reference& operator--();
+ Proxy operator--(int);
+};
+
+void check_bidirectional_iterator_requirements() {
+ // clang-format off
+ _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_predecrement, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{cannot decrement value of type 'missing_predecrement'}}
+ _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_postdecrement, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{cannot decrement value of type 'missing_postdecrement'}}
+ _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(not_returning_iter_reference, ""); // expected-error {{static assertion failed}}
+ // expected-note-re@*:* {{because type constraint 'same_as<int, __iter_reference<not_returning_iter_reference>{{ ?}}>' was not satisfied}}
+ // clang-format on
+}
+
+template <class Derived>
+struct valid_random_access_iterator : valid_forward_iterator<Derived> {
+ using difference_type = typename valid_forward_iterator<Derived>::difference_type;
+
+ Derived& operator--();
+ Derived operator--(int);
+
+ Derived& operator+=(difference_type);
+ Derived& operator-=(difference_type);
+
+ friend Derived operator+(valid_random_access_iterator, difference_type);
+ friend Derived operator+(difference_type, valid_random_access_iterator);
+ friend Derived operator-(valid_random_access_iterator, difference_type);
+ friend Derived operator-(difference_type, valid_random_access_iterator);
+ friend difference_type operator-(valid_random_access_iterator, valid_random_access_iterator);
+
+ int& operator[](difference_type) const;
+
+ friend std::strong_ordering operator<=>(Derived, Derived);
+};
+
+struct missing_plus_equals : valid_random_access_iterator<missing_plus_equals> {
+ void operator+=(difference_type) = delete;
+};
+
+struct missing_minus_equals : valid_random_access_iterator<missing_minus_equals> {
+ void operator-=(difference_type) = delete;
+};
+
+struct missing_plus_iter_diff : valid_random_access_iterator<missing_plus_iter_diff> {
+ void operator+(difference_type) = delete;
+};
+
+struct missing_plus_diff_iter : valid_random_access_iterator<missing_plus_diff_iter> {
+ friend missing_plus_diff_iter operator+(difference_type, missing_plus_diff_iter) = delete;
+};
+
+struct missing_plus_iter_diff_const_mut : valid_random_access_iterator<missing_plus_iter_diff_const_mut> {
+ friend missing_plus_iter_diff_const_mut operator+(missing_plus_iter_diff_const_mut&, difference_type);
+ friend missing_plus_iter_diff_const_mut operator+(const missing_plus_iter_diff_const_mut&, difference_type) = delete;
+};
+
+struct missing_plus_iter_diff_mut_const : valid_random_access_iterator<missing_plus_iter_diff_mut_const> {
+ friend missing_plus_iter_diff_mut_const operator+(missing_plus_iter_diff_mut_const, difference_type);
+ friend missing_plus_iter_diff_mut_const operator+(difference_type, missing_plus_iter_diff_mut_const&);
+ friend missing_plus_iter_diff_mut_const operator+(difference_type, const missing_plus_iter_diff_mut_const&) = delete;
+};
+
+struct missing_minus_iter_diff_const : valid_random_access_iterator<missing_minus_iter_diff_const> {
+ friend missing_minus_iter_diff_const operator-(missing_minus_iter_diff_const&, difference_type);
+ friend missing_minus_iter_diff_const operator-(const missing_minus_iter_diff_const&, difference_type) = delete;
+};
+
+struct missing_minus_iter_iter : valid_random_access_iterator<missing_minus_iter_iter> {
+ friend missing_minus_iter_iter operator-(missing_minus_iter_iter, missing_minus_iter_iter) = delete;
+};
+
+struct missing_minus_const_iter_iter : valid_random_access_iterator<missing_minus_const_iter_iter> {
+ friend difference_type operator-(missing_minus_const_iter_iter&, missing_minus_const_iter_iter);
+ friend difference_type operator-(const missing_minus_const_iter_iter&, missing_minus_const_iter_iter) = delete;
+};
+
+struct missing_minus_iter_const_iter : valid_random_access_iterator<missing_minus_iter_const_iter> {
+ friend difference_type operator-(missing_minus_iter_const_iter, missing_minus_iter_const_iter&);
+ friend difference_type operator-(missing_minus_iter_const_iter, const missing_minus_iter_const_iter&) = delete;
+};
+
+struct missing_minus_const_iter_const_iter : valid_random_access_iterator<missing_minus_const_iter_const_iter> {
+ friend difference_type operator-(missing_minus_const_iter_const_iter&, missing_minus_const_iter_const_iter&);
+ friend difference_type operator-(const missing_minus_const_iter_const_iter&, missing_minus_const_iter_const_iter&);
+ friend difference_type operator-(missing_minus_const_iter_const_iter&, const missing_minus_const_iter_const_iter&);
+ friend difference_type
+ operator-(const missing_minus_const_iter_const_iter&, const missing_minus_const_iter_const_iter&) = delete;
+};
+
+struct missing_subscript_operator : valid_random_access_iterator<missing_subscript_operator> {
+ int& operator[](difference_type) = delete;
+};
+
+struct missing_const_subscript_operator : valid_random_access_iterator<missing_const_subscript_operator> {
+ int& operator[](difference_type);
+ int& operator[](difference_type) const = delete;
+};
+
+struct missing_less : valid_random_access_iterator<missing_less> {
+ friend bool operator<(missing_less, missing_less) = delete;
+};
+
+struct missing_const_mut_less : valid_random_access_iterator<missing_const_mut_less> {
+ friend bool operator<(missing_const_mut_less&, missing_const_mut_less&);
+ friend bool operator<(missing_const_mut_less&, const missing_const_mut_less&);
+ friend bool operator<(const missing_const_mut_less&, missing_const_mut_less&) = delete;
+ friend bool operator<(const missing_const_mut_less&, const missing_const_mut_less&);
+};
+
+struct missing_mut_const_less : valid_random_access_iterator<missing_mut_const_less> {
+ friend bool operator<(missing_mut_const_less&, missing_mut_const_less&);
+ friend bool operator<(missing_mut_const_less&, const missing_mut_const_less&) = delete;
+ friend bool operator<(const missing_mut_const_less&, missing_mut_const_less&);
+ friend bool operator<(const missing_mut_const_less&, const missing_mut_const_less&);
+};
+
+struct missing_const_const_less : valid_random_access_iterator<missing_const_const_less> {
+ friend bool operator<(missing_const_const_less&, missing_const_const_less&);
+ friend bool operator<(missing_const_const_less&, const missing_const_const_less&);
+ friend bool operator<(const missing_const_const_less&, missing_const_const_less&);
+ friend bool operator<(const missing_const_const_less&, const missing_const_const_less&) = delete;
+};
+
+struct missing_greater : valid_random_access_iterator<missing_greater> {
+ friend bool operator>(missing_greater, missing_greater) = delete;
+};
+
+struct missing_const_mut_greater : valid_random_access_iterator<missing_const_mut_greater> {
+ friend bool operator>(missing_const_mut_greater&, missing_const_mut_greater&);
+ friend bool operator>(missing_const_mut_greater&, const missing_const_mut_greater&);
+ friend bool operator>(const missing_const_mut_greater&, missing_const_mut_greater&) = delete;
+ friend bool operator>(const missing_const_mut_greater&, const missing_const_mut_greater&);
+};
+
+struct missing_mut_const_greater : valid_random_access_iterator<missing_mut_const_greater> {
+ friend bool operator>(missing_mut_const_greater&, missing_mut_const_greater&);
+ friend bool operator>(missing_mut_const_greater&, const missing_mut_const_greater&) = delete;
+ friend bool operator>(const missing_mut_const_greater&, missing_mut_const_greater&);
+ friend bool operator>(const missing_mut_const_greater&, const missing_mut_const_greater&);
+};
+
+struct missing_const_const_greater : valid_random_access_iterator<missing_const_const_greater> {
+ friend bool operator>(missing_const_const_greater&, missing_const_const_greater&);
+ friend bool operator>(missing_const_const_greater&, const missing_const_const_greater&);
+ friend bool operator>(const missing_const_const_greater&, missing_const_const_greater&);
+ friend bool operator>(const missing_const_const_greater&, const missing_const_const_greater&) = delete;
+};
+
+struct missing_less_eq : valid_random_access_iterator<missing_less_eq> {
+ friend bool operator<=(missing_less_eq, missing_less_eq) = delete;
+};
+
+struct missing_const_mut_less_eq : valid_random_access_iterator<missing_const_mut_less_eq> {
+ friend bool operator<=(missing_const_mut_less_eq&, missing_const_mut_less_eq&);
+ friend bool operator<=(missing_const_mut_less_eq&, const missing_const_mut_less_eq&);
+ friend bool operator<=(const missing_const_mut_less_eq&, missing_const_mut_less_eq&) = delete;
+ friend bool operator<=(const missing_const_mut_less_eq&, const missing_const_mut_less_eq&);
+};
+
+struct missing_mut_const_less_eq : valid_random_access_iterator<missing_mut_const_less_eq> {
+ friend bool operator<=(missing_mut_const_less_eq&, missing_mut_const_less_eq&);
+ friend bool operator<=(missing_mut_const_less_eq&, const missing_mut_const_less_eq&) = delete;
+ friend bool operator<=(const missing_mut_const_less_eq&, missing_mut_const_less_eq&);
+ friend bool operator<=(const missing_mut_const_less_eq&, const missing_mut_const_less_eq&);
+};
+
+struct missing_const_const_less_eq : valid_random_access_iterator<missing_const_const_less_eq> {
+ friend bool operator<=(missing_const_const_less_eq&, missing_const_const_less_eq&);
+ friend bool operator<=(missing_const_const_less_eq&, const missing_const_const_less_eq&);
+ friend bool operator<=(const missing_const_const_less_eq&, missing_const_const_less_eq&);
+ friend bool operator<=(const missing_const_const_less_eq&, const missing_const_const_less_eq&) = delete;
+};
+
+struct missing_greater_eq : valid_random_access_iterator<missing_greater_eq> {
+ friend bool operator>=(missing_greater_eq, missing_greater_eq) = delete;
+};
+
+struct missing_const_mut_greater_eq : valid_random_access_iterator<missing_const_mut_greater_eq> {
+ friend bool operator>=(missing_const_mut_greater_eq&, missing_const_mut_greater_eq&);
+ friend bool operator>=(missing_const_mut_greater_eq&, const missing_const_mut_greater_eq&);
+ friend bool operator>=(const missing_const_mut_greater_eq&, missing_const_mut_greater_eq&) = delete;
+ friend bool operator>=(const missing_const_mut_greater_eq&, const missing_const_mut_greater_eq&);
+};
+
+struct missing_mut_const_greater_eq : valid_random_access_iterator<missing_mut_const_greater_eq> {
+ friend bool operator>=(missing_mut_const_greater_eq&, missing_mut_const_greater_eq&);
+ friend bool operator>=(missing_mut_const_greater_eq&, const missing_mut_const_greater_eq&) = delete;
+ friend bool operator>=(const missing_mut_const_greater_eq&, missing_mut_const_greater_eq&);
+ friend bool operator>=(const missing_mut_const_greater_eq&, const missing_mut_const_greater_eq&);
+};
+
+struct missing_const_const_greater_eq : valid_random_access_iterator<missing_const_const_greater_eq> {
+ friend bool operator>=(missing_const_const_greater_eq&, missing_const_const_greater_eq&);
+ friend bool operator>=(missing_const_const_greater_eq&, const missing_const_const_greater_eq&);
+ friend bool operator>=(const missing_const_const_greater_eq&, missing_const_const_greater_eq&);
+ friend bool operator>=(const missing_const_const_greater_eq&, const missing_const_const_greater_eq&) = delete;
+};
+
+void check_random_access_iterator() {
+ // clang-format off
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_equals, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter += __n' would be invalid: overload resolution selected deleted operator '+='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_equals, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter -= __n' would be invalid: overload resolution selected deleted operator '-='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_diff, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter + __n' would be invalid: overload resolution selected deleted operator '+'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_diff_iter, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__n + __iter' would be invalid: overload resolution selected deleted operator '+'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_diff_const_mut, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) + __n' would be invalid: overload resolution selected deleted operator '+'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_diff_mut_const, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__n + std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '+'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_diff_const, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) - __n' would be invalid: overload resolution selected deleted operator '-'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_iter, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter - __iter' would be invalid: overload resolution selected deleted operator '-'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_const_iter_iter, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) - __iter' would be invalid: overload resolution selected deleted operator '-'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_const_iter, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter - std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '-'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_const_iter_const_iter, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) - std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '-'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_subscript_operator, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter[__n]' would be invalid: overload resolution selected deleted operator '[]'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_subscript_operator, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter)[__n]' would be invalid: overload resolution selected deleted operator '[]'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter < __iter' would be invalid: overload resolution selected deleted operator '<'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_less, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) < __iter' would be invalid: overload resolution selected deleted operator '<'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_less, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter < std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_less, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) < std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter > __iter' would be invalid: overload resolution selected deleted operator '>'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_greater, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) > __iter' would be invalid: overload resolution selected deleted operator '>'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_greater, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter > std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_greater, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) > std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>'}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter <= __iter' would be invalid: overload resolution selected deleted operator '<='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_less_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) <= __iter' would be invalid: overload resolution selected deleted operator '<='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_less_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter <= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_less_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) <= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter >= __iter' would be invalid: overload resolution selected deleted operator '>='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_greater_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) >= __iter' would be invalid: overload resolution selected deleted operator '>='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_greater_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because '__iter >= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>='}}
+ _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_greater_eq, ""); // expected-error {{static assertion failed}}
+ // expected-note@*:* {{because 'std::as_const(__iter) >= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>='}}
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/algorithms/debug_less.inconsistent.pass.cpp b/libcxx/test/libcxx-03/algorithms/debug_less.inconsistent.pass.cpp
new file mode 100644
index 0000000000000..701edd1335afa
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/debug_less.inconsistent.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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class _Compare> struct __debug_less
+
+// Make sure __debug_less asserts when the comparator is not consistent.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode=debug
+// UNSUPPORTED: c++03
+
+#include <algorithm>
+#include <iterator>
+
+#include "check_assertion.h"
+
+template <int ID>
+struct MyType {
+ int value;
+ explicit MyType(int xvalue = 0) : value(xvalue) {}
+};
+
+template <int ID1, int ID2>
+bool operator<(MyType<ID1> const& LHS, MyType<ID2> const& RHS) {
+ return LHS.value < RHS.value;
+}
+
+template <class ValueType>
+struct BadComparator {
+ bool operator()(ValueType const&, ValueType const&) const {
+ return true;
+ }
+};
+
+int main(int, char**) {
+ typedef MyType<0> MT0;
+ MT0 one(1);
+ MT0 two(2);
+
+ BadComparator<MT0> c;
+ std::__debug_less<BadComparator<MT0>> d(c);
+
+ TEST_LIBCPP_ASSERT_FAILURE(d(one, two), "Comparator does not induce a strict weak ordering");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/debug_less.pass.cpp b/libcxx/test/libcxx-03/algorithms/debug_less.pass.cpp
new file mode 100644
index 0000000000000..4889f94d170a1
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/debug_less.pass.cpp
@@ -0,0 +1,260 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class _Compare> struct __debug_less
+
+// __debug_less checks that a comparator actually provides a strict-weak ordering.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode=debug
+// UNSUPPORTED: c++03
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iterator>
+
+#include "test_macros.h"
+#include "check_assertion.h"
+
+template <int ID>
+struct MyType {
+ int value;
+ explicit MyType(int xvalue = 0) : value(xvalue) {}
+};
+
+template <int ID1, int ID2>
+bool operator<(MyType<ID1> const& LHS, MyType<ID2> const& RHS) {
+ return LHS.value < RHS.value;
+}
+
+struct CompareBase {
+ static int called;
+ static void reset() {
+ called = 0;
+ }
+};
+
+int CompareBase::called = 0;
+
+template <class ValueType>
+struct GoodComparator : public CompareBase {
+ bool operator()(ValueType const& lhs, ValueType const& rhs) const {
+ ++CompareBase::called;
+ return lhs < rhs;
+ }
+};
+
+template <class T1, class T2>
+struct TwoWayHomoComparator : public CompareBase {
+ bool operator()(T1 const& lhs, T2 const& rhs) const {
+ ++CompareBase::called;
+ return lhs < rhs;
+ }
+
+ bool operator()(T2 const& lhs, T1 const& rhs) const {
+ ++CompareBase::called;
+ return lhs < rhs;
+ }
+};
+
+template <class T1, class T2>
+struct OneWayHomoComparator : public CompareBase {
+ bool operator()(T1 const& lhs, T2 const& rhs) const {
+ ++CompareBase::called;
+ return lhs < rhs;
+ }
+};
+
+using std::__debug_less;
+
+typedef MyType<0> MT0;
+typedef MyType<1> MT1;
+
+void test_passing() {
+ int& called = CompareBase::called;
+ called = 0;
+ MT0 one(1);
+ MT0 two(2);
+ MT1 three(3);
+ MT1 four(4);
+
+ {
+ typedef GoodComparator<MT0> C;
+ typedef __debug_less<C> D;
+
+ C c;
+ D d(c);
+
+ assert(d(one, two) == true);
+ assert(called == 2);
+ called = 0;
+
+ assert(d(one, one) == false);
+ assert(called == 1);
+ called = 0;
+
+ assert(d(two, one) == false);
+ assert(called == 1);
+ called = 0;
+ }
+ {
+ typedef TwoWayHomoComparator<MT0, MT1> C;
+ typedef __debug_less<C> D;
+ C c;
+ D d(c);
+
+ assert(d(one, three) == true);
+ assert(called == 2);
+ called = 0;
+
+ assert(d(three, one) == false);
+ assert(called == 1);
+ called = 0;
+ }
+ {
+ typedef OneWayHomoComparator<MT0, MT1> C;
+ typedef __debug_less<C> D;
+ C c;
+ D d(c);
+
+ assert(d(one, three) == true);
+ assert(called == 1);
+ called = 0;
+ }
+}
+
+template <int>
+struct Tag {
+ explicit Tag(int v) : value(v) {}
+ int value;
+};
+
+template <class = void>
+struct FooImp {
+ explicit FooImp(int x) : x_(x) {}
+ int x_;
+};
+
+template <class T>
+inline bool operator<(FooImp<T> const& x, Tag<0> y) {
+ return x.x_ < y.value;
+}
+
+template <class T>
+inline bool operator<(Tag<0>, FooImp<T> const&) {
+ static_assert(sizeof(FooImp<T>) != sizeof(FooImp<T>), "should not be instantiated");
+ return false;
+}
+
+template <class T>
+inline bool operator<(Tag<1> x, FooImp<T> const& y) {
+ return x.value < y.x_;
+}
+
+template <class T>
+inline bool operator<(FooImp<T> const&, Tag<1>) {
+ static_assert(sizeof(FooImp<T>) != sizeof(FooImp<T>), "should not be instantiated");
+ return false;
+}
+
+typedef FooImp<> Foo;
+
+// Test that we don't attempt to call the comparator with the arguments reversed
+// for upper_bound and lower_bound since the comparator or type is not required
+// to support it, nor does it require the range to have a strict weak ordering.
+// See llvm.org/PR39458
+void test_upper_and_lower_bound() {
+ Foo table[] = {Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)};
+ {
+ Foo* iter = std::lower_bound(std::begin(table), std::end(table), Tag<0>(3));
+ assert(iter == (table + 2));
+ }
+ {
+ Foo* iter = std::upper_bound(std::begin(table), std::end(table), Tag<1>(3));
+ assert(iter == (table + 3));
+ }
+}
+
+struct NonConstArgCmp {
+ bool operator()(int& x, int &y) const {
+ return x < y;
+ }
+};
+
+void test_non_const_arg_cmp() {
+ {
+ NonConstArgCmp cmp;
+ __debug_less<NonConstArgCmp> dcmp(cmp);
+ int x = 0, y = 1;
+ assert(dcmp(x, y));
+ assert(!dcmp(y, x));
+ }
+ {
+ NonConstArgCmp cmp;
+ int arr[] = {5, 4, 3, 2, 1};
+ std::sort(std::begin(arr), std::end(arr), cmp);
+ assert(std::is_sorted(std::begin(arr), std::end(arr)));
+ }
+}
+
+struct ValueIterator {
+ typedef std::input_iterator_tag iterator_category;
+ typedef std::size_t value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t reference;
+ typedef std::size_t* pointer;
+
+ ValueIterator() { }
+
+ reference operator*() { return 0; }
+ ValueIterator& operator++() { return *this; }
+
+ friend bool operator==(ValueIterator, ValueIterator) { return true; }
+ friend bool operator!=(ValueIterator, ValueIterator) { return false; }
+};
+
+void test_value_iterator() {
+ // Ensure no build failures when iterators return values, not references.
+ assert(0 == std::lexicographical_compare(ValueIterator(), ValueIterator(),
+ ValueIterator(), ValueIterator()));
+}
+
+void test_value_categories() {
+ std::less<int> l;
+ std::__debug_less<std::less<int> > dl(l);
+ int lvalue = 42;
+ const int const_lvalue = 101;
+
+ assert(dl(lvalue, const_lvalue));
+ assert(dl(/*rvalue*/1, lvalue));
+ assert(dl(static_cast<int&&>(1), static_cast<const int&&>(2)));
+}
+
+#if TEST_STD_VER > 11
+constexpr bool test_constexpr() {
+ std::less<> cmp{};
+ __debug_less<std::less<> > dcmp(cmp);
+ assert(dcmp(1, 2));
+ assert(!dcmp(1, 1));
+ return true;
+}
+#endif
+
+int main(int, char**) {
+ test_passing();
+ test_upper_and_lower_bound();
+ test_non_const_arg_cmp();
+ test_value_iterator();
+ test_value_categories();
+#if TEST_STD_VER > 11
+ static_assert(test_constexpr(), "");
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/debug_three_way_comp.inconsistent.pass.cpp b/libcxx/test/libcxx-03/algorithms/debug_three_way_comp.inconsistent.pass.cpp
new file mode 100644
index 0000000000000..b9bb1c9136f65
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/debug_three_way_comp.inconsistent.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class _Comp> struct __debug_three_way_comp
+
+// Make sure __debug_three_way_comp asserts when the comparator is not consistent.
+
+// REQUIRES: libcpp-hardening-mode=debug
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <algorithm>
+#include <iterator>
+
+#include "check_assertion.h"
+
+struct AlwaysLess {
+ std::strong_ordering operator()(int, int) const { return std::strong_ordering::less; }
+};
+
+struct AlwaysGreater {
+ std::strong_ordering operator()(int, int) const { return std::strong_ordering::greater; }
+};
+
+struct InconsistentEquals {
+ std::strong_ordering operator()(int a, int) const {
+ if (a == 0)
+ return std::strong_ordering::equal;
+ return std::strong_ordering::greater;
+ }
+};
+
+int main(int, char**) {
+ int zero = 0;
+ int one = 1;
+
+ AlwaysLess alwaysLess;
+ std::__debug_three_way_comp<AlwaysLess> debugAlwaysLess(alwaysLess);
+ TEST_LIBCPP_ASSERT_FAILURE(debugAlwaysLess(zero, one), "Comparator does not induce a strict weak ordering");
+
+ AlwaysGreater alwaysGreater;
+ std::__debug_three_way_comp<AlwaysGreater> debugAlwaysGreater(alwaysGreater);
+ TEST_LIBCPP_ASSERT_FAILURE(debugAlwaysGreater(zero, one), "Comparator does not induce a strict weak ordering");
+
+ InconsistentEquals inconsistentEquals;
+ std::__debug_three_way_comp<InconsistentEquals> debugInconsistentEquals(inconsistentEquals);
+ TEST_LIBCPP_ASSERT_FAILURE(debugInconsistentEquals(zero, one), "Comparator does not induce a strict weak ordering");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp b/libcxx/test/libcxx-03/algorithms/half_positive.pass.cpp
new file mode 100644
index 0000000000000..88a18e8592921
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/half_positive.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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// __half_positive divides an integer number by 2 as unsigned number for known types.
+// It can be an important optimization for lower bound, for example.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__algorithm/half_positive.h>
+#include <cassert>
+#include <cstddef>
+#include <limits>
+
+#include "test_macros.h"
+#include "user_defined_integral.h"
+
+namespace {
+
+template <class IntType, class UnderlyingType = IntType>
+TEST_CONSTEXPR bool test(IntType max_v = IntType(std::numeric_limits<UnderlyingType>::max())) {
+ return std::__half_positive(max_v) == max_v / 2;
+}
+
+} // namespace
+
+int main(int, char**)
+{
+ {
+ assert(test<char>());
+ assert(test<int>());
+ assert(test<long>());
+ assert((test<UserDefinedIntegral<int>, int>()));
+ assert(test<std::size_t>());
+#if !defined(TEST_HAS_NO_INT128)
+ assert(test<__int128_t>());
+#endif // !defined(TEST_HAS_NO_INT128)
+ }
+
+#if TEST_STD_VER >= 11
+ {
+ static_assert(test<char>(), "");
+ static_assert(test<int>(), "");
+ static_assert(test<long>(), "");
+ static_assert(test<std::size_t>(), "");
+#if !defined(TEST_HAS_NO_INT128)
+ static_assert(test<__int128_t>(), "");
+#endif // !defined(TEST_HAS_NO_INT128)
+ }
+#endif // TEST_STD_VER >= 11
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/lifetimebound.verify.cpp b/libcxx/test/libcxx-03/algorithms/lifetimebound.verify.cpp
new file mode 100644
index 0000000000000..6bb1a4c6bbe3d
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/lifetimebound.verify.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
+// ADDITIONAL_COMPILE_FLAGS: -Wno-pessimizing-move -Wno-unused-variable
+
+#include <algorithm>
+
+#include "test_macros.h"
+
+struct Comp {
+ template <class T, class U>
+ bool operator()(T, U) {
+ return false;
+ }
+};
+
+void func() {
+ int i = 0;
+ {
+ auto&& v1 = std::min(0, i); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::min(i, 0); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::min(0, i, Comp{}); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::min(i, 0, Comp{}); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+ }
+ {
+ auto&& v1 = std::max(0, i); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::max(i, 0); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::max(0, i, Comp{}); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::max(i, 0, Comp{}); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+ }
+ {
+ auto&& v1 = std::minmax(0, i); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::minmax(i, 0); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::minmax(0, i, Comp{}); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::minmax(i, 0, Comp{}); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+ auto v5 = std::minmax(0, i); // expected-warning {{temporary whose address is used as value of local variable 'v5' will be destroyed at the end of the full-expression}}
+ auto v6 = std::minmax(i, 0); // expected-warning {{temporary whose address is used as value of local variable 'v6' will be destroyed at the end of the full-expression}}
+ auto v7 = std::minmax(0, i, Comp{}); // expected-warning {{temporary whose address is used as value of local variable 'v7' will be destroyed at the end of the full-expression}}
+ auto v8 = std::minmax(i, 0, Comp{}); // expected-warning {{temporary whose address is used as value of local variable 'v8' will be destroyed at the end of the full-expression}}
+ }
+#if TEST_STD_VER >= 17
+ {
+ auto&& v1 = std::clamp(1, i, i); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::clamp(i, 1, i); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::clamp(i, i, 1); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::clamp(1, i, i, Comp{}); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+ auto&& v5 = std::clamp(i, 1, i, Comp{}); // expected-warning {{temporary bound to local reference 'v5' will be destroyed at the end of the full-expression}}
+ auto&& v6 = std::clamp(i, i, 1, Comp{}); // expected-warning {{temporary bound to local reference 'v6' will be destroyed at the end of the full-expression}}
+ }
+#endif
+#if TEST_STD_VER >= 20
+ {
+ auto&& v1 = std::ranges::min(0, i); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::ranges::min(i, 0); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::ranges::min(0, i, Comp{}); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::ranges::min(i, 0, Comp{}); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+ }
+ {
+ auto&& v1 = std::ranges::max(0, i); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::ranges::max(i, 0); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::ranges::max(0, i, Comp{}); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::ranges::max(i, 0, Comp{}); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+ }
+ {
+ auto&& v1 = std::ranges::minmax(0, i); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::ranges::minmax(i, 0); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::ranges::minmax(0, i, Comp{}); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::ranges::minmax(i, 0, Comp{}); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+ auto v5 = std::ranges::minmax(0, i); // expected-warning {{temporary whose address is used as value of local variable 'v5' will be destroyed at the end of the full-expression}}
+ auto v6 = std::ranges::minmax(i, 0); // expected-warning {{temporary whose address is used as value of local variable 'v6' will be destroyed at the end of the full-expression}}
+ auto v7 = std::ranges::minmax(0, i, Comp{}); // expected-warning {{temporary whose address is used as value of local variable 'v7' will be destroyed at the end of the full-expression}}
+ auto v8 = std::ranges::minmax(i, 0, Comp{}); // expected-warning {{temporary whose address is used as value of local variable 'v8' will be destroyed at the end of the full-expression}}
+ }
+#endif // TEST_STD_VER >= 20
+}
diff --git a/libcxx/test/libcxx-03/algorithms/no_specializations.verify.cpp b/libcxx/test/libcxx-03/algorithms/no_specializations.verify.cpp
new file mode 100644
index 0000000000000..5b2475252b602
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/no_specializations.verify.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// Check that user-specializations are diagnosed
+// See [execpol.type]/3
+
+#include <execution>
+
+#if !__has_warning("-Winvalid-specializations")
+// expected-no-diagnostics
+#else
+struct S {};
+
+template <>
+struct std::is_execution_policy<S>; // expected-error {{cannot be specialized}}
+
+template <>
+constexpr bool std::is_execution_policy_v<S> = false; // expected-error {{cannot be specialized}}
+#endif
diff --git a/libcxx/test/libcxx-03/algorithms/nth_element_stability.pass.cpp b/libcxx/test/libcxx-03/algorithms/nth_element_stability.pass.cpp
new file mode 100644
index 0000000000000..7124e54c2285b
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/nth_element_stability.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// Test std::nth_element stability randomization
+
+// UNSUPPORTED: c++03
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <vector>
+
+#include "test_macros.h"
+
+struct MyType {
+ int value = 0;
+ constexpr bool operator<(const MyType& other) const { return value < other.value; }
+};
+
+std::vector<MyType> deterministic() {
+ static constexpr int kSize = 100;
+ std::vector<MyType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = (i % 2 ? i : kSize / 2 + i);
+ }
+ std::__nth_element<std::_ClassicAlgPolicy>(v.begin(), v.begin() + kSize / 2, v.end(), std::less<MyType>());
+ return v;
+}
+
+void test_randomization() {
+ static constexpr int kSize = 100;
+ std::vector<MyType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = (i % 2 ? i : kSize / 2 + i);
+ }
+ auto deterministic_v = deterministic();
+ std::nth_element(v.begin(), v.begin() + kSize / 2, v.end());
+ bool all_equal = true;
+ for (int i = 0; i < kSize; ++i) {
+ if (v[i].value != deterministic_v[i].value) {
+ all_equal = false;
+ }
+ }
+ assert(!all_equal);
+}
+
+void test_same() {
+ static constexpr int kSize = 100;
+ std::vector<MyType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = (i % 2 ? i : kSize / 2 + i);
+ }
+ auto snapshot_v = v;
+ auto snapshot_custom_v = v;
+ std::nth_element(v.begin(), v.begin() + kSize / 2, v.end());
+ std::nth_element(snapshot_v.begin(), snapshot_v.begin() + kSize / 2, snapshot_v.end());
+ std::nth_element(snapshot_custom_v.begin(), snapshot_custom_v.begin() + kSize / 2, snapshot_custom_v.end(), std::less<MyType>());
+ bool all_equal = true;
+ for (int i = 0; i < kSize; ++i) {
+ if (v[i].value != snapshot_v[i].value || v[i].value != snapshot_custom_v[i].value) {
+ all_equal = false;
+ }
+ if (i < kSize / 2) {
+ assert(v[i].value <= v[kSize / 2].value);
+ }
+ }
+ assert(all_equal);
+}
+
+#if TEST_STD_VER > 17
+constexpr bool test_constexpr() {
+ std::array<MyType, 10> v;
+ for (int i = 9; i >= 0; --i) {
+ v[9 - i].value = i;
+ }
+ std::nth_element(v.begin(), v.begin() + 5, v.end());
+ return std::is_partitioned(v.begin(), v.end(), [&](const MyType& m) { return m.value <= v[5].value; });
+}
+#endif
+
+int main(int, char**) {
+ test_randomization();
+ test_same();
+#if TEST_STD_VER > 17
+ static_assert(test_constexpr(), "");
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/partial_sort_stability.pass.cpp b/libcxx/test/libcxx-03/algorithms/partial_sort_stability.pass.cpp
new file mode 100644
index 0000000000000..3f9a5a0bd7708
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/partial_sort_stability.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// Test std::partial_sort stability randomization
+
+// UNSUPPORTED: c++03
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <vector>
+
+#include "test_macros.h"
+
+struct MyType {
+ int value = 0;
+ constexpr bool operator<(const MyType& other) const { return value < other.value; }
+};
+
+std::vector<MyType> deterministic() {
+ static constexpr int kSize = 100;
+ std::vector<MyType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = (i % 2 ? 1 : kSize / 2 + i);
+ }
+ auto comp = std::less<MyType>();
+ std::__partial_sort_impl<std::_ClassicAlgPolicy>(v.begin(), v.begin() + kSize / 2, v.end(), comp);
+ return v;
+}
+
+void test_randomization() {
+ static constexpr int kSize = 100;
+ std::vector<MyType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = (i % 2 ? 1 : kSize / 2 + i);
+ }
+ auto deterministic_v = deterministic();
+ std::partial_sort(v.begin(), v.begin() + kSize / 2, v.end());
+ bool all_equal = true;
+ for (int i = 0; i < kSize; ++i) {
+ if (v[i].value != deterministic_v[i].value) {
+ all_equal = false;
+ }
+ }
+ assert(!all_equal);
+}
+
+void test_same() {
+ static constexpr int kSize = 100;
+ std::vector<MyType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = (i % 2 ? 1 : kSize / 2 + i);
+ }
+ auto snapshot_v = v;
+ auto snapshot_custom_v = v;
+ std::partial_sort(v.begin(), v.begin() + kSize / 2, v.end());
+ std::partial_sort(snapshot_v.begin(), snapshot_v.begin() + kSize / 2, snapshot_v.end());
+ std::partial_sort(snapshot_custom_v.begin(), snapshot_custom_v.begin() + kSize / 2, snapshot_custom_v.end(), std::less<MyType>());
+ bool all_equal = true;
+ for (int i = 0; i < kSize; ++i) {
+ if (v[i].value != snapshot_v[i].value || v[i].value != snapshot_custom_v[i].value) {
+ all_equal = false;
+ }
+ if (i < kSize / 2) {
+ assert(v[i].value == 1);
+ }
+ }
+ assert(all_equal);
+}
+
+#if TEST_STD_VER > 17
+constexpr bool test_constexpr() {
+ std::array<MyType, 10> v;
+ for (int i = 9; i >= 0; --i) {
+ v[9 - i].value = i;
+ }
+ std::partial_sort(v.begin(), v.begin() + 5, v.end());
+ return std::is_sorted(v.begin(), v.begin() + 5);
+}
+#endif
+
+int main(int, char**) {
+ test_randomization();
+ test_same();
+#if TEST_STD_VER > 17
+ static_assert(test_constexpr(), "");
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/pstl.iterator-requirements.verify.cpp b/libcxx/test/libcxx-03/algorithms/pstl.iterator-requirements.verify.cpp
new file mode 100644
index 0000000000000..e5bd7e764c59b
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/pstl.iterator-requirements.verify.cpp
@@ -0,0 +1,193 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// REQUIRES: stdlib=libc++
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// <algorithm>
+// <numeric>
+
+// Make sure that all PSTL algorithms contain checks for iterator requirements.
+// This is not a requirement from the Standard, but we strive to catch misuse in
+// the PSTL both because we can, and because iterator category mistakes in the
+// PSTL can lead to subtle bugs.
+
+// Ignore spurious errors after the initial static_assert failure.
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
+
+// We only diagnose this in C++20 and above because we implement the checks with concepts.
+// UNSUPPORTED: c++17
+
+#include <algorithm>
+#include <cstddef>
+#include <execution>
+#include <numeric>
+
+#include "test_iterators.h"
+
+using non_forward_iterator = cpp17_input_iterator<int*>;
+struct non_output_iterator : forward_iterator<int*> {
+ constexpr int const& operator*() const; // prevent it from being an output iterator
+};
+
+void f(non_forward_iterator non_fwd, non_output_iterator non_output, std::execution::sequenced_policy pol) {
+ auto pred = [](auto&&...) -> bool { return true; };
+ auto func = [](auto&&...) -> int { return 1; };
+ int* it = nullptr;
+ int* out = nullptr;
+ std::size_t n = 0;
+ int val = 0;
+
+ {
+ (void)std::any_of(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: any_of}}
+ (void)std::all_of(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: all_of}}
+ (void)std::none_of(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: none_of}}
+ }
+
+ {
+ (void)std::copy(pol, non_fwd, non_fwd, it); // expected-error@*:* {{static assertion failed: copy}}
+ (void)std::copy(pol, it, it, non_fwd); // expected-error@*:* {{static assertion failed: copy}}
+ (void)std::copy(pol, it, it, non_output); // expected-error@*:* {{static assertion failed: copy}}
+ }
+ {
+ (void)std::copy_n(pol, non_fwd, n, it); // expected-error@*:* {{static assertion failed: copy_n}}
+ (void)std::copy_n(pol, it, n, non_fwd); // expected-error@*:* {{static assertion failed: copy_n}}
+ (void)std::copy_n(pol, it, n, non_output); // expected-error@*:* {{static assertion failed: copy_n}}
+ }
+
+ {
+ (void)std::count(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: count}}
+ (void)std::count_if(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: count_if}}
+ }
+
+ {
+ (void)std::equal(pol, non_fwd, non_fwd, it); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, non_fwd, non_fwd, it, pred); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd, pred); // expected-error@*:* {{static assertion failed: equal}}
+
+ (void)std::equal(pol, non_fwd, non_fwd, it, it); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, non_fwd, non_fwd, it, it, pred); // expected-error@*:* {{static assertion failed: equal}}
+ (void)std::equal(pol, it, it, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: equal}}
+ }
+
+ {
+ (void)std::fill(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: fill}}
+ (void)std::fill_n(pol, non_fwd, n, val); // expected-error@*:* {{static assertion failed: fill_n}}
+ }
+
+ {
+ (void)std::find(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: find}}
+ (void)std::find_if(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: find_if}}
+ (void)std::find_if_not(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: find_if_not}}
+ }
+
+ {
+ (void)std::for_each(pol, non_fwd, non_fwd, func); // expected-error@*:* {{static assertion failed: for_each}}
+ (void)std::for_each_n(pol, non_fwd, n, func); // expected-error@*:* {{static assertion failed: for_each_n}}
+ }
+
+ {
+ (void)std::generate(pol, non_fwd, non_fwd, func); // expected-error@*:* {{static assertion failed: generate}}
+ (void)std::generate_n(pol, non_fwd, n, func); // expected-error@*:* {{static assertion failed: generate_n}}
+ }
+
+ {
+ (void)std::is_partitioned(
+ pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: is_partitioned}}
+ }
+
+ {
+ (void)std::merge(pol, non_fwd, non_fwd, it, it, out); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, non_fwd, non_fwd, out); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, it, it, non_output); // expected-error@*:* {{static assertion failed: merge}}
+
+ (void)std::merge(pol, non_fwd, non_fwd, it, it, out, pred); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, non_fwd, non_fwd, out, pred); // expected-error@*:* {{static assertion failed: merge}}
+ (void)std::merge(pol, it, it, it, it, non_output, pred); // expected-error@*:* {{static assertion failed: merge}}
+ }
+
+ {
+ (void)std::move(pol, non_fwd, non_fwd, out); // expected-error@*:* {{static assertion failed: move}}
+ (void)std::move(pol, it, it, non_fwd); // expected-error@*:* {{static assertion failed: move}}
+ (void)std::move(pol, it, it, non_output); // expected-error@*:* {{static assertion failed: move}}
+ }
+
+ {
+ (void)std::replace_if(
+ pol, non_fwd, non_fwd, pred, val); // expected-error@*:* {{static assertion failed: replace_if}}
+ (void)std::replace(pol, non_fwd, non_fwd, val, val); // expected-error@*:* {{static assertion failed: replace}}
+
+ (void)std::replace_copy_if(
+ pol, non_fwd, non_fwd, out, pred, val); // expected-error@*:* {{static assertion failed: replace_copy_if}}
+ (void)std::replace_copy_if(
+ pol, it, it, non_fwd, pred, val); // expected-error@*:* {{static assertion failed: replace_copy_if}}
+ (void)std::replace_copy_if(
+ pol, it, it, non_output, pred, val); // expected-error@*:* {{static assertion failed: replace_copy_if}}
+
+ (void)std::replace_copy(
+ pol, non_fwd, non_fwd, out, val, val); // expected-error@*:* {{static assertion failed: replace_copy}}
+ (void)std::replace_copy(
+ pol, it, it, non_fwd, val, val); // expected-error@*:* {{static assertion failed: replace_copy}}
+ (void)std::replace_copy(
+ pol, it, it, non_output, val, val); // expected-error@*:* {{static assertion failed: replace_copy}}
+ }
+
+ {
+ (void)std::rotate_copy(
+ pol, non_fwd, non_fwd, non_fwd, out); // expected-error@*:* {{static assertion failed: rotate_copy}}
+ (void)std::rotate_copy(pol, it, it, it, non_fwd); // expected-error@*:* {{static assertion failed: rotate_copy}}
+ (void)std::rotate_copy(pol, it, it, it, non_output); // expected-error@*:* {{static assertion failed: rotate_copy}}
+ }
+
+ {
+ (void)std::sort(pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: sort}}
+ (void)std::sort(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: sort}}
+ }
+
+ {
+ (void)std::stable_sort(pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: stable_sort}}
+ (void)std::stable_sort(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: stable_sort}}
+ }
+
+ {
+ (void)std::transform(pol, non_fwd, non_fwd, out, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, non_fwd, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, non_output, func); // expected-error@*:* {{static assertion failed: transform}}
+
+ (void)std::transform(
+ pol, non_fwd, non_fwd, it, out, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, non_fwd, out, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(pol, it, it, it, non_fwd, func); // expected-error@*:* {{static assertion failed: transform}}
+ (void)std::transform(
+ pol, it, it, it, non_output, func); // expected-error@*:* {{static assertion failed: transform}}
+ }
+
+ {
+ (void)std::reduce(pol, non_fwd, non_fwd); // expected-error@*:* {{static assertion failed: reduce}}
+ (void)std::reduce(pol, non_fwd, non_fwd, val); // expected-error@*:* {{static assertion failed: reduce}}
+ (void)std::reduce(pol, non_fwd, non_fwd, val, func); // expected-error@*:* {{static assertion failed: reduce}}
+ }
+
+ {
+ (void)std::transform_reduce(
+ pol, non_fwd, non_fwd, it, val); // expected-error@*:* {{static assertion failed: transform_reduce}}
+ (void)std::transform_reduce(
+ pol, it, it, non_fwd, val); // expected-error@*:* {{static assertion failed: transform_reduce}}
+
+ (void)std::transform_reduce(
+ pol, non_fwd, non_fwd, it, val, func, func); // expected-error@*:* {{static assertion failed: transform_reduce}}
+ (void)std::transform_reduce(
+ pol, it, it, non_fwd, val, func, func); // expected-error@*:* {{static assertion failed: transform_reduce}}
+
+ (void)std::transform_reduce(
+ pol, non_fwd, non_fwd, val, func, func); // expected-error@*:* {{static assertion failed: transform_reduce}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp b/libcxx/test/libcxx-03/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp
new file mode 100644
index 0000000000000..b48ac02dd79c5
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/pstl.libdispatch.chunk_partitions.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// REQUIRES: libcpp-pstl-backend-libdispatch
+
+// __chunk_partitions __partition_chunks(ptrdiff_t);
+
+#include <__pstl/backends/libdispatch.h>
+#include <cassert>
+#include <cstddef>
+
+int main(int, char**) {
+ {
+ auto chunks = std::__pstl::__libdispatch::__partition_chunks(0);
+ assert(chunks.__chunk_count_ == 1);
+ assert(chunks.__first_chunk_size_ == 0);
+ assert(chunks.__chunk_size_ == 0);
+ }
+
+ {
+ auto chunks = std::__pstl::__libdispatch::__partition_chunks(1);
+ assert(chunks.__chunk_count_ == 1);
+ assert(chunks.__first_chunk_size_ == 1);
+ assert(chunks.__chunk_size_ == 1);
+ }
+
+ for (std::ptrdiff_t i = 2; i != 2ll << 20; ++i) {
+ auto chunks = std::__pstl::__libdispatch::__partition_chunks(i);
+ assert(chunks.__chunk_count_ >= 1);
+ assert(chunks.__chunk_count_ <= i);
+ assert((chunks.__chunk_count_ - 1) * chunks.__chunk_size_ + chunks.__first_chunk_size_ == i);
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_comparators.pass.cpp
new file mode 100644
index 0000000000000..dd026444330ea
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_comparators.pass.cpp
@@ -0,0 +1,264 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <algorithm>
+
+// this test checks that the comparators in the ranges algorithms aren't copied/moved
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <deque>
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct Less {
+ int *copies_;
+ constexpr explicit Less(int *copies) : copies_(copies) {}
+ constexpr Less(const Less& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr Less& operator=(const Less&) = default;
+ constexpr bool operator()(void*, void*) const { return false; }
+};
+
+struct Equal {
+ int *copies_;
+ constexpr explicit Equal(int *copies) : copies_(copies) {}
+ constexpr Equal(const Equal& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr Equal& operator=(const Equal&) = default;
+ constexpr bool operator()(void*, void*) const { return true; }
+};
+
+struct UnaryVoid {
+ int *copies_;
+ constexpr explicit UnaryVoid(int *copies) : copies_(copies) {}
+ constexpr UnaryVoid(const UnaryVoid& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr UnaryVoid& operator=(const UnaryVoid&) = default;
+ constexpr void operator()(void*) const {}
+};
+
+struct UnaryTrue {
+ int *copies_;
+ constexpr explicit UnaryTrue(int *copies) : copies_(copies) {}
+ constexpr UnaryTrue(const UnaryTrue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr UnaryTrue& operator=(const UnaryTrue&) = default;
+ constexpr bool operator()(void*) const { return true; }
+};
+
+struct NullaryValue {
+ int *copies_;
+ constexpr explicit NullaryValue(int *copies) : copies_(copies) {}
+ constexpr NullaryValue(const NullaryValue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr NullaryValue& operator=(const NullaryValue&) = default;
+ constexpr std::nullptr_t operator()() const { return nullptr; }
+};
+
+struct UnaryTransform {
+ int *copies_;
+ constexpr explicit UnaryTransform(int *copies) : copies_(copies) {}
+ constexpr UnaryTransform(const UnaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr UnaryTransform& operator=(const UnaryTransform&) = default;
+ constexpr std::nullptr_t operator()(void*) const { return nullptr; }
+};
+
+struct BinaryTransform {
+ int *copies_;
+ constexpr explicit BinaryTransform(int *copies) : copies_(copies) {}
+ constexpr BinaryTransform(const BinaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr BinaryTransform& operator=(const BinaryTransform&) = default;
+ constexpr std::nullptr_t operator()(void*, void*) const { return nullptr; }
+};
+
+constexpr bool all_the_algorithms()
+{
+ void *a[10] = {};
+ void *b[10] = {};
+ void *half[5] = {};
+ void **first = a;
+ void **mid = a+5;
+ void **last = a+10;
+ void **first2 = b;
+ void **mid2 = b+5;
+ void **last2 = b+10;
+ void *value = nullptr;
+ int count = 1;
+
+ int copies = 0;
+ (void)std::ranges::adjacent_find(first, last, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::adjacent_find(a, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::all_of(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::all_of(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::any_of(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::any_of(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::binary_search(first, last, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::binary_search(a, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::clamp(value, value, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::count_if(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::count_if(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::copy_if(first, last, first2, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::copy_if(a, first2, UnaryTrue(&copies)); assert(copies == 0);
+#if TEST_STD_VER >= 23
+ (void)std::ranges::ends_with(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::ends_with(a, b, Equal(&copies)); assert(copies == 0);
+#endif
+ (void)std::ranges::equal(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::equal(a, b, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::equal_range(first, last, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::equal_range(a, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::find_end(first, last, first2, mid2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::find_end(a, b, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::find_first_of(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::find_first_of(a, b, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if_not(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if_not(a, UnaryTrue(&copies)); assert(copies == 0);
+#if TEST_STD_VER >= 23
+ (void)std::ranges::find_last_if(first, last, UnaryTrue(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last_if(a, UnaryTrue(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last_if_not(first, last, UnaryTrue(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last_if_not(a, UnaryTrue(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::ranges::for_each(first, last, UnaryVoid(&copies)); assert(copies == 1); copies = 0;
+ (void)std::ranges::for_each(a, UnaryVoid(&copies)); assert(copies == 1); copies = 0;
+ (void)std::ranges::for_each_n(first, count, UnaryVoid(&copies)); assert(copies == 1); copies = 0;
+ (void)std::ranges::generate(first, last, NullaryValue(&copies)); assert(copies == 0);
+ (void)std::ranges::generate(a, NullaryValue(&copies)); assert(copies == 0);
+ (void)std::ranges::generate_n(first, count, NullaryValue(&copies)); assert(copies == 0);
+ (void)std::ranges::includes(first, last, first2, last2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::includes(a, b, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap_until(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap_until(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_partitioned(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::is_partitioned(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::is_permutation(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::is_permutation(a, b, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted_until(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted_until(a, Less(&copies)); assert(copies == 0);
+ if (TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED) {
+ (void)std::ranges::inplace_merge(first, mid, last, Less(&copies));
+ assert(copies == 0);
+ (void)std::ranges::inplace_merge(a, mid, Less(&copies));
+ assert(copies == 0);
+ }
+ (void)std::ranges::lexicographical_compare(first, last, first2, last2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::lexicographical_compare(a, b, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::lower_bound(first, last, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::lower_bound(a, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::make_heap(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::make_heap(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::max(value, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::max({ value, value }, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::max(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::max_element(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::max_element(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::merge(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::merge(half, half, b, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::min(value, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::min({ value, value }, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::min(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::min_element(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::min_element(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax(value, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax({ value, value }, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax_element(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax_element(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::mismatch(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::mismatch(a, b, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::next_permutation(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::next_permutation(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::none_of(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::none_of(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::nth_element(first, mid, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::nth_element(a, mid, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort(first, mid, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort(a, mid, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort_copy(first, last, first2, mid2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort_copy(a, b, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::partition(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::partition(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_copy(first, last, first2, last2, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_copy(a, first2, last2, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_point(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_point(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::pop_heap(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::pop_heap(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::prev_permutation(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::prev_permutation(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::push_heap(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::push_heap(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_copy_if(first, last, first2, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_copy_if(a, first2, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_if(first, last, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_if(a, UnaryTrue(&copies)); assert(copies == 0);
+ (void)std::ranges::replace_copy_if(first, last, first2, UnaryTrue(&copies), value); assert(copies == 0);
+ (void)std::ranges::replace_copy_if(a, first2, UnaryTrue(&copies), value); assert(copies == 0);
+ (void)std::ranges::replace_if(first, last, UnaryTrue(&copies), value); assert(copies == 0);
+ (void)std::ranges::replace_if(a, UnaryTrue(&copies), value); assert(copies == 0);
+ (void)std::ranges::search(first, last, first2, mid2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::search(a, b, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::search_n(first, last, count, value, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::search_n(a, count, value, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::set_difference(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::set_difference(a, b, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::set_intersection(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::set_intersection(a, b, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::set_symmetric_difference(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::set_symmetric_difference(a, b, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::set_union(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::set_union(a, b, first2, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::sort(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::sort(a, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::sort_heap(first, last, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::sort_heap(a, Less(&copies)); assert(copies == 0);
+ if (TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED) {
+ (void)std::ranges::stable_partition(first, last, UnaryTrue(&copies));
+ assert(copies == 0);
+ (void)std::ranges::stable_partition(a, UnaryTrue(&copies));
+ assert(copies == 0);
+ (void)std::ranges::stable_sort(first, last, Less(&copies));
+ assert(copies == 0);
+ (void)std::ranges::stable_sort(a, Less(&copies));
+ assert(copies == 0);
+ }
+#if TEST_STD_VER > 20
+ (void)std::ranges::starts_with(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::starts_with(a, b, Equal(&copies)); assert(copies == 0);
+#endif
+ (void)std::ranges::transform(first, last, first2, UnaryTransform(&copies)); assert(copies == 0);
+ (void)std::ranges::transform(a, first2, UnaryTransform(&copies)); assert(copies == 0);
+ (void)std::ranges::transform(first, mid, mid, last, first2, BinaryTransform(&copies)); assert(copies == 0);
+ (void)std::ranges::transform(a, b, first2, BinaryTransform(&copies)); assert(copies == 0);
+ (void)std::ranges::unique(first, last, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::unique(a, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::unique_copy(first, last, first2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::unique_copy(a, first2, Equal(&copies)); assert(copies == 0);
+ (void)std::ranges::upper_bound(first, last, value, Less(&copies)); assert(copies == 0);
+ (void)std::ranges::upper_bound(a, value, Less(&copies)); assert(copies == 0);
+
+ return true;
+}
+
+int main(int, char**)
+{
+ all_the_algorithms();
+ static_assert(all_the_algorithms());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_projections.pass.cpp b/libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_projections.pass.cpp
new file mode 100644
index 0000000000000..4919590ddffdc
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/ranges_robust_against_copying_projections.pass.cpp
@@ -0,0 +1,278 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <algorithm>
+
+// this test checks that the projections in the ranges algorithms aren't copied/moved
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <deque>
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct T {};
+
+struct Proj {
+ int *copies_;
+ constexpr explicit Proj(int *copies) : copies_(copies) {}
+ constexpr Proj(const Proj& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr Proj& operator=(const Proj&) = default;
+ constexpr void* operator()(T) const { return nullptr; }
+};
+
+struct Less {
+ constexpr bool operator()(void*, void*) const { return false; }
+};
+
+struct Equal {
+ constexpr bool operator()(void*, void*) const { return true; }
+};
+
+struct UnaryVoid {
+ constexpr void operator()(void*) const {}
+};
+
+struct UnaryTrue {
+ constexpr bool operator()(void*) const { return true; }
+};
+
+struct NullaryValue {
+ constexpr std::nullptr_t operator()() const { return nullptr; }
+};
+
+struct UnaryTransform {
+ constexpr T operator()(void*) const { return T(); }
+};
+
+struct BinaryTransform {
+ constexpr T operator()(void*, void*) const { return T(); }
+};
+
+constexpr bool all_the_algorithms()
+{
+ T a[10] = {};
+ T b[10] = {};
+ T half[5] = {};
+ T *first = a;
+ T *mid = a+5;
+ T *last = a+10;
+ T *first2 = b;
+ T *mid2 = b+5;
+ T *last2 = b+10;
+ void *value = nullptr;
+ int count = 1;
+
+ int copies = 0;
+ (void)std::ranges::adjacent_find(first, last, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::adjacent_find(a, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::all_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::all_of(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::any_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::any_of(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::binary_search(first, last, value, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::binary_search(a, value, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::clamp(T(), T(), T(), Less(), Proj(&copies)); assert(copies == 0);
+#if TEST_STD_VER >= 23
+ (void)std::ranges::contains(first, last, value, Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::contains(a, value, Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::contains_subrange(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::contains_subrange(a, b, Equal(), Proj(&copies), Proj(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::ranges::count(first, last, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::count(a, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::count_if(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::count_if(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::copy_if(first, last, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::copy_if(a, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+#if TEST_STD_VER >= 23
+ (void)std::ranges::ends_with(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::ends_with(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+#endif
+ (void)std::ranges::equal(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::equal(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::equal_range(first, last, value, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::equal_range(a, value, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find(first, last, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find(a, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_end(first, last, first2, mid2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_end(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_first_of(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_first_of(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if_not(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::find_if_not(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+#if TEST_STD_VER >= 23
+ (void)std::ranges::find_last(first, last, value, Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last(a, value, Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last_if(first, last, UnaryTrue(), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last_if(a, UnaryTrue(), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last_if_not(first, last, UnaryTrue(), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::find_last_if_not(a, UnaryTrue(), Proj(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::ranges::for_each(first, last, UnaryVoid(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::for_each(a, UnaryVoid(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::for_each_n(first, count, UnaryVoid(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::includes(first, last, first2, last2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::includes(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap_until(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_heap_until(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_partitioned(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_partitioned(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_permutation(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_permutation(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted_until(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::is_sorted_until(a, Less(), Proj(&copies)); assert(copies == 0);
+ if (TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED) {
+ (void)std::ranges::inplace_merge(first, mid, last, Less(), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::inplace_merge(a, mid, Less(), Proj(&copies));
+ assert(copies == 0);
+ }
+ (void)std::ranges::lexicographical_compare(first, last, first2, last2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::lexicographical_compare(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::lower_bound(first, last, value, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::lower_bound(a, value, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::make_heap(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::make_heap(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::max(T(), T(), Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::max({ T(), T() }, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::max(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::max_element(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::max_element(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::merge(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::merge(half, half, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::min(T(), T(), Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::min({ T(), T() }, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::min(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::min_element(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::min_element(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax(T(), T(), Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax({ T(), T() }, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax_element(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::minmax_element(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::mismatch(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::mismatch(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::next_permutation(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::next_permutation(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::none_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::none_of(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::nth_element(first, mid, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::nth_element(a, mid, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort(first, mid, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort(a, mid, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort_copy(first, last, first2, mid2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partial_sort_copy(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partition(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partition(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_copy(first, last, first2, last2, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_copy(a, first2, last2, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_point(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::partition_point(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::pop_heap(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::pop_heap(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::prev_permutation(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::prev_permutation(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::push_heap(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::push_heap(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_copy(first, last, first2, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_copy(a, first2, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_copy_if(first, last, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_copy_if(a, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove(first, last, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove(a, value, Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_if(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::remove_if(a, UnaryTrue(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace_copy(first, last, first2, value, T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace_copy(a, first2, value, T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace_copy_if(first, last, first2, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace_copy_if(a, first2, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace(first, last, value, T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace(a, value, T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace_if(first, last, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::replace_if(a, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::search(first, last, first2, mid2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::search(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::search_n(first, last, count, value, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::search_n(a, count, value, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_difference(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_difference(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_intersection(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_intersection(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_symmetric_difference(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_symmetric_difference(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_union(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::set_union(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::sort(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::sort(a, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::sort_heap(first, last, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::sort_heap(a, Less(), Proj(&copies)); assert(copies == 0);
+ if (TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED) {
+ (void)std::ranges::stable_partition(first, last, UnaryTrue(), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::stable_partition(a, UnaryTrue(), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::stable_sort(first, last, Less(), Proj(&copies));
+ assert(copies == 0);
+ (void)std::ranges::stable_sort(a, Less(), Proj(&copies));
+ assert(copies == 0);
+ }
+#if TEST_STD_VER > 20
+ (void)std::ranges::starts_with(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::starts_with(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+#endif
+ (void)std::ranges::transform(first, last, first2, UnaryTransform(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::transform(a, first2, UnaryTransform(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::transform(first, mid, mid, last, first2, BinaryTransform(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::transform(a, b, first2, BinaryTransform(), Proj(&copies), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::unique(first, last, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::unique(a, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::unique_copy(first, last, first2, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::unique_copy(a, first2, Equal(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::upper_bound(first, last, value, Less(), Proj(&copies)); assert(copies == 0);
+ (void)std::ranges::upper_bound(a, value, Less(), Proj(&copies)); assert(copies == 0);
+
+ return true;
+}
+
+void test_deque() {
+ std::deque<T> d;
+ int copies = 0;
+ void* value = nullptr;
+
+ (void)std::ranges::find(d, value, Proj(&copies));
+ assert(copies == 0);
+}
+
+int main(int, char**) {
+ test_deque();
+ all_the_algorithms();
+ static_assert(all_the_algorithms());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp
new file mode 100644
index 0000000000000..256251686bb3e
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/robust_against_copying_comparators.pass.cpp
@@ -0,0 +1,323 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+#include <algorithm>
+#include <cassert>
+#include <compare>
+#include <cstddef>
+#include <deque>
+#include <ranges>
+#include <type_traits>
+#include <vector>
+
+#include "test_macros.h"
+
+template <class T>
+struct Less {
+ int* copies_;
+ TEST_CONSTEXPR explicit Less(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 Less(const Less& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 Less& operator=(const Less&) = default;
+ TEST_CONSTEXPR bool operator()(T, T) const { return false; }
+};
+
+template <class T>
+struct Equal {
+ int* copies_;
+ TEST_CONSTEXPR explicit Equal(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 Equal(const Equal& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 Equal& operator=(const Equal&) = default;
+ TEST_CONSTEXPR bool operator()(T, T) const { return true; }
+};
+
+template <class T>
+struct UnaryVoid {
+ int* copies_;
+ TEST_CONSTEXPR explicit UnaryVoid(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 UnaryVoid(const UnaryVoid& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 UnaryVoid& operator=(const UnaryVoid&) = default;
+ TEST_CONSTEXPR_CXX14 void operator()(T) const {}
+};
+
+template <class T>
+struct UnaryTrue {
+ int* copies_;
+ TEST_CONSTEXPR explicit UnaryTrue(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 UnaryTrue(const UnaryTrue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 UnaryTrue& operator=(const UnaryTrue&) = default;
+ TEST_CONSTEXPR bool operator()(T) const { return true; }
+};
+
+template <class T>
+struct NullaryValue {
+ int* copies_;
+ TEST_CONSTEXPR explicit NullaryValue(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 NullaryValue(const NullaryValue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 NullaryValue& operator=(const NullaryValue&) = default;
+ TEST_CONSTEXPR T operator()() const { return 0; }
+};
+
+template <class T>
+struct UnaryTransform {
+ int* copies_;
+ TEST_CONSTEXPR explicit UnaryTransform(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 UnaryTransform(const UnaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 UnaryTransform& operator=(const UnaryTransform&) = default;
+ TEST_CONSTEXPR T operator()(T) const { return 0; }
+};
+
+template <class T>
+struct BinaryTransform {
+ int* copies_;
+ TEST_CONSTEXPR explicit BinaryTransform(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 BinaryTransform(const BinaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 BinaryTransform& operator=(const BinaryTransform&) = default;
+ TEST_CONSTEXPR T operator()(T, T) const { return 0; }
+};
+
+#if TEST_STD_VER > 17
+template <class T>
+struct ThreeWay {
+ int* copies_;
+ constexpr explicit ThreeWay(int* copies) : copies_(copies) {}
+ constexpr ThreeWay(const ThreeWay& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr ThreeWay& operator=(const ThreeWay&) = default;
+ constexpr std::strong_ordering operator()(T, T) const { return std::strong_ordering::equal; }
+};
+#endif
+
+template <class T>
+TEST_CONSTEXPR_CXX20 bool all_the_algorithms() {
+ T a[10] = {};
+ T b[10] = {};
+ T* first = a;
+ T* mid = a + 5;
+ T* last = a + 10;
+ T* first2 = b;
+ T* mid2 = b + 5;
+ T* last2 = b + 10;
+ T value = 0;
+ int count = 1;
+
+ int copies = 0;
+ (void)std::adjacent_find(first, last, Equal<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER >= 11
+ (void)std::all_of(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::any_of(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::binary_search(first, last, value, Less<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER > 17
+ (void)std::clamp(value, value, value, Less<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::count_if(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::copy_if(first, last, first2, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::equal(first, last, first2, Equal<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER > 11
+ (void)std::equal(first, last, first2, last2, Equal<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::equal_range(first, last, value, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_end(first, last, first2, mid2, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_first_of(first, last, first2, last2, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_if(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_if_not(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::for_each(first, last, UnaryVoid<T>(&copies));
+ assert(copies == 1);
+ copies = 0;
+#if TEST_STD_VER > 14
+ (void)std::for_each_n(first, count, UnaryVoid<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::generate(first, last, NullaryValue<T>(&copies));
+ assert(copies == 0);
+ (void)std::generate_n(first, count, NullaryValue<T>(&copies));
+ assert(copies == 0);
+ (void)std::includes(first, last, first2, last2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_heap(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_heap_until(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_partitioned(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_permutation(first, last, first2, Equal<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER > 11
+ (void)std::is_permutation(first, last, first2, last2, Equal<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::is_sorted(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_sorted_until(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ (void)std::inplace_merge(first, mid, last, Less<T>(&copies));
+ assert(copies == 0);
+ }
+ (void)std::lexicographical_compare(first, last, first2, last2, Less<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER > 17
+ (void)std::lexicographical_compare_three_way(first, last, first2, last2, ThreeWay<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::lower_bound(first, last, value, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::make_heap(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::max(value, value, Less<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER >= 11
+ (void)std::max({value, value}, Less<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::max_element(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::merge(first, mid, mid, last, first2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::min(value, value, Less<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER >= 11
+ (void)std::min({value, value}, Less<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::min_element(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::minmax(value, value, Less<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER >= 11
+ (void)std::minmax({value, value}, Less<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::minmax_element(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::mismatch(first, last, first2, Equal<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER > 11
+ (void)std::mismatch(first, last, first2, last2, Equal<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::next_permutation(first, last, Less<T>(&copies));
+ assert(copies == 0);
+#if TEST_STD_VER >= 11
+ (void)std::none_of(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+#endif
+ (void)std::nth_element(first, mid, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::partial_sort(first, mid, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::partial_sort_copy(first, last, first2, mid2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::partition(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::partition_copy(first, last, first2, last2, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::partition_point(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::pop_heap(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::prev_permutation(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::push_heap(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::remove_copy_if(first, last, first2, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::remove_if(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::replace_copy_if(first, last, first2, UnaryTrue<T>(&copies), value);
+ assert(copies == 0);
+ (void)std::replace_if(first, last, UnaryTrue<T>(&copies), value);
+ assert(copies == 0);
+ (void)std::search(first, last, first2, mid2, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::search_n(first, last, count, value, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::set_difference(first, mid, mid, last, first2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::set_intersection(first, mid, mid, last, first2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::set_symmetric_difference(first, mid, mid, last, first2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::set_union(first, mid, mid, last, first2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::sort(first, first + 3, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::sort(first, first + 4, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::sort(first, first + 5, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::sort(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::sort_heap(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ (void)std::stable_partition(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ }
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ (void)std::stable_sort(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ }
+ (void)std::transform(first, last, first2, UnaryTransform<T>(&copies));
+ assert(copies == 0);
+ (void)std::transform(first, mid, mid, first2, BinaryTransform<T>(&copies));
+ assert(copies == 0);
+ (void)std::unique(first, last, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::unique_copy(first, last, first2, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::upper_bound(first, last, value, Less<T>(&copies));
+ assert(copies == 0);
+
+ return true;
+}
+
+bool test_segmented_iterator() {
+ int copies = 0;
+ std::deque<int> dq(10);
+ (void)std::for_each(dq.begin(), dq.end(), UnaryVoid<int>(&copies));
+ assert(copies == 1);
+ copies = 0;
+
+#if TEST_STD_VER >= 20
+ std::vector<std::vector<int>> vecs(3, std::vector<int>(10));
+ auto v = std::views::join(vecs);
+ (void)std::for_each(v.begin(), v.end(), UnaryVoid<int>(&copies));
+ assert(copies == 1);
+ copies = 0;
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ all_the_algorithms<void*>();
+ all_the_algorithms<int>();
+ assert(test_segmented_iterator());
+#if TEST_STD_VER > 17
+ static_assert(all_the_algorithms<void*>());
+ static_assert(all_the_algorithms<int>());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp
new file mode 100644
index 0000000000000..03fef57ee259a
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp
@@ -0,0 +1,225 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 STL classic algorithms can be instantiated with a C++20-hostile iterator
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-ambiguous-reversed-operator
+
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <random>
+
+#include "test_macros.h"
+
+template <class Sub, class Iterator>
+struct IteratorAdaptorBase {
+ using OutTraits = std::iterator_traits<Iterator>;
+ using iterator_category = typename OutTraits::iterator_category;
+ using value_type = typename OutTraits::value_type;
+ using pointer = typename OutTraits::pointer;
+ using reference = typename OutTraits::reference;
+ using difference_type = typename OutTraits::difference_type;
+
+ IteratorAdaptorBase() {}
+ IteratorAdaptorBase(Iterator) {}
+
+ Sub& sub() { return static_cast<Sub&>(*this); }
+ const Sub& sub() const { return static_cast<Sub&>(*this); }
+
+ const Iterator& base() const { return it_; }
+
+ reference get() const { return *it_; }
+ reference operator*() const { return *it_; }
+ pointer operator->() const { return it_; }
+ reference operator[](difference_type) const { return *it_; }
+
+ Sub& operator++() { return static_cast<Sub&>(*this); }
+ Sub& operator--() { return static_cast<Sub&>(*this); }
+ Sub operator++(int) { return static_cast<Sub&>(*this); }
+ Sub operator--(int) { return static_cast<Sub&>(*this); }
+
+ Sub& operator+=(difference_type) { return static_cast<Sub&>(*this); }
+ Sub& operator-=(difference_type) { return static_cast<Sub&>(*this); }
+ bool operator==(Sub) const { return false; }
+ bool operator!=(Sub) const { return false; }
+ bool operator==(Iterator b) const { return *this == Sub(b); }
+ bool operator!=(Iterator b) const { return *this != Sub(b); }
+
+ friend Sub operator+(Sub, difference_type) { return Sub(); }
+ friend Sub operator+(difference_type, Sub) { return Sub(); }
+ friend Sub operator-(Sub, difference_type) { return Sub(); }
+ friend difference_type operator-(Sub, Sub) { return 0; }
+
+ friend bool operator<(Sub, Sub) { return false; }
+ friend bool operator>(Sub, Sub) { return false; }
+ friend bool operator<=(Sub, Sub) { return false; }
+ friend bool operator>=(Sub, Sub) { return false; }
+
+ private:
+ Iterator it_;
+};
+
+template <typename It>
+struct Cpp20HostileIterator
+ : IteratorAdaptorBase<Cpp20HostileIterator<It>, It> {
+ Cpp20HostileIterator() {}
+ Cpp20HostileIterator(It) {}
+};
+
+struct Pred {
+ bool operator()(int, int) const { return false; }
+ bool operator()(int) const { return false; }
+ int operator()() const { return 0; }
+};
+
+void test() {
+ Cpp20HostileIterator<int*> it;
+ Pred pred;
+ std::mt19937_64 rng;
+
+ (void) std::adjacent_find(it, it);
+ (void) std::adjacent_find(it, it, pred);
+ (void) std::all_of(it, it, pred);
+ (void) std::any_of(it, it, pred);
+ (void) std::binary_search(it, it, 0);
+ (void) std::binary_search(it, it, 0, pred);
+ (void) std::copy_backward(it, it, it);
+ (void) std::copy_if(it, it, it, pred);
+ (void) std::copy_n(it, 0, it);
+ (void) std::copy(it, it, it);
+ (void) std::count_if(it, it, pred);
+ (void) std::count(it, it, 0);
+ (void) std::equal_range(it, it, 0);
+ (void) std::equal_range(it, it, 0, pred);
+ (void) std::equal(it, it, it);
+ (void) std::equal(it, it, it, pred);
+#if TEST_STD_VER > 11
+ (void) std::equal(it, it, it, it);
+ (void) std::equal(it, it, it, it, pred);
+#endif
+ (void) std::fill_n(it, 0, 0);
+ (void) std::fill(it, it, 0);
+ (void) std::find_end(it, it, it, it);
+ (void) std::find_end(it, it, it, it, pred);
+ (void) std::find_first_of(it, it, it, it);
+ (void) std::find_first_of(it, it, it, it, pred);
+ (void) std::find_if_not(it, it, pred);
+ (void) std::find_if(it, it, pred);
+ (void) std::find(it, it, 0);
+#if TEST_STD_VER > 14
+ (void) std::for_each_n(it, 0, pred);
+#endif
+ (void) std::for_each(it, it, pred);
+ (void) std::generate_n(it, 0, pred);
+ (void) std::generate(it, it, pred);
+ (void) std::includes(it, it, it, it);
+ (void) std::includes(it, it, it, it, pred);
+ (void) std::inplace_merge(it, it, it);
+ (void) std::inplace_merge(it, it, it, pred);
+ (void) std::is_heap_until(it, it);
+ (void) std::is_heap_until(it, it, pred);
+ (void) std::is_heap(it, it);
+ (void) std::is_heap(it, it, pred);
+ (void) std::is_partitioned(it, it, pred);
+ (void) std::is_permutation(it, it, it);
+ (void) std::is_permutation(it, it, it, pred);
+#if TEST_STD_VER > 11
+ (void) std::is_permutation(it, it, it, it);
+ (void) std::is_permutation(it, it, it, it, pred);
+#endif
+ (void) std::is_sorted_until(it, it);
+ (void) std::is_sorted_until(it, it, pred);
+ (void) std::is_sorted(it, it);
+ (void) std::is_sorted(it, it, pred);
+ (void) std::lexicographical_compare(it, it, it, it);
+ (void) std::lexicographical_compare(it, it, it, it, pred);
+#if TEST_STD_VER > 17
+ (void)std::lexicographical_compare_three_way(it, it, it, it);
+ (void)std::lexicographical_compare_three_way(it, it, it, it, std::compare_three_way());
+#endif
+ (void) std::lower_bound(it, it, 0);
+ (void) std::lower_bound(it, it, 0, pred);
+ (void) std::make_heap(it, it);
+ (void) std::make_heap(it, it, pred);
+ (void) std::max_element(it, it);
+ (void) std::max_element(it, it, pred);
+ (void) std::merge(it, it, it, it, it);
+ (void) std::merge(it, it, it, it, it, pred);
+ (void) std::min_element(it, it);
+ (void) std::min_element(it, it, pred);
+ (void) std::minmax_element(it, it);
+ (void) std::minmax_element(it, it, pred);
+ (void) std::mismatch(it, it, it);
+ (void) std::mismatch(it, it, it, pred);
+ (void) std::move_backward(it, it, it);
+ (void) std::move(it, it, it);
+ (void) std::next_permutation(it, it);
+ (void) std::next_permutation(it, it, pred);
+ (void) std::none_of(it, it, pred);
+ (void) std::nth_element(it, it, it);
+ (void) std::nth_element(it, it, it, pred);
+ (void) std::partial_sort_copy(it, it, it, it);
+ (void) std::partial_sort_copy(it, it, it, it, pred);
+ (void) std::partial_sort(it, it, it);
+ (void) std::partial_sort(it, it, it, pred);
+ (void) std::partition_copy(it, it, it, it, pred);
+ (void) std::partition_point(it, it, pred);
+ (void) std::partition(it, it, pred);
+ (void) std::pop_heap(it, it);
+ (void) std::pop_heap(it, it, pred);
+ (void) std::prev_permutation(it, it);
+ (void) std::prev_permutation(it, it, pred);
+ (void) std::push_heap(it, it);
+ (void) std::push_heap(it, it, pred);
+ (void) std::remove_copy_if(it, it, it, pred);
+ (void) std::remove_copy(it, it, it, 0);
+ (void) std::remove_if(it, it, pred);
+ (void) std::remove(it, it, 0);
+ (void) std::replace_copy_if(it, it, it, pred, 0);
+ (void) std::replace_copy(it, it, it, 0, 0);
+ (void) std::replace_if(it, it, pred, 0);
+ (void) std::replace(it, it, 0, 0);
+ (void) std::reverse_copy(it, it, it);
+ (void) std::reverse(it, it);
+ (void) std::rotate_copy(it, it, it, it);
+ (void) std::rotate(it, it, it);
+#if TEST_STD_VER > 14
+ (void) std::sample(it, it, it, 0, rng);
+#endif
+ (void) std::search(it, it, it, it);
+ (void) std::search(it, it, it, it, pred);
+#if TEST_STD_VER > 14
+ (void) std::search(it, it, std::default_searcher<Cpp20HostileIterator<int*>>(it, it));
+#endif
+ (void) std::set_difference(it, it, it, it, it);
+ (void) std::set_difference(it, it, it, it, it, pred);
+ (void) std::set_intersection(it, it, it, it, it);
+ (void) std::set_intersection(it, it, it, it, it, pred);
+ (void) std::set_symmetric_difference(it, it, it, it, it);
+ (void) std::set_symmetric_difference(it, it, it, it, it, pred);
+ (void) std::set_union(it, it, it, it, it);
+ (void) std::set_union(it, it, it, it, it, pred);
+#if TEST_STD_VER > 17
+ (void) std::shift_left(it, it, 0);
+ (void) std::shift_right(it, it, 0);
+#endif
+ (void) std::shuffle(it, it, rng);
+ (void) std::sort_heap(it, it);
+ (void) std::sort_heap(it, it, pred);
+ (void) std::sort(it, it);
+ (void) std::sort(it, it, pred);
+ (void) std::stable_partition(it, it, pred);
+ (void) std::stable_sort(it, it);
+ (void) std::swap_ranges(it, it, it);
+ (void) std::transform(it, it, it, pred);
+ (void) std::transform(it, it, it, it, pred);
+ (void) std::unique_copy(it, it, it);
+ (void) std::unique(it, it);
+ (void) std::upper_bound(it, it, 0);
+}
diff --git a/libcxx/test/libcxx-03/algorithms/robust_against_using_non_transparent_comparators.pass.cpp b/libcxx/test/libcxx-03/algorithms/robust_against_using_non_transparent_comparators.pass.cpp
new file mode 100644
index 0000000000000..39870ebe7ff02
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/robust_against_using_non_transparent_comparators.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
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+
+#include "test_macros.h"
+
+template <class T>
+struct Iterator {
+ using value_type = T;
+ using pointer = value_type*;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::forward_iterator_tag;
+ struct reference {
+ T* ptr_;
+
+ reference(T* ptr) : ptr_(ptr) {}
+
+ friend bool operator<(reference a, reference b) { return *a.ptr_ < *b.ptr_; }
+ friend bool operator<(reference a, value_type const& b) { return *a.ptr_ < b; }
+ friend bool operator<(value_type const& a, reference b) { return a < *b.ptr_; }
+
+ operator T&() const;
+ };
+
+ Iterator& operator++() {
+ ptr_++;
+ return *this;
+ }
+
+ Iterator operator++(int) {
+ Iterator tmp = *this;
+ ptr_++;
+ return tmp;
+ }
+
+ friend bool operator==(Iterator const& a, Iterator const& b) { return a.ptr_ == b.ptr_; }
+ friend bool operator!=(Iterator const& a, Iterator const& b) { return !(a == b); }
+
+ reference operator*() const { return reference(ptr_); }
+
+ explicit Iterator(T* ptr) : ptr_(ptr) {}
+ Iterator() = default;
+ Iterator(Iterator const&) = default;
+ Iterator(Iterator&&) = default;
+
+ Iterator& operator=(Iterator const&) = default;
+ Iterator& operator=(Iterator&&) = default;
+
+private:
+ T* ptr_;
+};
+
+int main(int, char**) {
+ int array[5] = {1, 2, 3, 4, 5};
+ Iterator<int> first(array);
+ Iterator<int> middle(array + 3);
+ Iterator<int> last(array + 5);
+ (void)std::binary_search(first, last, 3);
+ (void)std::equal_range(first, last, 3);
+ (void)std::includes(first, last, first, last);
+ (void)std::is_sorted_until(first, last);
+ (void)std::is_sorted(first, last);
+ (void)std::lexicographical_compare(first, last, first, last);
+ (void)std::lower_bound(first, last, 3);
+ (void)std::max_element(first, last);
+ (void)std::min_element(first, last);
+ (void)std::minmax_element(first, last);
+ (void)std::upper_bound(first, last, 3);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/sort_stability.pass.cpp b/libcxx/test/libcxx-03/algorithms/sort_stability.pass.cpp
new file mode 100644
index 0000000000000..712f12c255935
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/sort_stability.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// Test std::sort stability randomization
+
+// UNSUPPORTED: c++03
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <functional>
+#include <iterator>
+#include <vector>
+
+#include "test_macros.h"
+
+struct EqualType {
+ int value = 0;
+ constexpr bool operator<(const EqualType&) const { return false; }
+};
+
+std::vector<EqualType> deterministic() {
+ static constexpr int kSize = 100;
+ std::vector<EqualType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = kSize / 2 - i * (i % 2 ? -1 : 1);
+ }
+ std::less<EqualType> comp;
+ std::__sort_dispatch<std::_ClassicAlgPolicy>(v.begin(), v.end(), comp);
+ return v;
+}
+
+void test_randomization() {
+ static constexpr int kSize = 100;
+ std::vector<EqualType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = kSize / 2 - i * (i % 2 ? -1 : 1);
+ }
+ auto deterministic_v = deterministic();
+ std::sort(v.begin(), v.end());
+ bool all_equal = true;
+ for (int i = 0; i < kSize; ++i) {
+ if (v[i].value != deterministic_v[i].value) {
+ all_equal = false;
+ }
+ }
+ assert(!all_equal);
+}
+
+void test_same() {
+ static constexpr int kSize = 100;
+ std::vector<EqualType> v;
+ v.resize(kSize);
+ for (int i = 0; i < kSize; ++i) {
+ v[i].value = kSize / 2 - i * (i % 2 ? -1 : 1);
+ }
+ auto snapshot_v = v;
+ auto snapshot_custom_v = v;
+ std::sort(v.begin(), v.end());
+ std::sort(snapshot_v.begin(), snapshot_v.end());
+ std::sort(snapshot_custom_v.begin(), snapshot_custom_v.end(),
+ [](const EqualType&, const EqualType&) { return false; });
+ bool all_equal = true;
+ for (int i = 0; i < kSize; ++i) {
+ if (v[i].value != snapshot_v[i].value || v[i].value != snapshot_custom_v[i].value) {
+ all_equal = false;
+ }
+ }
+ assert(all_equal);
+}
+
+#if TEST_STD_VER > 17
+constexpr bool test_constexpr() {
+ std::array<EqualType, 10> v;
+ for (int i = 9; i >= 0; --i) {
+ v[9 - i].value = i;
+ }
+ std::sort(v.begin(), v.end());
+ return std::is_sorted(v.begin(), v.end());
+}
+#endif
+
+int main(int, char**) {
+ test_randomization();
+ test_same();
+#if TEST_STD_VER > 17
+ static_assert(test_constexpr(), "");
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..9c488c255465f
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// template<class I>
+// concept __nothrow_forward_iterator;
+
+#include <memory>
+
+#include "test_iterators.h"
+
+static_assert(std::ranges::__nothrow_forward_iterator<forward_iterator<int*>>);
+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;
+}
+constexpr bool forward_subsumes_input(std::ranges::__nothrow_input_iterator auto);
+
+static_assert(forward_subsumes_input("foo"));
diff --git a/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp
new file mode 100644
index 0000000000000..2ddfdf66362e1
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.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
+
+// template<class R>
+// concept __nothrow_forward_range;
+
+#include <memory>
+
+#include "test_iterators.h"
+#include "test_range.h"
+
+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>>);
+static_assert(!std::ranges::__nothrow_forward_range<test_range<ForwardProxyIterator>>);
+
+constexpr bool forward_subsumes_input(std::ranges::__nothrow_forward_range auto&&) {
+ return true;
+}
+constexpr bool forward_subsumes_input(std::ranges::__nothrow_input_range auto&&);
+
+static_assert(forward_subsumes_input("foo"));
diff --git a/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..2da3f4297af70
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 I>
+// concept __nothrow_input_iterator;
+
+#include <memory>
+
+#include "test_iterators.h"
+
+struct InputProxyIterator {
+ using value_type = int;
+ using difference_type = int;
+ InputProxyIterator& operator++();
+ InputProxyIterator operator++(int);
+
+ int operator*() const;
+};
+
+static_assert(std::ranges::__nothrow_input_iterator<cpp20_input_iterator<int*>>);
+static_assert(!std::ranges::__nothrow_input_iterator<cpp17_output_iterator<int*>>);
+static_assert(std::input_iterator<InputProxyIterator>);
+static_assert(!std::ranges::__nothrow_input_iterator<InputProxyIterator>);
diff --git a/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp
new file mode 100644
index 0000000000000..2f851c4b83754
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+// concept __nothrow_input_range;
+
+#include <memory>
+
+#include "test_iterators.h"
+#include "test_range.h"
+
+// Has to be a template to work with `test_range`.
+template <typename>
+struct InputProxyIterator {
+ using value_type = int;
+ using difference_type = int;
+ InputProxyIterator& operator++();
+ InputProxyIterator operator++(int);
+
+ int operator*() const;
+};
+
+static_assert(std::ranges::__nothrow_input_range<test_range<cpp20_input_iterator>>);
+static_assert(std::ranges::input_range<test_range<InputProxyIterator>>);
+static_assert(!std::ranges::__nothrow_input_range<test_range<InputProxyIterator>>);
diff --git a/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp
new file mode 100644
index 0000000000000..a605095c8becf
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 S, class I>
+// concept __nothrow_sentinel_for;
+
+#include <iterator>
+#include <memory>
+
+static_assert(std::ranges::__nothrow_sentinel_for<int*, int*>);
+static_assert(!std::ranges::__nothrow_sentinel_for<int*, long*>);
+
+// Because `__nothrow_sentinel_for` is essentially an alias for `sentinel_for`,
+// the two concepts should subsume each other.
+
+constexpr bool ntsf_subsumes_sf(std::ranges::__nothrow_sentinel_for<char*> auto) requires true {
+ return true;
+}
+constexpr bool ntsf_subsumes_sf(std::sentinel_for<char*> auto);
+
+static_assert(ntsf_subsumes_sf("foo"));
+
+constexpr bool sf_subsumes_ntsf(std::sentinel_for<char*> auto) requires true {
+ return true;
+}
+constexpr bool sf_subsumes_ntsf(std::ranges::__nothrow_sentinel_for<char*> auto);
+
+static_assert(sf_subsumes_ntsf("foo"));
diff --git a/libcxx/test/libcxx-03/algorithms/vectorization.compile.pass.cpp b/libcxx/test/libcxx-03/algorithms/vectorization.compile.pass.cpp
new file mode 100644
index 0000000000000..733a147b80cc3
--- /dev/null
+++ b/libcxx/test/libcxx-03/algorithms/vectorization.compile.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// We don't know how to vectorize algorithms on GCC
+// XFAIL: gcc
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// We don't vectorize algorithms before C++14
+// XFAIL: c++03, c++11
+
+// We don't vectorize algorithms on AIX right now.
+// XFAIL: target={{.+}}-aix{{.*}}
+
+// We don't vectorize on AppleClang 15 since that apparently breaks std::mismatch
+// XFAIL: apple-clang-15
+
+// This test ensures that we enable the vectorization of algorithms on the expected
+// platforms.
+
+#include <algorithm>
+
+#ifndef _LIBCPP_VECTORIZE_ALGORITHMS
+# error It looks like the test needs to be updated since _LIBCPP_VECTORIZE_ALGORITHMS isn't defined anymore
+#endif
+
+#if !_LIBCPP_VECTORIZE_ALGORITHMS
+# error Algorithms should be vectorized on this platform
+#endif
diff --git a/libcxx/test/libcxx-03/assertions/customize_verbose_abort.compile-time.pass.cpp b/libcxx/test/libcxx-03/assertions/customize_verbose_abort.compile-time.pass.cpp
new file mode 100644
index 0000000000000..69154c3f7eaff
--- /dev/null
+++ b/libcxx/test/libcxx-03/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: clang-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_VERBOSE_ABORT(...)=my_abort(__VA_ARGS__)
+
+#include <cstdlib>
+
+void my_abort(char const*, ...) {
+ std::exit(EXIT_SUCCESS);
+}
+
+int main(int, char**) {
+ _LIBCPP_VERBOSE_ABORT("%s", "message");
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp b/libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp
new file mode 100644
index 0000000000000..390c6b6db190d
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/customize_verbose_abort.link-time.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that we can set a custom verbose termination function at link-time.
+
+// We flag uses of the verbose termination function in older dylibs at compile-time to avoid runtime
+// failures when back-deploying.
+// XFAIL: availability-verbose_abort-missing
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__verbose_abort>
+#include <cstdlib>
+
+void std::__libcpp_verbose_abort(char const*, ...) _NOEXCEPT { std::exit(EXIT_SUCCESS); }
+
+int main(int, char**) {
+ std::__libcpp_verbose_abort("%s", "message");
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/assertions/default_verbose_abort.pass.cpp b/libcxx/test/libcxx-03/assertions/default_verbose_abort.pass.cpp
new file mode 100644
index 0000000000000..803868b757794
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/default_verbose_abort.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that the default verbose termination function aborts the program.
+// XFAIL: availability-verbose_abort-missing
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__verbose_abort>
+#include <csignal>
+#include <cstdlib>
+
+void signal_handler(int signal) {
+ if (signal == SIGABRT)
+ std::_Exit(EXIT_SUCCESS);
+ std::_Exit(EXIT_FAILURE);
+}
+
+int main(int, char**) {
+ if (std::signal(SIGABRT, signal_handler) != SIG_ERR)
+ std::__libcpp_verbose_abort("%s", "foo");
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/debug.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/debug.pass.cpp
new file mode 100644
index 0000000000000..ea9770b0b2fbc
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/debug.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that assertions trigger without the user having to do anything when the debug mode has been enabled
+// by default.
+
+// REQUIRES: libcpp-hardening-mode=debug
+// `check_assertion.h` is only available starting from C++11.
+// UNSUPPORTED: c++03
+// `check_assertion.h` requires Unix headers.
+// REQUIRES: has-unix-headers
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire"); }(), "Should fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/extensive.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/extensive.pass.cpp
new file mode 100644
index 0000000000000..5743f95e472d7
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/extensive.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that assertions trigger without the user having to do anything when the extensive hardening mode
+// has been enabled by default.
+
+// REQUIRES: libcpp-hardening-mode=extensive
+// `check_assertion.h` is only available starting from C++11.
+// UNSUPPORTED: c++03
+// `check_assertion.h` requires Unix headers.
+// REQUIRES: has-unix-headers
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire"); }(), "Should fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/fast.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/fast.pass.cpp
new file mode 100644
index 0000000000000..85181859fdad0
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/fast.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that assertions trigger without the user having to do anything when the fast hardening mode has
+// been enabled by default.
+
+// REQUIRES: libcpp-hardening-mode=fast
+// `check_assertion.h` is only available starting from C++11.
+// UNSUPPORTED: c++03
+// `check_assertion.h` requires Unix headers.
+// REQUIRES: has-unix-headers
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Should fire"); }(), "Should fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/hardening_mode_incorrect_value.sh.cpp b/libcxx/test/libcxx-03/assertions/modes/hardening_mode_incorrect_value.sh.cpp
new file mode 100644
index 0000000000000..751ff7247445f
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/hardening_mode_incorrect_value.sh.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test verifies that setting the hardening mode to a value that's not part of the predefined constants triggers
+// a compile-time error.
+
+// Modules build produces a different error ("Could not build module 'std'").
+// UNSUPPORTED: clang-modules-build
+// REQUIRES: verify-support
+
+// Note that GCC doesn't support `-Wno-macro-redefined`.
+// RUN: %{verify} -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=42
+// Make sure that common cases of misuse produce readable errors. We deliberately disallow setting the hardening mode as
+// if it were a boolean flag.
+// RUN: %{verify} -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=0
+// RUN: %{verify} -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=1
+// RUN: %{verify} -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE
+
+#include <cassert>
+
+// expected-error@*:* {{_LIBCPP_HARDENING_MODE must be set to one of the following values: _LIBCPP_HARDENING_MODE_NONE, _LIBCPP_HARDENING_MODE_FAST, _LIBCPP_HARDENING_MODE_EXTENSIVE, _LIBCPP_HARDENING_MODE_DEBUG}}
diff --git a/libcxx/test/libcxx-03/assertions/modes/none.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/none.pass.cpp
new file mode 100644
index 0000000000000..b64290a31a129
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/none.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test checks that if no hardening mode is defined (i.e., in the unchecked mode), by default assertions aren't
+// triggered.
+
+// REQUIRES: libcpp-hardening-mode=none
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__assert>
+#include <cassert>
+
+bool executed_condition = false;
+bool f() {
+ executed_condition = true;
+ return false;
+}
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(f(), "Should not execute anything");
+ assert(!executed_condition); // Really make sure we did not execute anything.
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/override_with_debug_mode.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/override_with_debug_mode.pass.cpp
new file mode 100644
index 0000000000000..02565d0b6a176
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/override_with_debug_mode.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 test ensures that we can override any hardening mode with the debug mode on a per-TU basis.
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// The ability to set a custom abort message is required to compare the assertion message.
+// XFAIL: availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_INTERNAL(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_INTERNAL(false, "Debug-mode assertions should fire"); }(),
+ "Debug-mode assertions should fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/override_with_extensive_mode.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/override_with_extensive_mode.pass.cpp
new file mode 100644
index 0000000000000..74fe70feb077c
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/override_with_extensive_mode.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override any hardening mode with the extensive hardening mode on a per-TU basis.
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// The ability to set a custom abort message is required to compare the assertion message (which only happens in the
+// debug mode).
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// HWASAN replaces TRAP with abort or error exit code.
+// XFAIL: hwasan
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ [] { _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(false, "Extensive-mode assertions should fire"); }(),
+ "Extensive-mode assertions should fire");
+ _LIBCPP_ASSERT_INTERNAL(false, "Debug-mode assertions should not fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/override_with_fast_mode.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/override_with_fast_mode.pass.cpp
new file mode 100644
index 0000000000000..f243897a986b0
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/override_with_fast_mode.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override any hardening mode with the fast mode on a per-TU basis.
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// The ability to set a custom abort message is required to compare the assertion message (which only happens in the
+// debug mode).
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// HWASAN replaces TRAP with abort or error exit code.
+// XFAIL: hwasan
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ TEST_LIBCPP_ASSERT_FAILURE([] { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Fast-mode assertions should fire"); }(),
+ "Fast-mode assertions should fire");
+ _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(false, "Extensive-mode assertions should not fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/modes/override_with_unchecked_mode.pass.cpp b/libcxx/test/libcxx-03/assertions/modes/override_with_unchecked_mode.pass.cpp
new file mode 100644
index 0000000000000..0922556c8dc01
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/modes/override_with_unchecked_mode.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
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can override any hardening mode with the unchecked mode on a per-TU basis.
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+// ADDITIONAL_COMPILE_FLAGS: -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE
+
+#include <cassert>
+#include "check_assertion.h"
+
+int main(int, char**) {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(true, "Should not fire");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "Also should not fire");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/assertions/single_expression.pass.cpp b/libcxx/test/libcxx-03/assertions/single_expression.pass.cpp
new file mode 100644
index 0000000000000..474edc9dc0833
--- /dev/null
+++ b/libcxx/test/libcxx-03/assertions/single_expression.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that `_LIBCPP_ASSERT` and `_LIBCPP_ASSUME` are each a single expression.
+// This is useful so we can use them in places that require an expression, such as
+// in a constructor initializer list.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__assert>
+#include <cassert>
+
+void f() {
+ int i = (_LIBCPP_ASSERT(true, "message"), 3);
+ assert(i == 3);
+ return _LIBCPP_ASSERT(true, "message");
+}
+
+void g() {
+ int i = (_LIBCPP_ASSUME(true), 3);
+ assert(i == 3);
+ return _LIBCPP_ASSUME(true);
+}
+
+int main(int, char**) {
+ f();
+ g();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.align/align.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.align/align.pass.cpp
new file mode 100644
index 0000000000000..5990fc411e504
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.align/align.pass.cpp
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-1024-bit-atomics
+// ADDITIONAL_COMPILE_FLAGS: -Wno-psabi
+// ... since C++20 std::__atomic_base initializes, so we get a warning about an
+// ABI change for vector variants since the constructor code for that is
+// different if one were to compile with architecture-specific vector
+// extensions enabled.
+// This however isn't ABI breaking as it was impossible for any code to trigger
+// this without using libc++ internals.
+
+// GCC currently fails because it needs -fabi-version=6 to fix mangling of
+// std::atomic when used with __attribute__((vector(X))).
+// XFAIL: gcc
+
+// This fails on PowerPC, as the LLIArr2 and Padding structs do not have
+// adequate alignment, despite these types returning true for the query of
+// being lock-free. This is an issue that occurs when linking in the
+// PowerPC GNU libatomic library into the test.
+// XFAIL: target=powerpc{{.*}}le-unknown-linux-gnu
+
+// <atomic>
+
+// Verify that the content of atomic<T> is properly aligned if the type is
+// lock-free. This can't be observed through the atomic<T> API. It is
+// nonetheless required for correctness of the implementation: lock-free implies
+// that ISA instructions are used, and these instructions assume "suitable
+// alignment". Supported architectures all require natural alignment for
+// lock-freedom (e.g. load-linked / store-conditional, or cmpxchg).
+
+#include <atomic>
+#include <cassert>
+#include <cstddef>
+
+template <typename T>
+struct atomic_test : public std::__atomic_base<T> {
+ atomic_test() {
+ if (this->is_lock_free()) {
+ using AtomicImpl = decltype(this->__a_);
+ assert(alignof(AtomicImpl) >= sizeof(AtomicImpl) &&
+ "expected natural alignment for lock-free type");
+ }
+ }
+};
+
+int main(int, char**) {
+
+// structs and unions can't be defined in the template invocation.
+// Work around this with a typedef.
+#define CHECK_ALIGNMENT(T) \
+ do { \
+ typedef T type; \
+ atomic_test<type> t; \
+ } while (0)
+
+ CHECK_ALIGNMENT(bool);
+ CHECK_ALIGNMENT(char);
+ CHECK_ALIGNMENT(signed char);
+ CHECK_ALIGNMENT(unsigned char);
+ CHECK_ALIGNMENT(char16_t);
+ CHECK_ALIGNMENT(char32_t);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ CHECK_ALIGNMENT(wchar_t);
+#endif
+ CHECK_ALIGNMENT(short);
+ CHECK_ALIGNMENT(unsigned short);
+ CHECK_ALIGNMENT(int);
+ CHECK_ALIGNMENT(unsigned int);
+ CHECK_ALIGNMENT(long);
+ CHECK_ALIGNMENT(unsigned long);
+ CHECK_ALIGNMENT(long long);
+ CHECK_ALIGNMENT(unsigned long long);
+ CHECK_ALIGNMENT(std::nullptr_t);
+ CHECK_ALIGNMENT(void *);
+ CHECK_ALIGNMENT(float);
+ CHECK_ALIGNMENT(double);
+ CHECK_ALIGNMENT(long double);
+ CHECK_ALIGNMENT(int __attribute__((vector_size(1 * sizeof(int)))));
+ CHECK_ALIGNMENT(int __attribute__((vector_size(2 * sizeof(int)))));
+ CHECK_ALIGNMENT(int __attribute__((vector_size(4 * sizeof(int)))));
+ CHECK_ALIGNMENT(int __attribute__((vector_size(16 * sizeof(int)))));
+ CHECK_ALIGNMENT(int __attribute__((vector_size(32 * sizeof(int)))));
+ CHECK_ALIGNMENT(float __attribute__((vector_size(1 * sizeof(float)))));
+ CHECK_ALIGNMENT(float __attribute__((vector_size(2 * sizeof(float)))));
+ CHECK_ALIGNMENT(float __attribute__((vector_size(4 * sizeof(float)))));
+ CHECK_ALIGNMENT(float __attribute__((vector_size(16 * sizeof(float)))));
+ CHECK_ALIGNMENT(float __attribute__((vector_size(32 * sizeof(float)))));
+ CHECK_ALIGNMENT(double __attribute__((vector_size(1 * sizeof(double)))));
+ CHECK_ALIGNMENT(double __attribute__((vector_size(2 * sizeof(double)))));
+ CHECK_ALIGNMENT(double __attribute__((vector_size(4 * sizeof(double)))));
+ CHECK_ALIGNMENT(double __attribute__((vector_size(16 * sizeof(double)))));
+ CHECK_ALIGNMENT(double __attribute__((vector_size(32 * sizeof(double)))));
+ CHECK_ALIGNMENT(struct Empty {});
+ CHECK_ALIGNMENT(struct OneInt { int i; });
+ CHECK_ALIGNMENT(struct IntArr2 { int i[2]; });
+ CHECK_ALIGNMENT(struct FloatArr3 { float i[3]; });
+ CHECK_ALIGNMENT(struct LLIArr2 { long long int i[2]; });
+ CHECK_ALIGNMENT(struct LLIArr4 { long long int i[4]; });
+ CHECK_ALIGNMENT(struct LLIArr8 { long long int i[8]; });
+ CHECK_ALIGNMENT(struct LLIArr16 { long long int i[16]; });
+ CHECK_ALIGNMENT(struct Padding { char c; /* padding */ long long int i; });
+ CHECK_ALIGNMENT(union IntFloat { int i; float f; });
+ CHECK_ALIGNMENT(enum class StrongEnum { foo });
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.flag/init_bool.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.flag/init_bool.pass.cpp
new file mode 100644
index 0000000000000..7678775527419
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.flag/init_bool.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
+//
+//===----------------------------------------------------------------------===//
+
+// <atomic>
+
+// struct atomic_flag
+
+// TESTING EXTENSION atomic_flag(bool)
+
+#include <atomic>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 11
+// Ensure that static initialization happens; this is PR#37226
+extern std::atomic_flag global;
+struct X { X() { global.test_and_set(); }};
+X x;
+std::atomic_flag global{false};
+#endif
+
+int main(int, char**)
+{
+#if TEST_STD_VER >= 11
+ assert(global.test_and_set() == 1);
+#endif
+ {
+ std::atomic_flag f(false);
+ assert(f.test_and_set() == 0);
+ }
+ {
+ std::atomic_flag f(true);
+ assert(f.test_and_set() == 1);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.order/memory_order.underlying_type.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.order/memory_order.underlying_type.pass.cpp
new file mode 100644
index 0000000000000..5379ef8787d56
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.order/memory_order.underlying_type.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that std::memory_order has the same size under all
+// standard versions to make sure we're not breaking the ABI. This is
+// relevant because std::memory_order is a scoped enumeration in C++20,
+// but an unscoped enumeration pre-C++20.
+//
+// See PR40977 for details.
+
+#include <atomic>
+#include <type_traits>
+
+#include "test_macros.h"
+
+
+enum cpp17_memory_order {
+ cpp17_memory_order_relaxed, cpp17_memory_order_consume, cpp17_memory_order_acquire,
+ cpp17_memory_order_release, cpp17_memory_order_acq_rel, cpp17_memory_order_seq_cst
+};
+
+static_assert((std::is_same<std::underlying_type<cpp17_memory_order>::type,
+ std::underlying_type<std::memory_order>::type>::value),
+ "std::memory_order should have the same underlying type as a corresponding "
+ "unscoped enumeration would. Otherwise, our ABI changes from C++17 to C++20.");
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_strong.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_strong.pass.cpp
new file mode 100644
index 0000000000000..92f6a622c329c
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_strong.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none || libcpp-hardening-mode=fast
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-user-defined-warnings
+
+// <atomic>
+
+// bool compare_exchange_strong(T& expected, T desired, memory_order success, memory_order failure) const noexcept;
+//
+// Preconditions: failure is memory_order::relaxed, memory_order::consume, memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+#include "atomic_helpers.h"
+#include "check_assertion.h"
+
+template <typename T>
+struct TestCompareExchangeStrongInvalidMemoryOrder {
+ void operator()() const {
+ { // no assertion should trigger here
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ T t(T(2));
+ a.compare_exchange_strong(t, T(3), std::memory_order_relaxed, std::memory_order_relaxed);
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ T t(T(2));
+ a.compare_exchange_strong(t, T(3), std::memory_order_relaxed, std::memory_order_release);
+ }()),
+ "atomic_ref: failure memory order argument to strong atomic compare-and-exchange operation is invalid");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ T t(T(2));
+ a.compare_exchange_strong(t, T(3), std::memory_order_relaxed, std::memory_order_acq_rel);
+ }()),
+ "atomic_ref: failure memory order argument to strong atomic compare-and-exchange operation is invalid");
+ }
+};
+
+int main(int, char**) {
+ TestEachAtomicType<TestCompareExchangeStrongInvalidMemoryOrder>()();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_weak.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_weak.pass.cpp
new file mode 100644
index 0000000000000..3bee003b2143f
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.compare_exchange_weak.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none || libcpp-hardening-mode=fast
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-user-defined-warnings
+
+// <atomic>
+
+// bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) const noexcept;
+//
+// Preconditions: failure is memory_order::relaxed, memory_order::consume, memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+#include "atomic_helpers.h"
+#include "check_assertion.h"
+
+template <typename T>
+struct TestCompareExchangeWeakInvalidMemoryOrder {
+ void operator()() const {
+ { // no assertion should trigger here
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ T t(T(2));
+ a.compare_exchange_weak(t, T(3), std::memory_order_relaxed, std::memory_order_relaxed);
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ T t(T(2));
+ a.compare_exchange_weak(t, T(3), std::memory_order_relaxed, std::memory_order_release);
+ }()),
+ "atomic_ref: failure memory order argument to weak atomic compare-and-exchange operation is invalid");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ T t(T(2));
+ a.compare_exchange_weak(t, T(3), std::memory_order_relaxed, std::memory_order_acq_rel);
+ }()),
+ "atomic_ref: failure memory order argument to weak atomic compare-and-exchange operation is invalid");
+ }
+};
+
+int main(int, char**) {
+ TestEachAtomicType<TestCompareExchangeWeakInvalidMemoryOrder>()();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/assert.ctor.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.ctor.pass.cpp
new file mode 100644
index 0000000000000..3d4700406984c
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.ctor.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none || libcpp-hardening-mode=fast
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <atomic>
+
+// atomic_ref(T& obj);
+//
+// Preconditions: The referenced object is aligned to required_alignment.
+
+#include <atomic>
+#include <cstddef>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ { // no assertion should trigger here
+ alignas(float) std::byte c[sizeof(float)];
+ float* f = new (c) float(3.14f);
+ [[maybe_unused]] std::atomic_ref<float> r(*f);
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ alignas(float) std::byte c[2 * sizeof(float)]; // intentionally larger
+ float* f = new (c + 1) float(3.14f); // intentionally misaligned
+ [[maybe_unused]] std::atomic_ref<float> r(*f);
+ }()),
+ "atomic_ref ctor: referenced object must be aligned to required_alignment");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/assert.load.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.load.pass.cpp
new file mode 100644
index 0000000000000..504d135c4f3d7
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.load.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none || libcpp-hardening-mode=fast
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-user-defined-warnings
+
+// <atomic>
+
+// T load(memory_order order = memory_order::seq_cst) const noexcept;
+//
+// Preconditions: order is memory_order::relaxed, memory_order::consume, memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+#include "atomic_helpers.h"
+#include "check_assertion.h"
+
+template <typename T>
+struct TestLoadInvalidMemoryOrder {
+ void operator()() const {
+ { // no assertion should trigger here
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ (void)a.load(std::memory_order_relaxed);
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ (void)a.load(std::memory_order_release);
+ }()),
+ "atomic_ref: memory order argument to atomic load operation is invalid");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ (void)a.load(std::memory_order_acq_rel);
+ }()),
+ "atomic_ref: memory order argument to atomic load operation is invalid");
+ }
+};
+
+int main(int, char**) {
+ TestEachAtomicType<TestLoadInvalidMemoryOrder>()();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/assert.store.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.store.pass.cpp
new file mode 100644
index 0000000000000..1afa42528e14f
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.store.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none || libcpp-hardening-mode=fast
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-user-defined-warnings
+
+// <atomic>
+
+// void store(T desired, memory_order order = memory_order::seq_cst) const noexcept;
+//
+// Preconditions: order is memory_order::relaxed, memory_order::release, or memory_order::seq_cst.
+
+#include <atomic>
+
+#include "atomic_helpers.h"
+#include "check_assertion.h"
+
+template <typename T>
+struct TestStoreInvalidMemoryOrder {
+ void operator()() const {
+ { // no assertion should trigger here
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ a.store(T(2), std::memory_order_relaxed);
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ a.store(T(2), std::memory_order_consume);
+ }()),
+ "atomic_ref: memory order argument to atomic store operation is invalid");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ a.store(T(2), std::memory_order_acquire);
+ }()),
+ "atomic_ref: memory order argument to atomic store operation is invalid");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ a.store(T(2), std::memory_order_acq_rel);
+ }()),
+ "atomic_ref: memory order argument to atomic store operation is invalid");
+ }
+};
+
+int main(int, char**) {
+ TestEachAtomicType<TestStoreInvalidMemoryOrder>()();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/assert.wait.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.wait.pass.cpp
new file mode 100644
index 0000000000000..39178d2393be2
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/assert.wait.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none || libcpp-hardening-mode=fast
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-user-defined-warnings
+
+// <atomic>
+
+// void wait(T old, memory_order order = memory_order::seq_cst) const noexcept;
+//
+// Preconditions: order is memory_order::relaxed, memory_order::consume, memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+#include "atomic_helpers.h"
+#include "check_assertion.h"
+
+template <typename T>
+struct TestWaitInvalidMemoryOrder {
+ void operator()() const {
+ { // no assertion should trigger here
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ a.wait(T(2), std::memory_order_relaxed);
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ a.wait(T(2), std::memory_order_release);
+ }()),
+ "atomic_ref: memory order argument to atomic wait operation is invalid");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ T x(T(1));
+ std::atomic_ref<T> const a(x);
+ a.wait(T(2), std::memory_order_acq_rel);
+ }()),
+ "atomic_ref: memory order argument to atomic wait operation is invalid");
+ }
+};
+
+int main(int, char**) {
+ TestEachAtomicType<TestWaitInvalidMemoryOrder>()();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_strong.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_strong.verify.cpp
new file mode 100644
index 0000000000000..427c82dbd0af2
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_strong.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: diagnose-if-support
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <atomic>
+
+// bool compare_exchange_strong(T& expected, T desired, memory_order success,
+// memory_order failure) const noexcept;
+//
+// Preconditions: failure is memory_order::relaxed, memory_order::consume,
+// memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+void test() {
+ using T = int;
+
+ T x(T(1));
+ std::atomic_ref const a(x);
+
+ T expected(T(2));
+ T const desired(T(3));
+ std::memory_order const success = std::memory_order_relaxed;
+ // clang-format off
+ a.compare_exchange_strong(expected, desired, success, std::memory_order_relaxed);
+ a.compare_exchange_strong(expected, desired, success, std::memory_order_consume);
+ a.compare_exchange_strong(expected, desired, success, std::memory_order_acquire);
+ a.compare_exchange_strong(expected, desired, success, std::memory_order_seq_cst);
+ a.compare_exchange_strong(expected, desired, success, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ a.compare_exchange_strong(expected, desired, success, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_weak.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_weak.verify.cpp
new file mode 100644
index 0000000000000..6a1046074dd26
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/compare_exchange_weak.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: diagnose-if-support
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <atomic>
+
+// bool compare_exchange_weak(T& expected, T desired, memory_order success,
+// memory_order failure) const noexcept;
+//
+// Preconditions: failure is memory_order::relaxed, memory_order::consume,
+// memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+void test() {
+ using T = int;
+
+ T x(T(42));
+ std::atomic_ref const a(x);
+
+ T expected(T(2));
+ T const desired(T(3));
+ std::memory_order const success = std::memory_order_relaxed;
+ // clang-format off
+ a.compare_exchange_weak(expected, desired, success, std::memory_order_relaxed);
+ a.compare_exchange_weak(expected, desired, success, std::memory_order_consume);
+ a.compare_exchange_weak(expected, desired, success, std::memory_order_acquire);
+ a.compare_exchange_weak(expected, desired, success, std::memory_order_seq_cst);
+ a.compare_exchange_weak(expected, desired, success, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ a.compare_exchange_weak(expected, desired, success, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/load.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/load.verify.cpp
new file mode 100644
index 0000000000000..9fdecb16d9d9b
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/load.verify.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: diagnose-if-support
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <atomic>
+
+// T load(memory_order order = memory_order::seq_cst) const noexcept;
+//
+// Preconditions: order is memory_order::relaxed, memory_order::consume, memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+void test() {
+ using T = int;
+
+ T x(T(1));
+ std::atomic_ref const a(x);
+
+ // clang-format off
+ (void)a.load(std::memory_order_relaxed);
+ (void)a.load(std::memory_order_consume);
+ (void)a.load(std::memory_order_acquire);
+ (void)a.load(std::memory_order_seq_cst);
+ (void)a.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ (void)a.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/store.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/store.verify.cpp
new file mode 100644
index 0000000000000..0be4e5ebfa2cc
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/store.verify.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: diagnose-if-support
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <atomic>
+
+// void store(T desired, memory_order order = memory_order::seq_cst) const noexcept;
+//
+// Preconditions: order is memory_order::relaxed, memory_order::release, or memory_order::seq_cst.
+
+#include <atomic>
+
+void test() {
+ using T = int;
+
+ T x(T(1));
+ std::atomic_ref const a(x);
+
+ T const desired(T(2));
+
+ // clang-format off
+ a.store(desired, std::memory_order_relaxed);
+ a.store(desired, std::memory_order_release);
+ a.store(desired, std::memory_order_seq_cst);
+ a.store(desired, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+ a.store(desired, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+ a.store(desired, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.ref/wait.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.ref/wait.verify.cpp
new file mode 100644
index 0000000000000..718e716ebdb32
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.ref/wait.verify.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: diagnose-if-support
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <atomic>
+
+// void wait(T old, memory_order order = memory_order::seq_cst) const noexcept;
+//
+// Preconditions: order is memory_order::relaxed, memory_order::consume, memory_order::acquire, or memory_order::seq_cst.
+
+#include <atomic>
+
+void test() {
+ using T = int;
+
+ T x(T(1));
+ std::atomic_ref const a(x);
+
+ T const old(T(2));
+
+ // clang-format off
+ a.wait(old, std::memory_order_relaxed);
+ a.wait(old, std::memory_order_consume);
+ a.wait(old, std::memory_order_acquire);
+ a.wait(old, std::memory_order_seq_cst);
+ a.wait(old, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ a.wait(old, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
new file mode 100644
index 0000000000000..349dc51aaa0e6
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.syn/compatible_with_stdatomic.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// This test verifies that <stdatomic.h> redirects to <atomic>.
+
+// Before C++23, <stdatomic.h> can be included after <atomic>, but including it
+// first doesn't work because its macros break <atomic>. Fixing that is the point
+// of the C++23 change that added <stdatomic.h> to C++. Thus, this test verifies
+// that <stdatomic.h> can be included first.
+#include <stdatomic.h>
+#include <atomic>
+
+#include <type_traits>
+
+static_assert(std::is_same<atomic_int, std::atomic<int> >::value, "");
diff --git a/libcxx/test/libcxx-03/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
new file mode 100644
index 0000000000000..a788ea32dddc8
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.syn/incompatible_with_stdatomic.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// REQUIRES: c++03 || c++11 || c++14 || c++17 || c++20
+
+// No diagnostic gets emitted when we build with modules.
+// XFAIL: clang-modules-build
+
+// This test ensures that we issue a reasonable diagnostic when including <atomic> after
+// <stdatomic.h> has been included. Before C++23, this otherwise leads to obscure errors
+// because <atomic> may try to redefine things defined by <stdatomic.h>.
+
+// Ignore additional weird errors that happen when the two headers are mixed.
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error -Xclang -verify-ignore-unexpected=warning
+
+#include <stdatomic.h>
+#include <atomic>
+
+// expected-error@*:* {{<atomic> is incompatible with <stdatomic.h> before C++23.}}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.syn/wait.issue_85107.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.syn/wait.issue_85107.pass.cpp
new file mode 100644
index 0000000000000..03eaa0e55ac6a
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.syn/wait.issue_85107.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
+// UNSUPPORTED: no-threads
+
+// This bug was first fixed in LLVM 19. This can't be XFAIL because
+// the test is a no-op (and would XPASS) on some targets.
+// UNSUPPORTED: using-built-library-before-llvm-19
+
+// XFAIL: availability-synchronization_library-missing
+
+// This is a regression test for https://github.com/llvm/llvm-project/issues/85107, which describes
+// how we were using UL_COMPARE_AND_WAIT instead of UL_COMPARE_AND_WAIT64 in the implementation of
+// atomic::wait, leading to potential infinite hangs.
+
+#include <atomic>
+#include <cassert>
+#include <chrono>
+
+#include "make_test_thread.h"
+
+int main(int, char**) {
+ if constexpr (sizeof(std::__cxx_contention_t) == 8 && sizeof(long) > 4) {
+ std::atomic<bool> done = false;
+ auto const timeout = std::chrono::system_clock::now() + std::chrono::seconds(600); // fail after 10 minutes
+
+ auto timeout_thread = support::make_test_thread([&] {
+ while (!done) {
+ assert(std::chrono::system_clock::now() < timeout); // make sure we don't hang forever
+ }
+ });
+
+ // https://github.com/llvm/llvm-project/issues/85107
+ // [libc++] atomic_wait uses UL_COMPARE_AND_WAIT when it should use UL_COMPARE_AND_WAIT64 on Darwin
+ constexpr std::__cxx_contention_t old_val = 0;
+ constexpr std::__cxx_contention_t new_val = old_val + (1ll << 32);
+ std::__cxx_atomic_contention_t ct(new_val);
+
+ // This would hang forever if the bug is present, but the test will fail in a bounded amount of
+ // time due to the timeout above.
+ std::__libcpp_atomic_wait(&ct, old_val);
+
+ done = true;
+ timeout_thread.join();
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.generic/atomics.types.float/lockfree.pass.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.generic/atomics.types.float/lockfree.pass.cpp
new file mode 100644
index 0000000000000..352e705151513
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.types.generic/atomics.types.float/lockfree.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
+// XFAIL: !has-64-bit-atomics
+
+// static constexpr bool is_always_lock_free = implementation-defined;
+// bool is_lock_free() const volatile noexcept;
+// bool is_lock_free() const noexcept;
+
+#include <atomic>
+#include <cassert>
+#include <concepts>
+
+#include "test_macros.h"
+
+template <class T>
+void test() {
+ // static constexpr bool is_always_lock_free = implementation-defined;
+ {
+ bool r = std::atomic<T>::is_always_lock_free;
+ assert(r == __atomic_always_lock_free(sizeof(std::__cxx_atomic_impl<T>), 0));
+ }
+
+ // bool is_lock_free() const volatile noexcept;
+ {
+ const volatile std::atomic<T> a;
+ bool r = a.is_lock_free();
+ assert(r == __cxx_atomic_is_lock_free(sizeof(std::__cxx_atomic_impl<T>)));
+ }
+
+ // bool is_lock_free() const noexcept;
+ {
+ const std::atomic<T> a;
+ bool r = a.is_lock_free();
+ assert(r == __cxx_atomic_is_lock_free(sizeof(std::__cxx_atomic_impl<T>)));
+ }
+}
+
+int main(int, char**) {
+ test<float>();
+ test<double>();
+ // TODO https://github.com/llvm/llvm-project/issues/47978
+ // test<long double>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp
new file mode 100644
index 0000000000000..320ef57dcb6f9
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <atomic>
+
+// template <class T>
+// T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op)
+// template <class T>
+// T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op);
+
+#include <atomic>
+
+void void_pointer() {
+ {
+ volatile std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_add(&obj, 0);
+ }
+ {
+ std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_add(&obj, 0);
+ }
+}
+
+struct Incomplete;
+
+void pointer_to_incomplete_type() {
+ {
+ volatile std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_add(&obj, 0);
+ }
+ {
+ std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_add(&obj, 0);
+ }
+}
+
+void function_pointer() {
+ {
+ volatile std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_add(&fun, 0);
+ }
+ {
+ std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_add(&fun, 0);
+ }
+}
+
+struct S {
+ void fun(int);
+};
+
+void member_function_pointer() {
+ {
+ volatile std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_add'}}
+ std::atomic_fetch_add(&fun, 0);
+ }
+ {
+ std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_add'}}
+ std::atomic_fetch_add(&fun, 0);
+ }
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp
new file mode 100644
index 0000000000000..bdd8089feb281
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <atomic>
+
+// template <class T>
+// T*
+// atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
+// memory_order m);
+// template <class T>
+// T*
+// atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
+
+#include <atomic>
+
+void void_pointer() {
+ {
+ volatile std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_add_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_add_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+}
+
+struct Incomplete;
+
+void pointer_to_incomplete_type() {
+ {
+ volatile std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_add_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_add_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+}
+
+void function_pointer() {
+ {
+ volatile std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+}
+
+struct S {
+ void fun(int);
+};
+
+void member_function_pointer() {
+ {
+ volatile std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_add_explicit'}}
+ std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_add_explicit'}}
+ std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp
new file mode 100644
index 0000000000000..2c9f89891d5be
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <atomic>
+
+// template <class T>
+// T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op)
+// template <class T>
+// T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op);
+
+#include <atomic>
+
+void void_pointer() {
+ {
+ volatile std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_sub(&obj, 0);
+ }
+ {
+ std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_sub(&obj, 0);
+ }
+}
+
+struct Incomplete;
+
+void pointer_to_incomplete_type() {
+ {
+ volatile std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_sub(&obj, 0);
+ }
+ {
+ std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_sub(&obj, 0);
+ }
+}
+
+void function_pointer() {
+ {
+ volatile std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_sub(&fun, 0);
+ }
+ {
+ std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_sub(&fun, 0);
+ }
+}
+
+struct S {
+ void fun(int);
+};
+
+void member_function_pointer() {
+ {
+ volatile std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub'}}
+ std::atomic_fetch_sub(&fun, 0);
+ }
+ {
+ std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub'}}
+ std::atomic_fetch_sub(&fun, 0);
+ }
+}
diff --git a/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp
new file mode 100644
index 0000000000000..88c42750b608a
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <atomic>
+
+// template <class T>
+// T*
+// atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
+// memory_order m);
+// template <class T>
+// T*
+// atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
+
+#include <atomic>
+
+void void_pointer() {
+ {
+ volatile std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_sub_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<void*> obj;
+ // expected-error@*:* {{incomplete type 'void' where a complete type is required}}
+ std::atomic_fetch_sub_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+}
+
+struct Incomplete;
+
+void pointer_to_incomplete_type() {
+ {
+ volatile std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_sub_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<Incomplete*> obj;
+ // expected-error@*:* {{incomplete type 'Incomplete' where a complete type is required}}
+ std::atomic_fetch_sub_explicit(&obj, 0, std::memory_order_relaxed);
+ }
+}
+
+void function_pointer() {
+ {
+ volatile std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<void (*)(int)> fun;
+ // expected-error-re@*:* {{static assertion failed due to requirement '!is_function<void (int)>::value'{{.*}}Pointer to function isn't allowed}}
+ std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+}
+
+struct S {
+ void fun(int);
+};
+
+void member_function_pointer() {
+ {
+ volatile std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub_explicit'}}
+ std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+ {
+ std::atomic<void (S::*)(int)> fun;
+ // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub_explicit'}}
+ std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed);
+ }
+}
diff --git a/libcxx/test/libcxx-03/atomics/bit-int.verify.cpp b/libcxx/test/libcxx-03/atomics/bit-int.verify.cpp
new file mode 100644
index 0000000000000..03880a1b6215c
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/bit-int.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
+//
+//===----------------------------------------------------------------------===//
+
+// <atomic>
+
+// Make sure that `std::atomic` doesn't work with `_BitInt`. The intent is to
+// disable them for now until their behavior can be designed better later.
+// See https://reviews.llvm.org/D84049 for details.
+
+// UNSUPPORTED: c++03
+
+#include <atomic>
+
+void f() {
+ // expected-error@*:*1 {{_Atomic cannot be applied to integer type '_BitInt(32)'}}
+ std::atomic<_BitInt(32)> x(42);
+}
diff --git a/libcxx/test/libcxx-03/atomics/diagnose_invalid_memory_order.verify.cpp b/libcxx/test/libcxx-03/atomics/diagnose_invalid_memory_order.verify.cpp
new file mode 100644
index 0000000000000..1b0b945f33700
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/diagnose_invalid_memory_order.verify.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: diagnose-if-support
+
+// <atomic>
+
+// Test that invalid memory order arguments are diagnosed where possible.
+
+#include <atomic>
+
+void f() {
+ std::atomic<int> x(42);
+ volatile std::atomic<int>& vx = x;
+ int val1 = 1; ((void)val1);
+ int val2 = 2; ((void)val2);
+ // load operations
+ {
+ x.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ x.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ x.load(std::memory_order_relaxed);
+ x.load(std::memory_order_consume);
+ x.load(std::memory_order_acquire);
+ x.load(std::memory_order_seq_cst);
+ }
+ {
+ std::atomic_load_explicit(&x, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_load_explicit(&x, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_load_explicit(&vx, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_load_explicit(&vx, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ std::atomic_load_explicit(&x, std::memory_order_relaxed);
+ std::atomic_load_explicit(&x, std::memory_order_consume);
+ std::atomic_load_explicit(&x, std::memory_order_acquire);
+ std::atomic_load_explicit(&x, std::memory_order_seq_cst);
+ }
+ // store operations
+ {
+ x.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+ x.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+ x.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ x.store(42, std::memory_order_relaxed);
+ x.store(42, std::memory_order_release);
+ x.store(42, std::memory_order_seq_cst);
+ }
+ {
+ std::atomic_store_explicit(&x, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_store_explicit(&x, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_store_explicit(&x, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_store_explicit(&vx, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_store_explicit(&vx, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_store_explicit(&vx, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ std::atomic_store_explicit(&x, 42, std::memory_order_relaxed);
+ std::atomic_store_explicit(&x, 42, std::memory_order_release);
+ std::atomic_store_explicit(&x, 42, std::memory_order_seq_cst);
+ }
+ // compare exchange weak
+ {
+ x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
+ x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
+ x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
+ x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
+ // Test that the cmpxchg overload with only one memory order argument
+ // does not generate any diagnostics.
+ x.compare_exchange_weak(val1, val2, std::memory_order_release);
+ }
+ {
+ std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_compare_exchange_weak_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_compare_exchange_weak_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
+ std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
+ std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
+ std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
+ }
+ // compare exchange strong
+ {
+ x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ vx.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
+ x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
+ x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
+ x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
+ // Test that the cmpxchg overload with only one memory order argument
+ // does not generate any diagnostics.
+ x.compare_exchange_strong(val1, val2, std::memory_order_release);
+ }
+ {
+ std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_compare_exchange_strong_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+ std::atomic_compare_exchange_strong_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+ // valid memory orders
+ std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
+ std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
+ std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
+ std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
+ }
+}
diff --git a/libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.compile.pass.cpp b/libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.compile.pass.cpp
new file mode 100644
index 0000000000000..6df80daf9414e
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.compile.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: no-threads
+
+// This test ensures that we don't hijack the <stdatomic.h> header (e.g. by providing
+// an empty header) even when compiling before C++23, since some users were using the
+// Clang or platform provided header before libc++ added its own.
+
+// On GCC, the compiler-provided <stdatomic.h> is not C++ friendly, so including <stdatomic.h>
+// doesn't work at all if we don't use the <stdatomic.h> provided by libc++ in C++23 and above.
+// XFAIL: (c++11 || c++14 || c++17 || c++20) && gcc
+
+#include <stdatomic.h>
+
+void f() {
+ atomic_int i; // just make sure the header isn't empty
+ (void)i;
+}
diff --git a/libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp b/libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp
new file mode 100644
index 0000000000000..a8a99e6937f31
--- /dev/null
+++ b/libcxx/test/libcxx-03/atomics/stdatomic.h.syn/dont_hijack_header.cxx23.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+
+// This test verifies that <stdatomic.h> DOES NOT redirect to <atomic> before C++23,
+// since doing so is a breaking change. Several things can break when that happens,
+// because the type of _Atomic(T) changes from _Atomic(T) to std::atomic<T>.
+//
+// For example, redeclarations can become invalid depending on whether they
+// have been declared with <stdatomic.h> in scope or not.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17 || c++20
+
+// On GCC, the compiler-provided <stdatomic.h> is not C++ friendly, so including <stdatomic.h>
+// doesn't work at all if we don't use the <stdatomic.h> provided by libc++ in C++23 and above.
+// XFAIL: (c++11 || c++14 || c++17 || c++20) && gcc
+
+#include <atomic>
+#include <stdatomic.h>
+#include <type_traits>
+
+static_assert(!std::is_same<_Atomic(int), std::atomic<int> >::value, "");
diff --git a/libcxx/test/libcxx-03/clang_modules_include.gen.py b/libcxx/test/libcxx-03/clang_modules_include.gen.py
new file mode 100644
index 0000000000000..379ac22c8f47f
--- /dev/null
+++ b/libcxx/test/libcxx-03/clang_modules_include.gen.py
@@ -0,0 +1,97 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that we can include each header in a TU while using modules.
+# This is important notably because the LLDB data formatters use
+# libc++ headers with modules enabled.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+# block Lit from interpreting a RUN/XFAIL/etc inside the generation script
+# END.
+
+import sys
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+ lit_header_restrictions,
+ lit_header_undeprecations,
+ public_headers,
+)
+
+for header in public_headers:
+ print(
+ f"""\
+//--- {header}.compile.pass.cpp
+// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only
+
+// Older macOS SDKs were not properly modularized, which causes issues with localization.
+// This feature should instead be based on the SDK version.
+// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
+
+// GCC doesn't support -fcxx-modules
+// UNSUPPORTED: gcc
+
+// The Windows headers don't appear to be compatible with modules
+// UNSUPPORTED: windows
+// UNSUPPORTED: buildhost=windows
+
+// The Android headers don't appear to be compatible with modules yet
+// UNSUPPORTED: LIBCXX-ANDROID-FIXME
+
+// TODO: Investigate this failure
+// UNSUPPORTED: LIBCXX-FREEBSD-FIXME
+
+// TODO: Investigate why this doesn't work on Picolibc once the locale base API is refactored
+// UNSUPPORTED: LIBCXX-PICOLIBC-FIXME
+
+// TODO: Fix seemingly circular inclusion or <wchar.h> on AIX
+// UNSUPPORTED: LIBCXX-AIX-FIXME
+
+// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
+
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+#include <{header}>
+"""
+ )
+
+print(
+ f"""\
+//--- import_std.compile.pass.mm
+// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only
+
+// REQUIRES: clang-modules-build
+
+// Older macOS SDKs were not properly modularized, which causes issues with localization.
+// This feature should instead be based on the SDK version.
+// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
+
+// GCC doesn't support -fcxx-modules
+// UNSUPPORTED: gcc
+
+// The Windows headers don't appear to be compatible with modules
+// UNSUPPORTED: windows
+// UNSUPPORTED: buildhost=windows
+
+// The Android headers don't appear to be compatible with modules yet
+// UNSUPPORTED: LIBCXX-ANDROID-FIXME
+
+// TODO: Investigate this failure
+// UNSUPPORTED: LIBCXX-FREEBSD-FIXME
+
+// TODO: Investigate why this doesn't work on Picolibc once the locale base API is refactored
+// UNSUPPORTED: LIBCXX-PICOLIBC-FIXME
+
+// TODO: Fix seemingly circular inclusion or <wchar.h> on AIX
+// UNSUPPORTED: LIBCXX-AIX-FIXME
+
+ at import std;
+
+"""
+)
diff --git a/libcxx/test/libcxx-03/clang_tidy.gen.py b/libcxx/test/libcxx-03/clang_tidy.gen.py
new file mode 100644
index 0000000000000..dbab2875e3126
--- /dev/null
+++ b/libcxx/test/libcxx-03/clang_tidy.gen.py
@@ -0,0 +1,40 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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 our custom libc++ clang-tidy checks on all public headers.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+# block Lit from interpreting a RUN/XFAIL/etc inside the generation script
+# END.
+
+import sys
+sys.path.append(sys.argv[1])
+from libcxx.header_information import lit_header_restrictions, lit_header_undeprecations, public_headers
+
+for header in public_headers:
+ print(f"""\
+//--- {header}.sh.cpp
+
+// REQUIRES: has-clang-tidy
+
+// The frozen headers should not be updated to the latest libc++ style, so don't test.
+// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
+
+// The GCC compiler flags are not always compatible with clang-tidy.
+// UNSUPPORTED: gcc
+
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+// TODO: run clang-tidy with modules enabled once they are supported
+// RUN: %{{clang-tidy}} %s --warnings-as-errors=* -header-filter=.* --config-file=%{{libcxx-dir}}/.clang-tidy --load=%{{test-tools-dir}}/clang_tidy_checks/libcxx-tidy.plugin -- -Wweak-vtables %{{compile_flags}} -fno-modules
+
+#include <{header}>
+""")
diff --git a/libcxx/test/libcxx-03/clang_tidy.sh.py b/libcxx/test/libcxx-03/clang_tidy.sh.py
new file mode 100644
index 0000000000000..46f281f359209
--- /dev/null
+++ b/libcxx/test/libcxx-03/clang_tidy.sh.py
@@ -0,0 +1,11 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# REQUIRES: has-clang-tidy
+
+# RUN: %{python} %{libcxx-dir}/../clang-tools-extra/clang-tidy/tool/run-clang-tidy.py -clang-tidy-binary %{clang-tidy} -warnings-as-errors "*" -source-filter=".*libcxx/src.*" -quiet -p %{bin-dir}/..
diff --git a/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp b/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp
new file mode 100644
index 0000000000000..4958a258137a1
--- /dev/null
+++ b/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_integer.compile.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Concept helpers for the internal type traits for the fundamental types.
+
+// template <class _Tp>
+// concept __signed_or_unsigned_integer;
+
+#include <__type_traits/integer_traits.h>
+
+#include "test_macros.h"
+
+struct SomeObject {};
+
+enum SomeEnum {};
+
+enum class SomeScopedEnum {};
+
+// Unsigned
+static_assert(std::__signed_or_unsigned_integer<unsigned char>);
+static_assert(std::__signed_or_unsigned_integer<unsigned short int>);
+static_assert(std::__signed_or_unsigned_integer<unsigned int>);
+static_assert(std::__signed_or_unsigned_integer<unsigned long int>);
+static_assert(std::__signed_or_unsigned_integer<unsigned long long int>);
+static_assert(std::__signed_or_unsigned_integer<unsigned short int>);
+#if _LIBCPP_HAS_INT128
+static_assert(std::__signed_or_unsigned_integer<__uint128_t>);
+#endif
+// Signed
+static_assert(std::__signed_or_unsigned_integer<signed char>);
+static_assert(std::__signed_or_unsigned_integer<short int>);
+static_assert(std::__signed_or_unsigned_integer<int>);
+static_assert(std::__signed_or_unsigned_integer<long int>);
+static_assert(std::__signed_or_unsigned_integer<long long int>);
+static_assert(std::__signed_or_unsigned_integer<short int>);
+#if _LIBCPP_HAS_INT128
+static_assert(std::__signed_or_unsigned_integer<__int128_t>);
+#endif
+// Non-integer
+static_assert(!std::__signed_or_unsigned_integer<bool>);
+static_assert(!std::__signed_or_unsigned_integer<char>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__signed_or_unsigned_integer<wchar_t>);
+#endif
+static_assert(!std::__signed_or_unsigned_integer<char8_t>);
+static_assert(!std::__signed_or_unsigned_integer<char16_t>);
+static_assert(!std::__signed_or_unsigned_integer<char32_t>);
+static_assert(!std::__signed_or_unsigned_integer<float>);
+static_assert(!std::__signed_or_unsigned_integer<double>);
+static_assert(!std::__signed_or_unsigned_integer<long double>);
+static_assert(!std::__signed_or_unsigned_integer<void>);
+static_assert(!std::__signed_or_unsigned_integer<int*>);
+static_assert(!std::__signed_or_unsigned_integer<unsigned int*>);
+static_assert(!std::__signed_or_unsigned_integer<SomeObject>);
+static_assert(!std::__signed_or_unsigned_integer<SomeEnum>);
+static_assert(!std::__signed_or_unsigned_integer<SomeScopedEnum>);
diff --git a/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp b/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp
new file mode 100644
index 0000000000000..3fa342685770c
--- /dev/null
+++ b/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_signed_integer.compile.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Concept helpers for the internal type traits for the fundamental types.
+
+// template <class _Tp>
+// concept __signed_integer;
+
+#include <__type_traits/integer_traits.h>
+
+#include "test_macros.h"
+
+struct SomeObject {};
+
+enum SomeEnum {};
+
+enum class SomeScopedEnum {};
+
+// Unsigned
+static_assert(!std::__signed_integer<unsigned char>);
+static_assert(!std::__signed_integer<unsigned short int>);
+static_assert(!std::__signed_integer<unsigned int>);
+static_assert(!std::__signed_integer<unsigned long int>);
+static_assert(!std::__signed_integer<unsigned long long int>);
+static_assert(!std::__signed_integer<unsigned short int>);
+#if _LIBCPP_HAS_INT128
+static_assert(!std::__signed_integer<__uint128_t>);
+#endif
+// Signed
+static_assert(std::__signed_integer<signed char>);
+static_assert(std::__signed_integer<short int>);
+static_assert(std::__signed_integer<int>);
+static_assert(std::__signed_integer<long int>);
+static_assert(std::__signed_integer<long long int>);
+static_assert(std::__signed_integer<short int>);
+#if _LIBCPP_HAS_INT128
+static_assert(std::__signed_integer<__int128_t>);
+#endif
+// Non-integer
+static_assert(!std::__signed_integer<bool>);
+static_assert(!std::__signed_integer<char>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__signed_integer<wchar_t>);
+#endif
+static_assert(!std::__signed_integer<char8_t>);
+static_assert(!std::__signed_integer<char16_t>);
+static_assert(!std::__signed_integer<char32_t>);
+static_assert(!std::__signed_integer<float>);
+static_assert(!std::__signed_integer<double>);
+static_assert(!std::__signed_integer<long double>);
+static_assert(!std::__signed_integer<void>);
+static_assert(!std::__signed_integer<int*>);
+static_assert(!std::__signed_integer<unsigned int*>);
+static_assert(!std::__signed_integer<SomeObject>);
+static_assert(!std::__signed_integer<SomeEnum>);
+static_assert(!std::__signed_integer<SomeScopedEnum>);
diff --git a/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp b/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp
new file mode 100644
index 0000000000000..ff60f32319171
--- /dev/null
+++ b/libcxx/test/libcxx-03/concepts/concepts.arithmetic/__libcpp_unsigned_integer.compile.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Concept helpers for the internal type traits for the fundamental types.
+
+// template <class _Tp>
+// concept __unsigned_integer;
+
+#include <__type_traits/integer_traits.h>
+
+#include "test_macros.h"
+
+struct SomeObject {};
+
+enum SomeEnum {};
+
+enum class SomeScopedEnum {};
+
+// Unsigned
+static_assert(std::__unsigned_integer<unsigned char>);
+static_assert(std::__unsigned_integer<unsigned short int>);
+static_assert(std::__unsigned_integer<unsigned int>);
+static_assert(std::__unsigned_integer<unsigned long int>);
+static_assert(std::__unsigned_integer<unsigned long long int>);
+static_assert(std::__unsigned_integer<unsigned short int>);
+#if _LIBCPP_HAS_INT128
+static_assert(std::__unsigned_integer<__uint128_t>);
+#endif
+// Signed
+static_assert(!std::__unsigned_integer<signed char>);
+static_assert(!std::__unsigned_integer<short int>);
+static_assert(!std::__unsigned_integer<int>);
+static_assert(!std::__unsigned_integer<long int>);
+static_assert(!std::__unsigned_integer<long long int>);
+static_assert(!std::__unsigned_integer<short int>);
+#if _LIBCPP_HAS_INT128
+static_assert(!std::__unsigned_integer<__int128_t>);
+#endif
+// Non-integer
+static_assert(!std::__unsigned_integer<bool>);
+static_assert(!std::__unsigned_integer<char>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__unsigned_integer<wchar_t>);
+#endif
+static_assert(!std::__unsigned_integer<char8_t>);
+static_assert(!std::__unsigned_integer<char16_t>);
+static_assert(!std::__unsigned_integer<char32_t>);
+static_assert(!std::__unsigned_integer<float>);
+static_assert(!std::__unsigned_integer<double>);
+static_assert(!std::__unsigned_integer<long double>);
+static_assert(!std::__unsigned_integer<void>);
+static_assert(!std::__unsigned_integer<int*>);
+static_assert(!std::__unsigned_integer<unsigned int*>);
+static_assert(!std::__unsigned_integer<SomeObject>);
+static_assert(!std::__unsigned_integer<SomeEnum>);
+static_assert(!std::__unsigned_integer<SomeScopedEnum>);
diff --git a/libcxx/test/libcxx-03/containers/associative/map/at.abort.pass.cpp b/libcxx/test/libcxx-03/containers/associative/map/at.abort.pass.cpp
new file mode 100644
index 0000000000000..d68ee5f528599
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/map/at.abort.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// mapped_type& at(const key_type& k);
+
+// Make sure we abort() when exceptions are disabled and we fetch a key that
+// is not in the map.
+
+// REQUIRES: no-exceptions
+
+#include <csignal>
+#include <cstdlib>
+#include <map>
+
+#include "test_macros.h"
+
+void exit_success(int) { std::_Exit(EXIT_SUCCESS); }
+
+int main(int, char**) {
+ std::signal(SIGABRT, exit_success);
+ std::map<int, int> map;
+ map.at(1);
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/map/at.const.abort.pass.cpp b/libcxx/test/libcxx-03/containers/associative/map/at.const.abort.pass.cpp
new file mode 100644
index 0000000000000..bbc8c7c4d726a
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/map/at.const.abort.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// const mapped_type& at(const key_type& k) const;
+
+// Make sure we abort() when exceptions are disabled and we fetch a key that
+// is not in the map.
+
+// REQUIRES: no-exceptions
+
+#include <csignal>
+#include <cstdlib>
+#include <map>
+
+#include "test_macros.h"
+
+void exit_success(int) { std::_Exit(EXIT_SUCCESS); }
+
+int main(int, char**) {
+ std::signal(SIGABRT, exit_success);
+ std::map<int, int> const map;
+ map.at(1);
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/map/find.modules.compile.pass.mm b/libcxx/test/libcxx-03/containers/associative/map/find.modules.compile.pass.mm
new file mode 100644
index 0000000000000..82b1c494c9566
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/map/find.modules.compile.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that we don't get a compiler error when trying to use std::map::find
+// from Objective-C++. This happened in Objective-C++ mode with modules enabled (rdar://106813461).
+
+// REQUIRES: objective-c++
+
+#include <map>
+
+void f(std::map<int, int> const& map, int key) { (void)map.find(key); }
diff --git a/libcxx/test/libcxx-03/containers/associative/map/scary.compile.pass.cpp b/libcxx/test/libcxx-03/containers/associative/map/scary.compile.pass.cpp
new file mode 100644
index 0000000000000..89e753f854926
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/map/scary.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+// class multimap
+
+// Extension: SCARY/N2913 iterator compatibility between map and multimap
+
+#include <map>
+
+#include "test_macros.h"
+
+void test() {
+ typedef std::map<int, int> M1;
+ typedef std::multimap<int, int> M2;
+
+ ASSERT_SAME_TYPE(M1::iterator, M2::iterator);
+ ASSERT_SAME_TYPE(M1::const_iterator, M2::const_iterator);
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/non_const_comparator.incomplete.verify.cpp b/libcxx/test/libcxx-03/containers/associative/non_const_comparator.incomplete.verify.cpp
new file mode 100644
index 0000000000000..bae78ba4b78c6
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/non_const_comparator.incomplete.verify.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test that libc++ does not generate a warning diagnostic about the comparator
+// too early for containers of incomplete types.
+//
+// See PR41360.
+
+#include <set>
+#include <map>
+#include <functional>
+
+template <template <typename...> class Container>
+void test_set() {
+ struct KeyBase {};
+ struct KeyDerived; // derives from KeyBase, but incomplete at this point
+
+ // Name the type but don't instantiate it.
+ using C = Container<KeyDerived*, std::less<KeyBase*>>;
+
+ // Instantiate it but don't ODR use any members.
+ typename C::value_type dummy;
+ (void)dummy;
+
+ // Complete the types.
+ struct KeyDerived : KeyBase {};
+
+ C c; // ODR use it, which should be OK
+}
+
+template <template <typename...> class Container>
+void test_map() {
+ struct Value {};
+ struct KeyBase {};
+ struct KeyDerived;
+ using C = Container<KeyDerived*, Value, std::less<KeyBase*>>;
+ typename C::value_type dummy;
+ (void)dummy;
+ struct KeyDerived : KeyBase {};
+ C c;
+}
+
+void f() {
+ // expected-no-diagnostics
+ test_set<std::set>();
+ test_set<std::multiset>();
+ test_map<std::map>();
+ test_map<std::multimap>();
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/non_const_comparator.verify.cpp b/libcxx/test/libcxx-03/containers/associative/non_const_comparator.verify.cpp
new file mode 100644
index 0000000000000..cb7a044abd8c0
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/non_const_comparator.verify.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
+// REQUIRES: diagnose-if-support
+
+// Test that libc++ generates a warning diagnostic when the container is
+// provided a non-const callable comparator.
+
+#include <__type_traits/invoke.h>
+#include <map>
+#include <set>
+
+struct BadCompare {
+ template <class T, class U>
+ bool operator()(T const& t, U const& u) {
+ return t < u;
+ }
+};
+
+void f() {
+ static_assert(!std::__is_invocable_v<BadCompare const&, int const&, int const&>, "");
+ static_assert(std::__is_invocable_v<BadCompare&, int const&, int const&>, "");
+
+ // expected-warning at set:* 2 {{the specified comparator type does not provide a viable const call operator}}
+ // expected-warning at map:* 2 {{the specified comparator type does not provide a viable const call operator}}
+ {
+ using C = std::set<int, BadCompare>;
+ C s;
+ }
+ {
+ using C = std::multiset<long, BadCompare>;
+ C s;
+ }
+ {
+ using C = std::map<int, int, BadCompare>;
+ C s;
+ }
+ {
+ using C = std::multimap<long, int, BadCompare>;
+ C s;
+ }
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/reference_comparator_abi.compile.pass.cpp b/libcxx/test/libcxx-03/containers/associative/reference_comparator_abi.compile.pass.cpp
new file mode 100644
index 0000000000000..f364fc817c164
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/reference_comparator_abi.compile.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
+//
+//===----------------------------------------------------------------------===//
+
+// Pin down the ABI of associative containers with respect to their size and alignment
+// when passed a comparator that is a reference.
+//
+// While it's not even clear that reference comparators are legal in containers, an
+// unintended ABI break was discovered after implementing the new compressed pair
+// mechanism based on [[no_unique_address]], and this is a regression test for that.
+// If we decide to make reference comparators ill-formed, this test would become
+// unnecessary.
+//
+// See https://github.com/llvm/llvm-project/issues/118559 for more details.
+
+#include <set>
+#include <map>
+
+#include "test_macros.h"
+
+struct TEST_ALIGNAS(16) Cmp {
+ bool operator()(int, int) const;
+};
+
+template <class Compare>
+struct Set {
+ char b;
+ std::set<int, Compare> s;
+};
+
+template <class Compare>
+struct Multiset {
+ char b;
+ std::multiset<int, Compare> s;
+};
+
+template <class Compare>
+struct Map {
+ char b;
+ std::map<int, char, Compare> s;
+};
+
+template <class Compare>
+struct Multimap {
+ char b;
+ std::multimap<int, char, Compare> s;
+};
+
+static_assert(sizeof(Set<Cmp&>) == sizeof(Set<bool (*)(int, int)>), "");
+static_assert(sizeof(Multiset<Cmp&>) == sizeof(Multiset<bool (*)(int, int)>), "");
+
+static_assert(sizeof(Map<Cmp&>) == sizeof(Map<bool (*)(int, int)>), "");
+static_assert(sizeof(Multimap<Cmp&>) == sizeof(Multimap<bool (*)(int, int)>), "");
diff --git a/libcxx/test/libcxx-03/containers/associative/set/scary.compile.pass.cpp b/libcxx/test/libcxx-03/containers/associative/set/scary.compile.pass.cpp
new file mode 100644
index 0000000000000..87ed05d84cdd7
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/set/scary.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <set>
+
+// class set
+// class multiset
+
+// Extension: SCARY/N2913 iterator compatibility between set and multiset
+
+#include <set>
+
+#include "test_macros.h"
+
+void test() {
+ typedef std::set<int> M1;
+ typedef std::multiset<int> M2;
+
+ ASSERT_SAME_TYPE(M1::iterator, M2::iterator);
+ ASSERT_SAME_TYPE(M1::const_iterator, M2::const_iterator);
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/tree_balance_after_insert.pass.cpp b/libcxx/test/libcxx-03/containers/associative/tree_balance_after_insert.pass.cpp
new file mode 100644
index 0000000000000..ccd84af44c3a5
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/tree_balance_after_insert.pass.cpp
@@ -0,0 +1,1612 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Not a portable test
+
+// Precondition: __root->__is_black_ == true
+// template <class _NodePtr>
+// void
+// __tree_balance_after_insert(_NodePtr __root, _NodePtr __x)
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__tree>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct Node {
+ Node* __left_;
+ Node* __right_;
+ Node* __parent_;
+ bool __is_black_;
+
+ Node* __parent_unsafe() const { return __parent_; }
+ void __set_parent(Node* x) { __parent_ = x; }
+
+ Node() : __left_(), __right_(), __parent_(), __is_black_() {}
+};
+
+void test1() {
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = &a;
+ b.__right_ = 0;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = 0;
+ d.__right_ = 0;
+ d.__is_black_ = false;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = 0;
+ b.__right_ = &a;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = 0;
+ d.__right_ = 0;
+ d.__is_black_ = false;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == &a);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = 0;
+ b.__right_ = 0;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = &a;
+ d.__right_ = 0;
+ d.__is_black_ = false;
+
+ a.__parent_ = &d;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == &a);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &d);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = 0;
+ b.__right_ = 0;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = 0;
+ d.__right_ = &a;
+ d.__is_black_ = false;
+
+ a.__parent_ = &d;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == &a);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &d);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+ Node i;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = &a;
+ b.__right_ = &g;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = &h;
+ d.__right_ = &i;
+ d.__is_black_ = false;
+
+ a.__parent_ = &b;
+ a.__left_ = &e;
+ a.__right_ = &f;
+ a.__is_black_ = false;
+
+ e.__parent_ = &a;
+ e.__is_black_ = true;
+
+ f.__parent_ = &a;
+ f.__is_black_ = true;
+
+ g.__parent_ = &b;
+ g.__is_black_ = true;
+
+ h.__parent_ = &d;
+ h.__is_black_ = true;
+
+ i.__parent_ = &d;
+ i.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &g);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == &h);
+ assert(d.__right_ == &i);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == &e);
+ assert(a.__right_ == &f);
+ assert(a.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+ Node i;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = &g;
+ b.__right_ = &a;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = &h;
+ d.__right_ = &i;
+ d.__is_black_ = false;
+
+ a.__parent_ = &b;
+ a.__left_ = &e;
+ a.__right_ = &f;
+ a.__is_black_ = false;
+
+ e.__parent_ = &a;
+ e.__is_black_ = true;
+
+ f.__parent_ = &a;
+ f.__is_black_ = true;
+
+ g.__parent_ = &b;
+ g.__is_black_ = true;
+
+ h.__parent_ = &d;
+ h.__is_black_ = true;
+
+ i.__parent_ = &d;
+ i.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &g);
+ assert(b.__right_ == &a);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == &h);
+ assert(d.__right_ == &i);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == &e);
+ assert(a.__right_ == &f);
+ assert(a.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+ Node i;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = &g;
+ b.__right_ = &h;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = &a;
+ d.__right_ = &i;
+ d.__is_black_ = false;
+
+ a.__parent_ = &d;
+ a.__left_ = &e;
+ a.__right_ = &f;
+ a.__is_black_ = false;
+
+ e.__parent_ = &a;
+ e.__is_black_ = true;
+
+ f.__parent_ = &a;
+ f.__is_black_ = true;
+
+ g.__parent_ = &b;
+ g.__is_black_ = true;
+
+ h.__parent_ = &b;
+ h.__is_black_ = true;
+
+ i.__parent_ = &d;
+ i.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &g);
+ assert(b.__right_ == &h);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == &a);
+ assert(d.__right_ == &i);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &d);
+ assert(a.__left_ == &e);
+ assert(a.__right_ == &f);
+ assert(a.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+ Node i;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = &g;
+ b.__right_ = &h;
+ b.__is_black_ = false;
+
+ d.__parent_ = &c;
+ d.__left_ = &i;
+ d.__right_ = &a;
+ d.__is_black_ = false;
+
+ a.__parent_ = &d;
+ a.__left_ = &e;
+ a.__right_ = &f;
+ a.__is_black_ = false;
+
+ e.__parent_ = &a;
+ e.__is_black_ = true;
+
+ f.__parent_ = &a;
+ f.__is_black_ = true;
+
+ g.__parent_ = &b;
+ g.__is_black_ = true;
+
+ h.__parent_ = &b;
+ h.__is_black_ = true;
+
+ i.__parent_ = &d;
+ i.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &c);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &g);
+ assert(b.__right_ == &h);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == &i);
+ assert(d.__right_ == &a);
+ assert(d.__is_black_ == true);
+
+ assert(a.__parent_ == &d);
+ assert(a.__left_ == &e);
+ assert(a.__right_ == &f);
+ assert(a.__is_black_ == false);
+ }
+}
+
+void test2() {
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &a;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ a.__parent_ = &c;
+ a.__left_ = 0;
+ a.__right_ = &b;
+ a.__is_black_ = false;
+
+ b.__parent_ = &a;
+ b.__left_ = 0;
+ b.__right_ = 0;
+ b.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &a;
+
+ a.__parent_ = &root;
+ a.__left_ = 0;
+ a.__right_ = &c;
+ a.__is_black_ = true;
+
+ c.__parent_ = &a;
+ c.__left_ = &b;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ b.__parent_ = &c;
+ b.__left_ = 0;
+ b.__right_ = 0;
+ b.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &a;
+ c.__right_ = &g;
+ c.__is_black_ = true;
+
+ a.__parent_ = &c;
+ a.__left_ = &d;
+ a.__right_ = &b;
+ a.__is_black_ = false;
+
+ b.__parent_ = &a;
+ b.__left_ = &e;
+ b.__right_ = &f;
+ b.__is_black_ = false;
+
+ d.__parent_ = &a;
+ d.__is_black_ = true;
+
+ e.__parent_ = &b;
+ e.__is_black_ = true;
+
+ f.__parent_ = &b;
+ f.__is_black_ = true;
+
+ g.__parent_ = &c;
+ g.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == &f);
+ assert(c.__right_ == &g);
+ assert(c.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == &d);
+ assert(a.__right_ == &e);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &a);
+ assert(d.__is_black_ == true);
+
+ assert(e.__parent_ == &a);
+ assert(e.__is_black_ == true);
+
+ assert(f.__parent_ == &c);
+ assert(f.__is_black_ == true);
+
+ assert(g.__parent_ == &c);
+ assert(g.__is_black_ == true);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+
+ root.__left_ = &a;
+
+ a.__parent_ = &root;
+ a.__left_ = &d;
+ a.__right_ = &c;
+ a.__is_black_ = true;
+
+ c.__parent_ = &a;
+ c.__left_ = &b;
+ c.__right_ = &g;
+ c.__is_black_ = false;
+
+ b.__parent_ = &c;
+ b.__left_ = &e;
+ b.__right_ = &f;
+ b.__is_black_ = false;
+
+ d.__parent_ = &a;
+ d.__is_black_ = true;
+
+ e.__parent_ = &b;
+ e.__is_black_ = true;
+
+ f.__parent_ = &b;
+ f.__is_black_ = true;
+
+ g.__parent_ = &c;
+ g.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == &f);
+ assert(c.__right_ == &g);
+ assert(c.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == &d);
+ assert(a.__right_ == &e);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &a);
+ assert(d.__is_black_ == true);
+
+ assert(e.__parent_ == &a);
+ assert(e.__is_black_ == true);
+
+ assert(f.__parent_ == &c);
+ assert(f.__is_black_ == true);
+
+ assert(g.__parent_ == &c);
+ assert(g.__is_black_ == true);
+ }
+}
+
+void test3() {
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = &a;
+ b.__right_ = 0;
+ b.__is_black_ = false;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &a;
+
+ a.__parent_ = &root;
+ a.__left_ = 0;
+ a.__right_ = &b;
+ a.__is_black_ = true;
+
+ b.__parent_ = &a;
+ b.__left_ = 0;
+ b.__right_ = &c;
+ b.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ std::__tree_balance_after_insert(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+
+ root.__left_ = &c;
+
+ c.__parent_ = &root;
+ c.__left_ = &b;
+ c.__right_ = &g;
+ c.__is_black_ = true;
+
+ b.__parent_ = &c;
+ b.__left_ = &a;
+ b.__right_ = &f;
+ b.__is_black_ = false;
+
+ a.__parent_ = &b;
+ a.__left_ = &d;
+ a.__right_ = &e;
+ a.__is_black_ = false;
+
+ d.__parent_ = &a;
+ d.__is_black_ = true;
+
+ e.__parent_ = &a;
+ e.__is_black_ = true;
+
+ f.__parent_ = &b;
+ f.__is_black_ = true;
+
+ g.__parent_ = &c;
+ g.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == &f);
+ assert(c.__right_ == &g);
+ assert(c.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == &d);
+ assert(a.__right_ == &e);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &a);
+ assert(d.__is_black_ == true);
+
+ assert(e.__parent_ == &a);
+ assert(e.__is_black_ == true);
+
+ assert(f.__parent_ == &c);
+ assert(f.__is_black_ == true);
+
+ assert(g.__parent_ == &c);
+ assert(g.__is_black_ == true);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+
+ root.__left_ = &a;
+
+ a.__parent_ = &root;
+ a.__left_ = &d;
+ a.__right_ = &b;
+ a.__is_black_ = true;
+
+ b.__parent_ = &a;
+ b.__left_ = &e;
+ b.__right_ = &c;
+ b.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = &f;
+ c.__right_ = &g;
+ c.__is_black_ = false;
+
+ d.__parent_ = &a;
+ d.__is_black_ = true;
+
+ e.__parent_ = &b;
+ e.__is_black_ = true;
+
+ f.__parent_ = &c;
+ f.__is_black_ = true;
+
+ g.__parent_ = &c;
+ g.__is_black_ = true;
+
+ std::__tree_balance_after_insert(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__left_ == &b);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == &f);
+ assert(c.__right_ == &g);
+ assert(c.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == &d);
+ assert(a.__right_ == &e);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(d.__parent_ == &a);
+ assert(d.__is_black_ == true);
+
+ assert(e.__parent_ == &a);
+ assert(e.__is_black_ == true);
+
+ assert(f.__parent_ == &c);
+ assert(f.__is_black_ == true);
+
+ assert(g.__parent_ == &c);
+ assert(g.__is_black_ == true);
+ }
+}
+
+void test4() {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+
+ root.__left_ = &a;
+ a.__parent_ = &root;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &a);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &root);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ a.__right_ = &b;
+ b.__parent_ = &a;
+
+ std::__tree_balance_after_insert(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &a);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &root);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == &b);
+ assert(a.__is_black_ == true);
+
+ assert(b.__parent_ == &a);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == false);
+
+ b.__right_ = &c;
+ c.__parent_ = &b;
+
+ std::__tree_balance_after_insert(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ c.__right_ = &d;
+ d.__parent_ = &c;
+
+ std::__tree_balance_after_insert(root.__left_, &d);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == false);
+
+ d.__right_ = &e;
+ e.__parent_ = &d;
+
+ std::__tree_balance_after_insert(root.__left_, &e);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &d);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ assert(d.__parent_ == &b);
+ assert(d.__left_ == &c);
+ assert(d.__right_ == &e);
+ assert(d.__is_black_ == true);
+
+ assert(c.__parent_ == &d);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(e.__parent_ == &d);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == false);
+
+ e.__right_ = &f;
+ f.__parent_ = &e;
+
+ std::__tree_balance_after_insert(root.__left_, &f);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &d);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ assert(d.__parent_ == &b);
+ assert(d.__left_ == &c);
+ assert(d.__right_ == &e);
+ assert(d.__is_black_ == false);
+
+ assert(c.__parent_ == &d);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ assert(e.__parent_ == &d);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == &f);
+ assert(e.__is_black_ == true);
+
+ assert(f.__parent_ == &e);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == false);
+
+ f.__right_ = &g;
+ g.__parent_ = &f;
+
+ std::__tree_balance_after_insert(root.__left_, &g);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &d);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ assert(d.__parent_ == &b);
+ assert(d.__left_ == &c);
+ assert(d.__right_ == &f);
+ assert(d.__is_black_ == false);
+
+ assert(c.__parent_ == &d);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ assert(f.__parent_ == &d);
+ assert(f.__left_ == &e);
+ assert(f.__right_ == &g);
+ assert(f.__is_black_ == true);
+
+ assert(e.__parent_ == &f);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == false);
+
+ assert(g.__parent_ == &f);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == 0);
+ assert(g.__is_black_ == false);
+
+ g.__right_ = &h;
+ h.__parent_ = &g;
+
+ std::__tree_balance_after_insert(root.__left_, &h);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &d);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(d.__parent_ == &root);
+ assert(d.__left_ == &b);
+ assert(d.__right_ == &f);
+ assert(d.__is_black_ == true);
+
+ assert(b.__parent_ == &d);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ assert(f.__parent_ == &d);
+ assert(f.__left_ == &e);
+ assert(f.__right_ == &g);
+ assert(f.__is_black_ == false);
+
+ assert(e.__parent_ == &f);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == true);
+
+ assert(g.__parent_ == &f);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == false);
+}
+
+void test5() {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+
+ root.__left_ = &h;
+ h.__parent_ = &root;
+
+ std::__tree_balance_after_insert(root.__left_, &h);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &h);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(h.__parent_ == &root);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ h.__left_ = &g;
+ g.__parent_ = &h;
+
+ std::__tree_balance_after_insert(root.__left_, &g);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &h);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(h.__parent_ == &root);
+ assert(h.__left_ == &g);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ assert(g.__parent_ == &h);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == 0);
+ assert(g.__is_black_ == false);
+
+ g.__left_ = &f;
+ f.__parent_ = &g;
+
+ std::__tree_balance_after_insert(root.__left_, &f);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &g);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(g.__parent_ == &root);
+ assert(g.__left_ == &f);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(f.__parent_ == &g);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == false);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == false);
+
+ f.__left_ = &e;
+ e.__parent_ = &f;
+
+ std::__tree_balance_after_insert(root.__left_, &e);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &g);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(g.__parent_ == &root);
+ assert(g.__left_ == &f);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(f.__parent_ == &g);
+ assert(f.__left_ == &e);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == true);
+
+ assert(e.__parent_ == &f);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == false);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ e.__left_ = &d;
+ d.__parent_ = &e;
+
+ std::__tree_balance_after_insert(root.__left_, &d);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &g);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(g.__parent_ == &root);
+ assert(g.__left_ == &e);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(e.__parent_ == &g);
+ assert(e.__left_ == &d);
+ assert(e.__right_ == &f);
+ assert(e.__is_black_ == true);
+
+ assert(d.__parent_ == &e);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == false);
+
+ assert(f.__parent_ == &e);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == false);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ d.__left_ = &c;
+ c.__parent_ = &d;
+
+ std::__tree_balance_after_insert(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &g);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(g.__parent_ == &root);
+ assert(g.__left_ == &e);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(e.__parent_ == &g);
+ assert(e.__left_ == &d);
+ assert(e.__right_ == &f);
+ assert(e.__is_black_ == false);
+
+ assert(d.__parent_ == &e);
+ assert(d.__left_ == &c);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ assert(c.__parent_ == &d);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(f.__parent_ == &e);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ c.__left_ = &b;
+ b.__parent_ = &c;
+
+ std::__tree_balance_after_insert(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &g);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(g.__parent_ == &root);
+ assert(g.__left_ == &e);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(e.__parent_ == &g);
+ assert(e.__left_ == &c);
+ assert(e.__right_ == &f);
+ assert(e.__is_black_ == false);
+
+ assert(c.__parent_ == &e);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == false);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == false);
+
+ assert(f.__parent_ == &e);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ b.__left_ = &a;
+ a.__parent_ = &b;
+
+ std::__tree_balance_after_insert(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &e);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(e.__parent_ == &root);
+ assert(e.__left_ == &c);
+ assert(e.__right_ == &g);
+ assert(e.__is_black_ == true);
+
+ assert(c.__parent_ == &e);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == false);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ assert(g.__parent_ == &e);
+ assert(g.__left_ == &f);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == false);
+
+ assert(f.__parent_ == &g);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+}
+
+int main(int, char**) {
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/tree_key_value_traits.pass.cpp b/libcxx/test/libcxx-03/containers/associative/tree_key_value_traits.pass.cpp
new file mode 100644
index 0000000000000..04dcb8f54fafc
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/tree_key_value_traits.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__tree>
+#include <map>
+#include <set>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+void testKeyValueTrait() {
+ {
+ typedef int Tp;
+ typedef std::__tree_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, int>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
+ static_assert(Traits::__is_map == false, "");
+ }
+ {
+ typedef std::pair<int, int> Tp;
+ typedef std::__tree_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
+ static_assert(Traits::__is_map == false, "");
+ }
+ {
+ typedef std::pair<const int, int> Tp;
+ typedef std::__tree_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
+ static_assert(Traits::__is_map == false, "");
+ }
+ {
+ typedef std::__value_type<int, int> Tp;
+ typedef std::__tree_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, int>::value), "");
+ static_assert((std::is_same<Traits::mapped_type, int>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, std::pair<const int, int> >::value), "");
+ static_assert((std::is_same<Traits::__map_value_type, std::pair<const int, int> >::value), "");
+ static_assert(Traits::__is_map == true, "");
+ }
+}
+
+int main(int, char**) {
+ testKeyValueTrait();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/tree_left_rotate.pass.cpp b/libcxx/test/libcxx-03/containers/associative/tree_left_rotate.pass.cpp
new file mode 100644
index 0000000000000..d97a1c89f1f70
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/tree_left_rotate.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// Not a portable test
+
+// Precondition: __x->__right_ != nullptr
+// template <class _NodePtr>
+// void
+// __tree_left_rotate(_NodePtr __x);
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__tree>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct Node {
+ Node* __left_;
+ Node* __right_;
+ Node* __parent_;
+
+ Node* __parent_unsafe() const { return __parent_; }
+ void __set_parent(Node* x) { __parent_ = x; }
+
+ Node() : __left_(), __right_(), __parent_() {}
+};
+
+void test1() {
+ Node root;
+ Node x;
+ Node y;
+ root.__left_ = &x;
+ x.__left_ = 0;
+ x.__right_ = &y;
+ x.__parent_ = &root;
+ y.__left_ = 0;
+ y.__right_ = 0;
+ y.__parent_ = &x;
+ std::__tree_left_rotate(&x);
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &y);
+ assert(root.__right_ == 0);
+ assert(y.__parent_ == &root);
+ assert(y.__left_ == &x);
+ assert(y.__right_ == 0);
+ assert(x.__parent_ == &y);
+ assert(x.__left_ == 0);
+ assert(x.__right_ == 0);
+}
+
+void test2() {
+ Node root;
+ Node x;
+ Node y;
+ Node a;
+ Node b;
+ Node c;
+ root.__left_ = &x;
+ x.__left_ = &a;
+ x.__right_ = &y;
+ x.__parent_ = &root;
+ y.__left_ = &b;
+ y.__right_ = &c;
+ y.__parent_ = &x;
+ a.__parent_ = &x;
+ b.__parent_ = &y;
+ c.__parent_ = &y;
+ std::__tree_left_rotate(&x);
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &y);
+ assert(root.__right_ == 0);
+ assert(y.__parent_ == &root);
+ assert(y.__left_ == &x);
+ assert(y.__right_ == &c);
+ assert(x.__parent_ == &y);
+ assert(x.__left_ == &a);
+ assert(x.__right_ == &b);
+ assert(a.__parent_ == &x);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(b.__parent_ == &x);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(c.__parent_ == &y);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+}
+
+int main(int, char**) {
+ test1();
+ test2();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/tree_remove.pass.cpp b/libcxx/test/libcxx-03/containers/associative/tree_remove.pass.cpp
new file mode 100644
index 0000000000000..e543c3360a685
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/tree_remove.pass.cpp
@@ -0,0 +1,1646 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Not a portable test
+
+// Returns __tree_next(__z)
+// template <class _NodePtr>
+// void
+// __tree_remove(_NodePtr __root, _NodePtr __z)
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__tree>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct Node {
+ Node* __left_;
+ Node* __right_;
+ Node* __parent_;
+ bool __is_black_;
+
+ Node* __parent_unsafe() const { return __parent_; }
+ void __set_parent(Node* x) { __parent_ = x; }
+
+ Node() : __left_(), __right_(), __parent_(), __is_black_() {}
+};
+
+void test1() {
+ {
+ // Left
+ // Case 1 -> Case 2 -> x is red turned to black
+ Node root;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node y;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &y;
+ b.__right_ = &d;
+ b.__is_black_ = true;
+
+ y.__parent_ = &b;
+ y.__left_ = 0;
+ y.__right_ = 0;
+ y.__is_black_ = true;
+
+ d.__parent_ = &b;
+ d.__left_ = &c;
+ d.__right_ = &e;
+ d.__is_black_ = false;
+
+ c.__parent_ = &d;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ e.__parent_ = &d;
+ e.__left_ = 0;
+ e.__right_ = 0;
+ e.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &y);
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &d);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(d.__parent_ == &root);
+ assert(d.__left_ == &b);
+ assert(d.__right_ == &e);
+ assert(d.__is_black_ == true);
+
+ assert(b.__parent_ == &d);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(e.__parent_ == &d);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == true);
+ }
+ {
+ // Right
+ // Case 1 -> Case 2 -> x is red turned to black
+ Node root;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node y;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__right_ = &y;
+ b.__left_ = &d;
+ b.__is_black_ = true;
+
+ y.__parent_ = &b;
+ y.__right_ = 0;
+ y.__left_ = 0;
+ y.__is_black_ = true;
+
+ d.__parent_ = &b;
+ d.__right_ = &c;
+ d.__left_ = &e;
+ d.__is_black_ = false;
+
+ c.__parent_ = &d;
+ c.__right_ = 0;
+ c.__left_ = 0;
+ c.__is_black_ = true;
+
+ e.__parent_ = &d;
+ e.__right_ = 0;
+ e.__left_ = 0;
+ e.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &y);
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &d);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(d.__parent_ == &root);
+ assert(d.__right_ == &b);
+ assert(d.__left_ == &e);
+ assert(d.__is_black_ == true);
+
+ assert(b.__parent_ == &d);
+ assert(b.__right_ == 0);
+ assert(b.__left_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__right_ == 0);
+ assert(c.__left_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(e.__parent_ == &d);
+ assert(e.__right_ == 0);
+ assert(e.__left_ == 0);
+ assert(e.__is_black_ == true);
+ }
+ {
+ // Left
+ // Case 1 -> Case 3 -> Case 4
+ Node root;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node y;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &y;
+ b.__right_ = &d;
+ b.__is_black_ = true;
+
+ y.__parent_ = &b;
+ y.__left_ = 0;
+ y.__right_ = 0;
+ y.__is_black_ = true;
+
+ d.__parent_ = &b;
+ d.__left_ = &c;
+ d.__right_ = &e;
+ d.__is_black_ = false;
+
+ c.__parent_ = &d;
+ c.__left_ = &f;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ e.__parent_ = &d;
+ e.__left_ = 0;
+ e.__right_ = 0;
+ e.__is_black_ = true;
+
+ f.__parent_ = &c;
+ f.__left_ = 0;
+ f.__right_ = 0;
+ f.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &y);
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &d);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(d.__parent_ == &root);
+ assert(d.__left_ == &f);
+ assert(d.__right_ == &e);
+ assert(d.__is_black_ == true);
+
+ assert(f.__parent_ == &d);
+ assert(f.__left_ == &b);
+ assert(f.__right_ == &c);
+ assert(f.__is_black_ == false);
+
+ assert(b.__parent_ == &f);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &f);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ assert(e.__parent_ == &d);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == true);
+ }
+ {
+ // Right
+ // Case 1 -> Case 3 -> Case 4
+ Node root;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node y;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__right_ = &y;
+ b.__left_ = &d;
+ b.__is_black_ = true;
+
+ y.__parent_ = &b;
+ y.__right_ = 0;
+ y.__left_ = 0;
+ y.__is_black_ = true;
+
+ d.__parent_ = &b;
+ d.__right_ = &c;
+ d.__left_ = &e;
+ d.__is_black_ = false;
+
+ c.__parent_ = &d;
+ c.__right_ = &f;
+ c.__left_ = 0;
+ c.__is_black_ = true;
+
+ e.__parent_ = &d;
+ e.__right_ = 0;
+ e.__left_ = 0;
+ e.__is_black_ = true;
+
+ f.__parent_ = &c;
+ f.__right_ = 0;
+ f.__left_ = 0;
+ f.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &y);
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &d);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(d.__parent_ == &root);
+ assert(d.__right_ == &f);
+ assert(d.__left_ == &e);
+ assert(d.__is_black_ == true);
+
+ assert(f.__parent_ == &d);
+ assert(f.__right_ == &b);
+ assert(f.__left_ == &c);
+ assert(f.__is_black_ == false);
+
+ assert(b.__parent_ == &f);
+ assert(b.__right_ == 0);
+ assert(b.__left_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &f);
+ assert(c.__right_ == 0);
+ assert(c.__left_ == 0);
+ assert(c.__is_black_ == true);
+
+ assert(e.__parent_ == &d);
+ assert(e.__right_ == 0);
+ assert(e.__left_ == 0);
+ assert(e.__is_black_ == true);
+ }
+}
+
+void test2() {
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = true;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = true;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = true;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &c);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &a);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &c);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &a);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = true;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &c);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &a);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &a);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &root);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &c);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &a);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &a);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &root);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = true;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &a);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &root);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &a);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &root);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = true;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+ {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ root.__left_ = &b;
+
+ b.__parent_ = &root;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = false;
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+ }
+}
+
+void test3() {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+
+ root.__left_ = &e;
+
+ e.__parent_ = &root;
+ e.__left_ = &c;
+ e.__right_ = &g;
+ e.__is_black_ = true;
+
+ c.__parent_ = &e;
+ c.__left_ = &b;
+ c.__right_ = &d;
+ c.__is_black_ = false;
+
+ g.__parent_ = &e;
+ g.__left_ = &f;
+ g.__right_ = &h;
+ g.__is_black_ = false;
+
+ b.__parent_ = &c;
+ b.__left_ = &a;
+ b.__right_ = 0;
+ b.__is_black_ = true;
+
+ d.__parent_ = &c;
+ d.__left_ = 0;
+ d.__right_ = 0;
+ d.__is_black_ = true;
+
+ f.__parent_ = &g;
+ f.__left_ = 0;
+ f.__right_ = 0;
+ f.__is_black_ = true;
+
+ h.__parent_ = &g;
+ h.__left_ = 0;
+ h.__right_ = 0;
+ h.__is_black_ = true;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = false;
+
+ assert(std::__tree_invariant(root.__left_));
+
+ std::__tree_remove(root.__left_, &h);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &e);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(e.__parent_ == &root);
+ assert(e.__left_ == &c);
+ assert(e.__right_ == &g);
+ assert(e.__is_black_ == true);
+
+ assert(c.__parent_ == &e);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == false);
+
+ assert(g.__parent_ == &e);
+ assert(g.__left_ == &f);
+ assert(g.__right_ == 0);
+ assert(g.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ assert(f.__parent_ == &g);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &g);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &e);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(e.__parent_ == &root);
+ assert(e.__left_ == &c);
+ assert(e.__right_ == &f);
+ assert(e.__is_black_ == true);
+
+ assert(c.__parent_ == &e);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == false);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ assert(f.__parent_ == &e);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &f);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &e);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(e.__parent_ == &c);
+ assert(e.__left_ == &d);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(d.__parent_ == &e);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &e);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &c);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(c.__parent_ == &root);
+ assert(c.__left_ == &b);
+ assert(c.__right_ == &d);
+ assert(c.__is_black_ == true);
+
+ assert(b.__parent_ == &c);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ assert(d.__parent_ == &c);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == 0);
+ assert(d.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &d);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &b);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(b.__parent_ == &root);
+ assert(b.__left_ == &a);
+ assert(b.__right_ == 0);
+ assert(b.__is_black_ == true);
+
+ assert(a.__parent_ == &b);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &a);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(a.__parent_ == &root);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(a.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+}
+
+void test4() {
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+ Node d;
+ Node e;
+ Node f;
+ Node g;
+ Node h;
+
+ root.__left_ = &d;
+
+ d.__parent_ = &root;
+ d.__left_ = &b;
+ d.__right_ = &f;
+ d.__is_black_ = true;
+
+ b.__parent_ = &d;
+ b.__left_ = &a;
+ b.__right_ = &c;
+ b.__is_black_ = false;
+
+ f.__parent_ = &d;
+ f.__left_ = &e;
+ f.__right_ = &g;
+ f.__is_black_ = false;
+
+ a.__parent_ = &b;
+ a.__left_ = 0;
+ a.__right_ = 0;
+ a.__is_black_ = true;
+
+ c.__parent_ = &b;
+ c.__left_ = 0;
+ c.__right_ = 0;
+ c.__is_black_ = true;
+
+ e.__parent_ = &f;
+ e.__left_ = 0;
+ e.__right_ = 0;
+ e.__is_black_ = true;
+
+ g.__parent_ = &f;
+ g.__left_ = 0;
+ g.__right_ = &h;
+ g.__is_black_ = true;
+
+ h.__parent_ = &g;
+ h.__left_ = 0;
+ h.__right_ = 0;
+ h.__is_black_ = false;
+
+ assert(std::__tree_invariant(root.__left_));
+
+ std::__tree_remove(root.__left_, &a);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &d);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(d.__parent_ == &root);
+ assert(d.__left_ == &b);
+ assert(d.__right_ == &f);
+ assert(d.__is_black_ == true);
+
+ assert(b.__parent_ == &d);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == &c);
+ assert(b.__is_black_ == true);
+
+ assert(f.__parent_ == &d);
+ assert(f.__left_ == &e);
+ assert(f.__right_ == &g);
+ assert(f.__is_black_ == false);
+
+ assert(c.__parent_ == &b);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == false);
+
+ assert(e.__parent_ == &f);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == true);
+
+ assert(g.__parent_ == &f);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &b);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &d);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(d.__parent_ == &root);
+ assert(d.__left_ == &c);
+ assert(d.__right_ == &f);
+ assert(d.__is_black_ == true);
+
+ assert(c.__parent_ == &d);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+ assert(c.__is_black_ == true);
+
+ assert(f.__parent_ == &d);
+ assert(f.__left_ == &e);
+ assert(f.__right_ == &g);
+ assert(f.__is_black_ == false);
+
+ assert(e.__parent_ == &f);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == true);
+
+ assert(g.__parent_ == &f);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &c);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &f);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(f.__parent_ == &root);
+ assert(f.__left_ == &d);
+ assert(f.__right_ == &g);
+ assert(f.__is_black_ == true);
+
+ assert(d.__parent_ == &f);
+ assert(d.__left_ == 0);
+ assert(d.__right_ == &e);
+ assert(d.__is_black_ == true);
+
+ assert(g.__parent_ == &f);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(e.__parent_ == &d);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == false);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &d);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &f);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(f.__parent_ == &root);
+ assert(f.__left_ == &e);
+ assert(f.__right_ == &g);
+ assert(f.__is_black_ == true);
+
+ assert(e.__parent_ == &f);
+ assert(e.__left_ == 0);
+ assert(e.__right_ == 0);
+ assert(e.__is_black_ == true);
+
+ assert(g.__parent_ == &f);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &e);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &g);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(g.__parent_ == &root);
+ assert(g.__left_ == &f);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(f.__parent_ == &g);
+ assert(f.__left_ == 0);
+ assert(f.__right_ == 0);
+ assert(f.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &f);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &g);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(g.__parent_ == &root);
+ assert(g.__left_ == 0);
+ assert(g.__right_ == &h);
+ assert(g.__is_black_ == true);
+
+ assert(h.__parent_ == &g);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == false);
+
+ std::__tree_remove(root.__left_, &g);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &h);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+
+ assert(h.__parent_ == &root);
+ assert(h.__left_ == 0);
+ assert(h.__right_ == 0);
+ assert(h.__is_black_ == true);
+
+ std::__tree_remove(root.__left_, &h);
+
+ assert(std::__tree_invariant(root.__left_));
+
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == 0);
+ assert(root.__right_ == 0);
+ assert(root.__is_black_ == false);
+}
+
+int main(int, char**) {
+ test1();
+ test2();
+ test3();
+ test4();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/tree_right_rotate.pass.cpp b/libcxx/test/libcxx-03/containers/associative/tree_right_rotate.pass.cpp
new file mode 100644
index 0000000000000..b86446f5be101
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/tree_right_rotate.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// Not a portable test
+
+// Precondition: __x->__left_ != nullptr
+// template <class _NodePtr>
+// void
+// __tree_right_rotate(_NodePtr __x);
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__tree>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct Node {
+ Node* __left_;
+ Node* __right_;
+ Node* __parent_;
+
+ Node* __parent_unsafe() const { return __parent_; }
+ void __set_parent(Node* x) { __parent_ = x; }
+
+ Node() : __left_(), __right_(), __parent_() {}
+};
+
+void test1() {
+ Node root;
+ Node x;
+ Node y;
+ root.__left_ = &x;
+ x.__left_ = &y;
+ x.__right_ = 0;
+ x.__parent_ = &root;
+ y.__left_ = 0;
+ y.__right_ = 0;
+ y.__parent_ = &x;
+ std::__tree_right_rotate(&x);
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &y);
+ assert(root.__right_ == 0);
+ assert(y.__parent_ == &root);
+ assert(y.__left_ == 0);
+ assert(y.__right_ == &x);
+ assert(x.__parent_ == &y);
+ assert(x.__left_ == 0);
+ assert(x.__right_ == 0);
+}
+
+void test2() {
+ Node root;
+ Node x;
+ Node y;
+ Node a;
+ Node b;
+ Node c;
+ root.__left_ = &x;
+ x.__left_ = &y;
+ x.__right_ = &c;
+ x.__parent_ = &root;
+ y.__left_ = &a;
+ y.__right_ = &b;
+ y.__parent_ = &x;
+ a.__parent_ = &y;
+ b.__parent_ = &y;
+ c.__parent_ = &x;
+ std::__tree_right_rotate(&x);
+ assert(root.__parent_ == 0);
+ assert(root.__left_ == &y);
+ assert(root.__right_ == 0);
+ assert(y.__parent_ == &root);
+ assert(y.__left_ == &a);
+ assert(y.__right_ == &x);
+ assert(x.__parent_ == &y);
+ assert(x.__left_ == &b);
+ assert(x.__right_ == &c);
+ assert(a.__parent_ == &y);
+ assert(a.__left_ == 0);
+ assert(a.__right_ == 0);
+ assert(b.__parent_ == &x);
+ assert(b.__left_ == 0);
+ assert(b.__right_ == 0);
+ assert(c.__parent_ == &x);
+ assert(c.__left_ == 0);
+ assert(c.__right_ == 0);
+}
+
+int main(int, char**) {
+ test1();
+ test2();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/unord.map/abi.compile.pass.cpp b/libcxx/test/libcxx-03/containers/associative/unord.map/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..55d42a8d017e1
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/unord.map/abi.compile.pass.cpp
@@ -0,0 +1,141 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-abi-fix-unordered-container-size-type, libcpp-abi-no-compressed-pair-padding
+
+// std::unique_ptr is used as an implementation detail of the unordered containers, so the layout of
+// unordered containers changes when bounded unique_ptr is enabled.
+// UNSUPPORTED: libcpp-has-abi-bounded-unique_ptr
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <cstdint>
+#include <unordered_map>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::uint16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+template <class T>
+class final_small_iter_allocator final {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::uint16_t;
+ using difference_type = std::int16_t;
+
+ final_small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
+ friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
+};
+
+template <class T, class Alloc>
+using unordered_map_alloc = std::unordered_map<T, T, std::hash<T>, std::equal_to<T>, Alloc>;
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 16, "");
+
+static_assert(sizeof(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 40, "");
+static_assert(sizeof(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 64, "");
+static_assert(sizeof(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
+ "");
+
+struct TEST_ALIGNAS(32) AlignedHash {};
+struct UnalignedEqualTo {};
+
+// This part of the ABI has been broken between LLVM 19 and LLVM 20.
+static_assert(sizeof(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 64, "");
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 32, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 20, "");
+static_assert(sizeof(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 20, "");
+static_assert(sizeof(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 44, "");
+static_assert(sizeof(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 16, "");
+
+static_assert(sizeof(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 20, "");
+static_assert(sizeof(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 20, "");
+static_assert(sizeof(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 44, "");
+static_assert(sizeof(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 12, "");
+static_assert(sizeof(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, std::allocator<std::pair<const int, int> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, min_allocator<std::pair<const int, int> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, test_allocator<std::pair<const int, int> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<int, final_small_iter_allocator<std::pair<const int, int> > >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, std::allocator<std::pair<const char, char> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, min_allocator<std::pair<const char, char> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, test_allocator<std::pair<const char, char> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, small_iter_allocator<std::pair<const char, char> > >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_map_alloc<char, final_small_iter_allocator<std::pair<const char, char> > >) == 4,
+ "");
+
+struct TEST_ALIGNAS(32) AlignedHash {};
+struct UnalignedEqualTo {};
+
+static_assert(sizeof(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 64);
+static_assert(TEST_ALIGNOF(std::unordered_map<int, int, AlignedHash, UnalignedEqualTo>) == 32);
+
+#else
+# error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx-03/containers/associative/unord.map/scary.compile.pass.cpp b/libcxx/test/libcxx-03/containers/associative/unord.map/scary.compile.pass.cpp
new file mode 100644
index 0000000000000..db2ef33b6ebf8
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/unord.map/scary.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// class unordered_map
+// class unordered_multimap
+
+// Extension: SCARY/N2913 iterator compatibility between unordered_map and unordered_multimap
+
+#include <unordered_map>
+
+#include "test_macros.h"
+
+void test() {
+ typedef std::unordered_map<int, int> M1;
+ typedef std::unordered_multimap<int, int> M2;
+
+ ASSERT_SAME_TYPE(M1::iterator, M2::iterator);
+ ASSERT_SAME_TYPE(M1::const_iterator, M2::const_iterator);
+ ASSERT_SAME_TYPE(M1::local_iterator, M2::local_iterator);
+ ASSERT_SAME_TYPE(M1::const_local_iterator, M2::const_local_iterator);
+}
diff --git a/libcxx/test/libcxx-03/containers/associative/unord.set/abi.compile.pass.cpp b/libcxx/test/libcxx-03/containers/associative/unord.set/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..bee2012bbea29
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/unord.set/abi.compile.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: libcpp-has-abi-fix-unordered-container-size-type, libcpp-abi-no-compressed-pair-padding
+
+// std::unique_ptr is used as an implementation detail of the unordered containers, so the layout of
+// unordered containers changes when bounded unique_ptr is enabled.
+// UNSUPPORTED: libcpp-has-abi-bounded-unique_ptr
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <cstdint>
+#include <unordered_set>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::uint16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+template <class T>
+class final_small_iter_allocator final {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::uint16_t;
+ using difference_type = std::int16_t;
+
+ final_small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
+ friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
+};
+
+template <class T, class Alloc>
+using unordered_set_alloc = std::unordered_set<T, std::hash<T>, std::equal_to<T>, Alloc>;
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(unordered_set_alloc<int, std::allocator<int> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<int, min_allocator<int> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<int, test_allocator<int> >) == 64, "");
+static_assert(sizeof(unordered_set_alloc<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 16, "");
+
+static_assert(sizeof(unordered_set_alloc<char, std::allocator<char> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<char, min_allocator<char> >) == 40, "");
+static_assert(sizeof(unordered_set_alloc<char, test_allocator<char> >) == 64, "");
+static_assert(sizeof(unordered_set_alloc<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, std::allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, small_iter_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, std::allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, small_iter_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 4, "");
+
+struct TEST_ALIGNAS(32) AlignedHash {};
+struct UnalignedEqualTo {};
+
+// This part of the ABI has been broken between LLVM 19 and LLVM 20.
+static_assert(sizeof(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 64, "");
+static_assert(TEST_ALIGNOF(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 32, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(unordered_set_alloc<int, std::allocator<int> >) == 20, "");
+static_assert(sizeof(unordered_set_alloc<int, min_allocator<int> >) == 20, "");
+static_assert(sizeof(unordered_set_alloc<int, test_allocator<int> >) == 44, "");
+static_assert(sizeof(unordered_set_alloc<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 16, "");
+
+static_assert(sizeof(unordered_set_alloc<char, std::allocator<char> >) == 20, "");
+static_assert(sizeof(unordered_set_alloc<char, min_allocator<char> >) == 20, "");
+static_assert(sizeof(unordered_set_alloc<char, test_allocator<char> >) == 44, "");
+static_assert(sizeof(unordered_set_alloc<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 16, "");
+
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, std::allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, min_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, test_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, small_iter_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<int, final_small_iter_allocator<int> >) == 4, "");
+
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, std::allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, min_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, test_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, small_iter_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(unordered_set_alloc<char, final_small_iter_allocator<char> >) == 4, "");
+
+struct TEST_ALIGNAS(32) AlignedHash {};
+struct UnalignedEqualTo {};
+
+static_assert(sizeof(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 64);
+static_assert(TEST_ALIGNOF(std::unordered_set<int, AlignedHash, UnalignedEqualTo>) == 32);
+
+#else
+# error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx-03/containers/associative/unord.set/scary.compile.pass.cpp b/libcxx/test/libcxx-03/containers/associative/unord.set/scary.compile.pass.cpp
new file mode 100644
index 0000000000000..cd33e1a91ec16
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/associative/unord.set/scary.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// class unordered_set
+// class unordered_multiset
+
+// Extension: SCARY/N2913 iterator compatibility between unordered_set and unordered_multiset
+
+#include <unordered_set>
+
+#include "test_macros.h"
+
+void test() {
+ typedef std::unordered_set<int> M1;
+ typedef std::unordered_multiset<int> M2;
+
+ ASSERT_SAME_TYPE(M1::iterator, M2::iterator);
+ ASSERT_SAME_TYPE(M1::const_iterator, M2::const_iterator);
+ ASSERT_SAME_TYPE(M1::local_iterator, M2::local_iterator);
+ ASSERT_SAME_TYPE(M1::const_local_iterator, M2::const_local_iterator);
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.input_range.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.input_range.pass.cpp
new file mode 100644
index 0000000000000..2db803b53441f
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.input_range.pass.cpp
@@ -0,0 +1,66 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <flat_map>
+
+// flat_map(key_container_type , mapped_container_type , const key_compare& __comp = key_compare())
+// flat_map(const key_container_type& , const mapped_container_type& , const _Allocator& )
+// flat_map(const key_container_type& , const mapped_container_type& , const key_compare&, const _Allocator& )
+// void replace(key_container_type&& , mapped_container_type&&)
+//
+
+#include <flat_map>
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ using M = std::flat_map<int, int>;
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m({1, 2, 3}, {4}); }()), "flat_map keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m({1, 2, 3}, {4}, std::less<int>{}); }()), "flat_map keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{1, 2, 3};
+ const std::vector values{4};
+ const std::allocator<int> alloc{};
+ M m(keys, values, alloc);
+ }()),
+ "flat_map keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{1, 2, 3};
+ const std::vector values{4};
+ const std::less<int> key_compare{};
+ const std::allocator<int> alloc{};
+ M m(keys, values, key_compare, alloc);
+ }()),
+ "flat_map keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::vector keys{1, 2, 3};
+ std::vector values{4};
+ M m;
+ m.replace(std::move(keys), std::move(values));
+ }()),
+ "flat_map keys and mapped containers have different size");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.sorted_unique.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.sorted_unique.pass.cpp
new file mode 100644
index 0000000000000..e6bd3f385af9c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/assert.sorted_unique.pass.cpp
@@ -0,0 +1,225 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// REQUIRES: libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <flat_map>
+
+// flat_map(key_container_type , mapped_container_type , const key_compare& __comp = key_compare())
+// flat_map(const key_container_type& , const mapped_container_type& , const _Allocator& )
+// flat_map(const key_container_type& , const mapped_container_type& , const key_compare&, const _Allocator& )
+// void replace(key_container_type&& , mapped_container_type&&)
+//
+
+#include <flat_map>
+#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ using M = std::flat_map<int, int>;
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {2, 2, 3}, {4, 5, 6}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {4, 2, 3}, {4, 5, 6}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {2, 2, 3}, {4, 5, 6}, std::less<int>{}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {4, 2, 3}, {4, 5, 6}, std::less<int>{}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{2, 2, 3};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, keys, values, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, keys, values, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{2, 2, 3};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, keys, values, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, keys, values, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v, comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v, comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ M m;
+ m.insert(std::sorted_unique, v.begin(), v.end());
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ M m;
+ m.insert(std::sorted_unique, v.begin(), v.end());
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {3, 6}};
+ M m;
+ m.insert(std::sorted_unique, v);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ M m;
+ m.insert(std::sorted_unique, v);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::vector keys{1, 1, 3};
+ std::vector values{4, 5, 6};
+ M m;
+ m.replace(std::move(keys), std::move(values));
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/scary.compile.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/scary.compile.pass.cpp
new file mode 100644
index 0000000000000..3fff89cd90acf
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.map/scary.compile.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <flat_map>
+
+// class flat_map
+// class flat_multimap
+
+// Extension: SCARY/N2913 iterator compatibility between flat_map and flat_multimap
+// Test for the absence of this feature
+
+#include <flat_map>
+#include <type_traits>
+
+#include "test_macros.h"
+
+void test() {
+ typedef std::flat_map<int, int> M1;
+ typedef std::flat_multimap<int, int> M2;
+
+ static_assert(!std::is_convertible_v<M1::iterator, M2::iterator>);
+ static_assert(!std::is_convertible_v<M2::iterator, M1::iterator>);
+
+ static_assert(!std::is_convertible_v<M1::const_iterator, M2::const_iterator>);
+ static_assert(!std::is_convertible_v<M2::const_iterator, M1::const_iterator>);
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.input_range.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.input_range.pass.cpp
new file mode 100644
index 0000000000000..504f36fcd00b8
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.input_range.pass.cpp
@@ -0,0 +1,66 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <flat_map>
+
+// flat_multimap(key_container_type , mapped_container_type , const key_compare& __comp = key_compare())
+// flat_multimap(const key_container_type& , const mapped_container_type& , const _Allocator& )
+// flat_multimap(const key_container_type& , const mapped_container_type& , const key_compare&, const _Allocator& )
+// void replace(key_container_type&& , mapped_container_type&&)
+//
+
+#include <flat_map>
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ using M = std::flat_multimap<int, int>;
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m({1, 2, 3}, {4}); }()), "flat_multimap keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m({1, 2, 3}, {4}, std::less<int>{}); }()),
+ "flat_multimap keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{1, 2, 3};
+ const std::vector values{4};
+ const std::allocator<int> alloc{};
+ M m(keys, values, alloc);
+ }()),
+ "flat_multimap keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{1, 2, 3};
+ const std::vector values{4};
+ const std::less<int> key_compare{};
+ const std::allocator<int> alloc{};
+ M m(keys, values, key_compare, alloc);
+ }()),
+ "flat_multimap keys and mapped containers have different size");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::vector keys{1, 2, 3};
+ std::vector values{4};
+ M m;
+ m.replace(std::move(keys), std::move(values));
+ }()),
+ "flat_multimap keys and mapped containers have different size");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.sorted_equivalent.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.sorted_equivalent.pass.cpp
new file mode 100644
index 0000000000000..6b8ad3c7ac9aa
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multimap/assert.sorted_equivalent.pass.cpp
@@ -0,0 +1,225 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// REQUIRES: libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <flat_map>
+
+// flat_multimap(key_container_type , mapped_container_type , const key_compare& __comp = key_compare())
+// flat_multimap(const key_container_type& , const mapped_container_type& , const _Allocator& )
+// flat_multimap(const key_container_type& , const mapped_container_type& , const key_compare&, const _Allocator& )
+// void replace(key_container_type&& , mapped_container_type&&)
+//
+
+#include <flat_map>
+#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ using M = std::flat_multimap<int, int>;
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m(std::sorted_equivalent, {2, 2, 1}, {4, 5, 6}); }()), "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m(std::sorted_equivalent, {4, 2, 3}, {4, 5, 6}); }()), "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m(std::sorted_equivalent, {2, 2, 1}, {4, 5, 6}, std::less<int>{}); }()), "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m(std::sorted_equivalent, {4, 2, 3}, {4, 5, 6}, std::less<int>{}); }()), "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{2, 2, 1};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, keys, values, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, keys, values, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{2, 2, 1};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, keys, values, comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::vector values{4, 5, 6};
+ const std::allocator<int> alloc{};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, keys, values, comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), comp);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), comp);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, v, comp);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, v, comp);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v, comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v, comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ M m;
+ m.insert(std::sorted_equivalent, v.begin(), v.end());
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ M m;
+ m.insert(std::sorted_equivalent, v.begin(), v.end());
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{2, 4}, {2, 5}, {1, 6}};
+ M m;
+ m.insert(std::sorted_equivalent, v);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<std::pair<int, int>> v{{4, 4}, {2, 5}, {3, 6}};
+ M m;
+ m.insert(std::sorted_equivalent, v);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::vector keys{2, 1, 3};
+ std::vector values{4, 5, 6};
+ M m;
+ m.replace(std::move(keys), std::move(values));
+ }()),
+ "Key container is not sorted");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/assert.sorted_unique.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/assert.sorted_unique.pass.cpp
new file mode 100644
index 0000000000000..54b07baaff27a
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/assert.sorted_unique.pass.cpp
@@ -0,0 +1,131 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// REQUIRES: libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <flat_set>
+
+// flat_multiset(container_type , const key_compare& __comp = key_compare())
+// flat_multiset(const container_type& , const _Allocator& )
+// flat_multiset(const container_type& , const key_compare&, const _Allocator& )
+// void replace(container_type&& )
+//
+
+#include <flat_set>
+#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ using M = std::flat_multiset<int>;
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_equivalent, {4, 2, 3}); }()), "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] { M m(std::sorted_equivalent, {4, 2, 3}, std::less<int>{}); }()), "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, keys, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::allocator<int> alloc{};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, keys, comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), comp);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v.begin(), v.end(), alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ M m(std::sorted_equivalent, v, comp);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v, comp, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_equivalent, v, alloc);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ M m;
+ m.insert(std::sorted_equivalent, v.begin(), v.end());
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ M m;
+ m.insert(std::sorted_equivalent, v);
+ }()),
+ "Key container is not sorted");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::vector keys{2, 1, 3};
+ M m;
+ m.replace(std::move(keys));
+ }()),
+ "Key container is not sorted");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert.temporary.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert.temporary.pass.cpp
new file mode 100644
index 0000000000000..c185d0c700ed2
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert.temporary.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, c++20
+
+// <flat_set>
+
+// https://github.com/llvm/llvm-project/issues/119016
+
+#include <flat_set>
+
+#include <cassert>
+#include <utility>
+#include <vector>
+
+#include "../flat_helpers.h"
+#include "test_macros.h"
+
+bool test() {
+ using M = std::flat_multiset<TrackCopyMove>;
+ {
+ M m;
+ TrackCopyMove t;
+ m.insert(t);
+ assert(m.begin()->copy_count == 1);
+ assert(m.begin()->move_count == 0);
+ }
+ {
+ M m;
+ TrackCopyMove t;
+ m.emplace(t);
+ assert(m.begin()->copy_count == 1);
+ assert(m.begin()->move_count == 0);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert_range.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert_range.pass.cpp
new file mode 100644
index 0000000000000..d69b05a4dee5d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/insert_range.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-localization
+
+// <flat_set>
+
+// As an extension, libc++ flat containers support inserting a non forward range into
+// a pre-C++23 container that doesn't provide insert_range(...), since many containers
+// out there are in that situation.
+// https://github.com/llvm/llvm-project/issues/136656
+
+#include <algorithm>
+#include <cassert>
+#include <flat_set>
+#include <ranges>
+#include <sstream>
+#include <vector>
+
+#include "../flat_helpers.h"
+#include "test_macros.h"
+
+void test() {
+ NotQuiteSequenceContainer<int> v;
+ std::flat_multiset s(v);
+ std::istringstream ints("0 1 1 0");
+ auto r = std::ranges::subrange(std::istream_iterator<int>(ints), std::istream_iterator<int>()) |
+ std::views::transform([](int i) { return i * i; });
+ static_assert(
+  { return requires { t.insert_range(t.end(), r); }; }(v),
+ "This test is to test the case where the underlying container does not provide insert_range");
+ s.insert_range(r);
+ assert(std::ranges::equal(s, std::vector<int>{0, 0, 1, 1}));
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/iterator.compile.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..0954e42e52001
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.multiset/iterator.compile.pass.cpp
@@ -0,0 +1,42 @@
+//
+// 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
+
+// <flat_set>
+
+// test that iterators from different types of flat_multiset are not compatible
+
+#include <deque>
+#include <functional>
+#include <flat_set>
+#include <type_traits>
+
+using Iter1 = std::flat_multiset<int>::iterator;
+using Iter2 = std::flat_multiset<double>::iterator;
+using Iter3 = std::flat_multiset<int, std::greater<>>::iterator;
+using Iter4 = std::flat_multiset<int, std::less<int>, std::deque<int>>::iterator;
+
+static_assert(std::is_convertible_v<Iter1, Iter1>);
+static_assert(!std::is_convertible_v<Iter1, Iter2>);
+static_assert(!std::is_convertible_v<Iter1, Iter3>);
+static_assert(!std::is_convertible_v<Iter1, Iter4>);
+
+static_assert(!std::is_convertible_v<Iter2, Iter1>);
+static_assert(std::is_convertible_v<Iter2, Iter2>);
+static_assert(!std::is_convertible_v<Iter2, Iter3>);
+static_assert(!std::is_convertible_v<Iter2, Iter4>);
+
+static_assert(!std::is_convertible_v<Iter3, Iter1>);
+static_assert(!std::is_convertible_v<Iter3, Iter2>);
+static_assert(std::is_convertible_v<Iter3, Iter3>);
+static_assert(!std::is_convertible_v<Iter3, Iter4>);
+
+static_assert(!std::is_convertible_v<Iter4, Iter1>);
+static_assert(!std::is_convertible_v<Iter4, Iter2>);
+static_assert(!std::is_convertible_v<Iter4, Iter3>);
+static_assert(std::is_convertible_v<Iter4, Iter4>);
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/assert.sorted_unique.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/assert.sorted_unique.pass.cpp
new file mode 100644
index 0000000000000..62903af7f4e47
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/assert.sorted_unique.pass.cpp
@@ -0,0 +1,226 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// REQUIRES: libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <flat_set>
+
+// flat_set(container_type , const key_compare& __comp = key_compare())
+// flat_set(const container_type& , const _Allocator& )
+// flat_set(const container_type& , const key_compare&, const _Allocator& )
+// void replace(container_type&& )
+//
+
+#include <flat_set>
+#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ using M = std::flat_set<int>;
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {2, 2, 3}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {4, 2, 3}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {2, 2, 3}, std::less<int>{}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {4, 2, 3}, std::less<int>{}); }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{2, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, keys, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, keys, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{2, 2, 3};
+ const std::allocator<int> alloc{};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, keys, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector keys{4, 2, 3};
+ const std::allocator<int> alloc{};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, keys, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{2, 2, 3};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{2, 2, 3};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{2, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v.begin(), v.end(), alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{2, 2, 3};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v, comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ M m(std::sorted_unique, v, comp);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{2, 2, 3};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ const std::less<int> comp{};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, comp, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{2, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ const std::allocator<int> alloc{};
+ M m(std::sorted_unique, v, alloc);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{2, 2, 3};
+ M m;
+ m.insert(std::sorted_unique, v.begin(), v.end());
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ const std::vector<int> v{4, 2, 3};
+ M m;
+ m.insert(std::sorted_unique, v.begin(), v.end());
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{2, 2, 3};
+ M m;
+ m.insert(std::sorted_unique, v);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::initializer_list<int> v{4, 2, 3};
+ M m;
+ m.insert(std::sorted_unique, v);
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::vector keys{1, 1, 3};
+ M m;
+ m.replace(std::move(keys));
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([] {
+ std::vector keys{2, 1, 3};
+ M m;
+ m.replace(std::move(keys));
+ }()),
+ "Either the key container is not sorted or it contains duplicates");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert.temporary.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert.temporary.pass.cpp
new file mode 100644
index 0000000000000..e71f35129ddac
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert.temporary.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, c++20
+
+// <flat_set>
+
+// https://github.com/llvm/llvm-project/issues/119016
+
+#include <flat_set>
+
+#include <cassert>
+#include <utility>
+#include <vector>
+
+#include "../flat_helpers.h"
+#include "test_macros.h"
+
+bool test() {
+ using M = std::flat_set<TrackCopyMove>;
+ {
+ M m;
+ TrackCopyMove t;
+ m.insert(t);
+ assert(m.begin()->copy_count == 1);
+ assert(m.begin()->move_count == 0);
+ }
+ {
+ M m;
+ TrackCopyMove t;
+ m.emplace(t);
+ assert(m.begin()->copy_count == 1);
+ assert(m.begin()->move_count == 0);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert_range.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert_range.pass.cpp
new file mode 100644
index 0000000000000..35b9737e85106
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/insert_range.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-localization
+
+// <flat_set>
+
+// As an extension, libc++ flat containers support inserting a non forward range into
+// a pre-C++23 container that doesn't provide insert_range(...), since many containers
+// out there are in that situation.
+// https://github.com/llvm/llvm-project/issues/136656
+
+#include <algorithm>
+#include <cassert>
+#include <flat_set>
+#include <ranges>
+#include <sstream>
+#include <vector>
+
+#include "../flat_helpers.h"
+#include "test_macros.h"
+
+void test() {
+ NotQuiteSequenceContainer<int> v;
+ std::flat_set s(v);
+ std::istringstream ints("0 1 1 0");
+ auto r = std::ranges::subrange(std::istream_iterator<int>(ints), std::istream_iterator<int>()) |
+ std::views::transform([](int i) { return i * i; });
+ static_assert(
+  { return requires { t.insert_range(t.end(), r); }; }(v),
+ "This test is to test the case where the underlying container does not provide insert_range");
+ s.insert_range(r);
+ assert(std::ranges::equal(s, std::vector<int>{0, 1}));
+}
+
+int main(int, char**) {
+ test();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/iterator.compile.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..f2b3f1a529787
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/iterator.compile.pass.cpp
@@ -0,0 +1,42 @@
+//
+// 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
+
+// <flat_set>
+
+// test that iterators from different types of flat_set are not compatible
+
+#include <deque>
+#include <functional>
+#include <flat_set>
+#include <type_traits>
+
+using Iter1 = std::flat_set<int>::iterator;
+using Iter2 = std::flat_set<double>::iterator;
+using Iter3 = std::flat_set<int, std::greater<>>::iterator;
+using Iter4 = std::flat_set<int, std::less<int>, std::deque<int>>::iterator;
+
+static_assert(std::is_convertible_v<Iter1, Iter1>);
+static_assert(!std::is_convertible_v<Iter1, Iter2>);
+static_assert(!std::is_convertible_v<Iter1, Iter3>);
+static_assert(!std::is_convertible_v<Iter1, Iter4>);
+
+static_assert(!std::is_convertible_v<Iter2, Iter1>);
+static_assert(std::is_convertible_v<Iter2, Iter2>);
+static_assert(!std::is_convertible_v<Iter2, Iter3>);
+static_assert(!std::is_convertible_v<Iter2, Iter4>);
+
+static_assert(!std::is_convertible_v<Iter3, Iter1>);
+static_assert(!std::is_convertible_v<Iter3, Iter2>);
+static_assert(std::is_convertible_v<Iter3, Iter3>);
+static_assert(!std::is_convertible_v<Iter3, Iter4>);
+
+static_assert(!std::is_convertible_v<Iter4, Iter1>);
+static_assert(!std::is_convertible_v<Iter4, Iter2>);
+static_assert(!std::is_convertible_v<Iter4, Iter3>);
+static_assert(std::is_convertible_v<Iter4, Iter4>);
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/scary.compile.pass.cpp b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/scary.compile.pass.cpp
new file mode 100644
index 0000000000000..99e93fc3b08b9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat.set/scary.compile.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <flat_set>
+
+// class flat_set
+// class flat_multiset
+
+// Extension: SCARY/N2913 iterator compatibility between flat_set and flat_multiset
+// Test for the absence of this feature
+
+#include <flat_set>
+#include <type_traits>
+
+#include "test_macros.h"
+
+void test() {
+ typedef std::flat_set<int, int> M1;
+ typedef std::flat_multiset<int, int> M2;
+
+ static_assert(!std::is_convertible_v<M1::iterator, M2::iterator>);
+ static_assert(!std::is_convertible_v<M2::iterator, M1::iterator>);
+
+ static_assert(!std::is_convertible_v<M1::const_iterator, M2::const_iterator>);
+ static_assert(!std::is_convertible_v<M2::const_iterator, M1::const_iterator>);
+}
diff --git a/libcxx/test/libcxx-03/containers/container.adaptors/flat_helpers.h b/libcxx/test/libcxx-03/containers/container.adaptors/flat_helpers.h
new file mode 100644
index 0000000000000..cc59f59cc4ecc
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container.adaptors/flat_helpers.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_LIBCXX_CONTAINERS_CONTAINER_ADAPTORS_FLAT_HELPERS_H
+#define TEST_LIBCXX_CONTAINERS_CONTAINER_ADAPTORS_FLAT_HELPERS_H
+
+#include <vector>
+
+struct TrackCopyMove {
+ mutable int copy_count = 0;
+ int move_count = 0;
+
+ constexpr TrackCopyMove() = default;
+ constexpr TrackCopyMove(const TrackCopyMove& other) : copy_count(other.copy_count), move_count(other.move_count) {
+ ++copy_count;
+ ++other.copy_count;
+ }
+
+ constexpr TrackCopyMove(TrackCopyMove&& other) noexcept : copy_count(other.copy_count), move_count(other.move_count) {
+ ++move_count;
+ ++other.move_count;
+ }
+ constexpr TrackCopyMove& operator=(const TrackCopyMove& other) {
+ ++copy_count;
+ ++other.copy_count;
+ return *this;
+ }
+ constexpr TrackCopyMove& operator=(TrackCopyMove&& other) noexcept {
+ ++move_count;
+ ++other.move_count;
+ return *this;
+ }
+ constexpr bool operator==(const TrackCopyMove&) const { return true; }
+ constexpr bool operator<(const TrackCopyMove&) const { return false; }
+};
+
+template <class T>
+struct NotQuiteSequenceContainer : std::vector<T> {
+ // hide the name insert_range
+ void insert_range() = delete;
+};
+
+#endif // TEST_LIBCXX_CONTAINERS_CONTAINER_ADAPTORS_FLAT_HELPERS_H
diff --git a/libcxx/test/libcxx-03/containers/container_traits.compile.pass.cpp b/libcxx/test/libcxx-03/containers/container_traits.compile.pass.cpp
new file mode 100644
index 0000000000000..22be217487951
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/container_traits.compile.pass.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// <__type_traits/container_traits.h>
+//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__type_traits/container_traits.h>
+
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <vector>
+#include <map>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "test_allocator.h"
+#include "test_macros.h"
+#include "MoveOnly.h"
+
+struct ThrowOnMove {
+ ThrowOnMove();
+ ThrowOnMove(const ThrowOnMove&) TEST_NOEXCEPT_COND(false);
+ ThrowOnMove(ThrowOnMove&&) TEST_NOEXCEPT_COND(false);
+ ThrowOnMove& operator=(ThrowOnMove&&) TEST_NOEXCEPT_COND(false);
+ ThrowOnMove& operator=(const ThrowOnMove&) TEST_NOEXCEPT_COND(false);
+
+ bool operator<(ThrowOnMove const&) const;
+ bool operator==(ThrowOnMove const&) const;
+};
+
+struct NonCopyThrowOnMove {
+ NonCopyThrowOnMove();
+ NonCopyThrowOnMove(NonCopyThrowOnMove&&) TEST_NOEXCEPT_COND(false);
+ NonCopyThrowOnMove(const NonCopyThrowOnMove&) = delete;
+ NonCopyThrowOnMove& operator=(NonCopyThrowOnMove&&) TEST_NOEXCEPT_COND(false);
+ NonCopyThrowOnMove& operator=(const NonCopyThrowOnMove&) = delete;
+
+ bool operator<(NonCopyThrowOnMove const&) const;
+ bool operator==(NonCopyThrowOnMove const&) const;
+};
+
+struct ThrowingHash {
+ template <class T>
+ std::size_t operator()(const T&) const TEST_NOEXCEPT_COND(false);
+};
+
+struct NoThrowHash {
+ template <class T>
+ std::size_t operator()(const T&) const TEST_NOEXCEPT;
+};
+
+template <bool Expected, class Container>
+void check() {
+ static_assert(
+ std::__container_traits<Container>::__emplacement_has_strong_exception_safety_guarantee == Expected, "");
+}
+
+void test() {
+ check<true, std::list<int> >();
+ check<true, std::list<int, test_allocator<int> > >();
+ check<true, std::list<MoveOnly> >();
+ check<true, std::list<ThrowOnMove> >();
+ check<true, std::list<NonCopyThrowOnMove> >();
+
+ check<true, std::forward_list<int> >();
+ check<true, std::forward_list<int, test_allocator<int> > >();
+ check<true, std::forward_list<MoveOnly> >();
+ check<true, std::forward_list<ThrowOnMove> >();
+ check<true, std::forward_list<NonCopyThrowOnMove> >();
+
+ check<true, std::deque<int> >();
+ check<true, std::deque<int, test_allocator<int> > >();
+ check<true, std::deque<MoveOnly> >();
+ check<true, std::deque<ThrowOnMove> >();
+ check<false, std::deque<NonCopyThrowOnMove> >();
+
+ check<true, std::vector<int> >();
+ check<true, std::vector<int, test_allocator<int> > >();
+ check<true, std::vector<MoveOnly> >();
+ check<true, std::vector<ThrowOnMove> >();
+ check<false, std::vector<NonCopyThrowOnMove> >();
+
+ check<true, std::set<int> >();
+ check<true, std::set<int, std::less<int>, test_allocator<int> > >();
+ check<true, std::set<MoveOnly> >();
+ check<true, std::set<ThrowOnMove> >();
+ check<true, std::set<NonCopyThrowOnMove> >();
+
+ check<true, std::multiset<int> >();
+ check<true, std::multiset<int, std::less<int>, test_allocator<int> > >();
+ check<true, std::multiset<MoveOnly> >();
+ check<true, std::multiset<ThrowOnMove> >();
+ check<true, std::multiset<NonCopyThrowOnMove> >();
+
+ check<true, std::map<int, int> >();
+ check<true, std::map<int, int, std::less<int>, test_allocator<int> > >();
+ check<true, std::map<MoveOnly, MoveOnly> >();
+ check<true, std::map<ThrowOnMove, ThrowOnMove> >();
+ check<true, std::map<NonCopyThrowOnMove, NonCopyThrowOnMove> >();
+
+ check<true, std::multimap<int, int> >();
+ check<true, std::multimap<int, int, std::less<int>, test_allocator<int> > >();
+ check<true, std::multimap<MoveOnly, MoveOnly> >();
+ check<true, std::multimap<ThrowOnMove, ThrowOnMove> >();
+ check<true, std::multimap<NonCopyThrowOnMove, NonCopyThrowOnMove> >();
+
+#if TEST_STD_VER < 11
+ check<false, std::unordered_set<int> >();
+ check<false, std::unordered_set<int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_set<MoveOnly> >();
+ check<false, std::unordered_set<MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_set<MoveOnly, ThrowingHash> >();
+
+ check<false, std::unordered_multiset<int> >();
+ check<false, std::unordered_multiset<int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_multiset<MoveOnly> >();
+ check<false, std::unordered_multiset<MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_multiset<MoveOnly, ThrowingHash> >();
+
+ check<false, std::unordered_map<int, int> >();
+ check<false, std::unordered_map<int, int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_map<MoveOnly, MoveOnly> >();
+ check<false, std::unordered_map<MoveOnly, MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_map<MoveOnly, MoveOnly, ThrowingHash> >();
+
+ check<false, std::unordered_multimap<int, int> >();
+ check<false, std::unordered_multimap<int, int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_multimap<MoveOnly, MoveOnly> >();
+ check<false, std::unordered_multimap<MoveOnly, MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_multimap<MoveOnly, MoveOnly, ThrowingHash> >();
+#else
+ check<true, std::unordered_set<int> >();
+ check<true, std::unordered_set<int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_set<MoveOnly> >();
+ check<true, std::unordered_set<MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_set<MoveOnly, ThrowingHash> >();
+
+ check<true, std::unordered_multiset<int> >();
+ check<true, std::unordered_multiset<int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_multiset<MoveOnly> >();
+ check<true, std::unordered_multiset<MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_multiset<MoveOnly, ThrowingHash> >();
+
+ check<true, std::unordered_map<int, int> >();
+ check<true, std::unordered_map<int, int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_map<MoveOnly, MoveOnly> >();
+ check<true, std::unordered_map<MoveOnly, MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_map<MoveOnly, MoveOnly, ThrowingHash> >();
+
+ check<true, std::unordered_multimap<int, int> >();
+ check<true, std::unordered_multimap<int, int, std::hash<int>, std::less<int>, test_allocator<int> > >();
+ check<false, std::unordered_multimap<MoveOnly, MoveOnly> >();
+ check<true, std::unordered_multimap<MoveOnly, MoveOnly, NoThrowHash> >();
+ check<false, std::unordered_multimap<MoveOnly, MoveOnly, ThrowingHash> >();
+#endif
+}
diff --git a/libcxx/test/libcxx-03/containers/gnu_cxx/hash_map.pass.cpp b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_map.pass.cpp
new file mode 100644
index 0000000000000..a8988f73891a0
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_map.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: clang-modules-build
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+
+#include <ext/hash_map>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.h"
+
+void test_default_does_not_allocate() {
+ DisableAllocationGuard g;
+ ((void)g);
+ {
+ __gnu_cxx::hash_map<int, int> h;
+ assert(h.bucket_count() == 0);
+ }
+ {
+ __gnu_cxx::hash_multimap<int, int> h;
+ assert(h.bucket_count() == 0);
+ }
+}
+
+int main(int, char**) {
+ test_default_does_not_allocate();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/gnu_cxx/hash_map_name_lookup.pass.cpp b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_map_name_lookup.pass.cpp
new file mode 100644
index 0000000000000..7e87330ef855d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_map_name_lookup.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: clang-modules-build
+
+// Poison the std:: names we might use inside __gnu_cxx to ensure they're
+// properly qualified.
+struct allocator;
+struct pair;
+struct equal_to;
+struct unique_ptr;
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+
+#include <ext/hash_map>
+
+#include "test_macros.h"
+
+namespace __gnu_cxx {
+template class hash_map<int, int>;
+}
+
+int main(int, char**) {
+ typedef __gnu_cxx::hash_map<int, int> Map;
+ Map m;
+ Map m2(m);
+ ((void)m2);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/gnu_cxx/hash_set.pass.cpp b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_set.pass.cpp
new file mode 100644
index 0000000000000..c325914bd4221
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_set.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: clang-modules-build
+
+// Prevent <ext/hash_set> from generating deprecated warnings for this test.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+
+#include <ext/hash_set>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.h"
+
+void test_default_does_not_allocate() {
+ DisableAllocationGuard g;
+ ((void)g);
+ {
+ __gnu_cxx::hash_set<int> h;
+ assert(h.bucket_count() == 0);
+ }
+ {
+ __gnu_cxx::hash_multiset<int> h;
+ assert(h.bucket_count() == 0);
+ }
+}
+
+int main(int, char**) {
+ test_default_does_not_allocate();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/gnu_cxx/hash_set_name_lookup.pass.cpp b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_set_name_lookup.pass.cpp
new file mode 100644
index 0000000000000..c5f64a4b820d5
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/gnu_cxx/hash_set_name_lookup.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: clang-modules-build
+
+// Poison the std:: names we might use inside __gnu_cxx to ensure they're
+// properly qualified.
+struct allocator;
+struct pair;
+struct equal_to;
+struct unique_ptr;
+
+// Prevent <ext/hash_set> from generating deprecated warnings for this test.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+
+#include <ext/hash_set>
+
+#include "test_macros.h"
+
+namespace __gnu_cxx {
+template class hash_set<int>;
+}
+
+int main(int, char**) {
+ typedef __gnu_cxx::hash_set<int> Set;
+ Set s;
+ Set s2(s);
+ ((void)s2);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/array/triviality.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/array/triviality.pass.cpp
new file mode 100644
index 0000000000000..8b0f5a391eb32
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/array/triviality.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure std::array<T, N> is trivially copyable whenever T is trivially copyable.
+// This is not technically mandated by the Standard, but libc++ has been providing
+// this property.
+
+#include <array>
+#include <type_traits>
+
+struct Empty {};
+
+struct TrivialCopy {
+ int i;
+ double j;
+};
+
+struct NonTrivialCopy {
+ NonTrivialCopy(NonTrivialCopy const&) {}
+ NonTrivialCopy& operator=(NonTrivialCopy const&) { return *this; }
+};
+
+template <typename T>
+void check_trivially_copyable() {
+ static_assert(std::is_trivially_copyable<std::array<T, 0> >::value, "");
+ static_assert(std::is_trivially_copyable<std::array<T, 1> >::value, "");
+ static_assert(std::is_trivially_copyable<std::array<T, 2> >::value, "");
+ static_assert(std::is_trivially_copyable<std::array<T, 3> >::value, "");
+}
+
+int main(int, char**) {
+ check_trivially_copyable<int>();
+ check_trivially_copyable<long>();
+ check_trivially_copyable<double>();
+ check_trivially_copyable<long double>();
+ check_trivially_copyable<Empty>();
+ check_trivially_copyable<TrivialCopy>();
+
+ // Check that std::array<T, 0> is still trivially copyable when T is not
+ static_assert(std::is_trivially_copyable<std::array<NonTrivialCopy, 0> >::value, "");
+ static_assert(!std::is_trivially_copyable<std::array<NonTrivialCopy, 1> >::value, "");
+ static_assert(!std::is_trivially_copyable<std::array<NonTrivialCopy, 2> >::value, "");
+ static_assert(!std::is_trivially_copyable<std::array<NonTrivialCopy, 3> >::value, "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/abi.compile.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..30586d8b2422c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/abi.compile.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-abi-no-compressed-pair-padding
+
+#include <cstdint>
+#include <deque>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::uint16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+template <class T>
+class final_small_iter_allocator final {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::uint16_t;
+ using difference_type = std::int16_t;
+
+ final_small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ final_small_iter_allocator(final_small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(final_small_iter_allocator, final_small_iter_allocator) { return true; }
+ friend bool operator!=(final_small_iter_allocator, final_small_iter_allocator) { return false; }
+};
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::deque<int>) == 48, "");
+static_assert(sizeof(std::deque<int, min_allocator<int> >) == 48, "");
+static_assert(sizeof(std::deque<int, test_allocator<int> >) == 80, "");
+static_assert(sizeof(std::deque<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(std::deque<int, final_small_iter_allocator<int> >) == 16, "");
+
+static_assert(sizeof(std::deque<char>) == 48, "");
+static_assert(sizeof(std::deque<char, min_allocator<char> >) == 48, "");
+static_assert(sizeof(std::deque<char, test_allocator<char> >) == 80, "");
+static_assert(sizeof(std::deque<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(std::deque<char, final_small_iter_allocator<char> >) == 16, "");
+
+static_assert(TEST_ALIGNOF(std::deque<int>) == 8, "");
+static_assert(TEST_ALIGNOF(std::deque<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::deque<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::deque<int, small_iter_allocator<int> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<int, final_small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::deque<char>) == 8, "");
+static_assert(TEST_ALIGNOF(std::deque<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::deque<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::deque<char, small_iter_allocator<char> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<char, final_small_iter_allocator<char> >) == 2, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::deque<int>) == 24, "");
+static_assert(sizeof(std::deque<int, min_allocator<int> >) == 24, "");
+static_assert(sizeof(std::deque<int, test_allocator<int> >) == 48, "");
+static_assert(sizeof(std::deque<int, small_iter_allocator<int> >) == 12, "");
+static_assert(sizeof(std::deque<int, final_small_iter_allocator<int> >) == 16, "");
+
+static_assert(sizeof(std::deque<char>) == 24, "");
+static_assert(sizeof(std::deque<char, min_allocator<char> >) == 24, "");
+static_assert(sizeof(std::deque<char, test_allocator<char> >) == 48, "");
+static_assert(sizeof(std::deque<char, small_iter_allocator<char> >) == 12, "");
+static_assert(sizeof(std::deque<char, final_small_iter_allocator<char> >) == 16, "");
+
+static_assert(TEST_ALIGNOF(std::deque<int>) == 4, "");
+static_assert(TEST_ALIGNOF(std::deque<int, min_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::deque<int, test_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::deque<int, small_iter_allocator<int> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<int, final_small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::deque<char>) == 4, "");
+static_assert(TEST_ALIGNOF(std::deque<char, min_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::deque<char, test_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::deque<char, small_iter_allocator<char> >) == 2, "");
+static_assert(TEST_ALIGNOF(std::deque<char, final_small_iter_allocator<char> >) == 2, "");
+
+#else
+# error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/asan.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/asan.pass.cpp
new file mode 100644
index 0000000000000..46ca62dda7b20
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/asan.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: asan
+
+// <deque>
+
+// reference operator[](size_type n);
+
+#include "asan_testing.h"
+#include <deque>
+#include <cassert>
+#include <cstdlib>
+
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
+
+void do_exit() { exit(0); }
+
+int main(int, char**) {
+ {
+ typedef cpp17_input_iterator<int*> MyInputIter;
+ // Should not trigger ASan.
+ std::deque<int> v;
+ int i[] = {42};
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1));
+ assert(v[0] == 42);
+ assert(is_double_ended_contiguous_container_asan_correct(v));
+ }
+ {
+ typedef int T;
+ typedef std::deque<T, min_allocator<T> > C;
+ const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ C c(std::begin(t), std::end(t));
+ assert(is_double_ended_contiguous_container_asan_correct(c));
+ }
+ {
+ typedef char T;
+ typedef std::deque<T, safe_allocator<T> > C;
+ const T t[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+ C c(std::begin(t), std::end(t));
+ c.pop_front();
+ assert(is_double_ended_contiguous_container_asan_correct(c));
+ }
+ __sanitizer_set_death_callback(do_exit);
+ {
+ typedef int T;
+ typedef std::deque<T> C;
+ const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ C c(std::begin(t), std::end(t));
+ assert(is_double_ended_contiguous_container_asan_correct(c));
+ T* ptr = &c[0];
+ for (size_t i = 0; i < (8 + sizeof(T) - 1) / sizeof(T); ++i)
+ c.pop_front();
+ *ptr = 1;
+ volatile T foo = c[c.size()]; // should trigger ASAN. Use volatile to prevent being optimized away.
+ assert(false); // if we got here, ASAN didn't trigger
+ ((void)foo);
+ }
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/asan_caterpillar.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/asan_caterpillar.pass.cpp
new file mode 100644
index 0000000000000..1701b89c72d87
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/asan_caterpillar.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
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// Regression test to error in deque::__annotate_from_to in deque,
+// with origin in deque::__add_back_capacity.
+
+// `check_assertion.h` is only available starting from C++11 and requires Unix headers and regex support.
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-localization
+
+#include <deque>
+#include <cstdio>
+#include "check_assertion.h"
+
+void test1() {
+ std::deque<char> test;
+ char buff[100000];
+ test.insert(test.begin(), buff, buff + 64000);
+
+ for (int i = 0; i < 1100; i += 1) {
+ test.insert(test.begin(), buff, buff + 320);
+ test.erase(test.end() - 320, test.end());
+ }
+
+ test.insert(test.begin(), buff, buff + 32000);
+}
+
+void test2() {
+ std::deque<char> test;
+ char buff[100000];
+ test.insert(test.end(), buff, buff + 64000);
+
+ for (int i = 0; i < 1100; i += 1) {
+ test.insert(test.end(), buff, buff + 320);
+ test.erase(test.begin(), test.begin() + 320);
+ }
+
+ test.insert(test.end(), buff, buff + 32000);
+}
+
+int main(int, char**) {
+ test1();
+ test2();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/asan_turning_off.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/asan_turning_off.pass.cpp
new file mode 100644
index 0000000000000..b31775a873481
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/asan_turning_off.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <deque>
+
+// Test based on: https://bugs.chromium.org/p/chromium/issues/detail?id=1419798#c5
+// Some allocators during deallocation may not call destructors and just reuse memory.
+// In those situations, one may want to deactivate annotations for a specific allocator.
+// It's possible with __asan_annotate_container_with_allocator template class.
+// This test confirms that those allocators work after turning off annotations.
+
+#include <cassert>
+#include <cstddef>
+#include <deque>
+#include <new>
+
+struct reuse_allocator {
+ static size_t const N = 100;
+ reuse_allocator() {
+ for (size_t i = 0; i < N; ++i)
+ __buffers[i] = new char[8 * 1024];
+ }
+ ~reuse_allocator() {
+ for (size_t i = 0; i < N; ++i)
+ delete[] (char*)__buffers[i];
+ }
+ void* alloc() {
+ assert(__next_id < N);
+ return __buffers[__next_id++];
+ }
+ void reset() { __next_id = 0; }
+ void* __buffers[N];
+ size_t __next_id = 0;
+} reuse_buffers;
+
+template <typename T>
+struct user_allocator {
+ using value_type = T;
+ user_allocator() = default;
+ template <class U>
+ user_allocator(user_allocator<U>) {}
+ friend bool operator==(user_allocator, user_allocator) { return true; }
+ friend bool operator!=(user_allocator x, user_allocator y) { return !(x == y); }
+
+ T* allocate(size_t) { return (T*)reuse_buffers.alloc(); }
+ void deallocate(T*, size_t) noexcept {}
+};
+
+#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
+template <class T>
+struct std::__asan_annotate_container_with_allocator<user_allocator<T>> : false_type {};
+#endif
+
+int main(int, char**) {
+ using D = std::deque<int, user_allocator<int>>;
+
+ {
+ D* d = new (reuse_buffers.alloc()) D();
+ for (int i = 0; i < 100; i++)
+ d->push_back(i);
+ }
+ reuse_buffers.reset();
+ {
+ D d;
+ for (int i = 0; i < 1000; i++)
+ d.push_back(i);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/assert.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/assert.pass.cpp
new file mode 100644
index 0000000000000..375a4cdcd58fe
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/assert.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// Test hardening assertions for std::deque.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <deque>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::deque<int> c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "deque::front called on an empty deque");
+ TEST_LIBCPP_ASSERT_FAILURE(c.back(), "deque::back called on an empty deque");
+ TEST_LIBCPP_ASSERT_FAILURE(c[0], "deque::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "deque::pop_front called on an empty deque");
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_back(), "deque::pop_back called on an empty deque");
+
+ // Repeat the test with a const reference to test the const overloads.
+ {
+ const std::deque<int>& cc = c;
+ TEST_LIBCPP_ASSERT_FAILURE(cc.front(), "deque::front called on an empty deque");
+ TEST_LIBCPP_ASSERT_FAILURE(cc.back(), "deque::back called on an empty deque");
+ TEST_LIBCPP_ASSERT_FAILURE(cc[0], "deque::operator[] index out of bounds");
+ }
+
+ c.push_back(1);
+ c.push_back(2);
+ c.push_back(3);
+ TEST_LIBCPP_ASSERT_FAILURE(c[3], "deque::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c[100], "deque::operator[] index out of bounds");
+
+ // Repeat the test with a const reference to test the const overloads.
+ {
+ const std::deque<int>& cc = c;
+ TEST_LIBCPP_ASSERT_FAILURE(cc[3], "deque::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(cc[100], "deque::operator[] index out of bounds");
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(c.erase(c.end()), "deque::erase(iterator) called with a non-dereferenceable iterator");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.erase(c.begin() + 1, c.begin()), "deque::erase(first, last) called with an invalid range");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/assert.pop_back.empty.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/assert.pop_back.empty.pass.cpp
new file mode 100644
index 0000000000000..6bdb117485609
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/assert.pop_back.empty.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
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// pop_back() more than the number of elements in a deque
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <deque>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::deque<int> q;
+ q.push_back(0);
+ q.pop_back();
+ TEST_LIBCPP_ASSERT_FAILURE(q.pop_back(), "deque::pop_back called on an empty deque");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/incomplete.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/incomplete.pass.cpp
new file mode 100644
index 0000000000000..ebf5869078331
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/incomplete.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// deque()
+// deque::iterator()
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
+
+#include <deque>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct A {
+ std::deque<A> d;
+ std::deque<A>::iterator it;
+ std::deque<A>::reverse_iterator it2;
+};
+
+int main(int, char**) {
+ A a;
+ assert(a.d.size() == 0);
+ a.it = a.d.begin();
+ a.it2 = a.d.rend();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/segmented_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/segmented_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..7ae67d8d0252f
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/segmented_iterator.compile.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <deque>
+
+using DequeIterator = typename std::deque<int>::iterator;
+static_assert(std::__is_segmented_iterator<DequeIterator>::value, "");
diff --git a/libcxx/test/libcxx-03/containers/sequences/deque/spare_block_handling.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/deque/spare_block_handling.pass.cpp
new file mode 100644
index 0000000000000..4fa4982de88fa
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/deque/spare_block_handling.pass.cpp
@@ -0,0 +1,288 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <deque>
+
+// Test how deque manages the spare blocks it keeps. The exact values it tests
+// for are not always important, but are sometimes needed to ensure the container
+// resizes or shrinks at the correct time.
+
+#include <deque>
+#include <cassert>
+#include <cstdio>
+#include <memory>
+#include <queue>
+#include <stack>
+#include <string>
+
+#include "min_allocator.h"
+#include "assert_macros.h"
+
+template <class Adaptor>
+struct ContainerAdaptor : public Adaptor {
+ using Adaptor::Adaptor;
+ typename Adaptor::container_type& GetContainer() { return Adaptor::c; }
+};
+
+template <class Deque>
+static void print(const Deque& d) {
+ std::printf(
+ "%zu : __front_spare() == %zu"
+ " : __back_spare() == %zu"
+ " : __capacity() == %zu"
+ " : bytes allocated == %zu\n",
+ d.size(),
+ d.__front_spare(),
+ d.__back_spare(),
+ d.__capacity(),
+ malloc_allocator_base::outstanding_bytes);
+}
+
+template <class T>
+using Deque = std::deque<T, malloc_allocator<T> >;
+
+template <class T>
+using BlockSize = std::__deque_block_size<T, std::ptrdiff_t>;
+
+struct LargeT {
+ LargeT() = default;
+ char buff[256] = {};
+};
+static_assert(BlockSize<LargeT>::value == 16, "");
+
+const auto& AllocBytes = malloc_allocator_base::outstanding_bytes;
+
+template <class Deque>
+struct PrintOnFailure {
+ explicit PrintOnFailure(Deque const& deque) : deque_(&deque) {}
+ void operator()() const { print(*deque_); }
+
+private:
+ const Deque* deque_;
+
+ PrintOnFailure(PrintOnFailure const&) = delete;
+};
+
+static void push_back() {
+ const auto BS = BlockSize<LargeT>::value;
+ std::unique_ptr<Deque<LargeT>> dp(new Deque<LargeT>);
+ auto& d = *dp;
+ PrintOnFailure<Deque<LargeT>> on_fail(d);
+
+ // Test nothing is allocated after default construction.
+ {
+ TEST_REQUIRE(d.size() == 0, on_fail);
+ TEST_REQUIRE(d.__capacity() == 0, on_fail);
+ TEST_REQUIRE(d.__block_count() == 0, on_fail);
+ }
+ // First push back allocates one block.
+ d.push_back({});
+ {
+ TEST_REQUIRE(d.size() == 1, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 14, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__capacity() == BS - 1, on_fail);
+ TEST_REQUIRE(d.__block_count() == 1, on_fail);
+ }
+
+ d.push_back({});
+ {
+ TEST_REQUIRE(d.size() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 13, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ }
+ // Push back until we need a new block.
+ for (int RemainingCap = d.__capacity() - d.size(); RemainingCap >= 0; --RemainingCap)
+ d.push_back({});
+ {
+ TEST_REQUIRE(d.__block_count() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 15, on_fail);
+ }
+
+ // Remove the only element in the new block. Test that we keep the empty
+ // block as a spare.
+ d.pop_back();
+ {
+ TEST_REQUIRE(d.__block_count() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 1, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 16, on_fail);
+ }
+
+ // Pop back again, keep the spare.
+ d.pop_back();
+ {
+ TEST_REQUIRE(d.__block_count() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 17, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 1, on_fail);
+ }
+
+ dp.reset();
+ TEST_REQUIRE(AllocBytes == 0, on_fail);
+}
+
+static void push_front() {
+ std::unique_ptr<Deque<LargeT>> dp(new Deque<LargeT>);
+ auto& d = *dp;
+ PrintOnFailure<Deque<LargeT>> on_fail(d);
+
+ // Test nothing is allocated after default construction.
+ {
+ TEST_REQUIRE(d.size() == 0, on_fail);
+ TEST_REQUIRE(d.__capacity() == 0, on_fail);
+ TEST_REQUIRE(d.__block_count() == 0, on_fail);
+ }
+ // First push front allocates one block, and we start the sequence in the
+ // middle.
+ d.push_front({});
+ {
+ TEST_REQUIRE(d.size() == 1, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 7, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 7, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__block_count() == 1, on_fail);
+ }
+
+ d.push_front({});
+ {
+ TEST_REQUIRE(d.size() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 6, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 7, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ }
+ // Push front until we need a new block.
+ for (int RemainingCap = d.__front_spare(); RemainingCap >= 0; --RemainingCap)
+ d.push_front({});
+ {
+ TEST_REQUIRE(d.__block_count() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 15, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 7, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ }
+
+ // Remove the only element in the new block. Test that we keep the empty
+ // block as a spare.
+ d.pop_front();
+ {
+ TEST_REQUIRE(d.__block_count() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 1, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 7, on_fail);
+ }
+
+ // Pop back again, keep the spare.
+ d.pop_front();
+ {
+ TEST_REQUIRE(d.__block_count() == 2, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 1, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 7, on_fail);
+ }
+
+ dp.reset();
+ TEST_REQUIRE(AllocBytes == 0, on_fail);
+}
+
+static void std_queue() {
+ using D = Deque<LargeT>;
+ using Queue = std::queue<LargeT, D>;
+ ContainerAdaptor<Queue> CA;
+ const D& d = CA.GetContainer();
+ Queue& q = CA;
+ PrintOnFailure<Deque<LargeT>> on_fail(d);
+
+ while (d.__block_count() < 4)
+ q.push({});
+ {
+ TEST_REQUIRE(d.__block_count() == 4, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 15, on_fail);
+ TEST_REQUIRE(d.__back_spare_blocks() == 0, on_fail);
+ }
+ while (d.__back_spare()) {
+ q.push({});
+ }
+ {
+ TEST_REQUIRE(d.__block_count() == 4, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 0, on_fail);
+ }
+ q.pop();
+ {
+ TEST_REQUIRE(d.__block_count() == 4, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 1, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 0, on_fail);
+ }
+
+ // Pop until we create a spare block at the front.
+ while (d.__front_spare() <= 15)
+ q.pop();
+
+ {
+ TEST_REQUIRE(d.__block_count() == 4, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 1, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 16, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 0, on_fail);
+ }
+
+ // Push at the end -- should re-use new spare block at front
+ q.push({});
+
+ {
+ TEST_REQUIRE(d.__block_count() == 4, on_fail);
+ TEST_REQUIRE(d.__front_spare_blocks() == 0, on_fail);
+ TEST_REQUIRE(d.__front_spare() == 0, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 15, on_fail);
+ }
+ while (!q.empty()) {
+ q.pop();
+ TEST_REQUIRE(d.__front_spare_blocks() + d.__back_spare_blocks() <= 2, on_fail);
+ }
+
+ // The empty state has two blocks
+ {
+ TEST_REQUIRE(d.__front_spare() == 16, on_fail);
+ TEST_REQUIRE(d.__back_spare() == 15, on_fail);
+ TEST_REQUIRE(d.__capacity() == 31, on_fail);
+ }
+}
+
+static void pop_front_push_back() {
+ Deque<char> d(32 * 1024, 'a');
+ bool take_from_front = true;
+ while (d.size() > 0) {
+ if (take_from_front) {
+ d.pop_front();
+ take_from_front = false;
+ } else {
+ d.pop_back();
+ take_from_front = true;
+ }
+ if (d.size() % 1000 == 0 || d.size() < 50) {
+ print(d);
+ }
+ }
+}
+
+int main(int, char**) {
+ push_back();
+ push_front();
+ std_queue();
+ pop_front_push_back();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/forwardlist/assert.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/forwardlist/assert.pass.cpp
new file mode 100644
index 0000000000000..6d1748e645025
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/forwardlist/assert.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
+//
+//===----------------------------------------------------------------------===//
+
+// <forward_list>
+
+// Test hardening assertions for std::forward_list.
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <forward_list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ { // Default-constructed list.
+ std::forward_list<int> c;
+ const auto& const_c = c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list");
+ }
+
+ { // Non-empty list becomes empty.
+ std::forward_list<int> c;
+ const auto& const_c = c;
+ c.push_front(1);
+
+ // Check that there's no assertion on valid access.
+ (void)c.front();
+ (void)const_c.front();
+
+ c.pop_front();
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/forwardlist/bool-conversion.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/forwardlist/bool-conversion.pass.cpp
new file mode 100644
index 0000000000000..237b0f155c7be
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/forwardlist/bool-conversion.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// <forward_list>
+
+// This test shows the effect of implementing `LWG4135`, before it this code
+// was ill-formed, as the predicate is not bool. `LWG4135` suggests that
+// std::erase explicitly specifying the lambda's return type as bool.
+
+#include <forward_list>
+
+struct Bool {
+ Bool() = default;
+ Bool(const Bool&) = delete;
+ operator bool() const { return true; }
+};
+
+struct Int {
+ Bool& operator==(Int) const {
+ static Bool b;
+ return b;
+ }
+};
+
+int main(int, char**) {
+ std::forward_list<Int> l;
+ std::erase(l, Int{});
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/abi.compile.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..a16ae1d527921
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/abi.compile.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cstdint>
+#include <list>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::int16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::list<int>) == 24, "");
+static_assert(sizeof(std::list<int, min_allocator<int> >) == 24, "");
+static_assert(sizeof(std::list<int, test_allocator<int> >) == 40, "");
+static_assert(sizeof(std::list<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::list<char>) == 24, "");
+static_assert(sizeof(std::list<char, min_allocator<char> >) == 24, "");
+static_assert(sizeof(std::list<char, test_allocator<char> >) == 40, "");
+static_assert(sizeof(std::list<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::list<int>) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::list<char>) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::list<char, small_iter_allocator<char> >) == 2, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::list<int>) == 12, "");
+static_assert(sizeof(std::list<int, min_allocator<int> >) == 12, "");
+static_assert(sizeof(std::list<int, test_allocator<int> >) == 24, "");
+static_assert(sizeof(std::list<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::list<char>) == 12, "");
+static_assert(sizeof(std::list<char, min_allocator<char> >) == 12, "");
+static_assert(sizeof(std::list<char, test_allocator<char> >) == 24, "");
+static_assert(sizeof(std::list<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::list<int>) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<int, min_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<int, test_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::list<char>) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<char, min_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<char, test_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::list<char, small_iter_allocator<char> >) == 2, "");
+
+#else
+# error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.cons/debug.copy.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.cons/debug.copy.pass.cpp
new file mode 100644
index 0000000000000..144a69691b4d3
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.cons/debug.copy.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// list(list&& c);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> l1;
+ l1.push_back(1);
+ l1.push_back(2);
+ l1.push_back(3);
+ std::list<int>::iterator i = l1.begin();
+ std::list<int> l2 = l1;
+ TEST_LIBCPP_ASSERT_FAILURE(l2.erase(i), "list::erase(iterator) called with an iterator not referring to this list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.erase_iter.end.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.erase_iter.end.pass.cpp
new file mode 100644
index 0000000000000..6441d533cfa29
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.erase_iter.end.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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// Call erase(const_iterator position) with end()
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ int a1[] = {1, 2, 3};
+ std::list<int> l1(a1, a1 + 3);
+ std::list<int>::const_iterator i = l1.end();
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(i), "list::erase(iterator) called with a non-dereferenceable iterator");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp
new file mode 100644
index 0000000000000..c344264852995
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// void pop_back();
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <list>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ int a[] = {1, 2, 3};
+ std::list<int> c(a, a + 3);
+ c.pop_back();
+ assert(c == std::list<int>(a, a + 2));
+ c.pop_back();
+ assert(c == std::list<int>(a, a + 1));
+ c.pop_back();
+ assert(c.empty());
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_back(), "list::pop_back() called on an empty list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp
new file mode 100644
index 0000000000000..59083b8f45924
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/bool-conversion.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// <list>
+
+// This test shows the effect of implementing `LWG4135`, before it this code
+// was ill-formed, as the predicate is not bool. `LWG4135` suggests that
+// std::erase explicitly specifying the lambda's return type as bool.
+
+#include <list>
+
+struct Bool {
+ Bool() = default;
+ Bool(const Bool&) = delete;
+ operator bool() const { return true; }
+};
+
+struct Int {
+ Bool& operator==(Int) const {
+ static Bool b;
+ return b;
+ }
+};
+
+int main(int, char**) {
+ std::list<Int> l;
+ std::erase(l, Int{});
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.emplace.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.emplace.pass.cpp
new file mode 100644
index 0000000000000..cd2f1eeea976a
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.emplace.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// template <class... Args> void emplace(const_iterator p, Args&&... args);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+struct A {
+ explicit A(int i, double d) {
+ (void)i;
+ (void)d;
+ }
+};
+
+int main(int, char**) {
+ std::list<A> c1;
+ std::list<A> c2;
+ TEST_LIBCPP_ASSERT_FAILURE(c1.emplace(c2.cbegin(), 2, 3.5),
+ "list::emplace(iterator, args...) called with an iterator not referring to this list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter.pass.cpp
new file mode 100644
index 0000000000000..fb61673f4b7a4
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// Call erase(const_iterator position) with iterator from another container
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ int a1[] = {1, 2, 3};
+ std::list<int> l1(a1, a1 + 3);
+ std::list<int> l2(a1, a1 + 3);
+ std::list<int>::const_iterator i = l2.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(i), "list::erase(iterator) called with an iterator not referring to this list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter_iter.pass.cpp
new file mode 100644
index 0000000000000..9d4198a120f99
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.erase.iter_iter.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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// Call erase(const_iterator first, const_iterator last); with various invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // First iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::list<int> l1(a1, a1 + 3);
+ std::list<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(l2.cbegin(), std::next(l1.cbegin())),
+ "list::erase(iterator, iterator) called with an iterator not referring to this list");
+ }
+
+ // Second iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::list<int> l1(a1, a1 + 3);
+ std::list<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(l1.cbegin(), std::next(l2.cbegin())),
+ "list::erase(iterator, iterator) called with an iterator not referring to this list");
+ }
+
+ // Both iterators from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::list<int> l1(a1, a1 + 3);
+ std::list<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(l2.cbegin(), std::next(l2.cbegin())),
+ "list::erase(iterator, iterator) called with an iterator not referring to this list");
+ }
+
+ // With an invalid range
+ {
+ int a1[] = {1, 2, 3};
+ std::list<int> l1(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(std::next(l1.cbegin()), l1.cbegin()),
+ "Attempted to increment a non-incrementable list::const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..13326a1d97ce5
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_iter_iter.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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// template <InputIterator Iter>
+// iterator insert(const_iterator position, Iter first, Iter last);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> v(100);
+ std::list<int> v2(100);
+ int a[] = {1, 2, 3, 4, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(v.insert(v2.cbegin(), a, a + 5),
+ "list::insert(iterator, range) called with an iterator not referring to this list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_rvalue.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_rvalue.pass.cpp
new file mode 100644
index 0000000000000..f4bce9a50a050
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_rvalue.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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// iterator insert(const_iterator position, value_type&& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> v1(3);
+ std::list<int> v2(3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v1.insert(v2.begin(), 4), "list::insert(iterator, x) called with an iterator not referring to this list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_size_value.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_size_value.pass.cpp
new file mode 100644
index 0000000000000..46bad61f9c981
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_size_value.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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// iterator insert(const_iterator position, size_type n, const value_type& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> c1(100);
+ std::list<int> c2;
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c1.insert(c2.cbegin(), 5, 1), "list::insert(iterator, n, x) called with an iterator not referring to this list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_value.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_value.pass.cpp
new file mode 100644
index 0000000000000..16fa8efd07b6b
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.modifiers/debug.insert.iter_value.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// iterator insert(const_iterator position, const value_type& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> v1(3);
+ std::list<int> v2(3);
+ int i = 4;
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v1.insert(v2.begin(), i), "list::insert(iterator, x) called with an iterator not referring to this list");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list.pass.cpp
new file mode 100644
index 0000000000000..be759d06036c3
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// void splice(const_iterator position, list& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> v1(3);
+ std::list<int> v2(3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v1.splice(v2.begin(), v2), "list::splice(iterator, list) called with an iterator not referring to this list");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter.pass.cpp
new file mode 100644
index 0000000000000..1786a6c64edcb
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// void splice(const_iterator position, list<T,Allocator>& x, iterator i);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> v1(3);
+ std::list<int> v2(3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v1.splice(v1.begin(), v2, v1.begin()),
+ "list::splice(iterator, list, iterator) called with the second iterator not referring to the list argument");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..b7c869fc8f915
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/list/list.ops/debug.splice.pos_list_iter_iter.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// void splice(const_iterator position, list& x, iterator first, iterator last);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::list<int> v1(3);
+ std::list<int> v2(3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v1.splice(v1.begin(), v2, v2.begin(), v1.end()),
+ "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector.bool/abi.compile.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector.bool/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..cc6b0d94e7daf
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector.bool/abi.compile.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: libcpp-abi-no-compressed-pair-padding
+
+#include <cstdint>
+#include <vector>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::int16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::vector<bool>) == 24, "");
+static_assert(sizeof(std::vector<bool, min_allocator<bool> >) == 24, "");
+static_assert(sizeof(std::vector<bool, test_allocator<bool> >) == 40, "");
+static_assert(sizeof(std::vector<bool, small_iter_allocator<bool> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<bool>) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, min_allocator<bool> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, test_allocator<bool> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, small_iter_allocator<bool> >) == 2, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::vector<bool>) == 12, "");
+static_assert(sizeof(std::vector<bool, min_allocator<bool> >) == 12, "");
+static_assert(sizeof(std::vector<bool, test_allocator<bool> >) == 24, "");
+static_assert(sizeof(std::vector<bool, small_iter_allocator<bool> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<bool>) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, min_allocator<bool> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, test_allocator<bool> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<bool, small_iter_allocator<bool> >) == 2, "");
+
+#else
+# error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector.bool/assert.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector.bool/assert.pass.cpp
new file mode 100644
index 0000000000000..41badad8f569d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector.bool/assert.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Test hardening assertions for std::vector<bool>.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class Allocator>
+void test() {
+ std::vector<bool, Allocator> c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "vector<bool>::front() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(c.back(), "vector<bool>::back() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(c[0], "vector<bool>::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_back(), "vector<bool>::pop_back called on an empty vector");
+
+ // Repeat the test with a const reference to test the const overloads.
+ {
+ const std::vector<bool, Allocator>& cc = c;
+ TEST_LIBCPP_ASSERT_FAILURE(cc.front(), "vector<bool>::front() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(cc.back(), "vector<bool>::back() called on an empty vector");
+ TEST_LIBCPP_ASSERT_FAILURE(cc[0], "vector<bool>::operator[] index out of bounds");
+ }
+
+ c.push_back(true);
+ c.push_back(false);
+ c.push_back(true);
+ TEST_LIBCPP_ASSERT_FAILURE(c[3], "vector<bool>::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c[100], "vector<bool>::operator[] index out of bounds");
+
+ // Repeat the test with a const reference to test the const overloads.
+ {
+ const std::vector<bool, Allocator>& cc = c;
+ TEST_LIBCPP_ASSERT_FAILURE(cc[3], "vector<bool>::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(cc[100], "vector<bool>::operator[] index out of bounds");
+ }
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.erase(c.end()), "vector<bool>::erase(iterator) called with a non-dereferenceable iterator");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.erase(c.begin() + 1, c.begin()), "vector<bool>::erase(iterator, iterator) called with an invalid range");
+}
+
+int main(int, char**) {
+ test<std::allocator<bool>>();
+ test<min_allocator<bool>>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector.bool/trivial_for_purposes_of_call.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector.bool/trivial_for_purposes_of_call.pass.cpp
new file mode 100644
index 0000000000000..4d37b83ba9cd6
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector.bool/trivial_for_purposes_of_call.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// typedef ... iterator;
+// typedef ... const_iterator;
+
+// The libc++ __bit_iterator type has weird ABI calling conventions as a quirk
+// of the implementation. The const bit iterator is trivial, but the non-const
+// bit iterator is not because it declares a user-defined copy constructor.
+//
+// Changing this now is an ABI break, so this test ensures that each type
+// is trivial/non-trivial as expected.
+
+// The definition of 'non-trivial for the purposes of calls':
+// A type is considered non-trivial for the purposes of calls if:
+// * it has a non-trivial copy constructor, move constructor, or
+// destructor, or
+// * all of its copy and move constructors are deleted.
+
+// UNSUPPORTED: c++03
+
+#include <cassert>
+#include <type_traits>
+#include <vector>
+
+template <class T>
+using IsTrivialForCall = std::integral_constant<
+ bool,
+ std::is_trivially_copy_constructible<T>::value && std::is_trivially_move_constructible<T>::value &&
+ std::is_trivially_destructible<T>::value
+ // Ignore the all-deleted case, it shouldn't occur here.
+ >;
+
+void test_const_iterator() {
+ using It = std::vector<bool>::const_iterator;
+ static_assert(IsTrivialForCall<It>::value, "");
+}
+
+void test_non_const_iterator() {
+ using It = std::vector<bool>::iterator;
+ static_assert(!IsTrivialForCall<It>::value, "");
+}
+
+int main(int, char**) {
+ test_const_iterator();
+ test_non_const_iterator();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/abi.compile.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/abi.compile.pass.cpp
new file mode 100644
index 0000000000000..57684951c8e8e
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/abi.compile.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <cstdint>
+#include <vector>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <class T>
+class small_pointer {
+public:
+ using value_type = T;
+ using difference_type = std::int16_t;
+ using pointer = small_pointer;
+ using reference = T&;
+ using iterator_category = std::random_access_iterator_tag;
+
+private:
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::int16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::vector<int>) == 24, "");
+static_assert(sizeof(std::vector<int, min_allocator<int> >) == 24, "");
+static_assert(sizeof(std::vector<int, test_allocator<int> >) == 40, "");
+static_assert(sizeof(std::vector<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::vector<char>) == 24, "");
+static_assert(sizeof(std::vector<char, min_allocator<char> >) == 24, "");
+static_assert(sizeof(std::vector<char, test_allocator<char> >) == 40, "");
+static_assert(sizeof(std::vector<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<int>) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<int, min_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<int, test_allocator<int> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::vector<char>) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<char, min_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<char, test_allocator<char> >) == 8, "");
+static_assert(TEST_ALIGNOF(std::vector<char, small_iter_allocator<char> >) == 2, "");
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::vector<int>) == 12, "");
+static_assert(sizeof(std::vector<int, min_allocator<int> >) == 12, "");
+static_assert(sizeof(std::vector<int, test_allocator<int> >) == 24, "");
+static_assert(sizeof(std::vector<int, small_iter_allocator<int> >) == 6, "");
+
+static_assert(sizeof(std::vector<char>) == 12, "");
+static_assert(sizeof(std::vector<char, min_allocator<char> >) == 12, "");
+static_assert(sizeof(std::vector<char, test_allocator<char> >) == 24, "");
+static_assert(sizeof(std::vector<char, small_iter_allocator<char> >) == 6, "");
+
+static_assert(TEST_ALIGNOF(std::vector<int>) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<int, min_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<int, test_allocator<int> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<int, small_iter_allocator<int> >) == 2, "");
+
+static_assert(TEST_ALIGNOF(std::vector<char>) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<char, min_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<char, test_allocator<char> >) == 4, "");
+static_assert(TEST_ALIGNOF(std::vector<char, small_iter_allocator<char> >) == 2, "");
+
+#else
+# error std::size_t has an unexpected size
+#endif
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/asan.pass.cpp
new file mode 100644
index 0000000000000..03d2b3e6ce9b9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/asan.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: asan
+
+// <vector>
+
+// reference operator[](size_type n);
+
+#include <vector>
+#include <cassert>
+#include <cstdlib>
+
+#include "asan_testing.h"
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
+
+void do_exit() { exit(0); }
+
+int main(int, char**) {
+#if TEST_STD_VER >= 11
+ {
+ typedef int T;
+ typedef cpp17_input_iterator<T*> MyInputIter;
+ std::vector<T, min_allocator<T>> v;
+ v.reserve(1);
+ int i[] = {42};
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1));
+ assert(v[0] == 42);
+ assert(is_contiguous_container_asan_correct(v));
+ }
+ {
+ typedef char T;
+ typedef cpp17_input_iterator<T*> MyInputIter;
+ std::vector<T, unaligned_allocator<T>> v;
+ v.reserve(1);
+ char i[] = {'a', 'b'};
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 2));
+ assert(v[0] == 'a');
+ assert(v[1] == 'b');
+ assert(is_contiguous_container_asan_correct(v));
+ }
+#endif // TEST_STD_VER >= 11
+ {
+ typedef cpp17_input_iterator<int*> MyInputIter;
+ // Sould not trigger ASan.
+ std::vector<int> v;
+ v.reserve(1);
+ int i[] = {42};
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1));
+ assert(v[0] == 42);
+ assert(is_contiguous_container_asan_correct(v));
+ }
+
+ __sanitizer_set_death_callback(do_exit);
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ C c(std::begin(t), std::end(t));
+ c.reserve(2 * c.size());
+ assert(is_contiguous_container_asan_correct(c));
+ assert(!__sanitizer_verify_contiguous_container(c.data(), c.data() + 1, c.data() + c.capacity()));
+ volatile T foo = c[c.size()]; // should trigger ASAN. Use volatile to prevent being optimized away.
+ assert(false); // if we got here, ASAN didn't trigger
+ ((void)foo);
+ }
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp
new file mode 100644
index 0000000000000..dcfa8029cfc0d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/asan_throw.pass.cpp
@@ -0,0 +1,233 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-exceptions
+// Test asan vector annotations with a class that throws in a CTOR.
+
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "asan_testing.h"
+
+class X {
+public:
+ X(const X& x) { Init(x.a); }
+ X(char arg) { Init(arg); }
+ X() { Init(42); }
+ X& operator=(const X& x) {
+ Init(x.a);
+ return *this;
+ }
+ void Init(char arg) {
+ if (arg == 42)
+ throw 0;
+ if (arg == 66)
+ arg = 42;
+ a = arg;
+ }
+ char get() const { return a; }
+ void set(char arg) { a = arg; }
+
+private:
+ char a;
+};
+
+class ThrowOnCopy {
+public:
+ ThrowOnCopy() : should_throw(false) {}
+ explicit ThrowOnCopy(bool xshould_throw) : should_throw(xshould_throw) {}
+
+ ThrowOnCopy(ThrowOnCopy const& other) : should_throw(other.should_throw) {
+ if (should_throw) {
+ throw 0;
+ }
+ }
+ ThrowOnCopy& operator=(ThrowOnCopy const&) = default;
+
+ bool should_throw;
+};
+
+void test_push_back() {
+ std::vector<X> v;
+ v.reserve(2);
+ v.push_back(X(2));
+ assert(v.size() == 1);
+ try {
+ v.push_back(X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace_back() {
+#if TEST_STD_VER >= 11
+ std::vector<X> v;
+ v.reserve(2);
+ v.push_back(X(2));
+ assert(v.size() == 1);
+ try {
+ v.emplace_back(42);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+#endif
+}
+
+void test_insert_range() {
+ std::vector<X> v;
+ v.reserve(4);
+ v.push_back(X(1));
+ v.push_back(X(2));
+ assert(v.size() == 2);
+ assert(v.capacity() >= 4);
+ try {
+ char a[2] = {21, 42};
+ v.insert(v.end(), a, a + 2);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 2);
+ }
+ assert(v.size() == 2);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_insert() {
+ std::vector<X> v;
+ v.reserve(3);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ try {
+ v.insert(v.end(), X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 2);
+ }
+ assert(v.size() == 2);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace() {
+#if TEST_STD_VER >= 11
+ std::vector<X> v;
+ v.reserve(3);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ try {
+ v.emplace(v.end(), 42);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 2);
+ }
+ assert(v.size() == 2);
+ assert(is_contiguous_container_asan_correct(v));
+#endif
+}
+
+void test_insert_range2() {
+ std::vector<X> v;
+ v.reserve(4);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ assert(v.capacity() >= 4);
+ try {
+ char a[2] = {10, 42};
+ v.insert(v.begin(), a, a + 2);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() <= 4);
+ assert(is_contiguous_container_asan_correct(v));
+ return;
+ }
+ assert(0);
+}
+
+void test_insert_n() {
+ std::vector<X> v;
+ v.reserve(10);
+ v.insert(v.end(), X(1));
+ v.insert(v.begin(), X(2));
+ assert(v.size() == 2);
+ try {
+ v.insert(v.begin(), 1, X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() <= 3);
+ assert(is_contiguous_container_asan_correct(v));
+ return;
+ }
+ assert(0);
+}
+
+void test_insert_n2() {
+ std::vector<ThrowOnCopy> v(10);
+ v.reserve(100);
+ assert(v.size() == 10);
+ v[6].should_throw = true;
+ try {
+ v.insert(v.cbegin(), 5, ThrowOnCopy());
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 11);
+ assert(is_contiguous_container_asan_correct(v));
+ return;
+ }
+ assert(0);
+}
+
+void test_resize() {
+ std::vector<X> v;
+ v.reserve(3);
+ v.push_back(X(0));
+ try {
+ v.resize(3);
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_resize_param() {
+ std::vector<X> v;
+ v.reserve(3);
+ v.push_back(X(0));
+ try {
+ v.resize(3, X(66));
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 1);
+ }
+ assert(v.size() == 1);
+ assert(is_contiguous_container_asan_correct(v));
+}
+
+int main(int, char**) {
+ test_push_back();
+ test_emplace_back();
+ test_insert_range();
+ test_insert();
+ test_emplace();
+ test_insert_range2();
+ test_insert_n();
+ test_insert_n2();
+ test_resize();
+ test_resize_param();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/asan_turning_off.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/asan_turning_off.pass.cpp
new file mode 100644
index 0000000000000..1ad60d0544d41
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/asan_turning_off.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <vector>
+
+// Test based on: https://bugs.chromium.org/p/chromium/issues/detail?id=1419798#c5
+// Some allocators during deallocation may not call destructors and just reuse memory.
+// In those situations, one may want to deactivate annotations for a specific allocator.
+// It's possible with __asan_annotate_container_with_allocator template class.
+// This test confirms that those allocators work after turning off annotations.
+
+#include <assert.h>
+#include <stdlib.h>
+#include <vector>
+#include <new>
+
+struct reuse_allocator {
+ static size_t const N = 100;
+ reuse_allocator() {
+ for (size_t i = 0; i < N; ++i)
+ __buffers[i] = malloc(8 * 1024);
+ }
+ ~reuse_allocator() {
+ for (size_t i = 0; i < N; ++i)
+ free(__buffers[i]);
+ }
+ void* alloc() {
+ assert(__next_id < N);
+ return __buffers[__next_id++];
+ }
+ void reset() { __next_id = 0; }
+ void* __buffers[N];
+ size_t __next_id = 0;
+} reuse_buffers;
+
+template <typename T>
+struct user_allocator {
+ using value_type = T;
+ user_allocator() = default;
+ template <class U>
+ user_allocator(user_allocator<U>) {}
+ friend bool operator==(user_allocator, user_allocator) { return true; }
+ friend bool operator!=(user_allocator x, user_allocator y) { return !(x == y); }
+
+ T* allocate(size_t) { return (T*)reuse_buffers.alloc(); }
+ void deallocate(T*, size_t) noexcept {}
+};
+
+#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
+template <class T>
+struct std::__asan_annotate_container_with_allocator<user_allocator<T>> : false_type {};
+#endif
+
+int main(int, char**) {
+ using V = std::vector<int, user_allocator<int>>;
+
+ {
+ V* v = new (reuse_buffers.alloc()) V();
+ for (int i = 0; i < 100; i++)
+ v->push_back(i);
+ }
+ reuse_buffers.reset();
+ {
+ V v;
+ for (int i = 0; i < 1000; i++)
+ v.push_back(i);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.back.empty.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.back.empty.pass.cpp
new file mode 100644
index 0000000000000..169ad1def9e6f
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.back.empty.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Call back() on empty container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ assert(c.back() == 0);
+ c.clear();
+ TEST_LIBCPP_ASSERT_FAILURE(c.back(), "back() called on an empty vector");
+ }
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ assert(c.back() == 0);
+ c.clear();
+ TEST_LIBCPP_ASSERT_FAILURE(c.back(), "back() called on an empty vector");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.cback.empty.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.cback.empty.pass.cpp
new file mode 100644
index 0000000000000..5ceb4a16b9340
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.cback.empty.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Call back() on empty const container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ const C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.back(), "back() called on an empty vector");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ const C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.back(), "back() called on an empty vector");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.cfront.empty.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.cfront.empty.pass.cpp
new file mode 100644
index 0000000000000..20f94f1d3f0fa
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.cfront.empty.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Call front() on empty const container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ const C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "front() called on an empty vector");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ const C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "front() called on an empty vector");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.cindex.oob.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.cindex.oob.pass.cpp
new file mode 100644
index 0000000000000..3a9a7add3e30d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.cindex.oob.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Index const vector out of bounds.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ const C c(1);
+ assert(c[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(c[1], "vector[] index out of bounds");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ const C c(1);
+ assert(c[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(c[1], "vector[] index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.front.empty.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.front.empty.pass.cpp
new file mode 100644
index 0000000000000..85364c778ad64
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.front.empty.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Call front() on empty container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ assert(c.front() == 0);
+ c.clear();
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "front() called on an empty vector");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ assert(c.front() == 0);
+ c.clear();
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "front() called on an empty vector");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.index.oob.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.index.oob.pass.cpp
new file mode 100644
index 0000000000000..14cb89625f064
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.index.oob.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Index vector out of bounds.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ assert(c[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(c[1], "vector[] index out of bounds");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ assert(c[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(c[1], "vector[] index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.add.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.add.pass.cpp
new file mode 100644
index 0000000000000..a066ad30ebd71
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.add.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Add to iterator out of bounds.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-vector
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "fill_to_capacity.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.begin();
+ i += c.size();
+ assert(i == c.end());
+ i = c.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(i + 2, "__bounded_iter::operator+=: Attempt to advance an iterator past the end");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.begin();
+ i += c.size();
+ assert(i == c.end());
+ i = c.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(i + 2, "__bounded_iter::operator+=: Attempt to advance an iterator past the end");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.decrement.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.decrement.pass.cpp
new file mode 100644
index 0000000000000..59b9c16a6aa0e
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.decrement.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Decrement iterator prior to begin.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-vector
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ C::iterator i = c.end();
+ --i;
+ assert(i == c.begin());
+ TEST_LIBCPP_ASSERT_FAILURE(--i, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ C::iterator i = c.end();
+ --i;
+ assert(i == c.begin());
+ TEST_LIBCPP_ASSERT_FAILURE(--i, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..877d3655fbe2e
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.dereference.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-vector
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <vector>
+
+#include "check_assertion.h"
+#include "fill_to_capacity.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..e540f40f8c476
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.increment.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Increment iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-vector
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "fill_to_capacity.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.begin();
+ i += c.size();
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.begin();
+ i += c.size();
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.index.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.index.pass.cpp
new file mode 100644
index 0000000000000..63354af5af022
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.iterator.index.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Index iterator out of bounds.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-vector
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <vector>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "fill_to_capacity.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.begin();
+ assert(i[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ i[c.size()], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ i[c.size() + 1], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c(1);
+ fill_to_capacity(c);
+ C::iterator i = c.begin();
+ assert(i[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ i[c.size()], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ i[c.size() + 1], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/assert.pop_back.empty.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/assert.pop_back.empty.pass.cpp
new file mode 100644
index 0000000000000..6734f25b9db10
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/assert.pop_back.empty.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// pop_back() more than the number of elements in a vector
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::vector<int> v;
+ v.push_back(0);
+ v.pop_back();
+ TEST_LIBCPP_ASSERT_FAILURE(v.pop_back(), "vector::pop_back called on an empty vector");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.compare.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.compare.pass.cpp
new file mode 100644
index 0000000000000..f3b8fb35b8e7b
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.compare.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Compare iterators from different containers with <.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <vector>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c1;
+ C c2;
+ TEST_LIBCPP_ASSERT_FAILURE(c1.begin() < c2.begin(), "Attempted to compare incomparable iterators");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c1;
+ C c2;
+ TEST_LIBCPP_ASSERT_FAILURE(c1.begin() < c2.begin(), "Attempted to compare incomparable iterators");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.subtract.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.subtract.pass.cpp
new file mode 100644
index 0000000000000..e3668d96e757d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/debug.iterator.subtract.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// Subtract iterators from different containers.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <vector>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ C c1;
+ C c2;
+ TEST_LIBCPP_ASSERT_FAILURE(c1.begin() - c2.begin(), "Attempted to subtract incompatible iterators");
+ }
+
+ {
+ typedef int T;
+ typedef std::vector<T, min_allocator<T> > C;
+ C c1;
+ C c2;
+ TEST_LIBCPP_ASSERT_FAILURE(c1.begin() - c2.begin(), "Attempted to subtract incompatible iterators");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/erase.modules.compile.pass.mm b/libcxx/test/libcxx-03/containers/sequences/vector/erase.modules.compile.pass.mm
new file mode 100644
index 0000000000000..d27067399eda8
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/erase.modules.compile.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that we don't get a compiler error when trying to use std::vector::erase
+// from Objective-C++. This happened in Objective-C++ mode with modules enabled (rdar://106813461).
+
+// REQUIRES: objective-c++
+
+#include <vector>
+
+void f(std::vector<int> vec, std::vector<int>::iterator it) { (void)vec.erase(it); }
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/exception_safety_exceptions_disabled.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/exception_safety_exceptions_disabled.pass.cpp
new file mode 100644
index 0000000000000..66fdf37556bce
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/exception_safety_exceptions_disabled.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// ADDITIONAL_COMPILE_FLAGS: -fno-exceptions
+
+// UNSUPPORTED: c++03
+
+// <vector>
+
+// Test that vector always moves elements when exceptions are disabled.
+// vector is allowed to move or copy elements while resizing, so long as
+// it still provides the strong exception safety guarantee.
+
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+# error exceptions should be disabled.
+#endif
+
+bool allow_moves = false;
+
+class A {
+public:
+ A() {}
+ A(A&&) { assert(allow_moves); }
+ explicit A(int) {}
+ A(A const&) { assert(false); }
+};
+
+int main(int, char**) {
+ std::vector<A> v;
+
+ // Create a vector containing some number of elements that will
+ // have to be moved when it is resized.
+ v.reserve(10);
+ std::size_t old_cap = v.capacity();
+ for (std::size_t i = 0; i < v.capacity(); ++i) {
+ v.emplace_back(42);
+ }
+ assert(v.capacity() == old_cap);
+ assert(v.size() == v.capacity());
+
+ // The next emplace back should resize.
+ allow_moves = true;
+ v.emplace_back(42);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/fill_to_capacity.h b/libcxx/test/libcxx-03/containers/sequences/vector/fill_to_capacity.h
new file mode 100644
index 0000000000000..abf88c477fece
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/fill_to_capacity.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIBCXX_TEST_LIBCXX_CONTAINERS_SEQUENCES_VECTOR_FILL_TO_CAPACITY_H
+#define LIBCXX_TEST_LIBCXX_CONTAINERS_SEQUENCES_VECTOR_FILL_TO_CAPACITY_H
+
+#include <vector>
+
+template <typename T, typename A>
+void fill_to_capacity(std::vector<T, A>& vec) {
+ // Fill the given vector up to its capacity. Our bounded iterators are currently unable to catch an out-of-bounds
+ // access that goes beyond the container's logical storage (above the size) but is still within its physical storage
+ // (below the capacity) due to iterator stability guarantees. Filling a vector makes this distinction go away.
+ while (vec.size() < vec.capacity()) {
+ vec.push_back(T());
+ }
+}
+
+#endif // LIBCXX_TEST_LIBCXX_CONTAINERS_SEQUENCES_VECTOR_FILL_TO_CAPACITY_H
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/invalid_allocator.verify.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/invalid_allocator.verify.cpp
new file mode 100644
index 0000000000000..e2de7730f2599
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/invalid_allocator.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that vector diagnoses an allocator which has to implement rebind with an appropriate error message
+
+#include <vector>
+
+class FooAllocator {
+public:
+ using value_type = int;
+ FooAllocator() = default;
+
+ int* allocate(int num_objects);
+
+ void deallocate(int* ptr, int num_objects);
+
+ bool operator==(const FooAllocator&) const { return true; }
+ bool operator!=(const FooAllocator&) const { return false; }
+};
+
+void func() {
+ std::vector<int, FooAllocator>
+ v; //expected-error-re@*:* {{static assertion failed {{.*}}This allocator has to implement rebind}}
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/robust_against_adl.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/robust_against_adl.pass.cpp
new file mode 100644
index 0000000000000..c6868ce4cb867
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/robust_against_adl.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
+
+// <vector>
+
+#include <cstddef>
+#include <memory>
+#include <vector>
+
+#include "test_macros.h"
+
+struct Incomplete;
+template <class T>
+struct Holder {
+ T t;
+};
+
+template <class T, class AdlTrap = Holder<Incomplete>>
+struct MyAlloc {
+ using value_type = T;
+ MyAlloc() = default;
+ template <class U>
+ MyAlloc(const MyAlloc<U>&) {}
+ T* allocate(std::size_t n) { return std::allocator<T>().allocate(n); }
+ void deallocate(T* p, std::size_t n) { return std::allocator<T>().deallocate(p, n); }
+};
+
+int main(int, char**) {
+ std::vector<bool, MyAlloc<bool>> vb;
+ // std::fill_n triggers ADL because __bit_iterator has the container type as a template argument
+ // std::vector<bool, MyAlloc<bool>> wb(100);
+
+ std::vector<int, MyAlloc<int>> v;
+ std::vector<int, MyAlloc<int>> w(100);
+ v.push_back(1);
+ v.insert(v.end(), 2);
+ v.insert(v.end(), w.begin(), w.end());
+ v.pop_back();
+ v.erase(v.begin());
+ v.erase(v.begin(), v.end());
+#if TEST_STD_VER >= 14
+ // TODO: vector::swap is not robust against ADL because we compare allocators, and that
+ // triggers ADL when looking up operator==.
+ // v.swap(w);
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..9e3fb886e6075
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// template <class InputIter> vector(InputIter first, InputIter last);
+
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+void test_ctor_under_alloc() {
+ int arr1[] = {42};
+ int arr2[] = {1, 101, 42};
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3);
+ assert(Alloc::construct_called);
+ }
+ }
+ {
+ typedef std::vector<int, cpp03_overload_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3);
+ assert(Alloc::construct_called);
+ }
+ }
+}
+
+int main(int, char**) {
+ test_ctor_under_alloc();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
new file mode 100644
index 0000000000000..fa1bd2d4fda32
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// template <class InputIter> vector(InputIter first, InputIter last,
+// const allocator_type& a);
+
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+void test_ctor_under_alloc() {
+ int arr1[] = {42};
+ int arr2[] = {1, 101, 42};
+ {
+ typedef std::vector<int, cpp03_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ Alloc a;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1, a);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3, a);
+ assert(Alloc::construct_called);
+ }
+ }
+ {
+ typedef std::vector<int, cpp03_overload_allocator<int> > C;
+ typedef C::allocator_type Alloc;
+ Alloc a;
+ {
+ Alloc::construct_called = false;
+ C v(arr1, arr1 + 1, a);
+ assert(Alloc::construct_called);
+ }
+ {
+ Alloc::construct_called = false;
+ C v(arr2, arr2 + 3, a);
+ assert(Alloc::construct_called);
+ }
+ }
+}
+
+int main(int, char**) {
+ test_ctor_under_alloc();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/strings/basic.string/asan.pass.cpp b/libcxx/test/libcxx-03/containers/strings/basic.string/asan.pass.cpp
new file mode 100644
index 0000000000000..c7e0924be3df6
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/strings/basic.string/asan.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: asan
+// UNSUPPORTED: c++03
+
+// Basic test if ASan annotations work for basic_string.
+
+#include <string>
+#include <cassert>
+#include <cstdlib>
+
+#include "asan_testing.h"
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
+
+void do_exit() { exit(0); }
+
+int main(int, char**) {
+ {
+ typedef cpp17_input_iterator<char*> MyInputIter;
+ // Should not trigger ASan.
+ std::basic_string<char, std::char_traits<char>, safe_allocator<char>> v;
+ char i[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e',
+ 'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
+
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 29));
+ assert(v[0] == 'a');
+ assert(is_string_asan_correct(v));
+ }
+
+ __sanitizer_set_death_callback(do_exit);
+ {
+ using T = char;
+ using C = std::basic_string<T, std::char_traits<T>, safe_allocator<T>>;
+ const T t[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e',
+ 'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
+ C c(std::begin(t), std::end(t));
+ assert(is_string_asan_correct(c));
+ assert(__sanitizer_verify_contiguous_container(c.data(), c.data() + c.size() + 1, c.data() + c.capacity() + 1) !=
+ 0);
+ T foo = c[c.size() + 1]; // should trigger ASAN and call do_exit().
+ assert(false); // if we got here, ASAN didn't trigger
+ ((void)foo);
+
+ return 0;
+ }
+}
diff --git a/libcxx/test/libcxx-03/containers/strings/basic.string/asan_deque_integration.pass.cpp b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_deque_integration.pass.cpp
new file mode 100644
index 0000000000000..1205190b3a6e1
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_deque_integration.pass.cpp
@@ -0,0 +1,182 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: asan
+// UNSUPPORTED: c++03
+
+#include <cassert>
+#include <string>
+#include <array>
+#include <deque>
+#include "test_macros.h"
+#include "asan_testing.h"
+#include "min_allocator.h"
+
+// This tests exists to check if strings work well with deque, as those
+// may be partialy annotated, we cannot simply call
+// is_double_ended_contiguous_container_asan_correct, as it assumes that
+// object memory inside is not annotated, so we check everything in a more careful way.
+
+template <typename D>
+void verify_inside(D const& d) {
+ for (size_t i = 0; i < d.size(); ++i) {
+ assert(is_string_asan_correct(d[i]));
+ }
+}
+
+template <typename S, size_t N>
+S get_s(char c) {
+ S s;
+ for (size_t i = 0; i < N; ++i)
+ s.push_back(c);
+
+ return s;
+}
+
+template <class C, class S>
+void test_string() {
+ size_t const N = sizeof(S) < 256 ? (4096 / sizeof(S)) : 16;
+
+ {
+ C d1a(1), d1b(N), d1c(N + 1), d1d(5 * N);
+ verify_inside(d1a);
+ verify_inside(d1b);
+ verify_inside(d1c);
+ verify_inside(d1d);
+ }
+ {
+ C d2;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ d2.push_back(get_s<S, 1>(i % 10 + 'a'));
+ verify_inside(d2);
+ d2.push_back(get_s<S, 22>(i % 10 + 'b'));
+ verify_inside(d2);
+
+ d2.pop_front();
+ verify_inside(d2);
+ }
+ }
+ {
+ C d3;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ d3.push_front(get_s<S, 1>(i % 10 + 'a'));
+ verify_inside(d3);
+ d3.push_front(get_s<S, 28>(i % 10 + 'b'));
+ verify_inside(d3);
+
+ d3.pop_back();
+ verify_inside(d3);
+ }
+ }
+ {
+ C d4;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ // When there is no SSO, all elements inside should not be poisoned,
+ // so we can verify deque poisoning.
+ d4.push_front(get_s<S, 33>(i % 10 + 'a'));
+ verify_inside(d4);
+ assert(is_double_ended_contiguous_container_asan_correct(d4));
+ d4.push_back(get_s<S, 28>(i % 10 + 'b'));
+ verify_inside(d4);
+ assert(is_double_ended_contiguous_container_asan_correct(d4));
+ }
+ }
+ {
+ C d5;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ // In d4 we never had poisoned memory inside deque.
+ // Here we start with SSO, so part of the inside of the container,
+ // will be poisoned.
+ d5.push_front(S());
+ verify_inside(d5);
+ }
+ for (size_t i = 0; i < d5.size(); ++i) {
+ // We change the size to have long string.
+ // Memory owne by deque should not be poisoned by string.
+ d5[i].resize(100);
+ verify_inside(d5);
+ }
+
+ assert(is_double_ended_contiguous_container_asan_correct(d5));
+
+ d5.erase(d5.begin() + 2);
+ verify_inside(d5);
+
+ d5.erase(d5.end() - 2);
+ verify_inside(d5);
+
+ assert(is_double_ended_contiguous_container_asan_correct(d5));
+ }
+ {
+ C d6a;
+ assert(is_double_ended_contiguous_container_asan_correct(d6a));
+
+ C d6b(N + 2, get_s<S, 100>('a'));
+ d6b.push_front(get_s<S, 101>('b'));
+ while (!d6b.empty()) {
+ d6b.pop_back();
+ assert(is_double_ended_contiguous_container_asan_correct(d6b));
+ }
+
+ C d6c(N + 2, get_s<S, 102>('c'));
+ while (!d6c.empty()) {
+ d6c.pop_back();
+ assert(is_double_ended_contiguous_container_asan_correct(d6c));
+ }
+ }
+ {
+ C d7(9 * N + 2);
+
+ d7.insert(d7.begin() + 1, S());
+ verify_inside(d7);
+
+ d7.insert(d7.end() - 3, S());
+ verify_inside(d7);
+
+ d7.insert(d7.begin() + 2 * N, get_s<S, 1>('a'));
+ verify_inside(d7);
+
+ d7.insert(d7.end() - 2 * N, get_s<S, 1>('b'));
+ verify_inside(d7);
+
+ d7.insert(d7.begin() + 2 * N, 3 * N, get_s<S, 1>('c'));
+ verify_inside(d7);
+
+ // It may not be short for big element types, but it will be checked correctly:
+ d7.insert(d7.end() - 2 * N, 3 * N, get_s<S, 2>('d'));
+ verify_inside(d7);
+
+ d7.erase(d7.begin() + 2);
+ verify_inside(d7);
+
+ d7.erase(d7.end() - 2);
+ verify_inside(d7);
+ }
+}
+
+template <class S>
+void test_container() {
+ test_string<std::deque<S, std::allocator<S>>, S>();
+ test_string<std::deque<S, min_allocator<S>>, S>();
+ test_string<std::deque<S, safe_allocator<S>>, S>();
+}
+
+int main(int, char**) {
+ // Those tests support only types based on std::basic_string.
+ test_container<std::string>();
+ test_container<std::wstring>();
+#if TEST_STD_VER >= 11
+ test_container<std::u16string>();
+ test_container<std::u32string>();
+#endif
+#if TEST_STD_VER >= 20
+ test_container<std::u8string>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/strings/basic.string/asan_short.pass.cpp b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_short.pass.cpp
new file mode 100644
index 0000000000000..53c70bed189b5
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_short.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: asan
+// UNSUPPORTED: c++03
+
+// <string>
+
+// Basic test if ASan annotations work for short strings.
+
+#include <string>
+#include <cassert>
+#include <cstdlib>
+
+#include "asan_testing.h"
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+extern "C" void __sanitizer_set_death_callback(void (*callback)(void));
+
+void do_exit() { exit(0); }
+
+int main(int, char**) {
+ {
+ typedef cpp17_input_iterator<char*> MyInputIter;
+ // Should not trigger ASan.
+ std::basic_string<char, std::char_traits<char>, safe_allocator<char>> v;
+ char i[] = {'a', 'b', 'c', 'd'};
+
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 4));
+ assert(v[0] == 'a');
+ assert(is_string_asan_correct(v));
+ }
+
+ __sanitizer_set_death_callback(do_exit);
+ {
+ using T = char;
+ using C = std::basic_string<T, std::char_traits<T>, safe_allocator<T>>;
+ const T t[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
+ C c(std::begin(t), std::end(t));
+ assert(is_string_asan_correct(c));
+ assert(__sanitizer_verify_contiguous_container(c.data(), c.data() + c.size() + 1, c.data() + c.capacity() + 1) !=
+ 0);
+ volatile T foo = c[c.size() + 1]; // should trigger ASAN. Use volatile to prevent being optimized away.
+ assert(false); // if we got here, ASAN didn't trigger
+ ((void)foo);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/strings/basic.string/asan_turning_off.pass.cpp b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_turning_off.pass.cpp
new file mode 100644
index 0000000000000..c8ee17c580a4c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_turning_off.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: asan
+// UNSUPPORTED: c++03
+
+// Test based on: https://bugs.chromium.org/p/chromium/issues/detail?id=1419798#c5
+// Some allocators during deallocation may not call destructors and just reuse memory.
+// In those situations, one may want to deactivate annotations for a specific allocator.
+// It's possible with __asan_annotate_container_with_allocator template class.
+// This test confirms that those allocators work after turning off annotations.
+//
+// A context to this test is a situations when memory is repurposed and destructors are not called.
+// Related issue: https://github.com/llvm/llvm-project/issues/60384
+//
+// That issue appeared in the past and was addressed here: https://reviews.llvm.org/D145628
+//
+// There was also a discussion, if it's UB.
+// Related discussion: https://reviews.llvm.org/D136765#4155262
+// Related notes: https://eel.is/c++draft/basic.life#6
+// Probably it's no longer UB due a change in CWG2523.
+// https://cplusplus.github.io/CWG/issues/2523.html
+//
+// Therefore we make sure that it works that way, also because people rely on this behavior.
+// Annotations are turned off only, if a user explicitly turns off annotations for a specific allocator.
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string>
+#include <new>
+
+// Allocator with pre-allocated (with malloc in constructor) buffers.
+// Memory may be freed without calling destructors.
+struct reuse_allocator {
+ static size_t const N = 100;
+ reuse_allocator() {
+ for (size_t i = 0; i < N; ++i)
+ __buffers[i] = malloc(8 * 1024);
+ }
+ ~reuse_allocator() {
+ for (size_t i = 0; i < N; ++i)
+ free(__buffers[i]);
+ }
+ void* alloc() {
+ assert(__next_id < N);
+ return __buffers[__next_id++];
+ }
+ void reset() { __next_id = 0; }
+ void* __buffers[N];
+ size_t __next_id = 0;
+} reuse_buffers;
+
+template <typename T>
+struct user_allocator {
+ using value_type = T;
+ user_allocator() = default;
+ template <class U>
+ user_allocator(user_allocator<U>) {}
+ friend bool operator==(user_allocator, user_allocator) { return true; }
+ friend bool operator!=(user_allocator x, user_allocator y) { return !(x == y); }
+
+ T* allocate(size_t n) {
+ if (n * sizeof(T) > 8 * 1024)
+ throw std::bad_array_new_length();
+ return (T*)reuse_buffers.alloc();
+ }
+ void deallocate(T*, size_t) noexcept {}
+};
+
+// Turn off annotations for user_allocator:
+template <class T>
+struct std::__asan_annotate_container_with_allocator<user_allocator<T>> {
+ static bool const value = false;
+};
+
+int main(int, char**) {
+ using S = std::basic_string<char, std::char_traits<char>, user_allocator<char>>;
+
+ {
+ // Create a string with a buffer from reuse allocator object:
+ S* s = new (reuse_buffers.alloc()) S();
+ // Use string, so it's poisoned, if container annotations for that allocator are not turned off:
+ for (int i = 0; i < 40; i++)
+ s->push_back('a');
+ }
+ // Reset the state of the allocator, don't call destructors, allow memory to be reused:
+ reuse_buffers.reset();
+ {
+ // Create a next string with the same allocator, so the same buffer due to the reset:
+ S s;
+ // Use memory inside the string again, if it's poisoned, an error will be raised:
+ for (int i = 0; i < 60; i++)
+ s.push_back('a');
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/strings/basic.string/asan_vector_integration.pass.cpp b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_vector_integration.pass.cpp
new file mode 100644
index 0000000000000..b7d95b7069083
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/strings/basic.string/asan_vector_integration.pass.cpp
@@ -0,0 +1,182 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: asan
+// UNSUPPORTED: c++03
+
+#include <cassert>
+#include <string>
+#include <vector>
+#include <array>
+#include "test_macros.h"
+#include "asan_testing.h"
+#include "min_allocator.h"
+
+// This tests exists to check if strings work well with vector, as those
+// may be partialy annotated, we cannot simply call
+// is_contiguous_container_asan_correct, as it assumes that
+// object memory inside is not annotated, so we check everything in a more careful way.
+
+template <typename D>
+void verify_inside(D const& d) {
+ for (size_t i = 0; i < d.size(); ++i) {
+ assert(is_string_asan_correct(d[i]));
+ }
+}
+
+template <typename S, size_t N>
+S get_s(char c) {
+ S s;
+ for (size_t i = 0; i < N; ++i)
+ s.push_back(c);
+
+ return s;
+}
+
+template <class C, class S>
+void test_string() {
+ size_t const N = sizeof(S) < 256 ? (4096 / sizeof(S)) : 16;
+
+ {
+ C d1a(1), d1b(N), d1c(N + 1), d1d(5 * N);
+ verify_inside(d1a);
+ verify_inside(d1b);
+ verify_inside(d1c);
+ verify_inside(d1d);
+ }
+ {
+ C d2;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ d2.push_back(get_s<S, 1>(i % 10 + 'a'));
+ verify_inside(d2);
+ d2.push_back(get_s<S, 28>(i % 10 + 'b'));
+ verify_inside(d2);
+
+ d2.erase(d2.cbegin());
+ verify_inside(d2);
+ }
+ }
+ {
+ C d3;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ d3.push_back(get_s<S, 1>(i % 10 + 'a'));
+ verify_inside(d3);
+ d3.push_back(get_s<S, 28>(i % 10 + 'b'));
+ verify_inside(d3);
+
+ d3.pop_back();
+ verify_inside(d3);
+ }
+ }
+ {
+ C d4;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ // When there is no SSO, all elements inside should not be poisoned,
+ // so we can verify vector poisoning.
+ d4.push_back(get_s<S, 33>(i % 10 + 'a'));
+ verify_inside(d4);
+ assert(is_contiguous_container_asan_correct(d4));
+ d4.push_back(get_s<S, 28>(i % 10 + 'b'));
+ verify_inside(d4);
+ assert(is_contiguous_container_asan_correct(d4));
+ }
+ }
+ {
+ C d5;
+ for (size_t i = 0; i < 3 * N + 2; ++i) {
+ // In d4 we never had poisoned memory inside vector.
+ // Here we start with SSO, so part of the inside of the container,
+ // will be poisoned.
+ d5.push_back(S());
+ verify_inside(d5);
+ }
+ for (size_t i = 0; i < d5.size(); ++i) {
+ // We change the size to have long string.
+ // Memory owne by vector should not be poisoned by string.
+ d5[i].resize(100);
+ verify_inside(d5);
+ }
+
+ assert(is_contiguous_container_asan_correct(d5));
+
+ d5.erase(d5.begin() + 2);
+ verify_inside(d5);
+
+ d5.erase(d5.end() - 2);
+ verify_inside(d5);
+
+ assert(is_contiguous_container_asan_correct(d5));
+ }
+ {
+ C d6a;
+ assert(is_contiguous_container_asan_correct(d6a));
+
+ C d6b(N + 2, get_s<S, 100>('a'));
+ d6b.push_back(get_s<S, 101>('b'));
+ while (!d6b.empty()) {
+ d6b.pop_back();
+ assert(is_contiguous_container_asan_correct(d6b));
+ }
+
+ C d6c(N + 2, get_s<S, 102>('c'));
+ while (!d6c.empty()) {
+ d6c.pop_back();
+ assert(is_contiguous_container_asan_correct(d6c));
+ }
+ }
+ {
+ C d7(9 * N + 2);
+
+ d7.insert(d7.begin() + 1, S());
+ verify_inside(d7);
+
+ d7.insert(d7.end() - 3, S());
+ verify_inside(d7);
+
+ d7.insert(d7.begin() + 2 * N, get_s<S, 1>('a'));
+ verify_inside(d7);
+
+ d7.insert(d7.end() - 2 * N, get_s<S, 1>('b'));
+ verify_inside(d7);
+
+ d7.insert(d7.begin() + 2 * N, 3 * N, get_s<S, 1>('c'));
+ verify_inside(d7);
+
+ // It may not be short for big element types, but it will be checked correctly:
+ d7.insert(d7.end() - 2 * N, 3 * N, get_s<S, 2>('d'));
+ verify_inside(d7);
+
+ d7.erase(d7.begin() + 2);
+ verify_inside(d7);
+
+ d7.erase(d7.end() - 2);
+ verify_inside(d7);
+ }
+}
+
+template <class S>
+void test_container() {
+ test_string<std::vector<S, std::allocator<S>>, S>();
+ test_string<std::vector<S, min_allocator<S>>, S>();
+ test_string<std::vector<S, safe_allocator<S>>, S>();
+}
+
+int main(int, char**) {
+ // Those tests support only types based on std::basic_string.
+ test_container<std::string>();
+ test_container<std::wstring>();
+#if TEST_STD_VER >= 11
+ test_container<std::u16string>();
+ test_container<std::u32string>();
+#endif
+#if TEST_STD_VER >= 20
+ test_container<std::u8string>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/key_value_traits.pass.cpp b/libcxx/test/libcxx-03/containers/unord/key_value_traits.pass.cpp
new file mode 100644
index 0000000000000..e00a028489a72
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/key_value_traits.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__hash_table>
+#include <unordered_map>
+#include <unordered_set>
+#include <type_traits>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+void testKeyValueTrait() {
+ {
+ typedef int Tp;
+ typedef std::__hash_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, int>::value), "");
+ static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
+ static_assert(Traits::__is_map == false, "");
+ }
+ {
+ typedef std::pair<int, int> Tp;
+ typedef std::__hash_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
+ static_assert(Traits::__is_map == false, "");
+ }
+ {
+ typedef std::pair<const int, int> Tp;
+ typedef std::__hash_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, Tp>::value), "");
+ static_assert(Traits::__is_map == false, "");
+ }
+ {
+ typedef std::__hash_value_type<int, int> Tp;
+ typedef std::__hash_key_value_types<Tp> Traits;
+ static_assert((std::is_same<Traits::key_type, int>::value), "");
+ static_assert((std::is_same<Traits::mapped_type, int>::value), "");
+ static_assert((std::is_same<Traits::__node_value_type, Tp>::value), "");
+ static_assert((std::is_same<Traits::__container_value_type, std::pair<const int, int> >::value), "");
+ static_assert((std::is_same<Traits::__map_value_type, std::pair<const int, int> >::value), "");
+ static_assert(Traits::__is_map == true, "");
+ }
+}
+
+int main(int, char**) {
+ testKeyValueTrait();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/next_pow2.pass.cpp b/libcxx/test/libcxx-03/containers/unord/next_pow2.pass.cpp
new file mode 100644
index 0000000000000..53a1dd2d3fa76
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/next_pow2.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
+//
+//===----------------------------------------------------------------------===//
+//
+// REQUIRES: long_tests
+// UNSUPPORTED: c++03
+
+// Not a portable test
+
+// <__hash_table>
+
+// size_t __next_hash_pow2(size_t n);
+
+// If n <= 1, return n. If n is a power of 2, return n.
+// Otherwise, return the next power of 2.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__hash_table>
+#include <cassert>
+#include <cstdint>
+#include <unordered_map>
+
+#include "test_macros.h"
+
+bool is_power_of_two(unsigned long n) { return __builtin_popcount(n) == 1; }
+
+void test_next_pow2_val(std::size_t n) {
+ std::size_t npow2 = std::__next_hash_pow2(n);
+ assert(is_power_of_two(npow2) && npow2 > n);
+}
+
+void test_next_pow2() {
+ assert(!is_power_of_two(0));
+ assert(is_power_of_two(1));
+ assert(is_power_of_two(2));
+ assert(!is_power_of_two(3));
+
+ assert(std::__next_hash_pow2(0) == 0);
+ assert(std::__next_hash_pow2(1) == 1);
+
+ for (std::size_t n = 2; n < (sizeof(std::size_t) * 8 - 1); ++n) {
+ std::size_t pow2 = 1ULL << n;
+ assert(std::__next_hash_pow2(pow2) == pow2);
+ }
+
+ test_next_pow2_val(3);
+ test_next_pow2_val(7);
+ test_next_pow2_val(9);
+ test_next_pow2_val(15);
+ test_next_pow2_val(127);
+ test_next_pow2_val(129);
+}
+
+// Note: this is only really useful when run with -fsanitize=undefined.
+void fuzz_unordered_map_reserve(unsigned num_inserts, unsigned num_reserve1, unsigned num_reserve2) {
+ std::unordered_map<std::uint64_t, unsigned long> m;
+ m.reserve(num_reserve1);
+ for (unsigned I = 0; I < num_inserts; ++I)
+ m[I] = 0;
+ m.reserve(num_reserve2);
+ assert(m.bucket_count() >= num_reserve2);
+}
+
+int main(int, char**) {
+ test_next_pow2();
+
+ for (unsigned num_inserts = 0; num_inserts <= 64; ++num_inserts)
+ for (unsigned num_reserve1 = 1; num_reserve1 <= 64; ++num_reserve1)
+ for (unsigned num_reserve2 = 1; num_reserve2 <= 64; ++num_reserve2)
+ fuzz_unordered_map_reserve(num_inserts, num_reserve1, num_reserve2);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/next_prime.pass.cpp b/libcxx/test/libcxx-03/containers/unord/next_prime.pass.cpp
new file mode 100644
index 0000000000000..44b0eb96e2b9b
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/next_prime.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
+//
+//===----------------------------------------------------------------------===//
+//
+// REQUIRES: long_tests
+
+// Not a portable test
+
+// <__hash_table>
+
+// size_t __next_prime(size_t n);
+
+// If n == 0, return 0, else return the lowest prime greater than or equal to n
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__hash_table>
+#include <cassert>
+#include <cstddef>
+
+#include "test_macros.h"
+
+bool is_prime(std::size_t n) {
+ switch (n) {
+ case 0:
+ case 1:
+ return false;
+ }
+ for (std::size_t i = 2; i * i <= n; ++i) {
+ if (n % i == 0)
+ return false;
+ }
+ return true;
+}
+
+int main(int, char**) {
+ assert(std::__next_prime(0) == 0);
+ for (std::size_t n = 1; n <= 100000; ++n) {
+ std::size_t p = std::__next_prime(n);
+ assert(p >= n);
+ for (std::size_t i = n; i < p; ++i)
+ assert(!is_prime(i));
+ assert(is_prime(p));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/non_const_comparator.incomplete.verify.cpp b/libcxx/test/libcxx-03/containers/unord/non_const_comparator.incomplete.verify.cpp
new file mode 100644
index 0000000000000..c370cd65085a1
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/non_const_comparator.incomplete.verify.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
+
+// Test that libc++ does not generate a warning diagnostic about the comparator
+// or the hasher too early for containers of incomplete types.
+//
+// See PR41360.
+
+#include <unordered_set>
+#include <unordered_map>
+#include <functional>
+
+#include "test_macros.h"
+
+template <template <typename...> class Container>
+void test_set() {
+ struct KeyBase {};
+ struct KeyDerived; // derives from KeyBase, but incomplete at this point
+
+ // Name the type but don't instantiate it.
+ using C = Container<KeyDerived*, std::hash<KeyBase*>, std::equal_to<KeyBase*>>;
+
+ // Instantiate it but don't ODR use any members.
+ typename C::value_type dummy;
+ (void)dummy;
+
+ // Complete the types.
+ struct KeyDerived : KeyBase {};
+
+ C c; // ODR use it, which should be OK
+}
+
+template <template <typename...> class Container>
+void test_map() {
+ struct Value {};
+ struct KeyBase {};
+ struct KeyDerived;
+ using C = Container<KeyDerived*, Value, std::hash<KeyBase*>, std::equal_to<KeyBase*>>;
+ typename C::value_type dummy;
+ (void)dummy;
+ struct KeyDerived : KeyBase {};
+ C c;
+}
+
+void f() {
+ // expected-no-diagnostics
+ test_set<std::unordered_set>();
+ test_set<std::unordered_multiset>();
+ test_map<std::unordered_map>();
+ test_map<std::unordered_multimap>();
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/non_const_comparator.verify.cpp b/libcxx/test/libcxx-03/containers/unord/non_const_comparator.verify.cpp
new file mode 100644
index 0000000000000..c3418302d0315
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/non_const_comparator.verify.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
+// REQUIRES: diagnose-if-support
+
+// Test that libc++ generates a warning diagnostic when the container is
+// provided a non-const callable comparator or a non-const hasher.
+
+#include <__type_traits/invoke.h>
+#include <unordered_set>
+#include <unordered_map>
+
+struct BadHash {
+ template <class T>
+ std::size_t operator()(T const& t) {
+ return std::hash<T>{}(t);
+ }
+};
+
+struct BadEqual {
+ template <class T, class U>
+ bool operator()(T const& t, U const& u) {
+ return t == u;
+ }
+};
+
+void f() {
+ static_assert(!std::__is_invocable_v<BadEqual const&, int const&, int const&>, "");
+ static_assert(std::__is_invocable_v<BadEqual&, int const&, int const&>, "");
+
+ // expected-warning at unordered_set:* 2 {{the specified comparator type does not provide a viable const call operator}}
+ // expected-warning at unordered_map:* 2 {{the specified comparator type does not provide a viable const call operator}}
+ // expected-warning at unordered_set:* 2 {{the specified hash functor does not provide a viable const call operator}}
+ // expected-warning at unordered_map:* 2 {{the specified hash functor does not provide a viable const call operator}}
+
+ {
+ using C = std::unordered_set<int, BadHash, BadEqual>;
+ C s;
+ }
+ {
+ using C = std::unordered_multiset<long, BadHash, BadEqual>;
+ C s;
+ }
+ {
+ using C = std::unordered_map<int, int, BadHash, BadEqual>;
+ C s;
+ }
+ {
+ using C = std::unordered_multimap<long, int, BadHash, BadEqual>;
+ C s;
+ }
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket.pass.cpp
new file mode 100644
index 0000000000000..26621bce52187
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// size_type bucket(const key_type& __k) const;
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_map<int, std::string> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket(3), "unordered container::bucket(key) called when bucket_count() == 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket_size.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket_size.pass.cpp
new file mode 100644
index 0000000000000..ce6534f95f8dc
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.bucket_size.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+// class Alloc = allocator<pair<const Key, T>>>
+// class unordered_map
+
+// size_type bucket_size(size_type n) const
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_map<int, std::string> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket_size(3), "unordered container::bucket_size(n) called with n >= bucket_count()");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..f57341d64ff39
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.dereference.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_map<int, std::string> C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ {
+ typedef std::unordered_map<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..3f4d1c2d3bdbb
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.iterator.increment.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <cassert>
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_map<int, std::string> C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.begin();
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container iterator");
+ C::const_iterator i2 = c.cbegin();
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ {
+ typedef std::unordered_map<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.begin();
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container iterator");
+ C::const_iterator i2 = c.cbegin();
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..8b47f54895560
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.dereference.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_map<int, std::string> C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ {
+ typedef std::unordered_map<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..8f8305833e077
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.local_iterator.increment.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment local_iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_map<int, std::string> C;
+ C c;
+ c.insert(std::make_pair(42, std::string()));
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ {
+ typedef std::unordered_map<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c({{42, std::string()}});
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.max_load_factor.pass.cpp
new file mode 100644
index 0000000000000..117758c5385e0
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/assert.max_load_factor.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+// class Alloc = allocator<pair<const Key, T>>>
+// class unordered_map
+
+// float max_load_factor() const;
+// void max_load_factor(float mlf);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_map<int, std::string> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.max_load_factor(0), "unordered container::max_load_factor(lf) called with lf <= 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/at.abort.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/at.abort.pass.cpp
new file mode 100644
index 0000000000000..bd6da6c4d69c9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/at.abort.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// class unordered_map
+
+// mapped_type& at(const key_type& k);
+
+// Make sure we abort() when exceptions are disabled and we fetch a key that
+// is not in the map.
+
+// REQUIRES: no-exceptions
+// UNSUPPORTED: c++03
+
+#include <csignal>
+#include <cstdlib>
+#include <unordered_map>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::signal(SIGABRT, [](int) { std::_Exit(EXIT_SUCCESS); });
+ std::unordered_map<int, int> map;
+ map.at(1);
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/at.const.abort.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/at.const.abort.pass.cpp
new file mode 100644
index 0000000000000..badd243dc1264
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/at.const.abort.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// class unordered_map
+
+// const mapped_type& at(const key_type& k) const;
+
+// Make sure we abort() when exceptions are disabled and we fetch a key that
+// is not in the map.
+
+// REQUIRES: no-exceptions
+// UNSUPPORTED: c++03
+
+#include <csignal>
+#include <cstdlib>
+#include <unordered_map>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::signal(SIGABRT, [](int) { std::_Exit(EXIT_SUCCESS); });
+ std::unordered_map<int, int> const map;
+ map.at(1);
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_const_lvalue.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_const_lvalue.pass.cpp
new file mode 100644
index 0000000000000..927a9e8813325
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_const_lvalue.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// iterator insert(const_iterator p, const value_type& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+ typedef std::unordered_map<double, int> C;
+ typedef C::value_type P;
+ C c;
+ C c2;
+ C::const_iterator e = c2.end();
+ P v(3.5, 3);
+#if TEST_STD_VER < 11
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.insert(e, v),
+ "unordered_map::insert(const_iterator, const value_type&) called with an iterator not "
+ "referring to this unordered_map");
+#else
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.insert(e, v),
+ "unordered_map::insert(const_iterator, value_type&&) called with an iterator not "
+ "referring to this unordered_map");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_rvalue.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_rvalue.pass.cpp
new file mode 100644
index 0000000000000..e8a34c3c60851
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/debug.insert.hint_rvalue.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class P,
+// class = typename enable_if<is_convertible<P, value_type>::value>::type>
+// iterator insert(const_iterator p, P&& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+ typedef std::unordered_map<double, int> C;
+ typedef C::value_type P;
+ C c;
+ C c2;
+ C::const_iterator e = c2.end();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.insert(e, P(3.5, 3)),
+ "unordered_map::insert(const_iterator, const value_type&) called with an iterator not "
+ "referring to this unordered_map");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/debug.swap.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/debug.swap.pass.cpp
new file mode 100644
index 0000000000000..cda7f971da1e5
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/debug.swap.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class Value, class Hash = hash<Key>, class Pred = equal_to<Key>,
+// class Alloc = allocator<pair<const Key, Value>>>
+// class unordered_map
+
+// void swap(unordered_map& x, unordered_map& y);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(3, 3), P(7, 7), P(9, 9), P(10, 10)};
+ P a2[] = {P(0, 0), P(2, 2), P(4, 4), P(5, 5), P(6, 6), P(8, 8), P(11, 11)};
+ std::unordered_map<int, int> c1(a1, a1 + sizeof(a1) / sizeof(a1[0]));
+ std::unordered_map<int, int> c2(a2, a2 + sizeof(a2) / sizeof(a2[0]));
+ std::unordered_map<int, int>::iterator i1 = c1.begin();
+ std::unordered_map<int, int>::iterator i2 = c2.begin();
+ swap(c1, c2);
+ c1.erase(i2);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c1.erase(i1), "unordered container erase(iterator) called with an iterator not referring to this container");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter.pass.cpp
new file mode 100644
index 0000000000000..ef5a53e3de470
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator position) with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // With end()
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_map<int, int> l1(a1, a1 + 3);
+ std::unordered_map<int, int>::const_iterator i = l1.end();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with a non-dereferenceable iterator");
+ }
+
+ // With iterator from another container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_map<int, int> l1(a1, a1 + 3);
+ std::unordered_map<int, int> l2(a1, a1 + 3);
+ std::unordered_map<int, int>::const_iterator i = l2.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with an iterator not referring to this container");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter_iter.pass.cpp
new file mode 100644
index 0000000000000..1f364bf2ec192
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.map/unord.map.modifiers/debug.erase.iter_iter.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // First iterator from a different container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_map<int, int> l1(a1, a1 + 3);
+ std::unordered_map<int, int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l1.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // Second iterator from a different container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_map<int, int> l1(a1, a1 + 3);
+ std::unordered_map<int, int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l1.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // Both iterators from a different container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_map<int, int> l1(a1, a1 + 3);
+ std::unordered_map<int, int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With iterators that don't form a valid range
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_map<int, int> l1(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(std::next(l1.cbegin()), l1.cbegin()),
+ "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket.pass.cpp
new file mode 100644
index 0000000000000..61c1651fdd956
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+// class Alloc = allocator<pair<const Key, T>>>
+// class unordered_multimap
+
+// size_type bucket(const key_type& __k) const;
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multimap<int, std::string> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket(3), "unordered container::bucket(key) called when bucket_count() == 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket_size.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket_size.pass.cpp
new file mode 100644
index 0000000000000..8f2efdb6e56e6
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.bucket_size.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+// class Alloc = allocator<pair<const Key, T>>>
+// class unordered_multimap
+
+// size_type bucket_size(size_type n) const
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multimap<int, std::string> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket_size(3), "unordered container::bucket_size(n) called with n >= bucket_count()");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..d295a82a8a1f5
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.dereference.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+#include <unordered_map>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_multimap<int, std::string> C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ {
+ typedef std::unordered_multimap<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..4247edc8def97
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.iterator.increment.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <cassert>
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_multimap<int, std::string> C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.begin();
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container iterator");
+ C::const_iterator i2 = c.cbegin();
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ {
+ typedef std::unordered_multimap<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c;
+ c.insert(std::make_pair(1, "one"));
+ C::iterator i = c.begin();
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container iterator");
+ C::const_iterator i2 = c.cbegin();
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..7ea87964e05f0
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.dereference.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_multimap<int, std::string> C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ {
+ typedef std::unordered_multimap<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..ffa3fec0ca1f1
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.local_iterator.increment.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment local_iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <cassert>
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef std::unordered_multimap<int, std::string> C;
+ C c;
+ c.insert(std::make_pair(42, std::string()));
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ {
+ typedef std::unordered_multimap<int,
+ std::string,
+ std::hash<int>,
+ std::equal_to<int>,
+ min_allocator<std::pair<const int, std::string>>>
+ C;
+ C c({{1, std::string()}});
+ c.insert(std::make_pair(42, std::string()));
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp
new file mode 100644
index 0000000000000..dda5fe8b632bd
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+// class Alloc = allocator<pair<const Key, T>>>
+// class unordered_multimap
+
+// float max_load_factor() const;
+// void max_load_factor(float mlf);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_map>
+#include <string>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multimap<int, std::string> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.max_load_factor(0), "unordered container::max_load_factor(lf) called with lf <= 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_const_lvalue.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_const_lvalue.pass.cpp
new file mode 100644
index 0000000000000..017431077b714
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_const_lvalue.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// iterator insert(const_iterator p, const value_type& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multimap<double, int> C;
+ typedef C::value_type P;
+ C c;
+ C c2;
+ C::const_iterator e = c2.end();
+ P v(3.5, 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.insert(e, v),
+ "unordered container::emplace_hint(const_iterator, args...) called with an iterator not "
+ "referring to this unordered container");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_rvalue.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_rvalue.pass.cpp
new file mode 100644
index 0000000000000..3713d78e347fa
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.insert.hint_rvalue.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class P,
+// class = typename enable_if<is_convertible<P, value_type>::value>::type>
+// iterator insert(const_iterator p, P&& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multimap<double, int> C;
+ typedef C::value_type P;
+ C c;
+ C c2;
+ C::const_iterator e = c2.end();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.insert(e, P(3.5, 3)),
+ "unordered container::emplace_hint(const_iterator, args...) called with an iterator not "
+ "referring to this unordered container");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.swap.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.swap.pass.cpp
new file mode 100644
index 0000000000000..d467182c8fae9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/debug.swap.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class Value, class Hash = hash<Key>, class Pred = equal_to<Key>,
+// class Alloc = allocator<pair<const Key, Value>>>
+// class unordered_multimap
+
+// void swap(unordered_multimap& x, unordered_multimap& y);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(3, 3), P(7, 7), P(9, 9), P(10, 10)};
+ P a2[] = {P(0, 0), P(2, 2), P(4, 4), P(5, 5), P(6, 6), P(8, 8), P(11, 11)};
+ std::unordered_multimap<int, int> c1(a1, a1 + sizeof(a1) / sizeof(a1[0]));
+ std::unordered_multimap<int, int> c2(a2, a2 + sizeof(a2) / sizeof(a2[0]));
+ std::unordered_multimap<int, int>::iterator i1 = c1.begin();
+ std::unordered_multimap<int, int>::iterator i2 = c2.begin();
+ swap(c1, c2);
+ c1.erase(i2);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c1.erase(i1), "unordered container erase(iterator) called with an iterator not referring to this container");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter.pass.cpp
new file mode 100644
index 0000000000000..0a430edf8b7b6
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator position) with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // With end()
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_multimap<int, int> l1(a1, a1 + 3);
+ std::unordered_multimap<int, int>::const_iterator i = l1.end();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with a non-dereferenceable iterator");
+ }
+
+ // With iterator from another container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_multimap<int, int> l1(a1, a1 + 3);
+ std::unordered_multimap<int, int> l2(a1, a1 + 3);
+ std::unordered_multimap<int, int>::const_iterator i = l2.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with an iterator not referring to this container");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter_iter.pass.cpp
new file mode 100644
index 0000000000000..8c1382c5bbae4
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multimap/unord.multimap.modifiers/debug.erase.iter_iter.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_map>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // With first iterator from another container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_multimap<int, int> l1(a1, a1 + 3);
+ std::unordered_multimap<int, int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l1.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With second iterator from another container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_multimap<int, int> l1(a1, a1 + 3);
+ std::unordered_multimap<int, int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l1.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With both iterators from another container
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_multimap<int, int> l1(a1, a1 + 3);
+ std::unordered_multimap<int, int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With an invalid range
+ {
+ typedef std::pair<int, int> P;
+ P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+ std::unordered_multimap<int, int> l1(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(std::next(l1.cbegin()), l1.cbegin()),
+ "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket.pass.cpp
new file mode 100644
index 0000000000000..eebf11c27bb17
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_multiset
+
+// size_type bucket(const key_type& __k) const;
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multiset<int> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket(3), "unordered container::bucket(key) called when bucket_count() == 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket_size.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket_size.pass.cpp
new file mode 100644
index 0000000000000..1c107ca11193c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.bucket_size.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_multiset
+
+// size_type bucket_size(size_type n) const
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multiset<int> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket_size(3), "unordered container::bucket_size(n) called with n >= bucket_count()");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..31edd6099c965
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.dereference.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T> C;
+ C c(1);
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c(1);
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..0e0e4aab303cd
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.iterator.increment.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T> C;
+ C c;
+ c.insert(42);
+ C::iterator i = c.begin();
+ assert(i != c.end());
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container const_iterator");
+ C::const_iterator i2 = c.cbegin();
+ assert(i2 != c.cend());
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c({42});
+ C::iterator i = c.begin();
+ assert(i != c.end());
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container const_iterator");
+ C::const_iterator i2 = c.cbegin();
+ assert(i2 != c.cend());
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..fe833c40bc351
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.dereference.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T> C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..142c07f83c066
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.local_iterator.increment.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment local_iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T> C;
+ C c;
+ c.insert(42);
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_multiset<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c({42});
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp
new file mode 100644
index 0000000000000..a38849482cee9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_multiset
+
+// float max_load_factor() const;
+// void max_load_factor(float mlf);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multiset<int> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.max_load_factor(0), "unordered container::max_load_factor(lf) called with lf <= 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter.pass.cpp
new file mode 100644
index 0000000000000..41818b814cf98
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator position) with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // With end()
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_multiset<int> l1(a1, a1 + 3);
+ std::unordered_multiset<int>::const_iterator i = l1.end();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with a non-dereferenceable iterator");
+ }
+
+ // With iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_multiset<int> l1(a1, a1 + 3);
+ std::unordered_multiset<int> l2(a1, a1 + 3);
+ std::unordered_multiset<int>::const_iterator i = l2.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with an iterator not referring to this container");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter_iter.pass.cpp
new file mode 100644
index 0000000000000..a85a61c17575c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.erase.iter_iter.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // With first iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_multiset<int> l1(a1, a1 + 3);
+ std::unordered_multiset<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l1.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With second iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_multiset<int> l1(a1, a1 + 3);
+ std::unordered_multiset<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l1.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With both iterators from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_multiset<int> l1(a1, a1 + 3);
+ std::unordered_multiset<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With an invalid range
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_multiset<int> l1(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(std::next(l1.cbegin()), l1.cbegin()),
+ "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.insert.hint_const_lvalue.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.insert.hint_const_lvalue.pass.cpp
new file mode 100644
index 0000000000000..2274dd3e710ee
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.insert.hint_const_lvalue.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// iterator insert(const_iterator p, const value_type& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_multiset<double> C;
+ typedef C::value_type P;
+ C c;
+ C c2;
+ C::const_iterator e = c2.end();
+ P v(3.5);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.insert(e, v),
+ "unordered container::emplace_hint(const_iterator, args...) called with an iterator not "
+ "referring to this unordered container");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.swap.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.swap.pass.cpp
new file mode 100644
index 0000000000000..aa6b56f83fcc9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.multiset/debug.swap.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_multiset
+
+// void swap(unordered_multiset& x, unordered_multiset& y);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ int a1[] = {1, 3, 7, 9, 10};
+ int a2[] = {0, 2, 4, 5, 6, 8, 11};
+ std::unordered_multiset<int> c1(a1, a1 + sizeof(a1) / sizeof(a1[0]));
+ std::unordered_multiset<int> c2(a2, a2 + sizeof(a2) / sizeof(a2[0]));
+ std::unordered_multiset<int>::iterator i1 = c1.begin();
+ std::unordered_multiset<int>::iterator i2 = c2.begin();
+ swap(c1, c2);
+ c1.erase(i2);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c1.erase(i1), "unordered container erase(iterator) called with an iterator not referring to this container");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket.pass.cpp
new file mode 100644
index 0000000000000..6504a88a2e1f6
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_set
+
+// size_type bucket(const key_type& __k) const;
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_set<int> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket(3), "unordered container::bucket(key) called when bucket_count() == 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket_size.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket_size.pass.cpp
new file mode 100644
index 0000000000000..18440548d76c2
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.bucket_size.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_set
+
+// size_type bucket_size(size_type n) const
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_set<int> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.bucket_size(3), "unordered container::bucket_size(n) called with n >= bucket_count()");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..8464601f61046
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.dereference.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_set<T> C;
+ C c(1);
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_set<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c(1);
+ C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ C::const_iterator i2 = c.cend();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..29446880900bc
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.iterator.increment.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_set<T> C;
+ C c;
+ c.insert(42);
+ C::iterator i = c.begin();
+ assert(i != c.end());
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container const_iterator");
+ C::const_iterator i2 = c.cbegin();
+ assert(i2 != c.cend());
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_set<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c({42});
+ C::iterator i = c.begin();
+ assert(i != c.end());
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-incrementable unordered container const_iterator");
+ C::const_iterator i2 = c.cbegin();
+ assert(i2 != c.cend());
+ ++i2;
+ assert(i2 == c.cend());
+ TEST_LIBCPP_ASSERT_FAILURE(++i2, "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..7163e3735cee0
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.dereference.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_set<T> C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_set<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c(1);
+ C::local_iterator i = c.end(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cend(0);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *i2, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.increment.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..c9fe5afd09702
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.local_iterator.increment.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment local_iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ typedef std::unordered_set<T> C;
+ C c;
+ c.insert(42);
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ {
+ typedef int T;
+ typedef std::unordered_set<T, std::hash<T>, std::equal_to<T>, min_allocator<T>> C;
+ C c({42});
+ C::size_type b = c.bucket(42);
+ C::local_iterator i = c.begin(b);
+ assert(i != c.end(b));
+ ++i;
+ assert(i == c.end(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ C::const_local_iterator i2 = c.cbegin(b);
+ assert(i2 != c.cend(b));
+ ++i2;
+ assert(i2 == c.cend(b));
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++i2, "Attempted to increment a non-incrementable unordered container const_local_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.max_load_factor.pass.cpp
new file mode 100644
index 0000000000000..80e89411d99c3
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/assert.max_load_factor.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_set
+
+// float max_load_factor() const;
+// void max_load_factor(float mlf);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_set<int> C;
+ C c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.max_load_factor(-0.5f), "unordered container::max_load_factor(lf) called with lf <= 0");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter.pass.cpp
new file mode 100644
index 0000000000000..8dbcb0576cd85
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator position) with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // With end()
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_set<int> l1(a1, a1 + 3);
+ std::unordered_set<int>::const_iterator i = l1.end();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with a non-dereferenceable iterator");
+ }
+
+ // With iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_set<int> l1(a1, a1 + 3);
+ std::unordered_set<int> l2(a1, a1 + 3);
+ std::unordered_set<int>::const_iterator i = l2.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "unordered container erase(iterator) called with an iterator not referring to this container");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter_iter.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter_iter.pass.cpp
new file mode 100644
index 0000000000000..c714b70ced328
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.erase.iter_iter.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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with first iterator from another container
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // With first iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_set<int> l1(a1, a1 + 3);
+ std::unordered_set<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l1.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With second iterator from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_set<int> l1(a1, a1 + 3);
+ std::unordered_set<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l1.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With both iterators from another container
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_set<int> l1(a1, a1 + 3);
+ std::unordered_set<int> l2(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), std::next(l2.cbegin())),
+ "unordered container::erase(iterator, iterator) called with an iterator not referring to this container");
+ }
+
+ // With an invalid range
+ {
+ int a1[] = {1, 2, 3};
+ std::unordered_set<int> l1(a1, a1 + 3);
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(std::next(l1.cbegin()), l1.cbegin()),
+ "Attempted to increment a non-incrementable unordered container const_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/debug.insert.hint_const_lvalue.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.insert.hint_const_lvalue.pass.cpp
new file mode 100644
index 0000000000000..2d4e0e7350831
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.insert.hint_const_lvalue.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// iterator insert(const_iterator p, const value_type& x);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ typedef std::unordered_set<double> C;
+ typedef C::value_type P;
+ C c;
+ C c2;
+ C::const_iterator e = c2.end();
+ P v(3.5);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c.insert(e, v),
+ "unordered_set::insert(const_iterator, const value_type&) called with an iterator not "
+ "referring to this unordered_set");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/debug.swap.pass.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.swap.pass.cpp
new file mode 100644
index 0000000000000..8f362f318f2e3
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/debug.swap.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+// class Alloc = allocator<Value>>
+// class unordered_set
+
+// void swap(unordered_set& x, unordered_set& y);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <unordered_set>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ int a1[] = {1, 3, 7, 9, 10};
+ int a2[] = {0, 2, 4, 5, 6, 8, 11};
+ std::unordered_set<int> c1(a1, a1 + sizeof(a1) / sizeof(a1[0]));
+ std::unordered_set<int> c2(a2, a2 + sizeof(a2) / sizeof(a2[0]));
+ std::unordered_set<int>::iterator i1 = c1.begin();
+ std::unordered_set<int>::iterator i2 = c2.begin();
+ swap(c1, c2);
+ c1.erase(i2);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ c1.erase(i1), "unordered container erase(iterator) called with an iterator not referring to this container");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/unord/unord.set/missing_hash_specialization.verify.cpp b/libcxx/test/libcxx-03/containers/unord/unord.set/missing_hash_specialization.verify.cpp
new file mode 100644
index 0000000000000..c66496acc6d07
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/unord/unord.set/missing_hash_specialization.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: diagnose-if-support
+// UNSUPPORTED: c++03
+
+// Libc++ only provides a defined primary template for std::hash in C++14 and
+// newer.
+// UNSUPPORTED: c++11
+
+// <unordered_set>
+
+// Test that we generate a reasonable diagnostic when the specified hash is
+// not enabled.
+
+#include <unordered_set>
+#include <utility>
+
+using VT = std::pair<int, int>;
+
+struct BadHashNoCopy {
+ BadHashNoCopy() = default;
+ BadHashNoCopy(BadHashNoCopy const&) = delete;
+
+ template <class T>
+ std::size_t operator()(T const&) const {
+ return 0;
+ }
+};
+
+struct BadHashNoCall {};
+
+struct GoodHashNoDefault {
+ explicit GoodHashNoDefault(void*) {}
+ template <class T>
+ std::size_t operator()(T const&) const {
+ return 0;
+ }
+};
+
+int main(int, char**) {
+ {
+ using Set = std::unordered_set<VT>;
+ Set s; // expected-error at __hash_table:* {{the specified hash does not meet the Hash requirements}}
+
+ // FIXME: It would be great to suppress the below diagnostic all together.
+ // but for now it's sufficient that it appears last. However there is
+ // currently no way to test the order diagnostics are issued.
+ // expected-error@*:* {{call to implicitly-deleted default constructor}}
+ }
+ {
+ using Set = std::unordered_set<int, BadHashNoCopy>;
+ Set s; // expected-error at __hash_table:* {{the specified hash does not meet the Hash requirements}}
+ }
+ {
+ using Set = std::unordered_set<int, BadHashNoCall>;
+ Set s; // expected-error at __hash_table:* {{the specified hash does not meet the Hash requirements}}
+ }
+ {
+ using Set = std::unordered_set<int, GoodHashNoDefault>;
+ Set s(/*bucketcount*/ 42, GoodHashNoDefault(nullptr));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
new file mode 100644
index 0000000000000..fbc8386a72ded
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/byte_alignment.verify.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, c++20, c++23
+
+// <mdspan>
+
+// template<class ElementType, size_t ByteAlignment>
+// class aligned_accessor;
+
+// ByteAlignement is required to be a power of two and greater or equal to alignof(ElementType).
+
+#include <mdspan>
+
+void not_power_of_two() {
+ // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: byte alignment must be a power of two}}
+ [[maybe_unused]] std::aligned_accessor<int, 12> acc;
+}
+
+struct alignas(8) S {};
+
+void insufficiently_aligned() {
+ // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: insufficient byte alignment}}
+ [[maybe_unused]] std::aligned_accessor<S, 4> acc;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/element_type.verify.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
new file mode 100644
index 0000000000000..91510a99aeec9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
@@ -0,0 +1,32 @@
+//
+// 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, c++23
+
+// <mdspan>
+
+// template<class ElementType, size_t ByteAlignment>
+// class aligned_accessor;
+
+// ElementType is required to be a complete object type that is neither an abstract class type nor an array type.
+
+#include <mdspan>
+
+class AbstractClass {
+public:
+ virtual void method() = 0;
+};
+
+void not_abstract_class() {
+ // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: template argument may not be an abstract class}}
+ [[maybe_unused]] std::aligned_accessor<AbstractClass, 8> acc;
+}
+
+void not_array_type() {
+ // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: template argument may not be an array type}}
+ [[maybe_unused]] std::aligned_accessor<int[5], 128> acc;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.conversion.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.conversion.pass.cpp
new file mode 100644
index 0000000000000..31766e4c51c3b
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.conversion.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
+//
+//===----------------------------------------------------------------------===//
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherIndexType, size_t... OtherExtents>
+// constexpr explicit(see below) extents(const extents<OtherIndexType, OtherExtents...>&) noexcept;
+//
+// Constraints:
+// * sizeof...(OtherExtents) == rank() is true.
+// * ((OtherExtents == dynamic_extent || Extents == dynamic_extent ||
+// OtherExtents == Extents) && ...) is true.
+//
+// Preconditions:
+// * other.extent(r) equals Er for each r for which Er is a static extent, and
+// * either
+// - sizeof...(OtherExtents) is zero, or
+// - other.extent(r) is representable as a value of type index_type for
+// every rank index r of other.
+//
+// Remarks: The expression inside explicit is equivalent to:
+// (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||
+// (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ std::extents<int, D, D> arg{1000, 5};
+
+ // working case
+ {
+ [[maybe_unused]] std::extents<size_t, D, 5> e(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<int, D, 3> e(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // value out of range
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<signed char, D, 5> e(arg); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
new file mode 100644
index 0000000000000..90cb0c84a063b
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_array.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
+//
+//===----------------------------------------------------------------------===//
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// Test construction from array:
+//
+// template<class OtherIndexType, size_t N>
+// constexpr explicit(N != rank_dynamic()) extents(const array<OtherIndexType, N>& exts) noexcept;
+//
+// Constraints:
+// * is_convertible_v<const OtherIndexType&, index_type> is true,
+// * is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
+// * N == rank_dynamic() || N == rank() is true.
+//
+// Preconditions:
+// * If N != rank_dynamic() is true, exts[r] equals Er for each r for which
+// Er is a static extent, and
+// * either
+// - N is zero, or
+// - exts[r] is nonnegative and is representable as a value of type index_type
+// for every rank index r.
+//
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ // working case
+ {
+ [[maybe_unused]] std::extents<int, D, 5> e1(std::array{1000, 5}); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<int, D, 5> e1(std::array{1000, 3}); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // value out of range
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(std::array{1000, 5}); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // negative value
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(std::array{-1, 5}); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
new file mode 100644
index 0000000000000..37e79aabf8532
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
@@ -0,0 +1,62 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// Test construction from integral:
+//
+// template<class ... OtherIndexTypes>
+// constexpr explicit extents(OtherIndexTypes ... exts) noexcept;
+//
+// Let N be sizeof...(OtherIndexTypes), and let
+// exts_arr be array<index_type, N>{static_cast<index_type>(std::move(exts))...}.
+//
+// Constraints:
+// * (is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
+// * (is_nothrow_constructible_v<index_type, OtherIndexType> && ...) is true, and
+// * N == rank_dynamic() || N == rank() is true.
+//
+// Preconditions:
+// * If N != rank_dynamic() is true, exts_arr[r] equals Er for each r for which
+// Er is a static extent, and
+// * either
+// - sizeof...(exts) == 0 is true, or
+// - each element of exts is nonnegative and is representable as a value of type index_type.
+//
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ // working case
+ {
+ [[maybe_unused]] std::extents<int, D, 5> e1(1000, 5); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<int, D, 5> e1(1000, 3); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // value out of range
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(1000, 5); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // negative value
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(-1, 5); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
new file mode 100644
index 0000000000000..650fecf62128c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
@@ -0,0 +1,63 @@
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// Test construction from span:
+//
+// template<class OtherIndexType, size_t N>
+// constexpr explicit(N != rank_dynamic()) extents(span<OtherIndexType, N> exts) noexcept;
+//
+// Constraints:
+// * is_convertible_v<const OtherIndexType&, index_type> is true,
+// * is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
+// * N == rank_dynamic() || N == rank() is true.
+//
+// Preconditions:
+// * If N != rank_dynamic() is true, exts[r] equals Er for each r for which
+// Er is a static extent, and
+// * either
+// - N is zero, or
+// - exts[r] is nonnegative and is representable as a value of type index_type
+// for every rank index r.
+//
+
+#include <cassert>
+#include <mdspan>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ // working case sanity check
+ {
+ std::array args{1000, 5};
+ [[maybe_unused]] std::extents<int, D, 5> e1(std::span{args});
+ }
+ // mismatch of static extent
+ {
+ std::array args{1000, 3};
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<int, D, 5> e1(std::span{args}); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // value out of range
+ {
+ std::array args{1000, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<signed char, D, 5> e1(std::span{args}); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // negative value
+ {
+ std::array args{-1, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<signed char, D, 5> e1(std::span{args}); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.obs.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.obs.pass.cpp
new file mode 100644
index 0000000000000..c473879d87b71
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/extents/assert.obs.pass.cpp
@@ -0,0 +1,65 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// static constexpr size_t static_extent(rank_type i) noexcept;
+//
+// Preconditions: i < rank() is true.
+//
+// Returns: Ei.
+//
+//
+// constexpr index_type extent(rank_type i) const noexcept;
+//
+// Preconditions: i < rank() is true.
+//
+// Returns: Di.
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // mismatch of static extent
+ {
+ std::extents<int> e;
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(0); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(0); }()), "extents access: index must be less than rank");
+ }
+ {
+ std::extents<int, D> e;
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
+ }
+ {
+ std::extents<int, 5> e;
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
+ }
+ {
+ std::extents<int, D, 5> e;
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
+ }
+ {
+ std::extents<int, 1, 2, 3, 4, 5, 6, 7, 8> e;
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(9); }()), "extents access: index must be less than rank");
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(9); }()), "extents access: index must be less than rank");
+ }
+
+ // check that static_extent works in constant expression with assertions enabled
+ static_assert(std::extents<int, D, 5>::static_extent(1) == 5);
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.conversion.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
new file mode 100644
index 0000000000000..7b6616f19d724
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherExtents>
+// constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+// mapping(const mapping<OtherExtents>&) noexcept;
+
+// Constraints: is_constructible_v<extents_type, OtherExtents> is true.
+//
+// Preconditions: other.required_span_size() is representable as a value of type index_type.
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ std::extents<int, D, D> arg_exts{100, 5};
+ std::layout_left::mapping<std::extents<int, D, D>> arg(arg_exts);
+
+ // working case
+ {
+ [[maybe_unused]] std::layout_left::mapping<std::extents<size_t, D, 5>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<int, D, 3>> m(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // non-representability of extents itself
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_left::mapping<std::extents<signed char, D>> m(
+ std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
+ }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // required_span_size not representable, while individual extents are
+ {
+ // check extents would be constructible
+ [[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
+ // but the product is not, so we can't use it for layout_left
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_left::mapping<std::extents<signed char, D, 5>> m(arg); }()),
+ "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
new file mode 100644
index 0000000000000..7c96f8ec9353f
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// constexpr mapping(const extents_type& e) noexcept;
+//
+// Preconditions: The size of the multidimensional index space e is representable as a value of type index_type ([basic.fundamental]).
+//
+// Effects: Direct-non-list-initializes extents_ with e.
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // value out of range
+ {
+ // the extents are representable but the product is not, so we can't use it for layout_left
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_left::mapping<std::extents<signed char, D, 5>> m(std::extents<signed char, D, 5>(100)); }()),
+ "layout_left::mapping extents ctor: product of extents must be representable as index_type.");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
new file mode 100644
index 0000000000000..e578bac2103b0
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_right.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherExtents>
+// constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+// mapping(const layout_right::mapping<OtherExtents>&) noexcept;
+
+// Constraints:
+// - extents_type::rank() <= 1 is true, and
+// - is_constructible_v<extents_type, OtherExtents> is true.
+//
+// Preconditions: other.required_span_size() is representable as a value of type index_type
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ std::extents<int, D> arg_exts{5};
+ std::layout_right::mapping<std::extents<int, D>> arg(arg_exts);
+
+ // working case
+ {
+ [[maybe_unused]] std::layout_left::mapping<std::extents<size_t, 5>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<int, 3>> m(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // non-representability of extents itself
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_left::mapping<std::extents<signed char, D>> m(
+ std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
+ }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+
+ // Can't trigger required_span_size() representability assertion, since for rank-1 the above check will trigger first,
+ // and this conversion constructor is constrained on rank <= 1.
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_stride.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_stride.pass.cpp
new file mode 100644
index 0000000000000..cec8df8aba8d6
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.ctor.layout_stride.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-ctad-maybe-unsupported
+
+// FIXME: https://github.com/llvm/llvm-project/issues/64719
+// There appear to be some issues around ctad which make it
+// currently impossible to get this code warning free.
+// Thus added the additional compile flag above
+
+// <mdspan>
+
+// template<class OtherExtents>
+// constexpr explicit(extents_type::rank() > 0)
+// mapping(const layout_stride::mapping<OtherExtents>& other);
+//
+// Constraints: is_constructible_v<extents_type, OtherExtents> is true.
+//
+// Preconditions:
+// - If extents_type::rank() > 0 is true, then for all r in the range [0, extents_type::rank()),
+// other.stride(r) equals other.extents().fwd-prod-of-extents(r), and
+// - other.required_span_size() is representable as a value of type index_type ([basic.fundamental]).
+//
+// Effects: Direct-non-list-initializes extents_ with other.extents().
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // working case
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(5), std::array<int, 1>{1});
+ [[maybe_unused]] std::layout_left::mapping<std::extents<size_t, 5>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(5), std::array<int, 1>{1});
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<int, 3>> m(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // non-representability of extents itself
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(500), std::array<int, 1>{1});
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<signed char, D>> m(arg); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // non-representability of required span size
+ {
+ std::layout_stride::mapping arg(std::extents<int, D, D>(100, 3), std::array<int, 2>{1, 100});
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_left::mapping<std::extents<signed char, D, D>> m(arg); }()),
+ "layout_left::mapping from layout_stride ctor: other.required_span_size() must be "
+ "representable as index_type.");
+ }
+ // strides are not layout_left compatible
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(5), std::array<int, 1>{2});
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_left::mapping<std::extents<size_t, 5>> m(arg); }()),
+ "layout_left::mapping from layout_stride ctor: strides are not compatible with layout_left.");
+ }
+ {
+ std::layout_stride::mapping arg(std::extents<int, D, D>(100, 3), std::array<int, 2>{2, 200});
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_left::mapping<std::extents<int, D, D>> m(arg); }()),
+ "layout_left::mapping from layout_stride ctor: strides are not compatible with layout_left.");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
new file mode 100644
index 0000000000000..79e424fbb52cb
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class... Indices>
+// constexpr index_type operator()(Indices... i) const noexcept;
+//
+// Constraints:
+// - sizeof...(Indices) == extents_type::rank() is true,
+// - (is_convertible_v<Indices, index_type> && ...) is true, and
+// - (is_nothrow_constructible_v<index_type, Indices> && ...) is true.
+//
+// Preconditions: extents_type::index-cast(i) is a multidimensional index in extents_ ([mdspan.overview]).
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // value out of range
+ {
+ std::layout_left::mapping<std::extents<unsigned char, 5>> m;
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_left::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_left::mapping<std::extents<signed char, 5>> m;
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_left::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_left::mapping<std::dextents<unsigned char, 1>> m(std::dextents<unsigned char, 1>(5));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_left::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_left::mapping<std::dextents<signed char, 1>> m(std::dextents<signed char, 1>(5));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_left::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_left::mapping<std::dextents<int, 3>> m(std::dextents<int, 3>(5, 7, 9));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, -1, -1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, 0, 0), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, -1, 0), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, 0, -1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 3, 3), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 7, 3), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 3, 9), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 7, 9), "layout_left::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_left::mapping<std::dextents<unsigned, 3>> m(std::dextents<int, 3>(5, 7, 9));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, -1, -1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, 0, 0), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, -1, 0), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, 0, -1), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 3, 3), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 7, 3), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 3, 9), "layout_left::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 7, 9), "layout_left::mapping: out of bounds indexing");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.stride.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.stride.pass.cpp
new file mode 100644
index 0000000000000..61a5149c6881a
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_left/assert.stride.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// layout_left::mapping
+//
+// constexpr index_type stride(rank_type i) const noexcept;
+//
+// Constraints: extents_type::rank() > 0 is true.
+//
+// Preconditions: i < extents_type::rank() is true.
+//
+// Returns: extents().rev-prod-of-extents(i).
+//
+//
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // value out of range
+ {
+ std::layout_left::mapping<std::dextents<int, 3>> m{std::dextents<int, 3>{100, 100, 100}};
+
+ TEST_LIBCPP_ASSERT_FAILURE(m.stride(4), "layout_left::mapping::stride(): invalid rank index");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.conversion.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
new file mode 100644
index 0000000000000..df16edb925407
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherExtents>
+// constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+// mapping(const mapping<OtherExtents>&) noexcept;
+
+// Constraints: is_constructible_v<extents_type, OtherExtents> is true.
+//
+// Preconditions: other.required_span_size() is representable as a value of type index_type.
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ std::extents<int, D, D> arg_exts{100, 5};
+ std::layout_right::mapping<std::extents<int, D, D>> arg(arg_exts);
+
+ // working case
+ {
+ [[maybe_unused]] std::layout_right::mapping<std::extents<size_t, D, 5>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<int, D, 3>> m(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // non-representability of extents itself
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_right::mapping<std::extents<signed char, D>> m(
+ std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
+ }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // required_span_size not representable, while individual extents are
+ {
+ // check extents would be constructible
+ [[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
+ // but the product is not, so we can't use it for layout_right
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_right::mapping<std::extents<signed char, D, 5>> m(arg); }()),
+ "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
new file mode 100644
index 0000000000000..52095691f6d24
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// constexpr mapping(const extents_type& e) noexcept;
+//
+// Preconditions: The size of the multidimensional index space e is representable as a value of type index_type ([basic.fundamental]).
+//
+// Effects: Direct-non-list-initializes extents_ with e.
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // value out of range
+ {
+ // the extents are representable but the product is not, so we can't use it for layout_right
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_right::mapping<std::extents<signed char, D, 5>> m(std::extents<signed char, D, 5>(100));
+ }()),
+ "layout_right::mapping extents ctor: product of extents must be representable as index_type.");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
new file mode 100644
index 0000000000000..1757ddb286b9c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_left.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherExtents>
+// constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
+// mapping(const layout_left::mapping<OtherExtents>&) noexcept;
+
+// Constraints:
+// - extents_type::rank() <= 1 is true, and
+// - is_constructible_v<extents_type, OtherExtents> is true.
+//
+// Preconditions: other.required_span_size() is representable as a value of type index_type
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ std::extents<int, D> arg_exts{5};
+ std::layout_left::mapping<std::extents<int, D>> arg(arg_exts);
+
+ // working case
+ {
+ [[maybe_unused]] std::layout_right::mapping<std::extents<size_t, 5>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<int, 3>> m(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // non-representability of extents itself
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_right::mapping<std::extents<signed char, D>> m(
+ std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
+ }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+
+ // Can't trigger required_span_size() representability assertion, since for rank-1 the above check will trigger first,
+ // and this conversion constructor is constrained on rank <= 1.
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_stride.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_stride.pass.cpp
new file mode 100644
index 0000000000000..b77d964540f9d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.ctor.layout_stride.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-ctad-maybe-unsupported
+
+// FIXME: https://github.com/llvm/llvm-project/issues/64719
+// There appear to be some issues around ctad which make it
+// currently impossible to get this code warning free.
+// Thus added the additional compile flag above
+
+// <mdspan>
+
+// template<class OtherExtents>
+// constexpr explicit(extents_type::rank() > 0)
+// mapping(const layout_stride::mapping<OtherExtents>& other);
+//
+// Constraints: is_constructible_v<extents_type, OtherExtents> is true.
+//
+// Preconditions:
+// - If extents_type::rank() > 0 is true, then for all r in the range [0, extents_type::rank()),
+// other.stride(r) equals other.extents().fwd-prod-of-extents(r), and
+// - other.required_span_size() is representable as a value of type index_type ([basic.fundamental]).
+//
+// Effects: Direct-non-list-initializes extents_ with other.extents().
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // working case
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(5), std::array<int, 1>{1});
+ [[maybe_unused]] std::layout_right::mapping<std::extents<size_t, 5>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(5), std::array<int, 1>{1});
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<int, 3>> m(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // non-representability of extents itself
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(500), std::array<int, 1>{1});
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<signed char, D>> m(arg); }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // non-representability of required span size
+ {
+ std::layout_stride::mapping arg(std::extents<int, D, D>(100, 3), std::array<int, 2>{3, 1});
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_right::mapping<std::extents<signed char, D, D>> m(arg); }()),
+ "layout_right::mapping from layout_stride ctor: other.required_span_size() must be "
+ "representable as index_type.");
+ }
+ // strides are not layout_right compatible
+ {
+ std::layout_stride::mapping arg(std::extents<int, D>(5), std::array<int, 1>{2});
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_right::mapping<std::extents<size_t, 5>> m(arg); }()),
+ "layout_right::mapping from layout_stride ctor: strides are not compatible with layout_right.");
+ }
+ {
+ std::layout_stride::mapping arg(std::extents<int, D, D>(100, 3), std::array<int, 2>{6, 2});
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_right::mapping<std::extents<int, D, D>> m(arg); }()),
+ "layout_right::mapping from layout_stride ctor: strides are not compatible with layout_right.");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
new file mode 100644
index 0000000000000..7fae6f87caf7c
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class... Indices>
+// constexpr index_type operator()(Indices... i) const noexcept;
+//
+// Constraints:
+// - sizeof...(Indices) == extents_type::rank() is true,
+// - (is_convertible_v<Indices, index_type> && ...) is true, and
+// - (is_nothrow_constructible_v<index_type, Indices> && ...) is true.
+//
+// Preconditions: extents_type::index-cast(i) is a multidimensional index in extents_ ([mdspan.overview]).
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // value out of range
+ {
+ std::layout_right::mapping<std::extents<unsigned char, 5>> m;
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_right::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_right::mapping<std::extents<signed char, 5>> m;
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_right::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_right::mapping<std::dextents<unsigned char, 1>> m(std::dextents<unsigned char, 1>(5));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_right::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_right::mapping<std::dextents<signed char, 1>> m(std::dextents<signed char, 1>(5));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_right::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_right::mapping<std::dextents<int, 3>> m(std::dextents<int, 3>(5, 7, 9));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, -1, -1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, 0, 0), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, -1, 0), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, 0, -1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 3, 3), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 7, 3), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 3, 9), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 7, 9), "layout_right::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_right::mapping<std::dextents<unsigned, 3>> m(std::dextents<int, 3>(5, 7, 9));
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, -1, -1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, 0, 0), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, -1, 0), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, 0, -1), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 3, 3), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 7, 3), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 3, 9), "layout_right::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 7, 9), "layout_right::mapping: out of bounds indexing");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.stride.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.stride.pass.cpp
new file mode 100644
index 0000000000000..8e3049c4736f0
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_right/assert.stride.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// layout_right::mapping
+//
+// constexpr index_type stride(rank_type i) const noexcept;
+//
+// Constraints: extents_type::rank() > 0 is true.
+//
+// Preconditions: i < extents_type::rank() is true.
+//
+// Returns: extents().rev-prod-of-extents(i).
+//
+//
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // value out of range
+ {
+ std::layout_right::mapping<std::dextents<int, 3>> m{std::dextents<int, 3>{100, 100, 100}};
+
+ TEST_LIBCPP_ASSERT_FAILURE(m.stride(4), "layout_right::mapping::stride(): invalid rank index");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp
new file mode 100644
index 0000000000000..7deb1215de0de
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// XFAIL: libcpp-hardening-mode=debug && target=powerpc{{.*}}le-unknown-linux-gnu
+
+// <mdspan>
+
+// template<class StridedLayoutMapping>
+// constexpr explicit(see below)
+// mapping(const StridedLayoutMapping& other) noexcept;
+//
+// Constraints:
+// - layout-mapping-alike<StridedLayoutMapping> is satisfied.
+// - is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type> is true.
+// - StridedLayoutMapping::is_always_unique() is true.
+// - StridedLayoutMapping::is_always_strided() is true.
+//
+// Preconditions:
+// - StridedLayoutMapping meets the layout mapping requirements ([mdspan.layout.policy.reqmts]),
+// - other.stride(r) > 0 is true for every rank index r of extents(),
+// - other.required_span_size() is representable as a value of type index_type ([basic.fundamental]), and
+// - OFFSET(other) == 0 is true.
+//
+// Effects: Direct-non-list-initializes extents_ with other.extents(), and for all d in the range [0, rank_),
+// direct-non-list-initializes strides_[d] with other.stride(d).
+//
+// Remarks: The expression inside explicit is equivalent to:
+// - !(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&
+// (is-mapping-of<layout_left, LayoutStrideMapping> ||
+// is-mapping-of<layout_right, LayoutStrideMapping> ||
+// is-mapping-of<layout_stride, LayoutStrideMapping>))
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "../../../../../std/containers/views/mdspan/CustomTestLayouts.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // working case
+ {
+ std::extents<int, D, D> arg_exts{100, 5};
+ std::layout_stride::mapping<std::extents<int, D, D>> arg(arg_exts, std::array<int, 2>{1, 100});
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<size_t, D, 5>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ std::extents<int, D, D> arg_exts{100, 5};
+ std::layout_stride::mapping<std::extents<int, D, D>> arg(arg_exts, std::array<int, 2>{1, 100});
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<int, D, 3>> m(arg); }()),
+ "extents construction: mismatch of provided arguments with static extents.");
+ }
+ // non-representability of extents itself
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<signed char, D>> m(
+ std::layout_stride::mapping<std::extents<int, D>>(std::extents<int, D>(500), std::array<int, 1>{1}));
+ }()),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
+ }
+ // all strides must be larger than zero
+ {
+ always_convertible_layout::mapping<std::dextents<int, 2>> offset_map(std::dextents<int, 2>{10, 10}, 100, -1);
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
+ "layout_stride::mapping converting ctor: all strides must be greater than 0");
+ }
+ // required_span_size not representable, while individual extents are
+ {
+ std::extents<int, D, D> arg_exts{100, 5};
+ std::layout_stride::mapping<std::extents<int, D, D>> arg(arg_exts, std::array<int, 2>{1, 100});
+ // check extents would be constructible
+ [[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
+ // but the product is not, so we can't use it for layout_stride
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_stride::mapping<std::extents<signed char, D, 5>> m(arg); }()),
+ "layout_stride::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+ }
+ // required_span_size not representable, while individual extents are, edge case
+ {
+ // required span size = (3-1)*50 + (10-1) * 3 + 1 = 128
+ std::extents<int, D, D> arg_exts{3, 10};
+ std::layout_stride::mapping<std::extents<int, D, D>> arg(arg_exts, std::array<int, 2>{50, 3});
+ // sanity check:
+ assert(arg.required_span_size() == 128);
+ // check extents would be constructible
+ [[maybe_unused]] std::extents<signed char, D, 10> e(arg_exts);
+ // but the product is not, so we can't use it for layout_stride
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::layout_stride::mapping<std::extents<signed char, D, 10>> m(arg); }()),
+ "layout_stride::mapping converting ctor: other.required_span_size() must be representable as index_type.");
+ }
+ // base offset must be 0 (i.e. mapping(0,...,0)==0) for a strided layout with positive strides
+ {
+ always_convertible_layout::mapping<std::dextents<int, 2>> offset_map(std::dextents<int, 2>{10, 10}, 3);
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
+ "layout_stride::mapping converting ctor: base offset of mapping must be zero.");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp
new file mode 100644
index 0000000000000..97a6d56e4f839
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.non_unique.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherIndexType>
+// constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
+//
+// Constraints:
+// - is_convertible_v<const OtherIndexType&, index_type> is true, and
+// - is_nothrow_constructible_v<index_type, const OtherIndexType&> is true.
+//
+// Preconditions:
+// - s[i] > 0 is true for all i in the range [0, rank_).
+// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type ([basic.fundamental]).
+// - If rank_ is greater than 0, then there exists a permutation P of the integers in the range [0, rank_),
+// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the range [1, rank_), where
+// pi is the ith element of P.
+// [Note 1: For layout_stride, this condition is necessary and sufficient for is_unique() to be true. end note]
+//
+// Effects: Direct-non-list-initializes extents_ with e, and for all d in the range [0, rank_), direct-non-list-initializes strides_[d] with as_const(s[d]).
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // overlapping strides
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<unsigned, D, 5, 7>> m(
+ std::extents<unsigned, D, 5, 7>(20), std::array<unsigned, 3>{4, 1, 200});
+ }()),
+ "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
+ }
+ // equal strides
+ {
+ // should work because one of the equal strides is associated with an extent of 1
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 1>> m1(
+ std::extents<unsigned, D, 5, 1>(2), std::array<unsigned, 3>{5, 1, 5});
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m2(
+ std::extents<unsigned, D, 5, 2>(1), std::array<unsigned, 3>{5, 1, 5});
+
+ // will fail because neither of the equal strides is associated with an extent of 1
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m3(
+ std::extents<unsigned, D, 5, 2>(2), std::array<unsigned, 3>{5, 1, 5});
+ }()),
+ "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp
new file mode 100644
index 0000000000000..860849ded2de2
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_array.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherIndexType>
+// constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
+//
+// Constraints:
+// - is_convertible_v<const OtherIndexType&, index_type> is true, and
+// - is_nothrow_constructible_v<index_type, const OtherIndexType&> is true.
+//
+// Preconditions:
+// - s[i] > 0 is true for all i in the range [0, rank_).
+// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type ([basic.fundamental]).
+// - If rank_ is greater than 0, then there exists a permutation P of the integers in the range [0, rank_),
+// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the range [1, rank_), where
+// pi is the ith element of P.
+// [Note 1: For layout_stride, this condition is necessary and sufficient for is_unique() to be true. end note]
+//
+// Effects: Direct-non-list-initializes extents_ with e, and for all d in the range [0, rank_), direct-non-list-initializes strides_[d] with as_const(s[d]).
+
+#include <cassert>
+#include <mdspan>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // the extents are representable but the product with strides is not, so we can't use it for layout_stride
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<signed char, D, 5>> m(
+ std::extents<signed char, D, 5>(20), std::array<int, 2>{20, 1});
+ }()),
+ "layout_stride::mapping ctor: required span size is not representable as index_type.");
+
+ // check that if we first overflow in strides conversion we also fail
+ static_assert(static_cast<unsigned char>(257u) == 1);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<unsigned char, D, 5>> m(
+ std::extents<unsigned char, D, 5>(20), std::array<unsigned, 2>{257, 1});
+ }()),
+ "layout_stride::mapping ctor: required span size is not representable as index_type.");
+
+ // negative strides are not allowed, check with unsigned index_type so we make sure we catch that
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
+ std::extents<unsigned, D, 5>(20), std::array<int, 2>{20, -1});
+ }()),
+ "layout_stride::mapping ctor: all strides must be greater than 0");
+ // zero strides are not allowed, check with unsigned index_type so we make sure we catch that
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
+ std::extents<unsigned, D, 5>(20), std::array<unsigned, 2>{20, 0});
+ }()),
+ "layout_stride::mapping ctor: all strides must be greater than 0");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.pass.cpp
new file mode 100644
index 0000000000000..fd0701e9ee3a7
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.non_unique.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherIndexType>
+// constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
+//
+// Constraints:
+// - is_convertible_v<const OtherIndexType&, index_type> is true, and
+// - is_nothrow_constructible_v<index_type, const OtherIndexType&> is true.
+//
+// Preconditions:
+// - s[i] > 0 is true for all i in the range [0, rank_).
+// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type ([basic.fundamental]).
+// - If rank_ is greater than 0, then there exists a permutation P of the integers in the range [0, rank_),
+// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the range [1, rank_), where
+// pi is the ith element of P.
+// [Note 1: For layout_stride, this condition is necessary and sufficient for is_unique() to be true. end note]
+//
+// Effects: Direct-non-list-initializes extents_ with e, and for all d in the range [0, rank_), direct-non-list-initializes strides_[d] with as_const(s[d]).
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // overlapping strides
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::array<unsigned, 3> strides{4, 1, 200};
+ std::layout_stride::mapping<std::extents<unsigned, D, 5, 7>> m(
+ std::extents<unsigned, D, 5, 7>(20), std::span(strides));
+ }()),
+ "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
+ }
+
+ // equal strides
+ {
+ // should work because one of the equal strides is associated with an extent of 1
+ std::array<unsigned, 3> strides{5, 1, 5};
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 1>> m1(
+ std::extents<unsigned, D, 5, 1>(2), std::span(strides));
+ [[maybe_unused]] std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m2(
+ std::extents<unsigned, D, 5, 2>(1), std::span(strides));
+
+ // will fail because neither of the equal strides is associated with an extent of 1
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::layout_stride::mapping<std::extents<unsigned, D, 5, 2>> m3(
+ std::extents<unsigned, D, 5, 2>(2), std::span(strides));
+ }()),
+ "layout_stride::mapping ctor: the provided extents and strides lead to a non-unique mapping");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.pass.cpp
new file mode 100644
index 0000000000000..70ab0616ec01b
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.ctor.extents_span.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherIndexType>
+// constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
+//
+// Constraints:
+// - is_convertible_v<const OtherIndexType&, index_type> is true, and
+// - is_nothrow_constructible_v<index_type, const OtherIndexType&> is true.
+//
+// Preconditions:
+// - s[i] > 0 is true for all i in the range [0, rank_).
+// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type ([basic.fundamental]).
+// - If rank_ is greater than 0, then there exists a permutation P of the integers in the range [0, rank_),
+// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the range [1, rank_), where
+// pi is the ith element of P.
+// [Note 1: For layout_stride, this condition is necessary and sufficient for is_unique() to be true. end note]
+//
+// Effects: Direct-non-list-initializes extents_ with e, and for all d in the range [0, rank_), direct-non-list-initializes strides_[d] with as_const(s[d]).
+
+#include <cassert>
+#include <mdspan>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+
+ // value out of range
+ {
+ // the extents are representable but the product with strides is not, so we can't use it for layout_stride
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::array<int, 2> strides{20, 1};
+ std::layout_stride::mapping<std::extents<signed char, D, 5>> m(
+ std::extents<signed char, D, 5>(20), std::span(strides));
+ }()),
+ "layout_stride::mapping ctor: required span size is not representable as index_type.");
+
+ // check that if we first overflow in strides conversion we also fail
+ static_assert(static_cast<unsigned char>(257u) == 1);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::array<unsigned, 2> strides{257, 1};
+ std::layout_stride::mapping<std::extents<unsigned char, D, 5>> m(
+ std::extents<unsigned char, D, 5>(20), std::span(strides));
+ }()),
+ "layout_stride::mapping ctor: required span size is not representable as index_type.");
+
+ // negative strides are not allowed, check with unsigned index_type so we make sure we catch that
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::array<int, 2> strides{20, -1};
+ std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
+ std::extents<unsigned, D, 5>(20), std::span(strides));
+ }()),
+ "layout_stride::mapping ctor: all strides must be greater than 0");
+ // zero strides are not allowed, check with unsigned index_type so we make sure we catch that
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] {
+ std::array<unsigned, 2> strides{20, 0};
+ std::layout_stride::mapping<std::extents<unsigned, D, 5>> m(
+ std::extents<unsigned, D, 5>(20), std::span(strides));
+ }()),
+ "layout_stride::mapping ctor: all strides must be greater than 0");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.index_operator.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.index_operator.pass.cpp
new file mode 100644
index 0000000000000..b5244a60af0f7
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.index_operator.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class... Indices>
+// constexpr index_type operator()(Indices... i) const noexcept;
+//
+// Constraints:
+// - sizeof...(Indices) == extents_type::rank() is true,
+// - (is_convertible_v<Indices, index_type> && ...) is true, and
+// - (is_nothrow_constructible_v<index_type, Indices> && ...) is true.
+//
+// Preconditions: extents_type::index-cast(i) is a multidimensional index in extents_ ([mdspan.overview]).
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // value out of range
+ {
+ std::layout_stride::mapping<std::extents<unsigned char, 5>> m;
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_stride::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_stride::mapping<std::extents<signed char, 5>> m;
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_stride::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_stride::mapping<std::dextents<unsigned char, 1>> m(
+ std::dextents<unsigned char, 1>(5), std::array<int, 1>{1});
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_stride::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_stride::mapping<std::dextents<signed char, 1>> m(
+ std::dextents<signed char, 1>(5), std::array<int, 1>{1});
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-130), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(1000), "layout_stride::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_stride::mapping<std::dextents<int, 3>> m(
+ std::dextents<int, 3>(5, 7, 9), std::array<int, 3>{1, 10, 100});
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, -1, -1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, 0, 0), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, -1, 0), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, 0, -1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 3, 3), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 7, 3), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 3, 9), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 7, 9), "layout_stride::mapping: out of bounds indexing");
+ }
+ {
+ std::layout_stride::mapping<std::dextents<unsigned, 3>> m(
+ std::dextents<int, 3>(5, 7, 9), std::array<int, 3>{1, 10, 100});
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, -1, -1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(-1, 0, 0), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, -1, 0), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(0, 0, -1), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 3, 3), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 7, 3), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(3, 3, 9), "layout_stride::mapping: out of bounds indexing");
+ TEST_LIBCPP_ASSERT_FAILURE(m(5, 7, 9), "layout_stride::mapping: out of bounds indexing");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.stride.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.stride.pass.cpp
new file mode 100644
index 0000000000000..ee2b731da203b
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/layout_stride/assert.stride.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// constexpr index_type stride(rank_type i) const noexcept { return strides_[i]; }
+
+// We intercept this inside layout_stride to give a consistent error message with
+// layout_left and layout_right, technically the precondition is coming from the
+// array access.
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // value out of range
+ {
+ std::layout_stride::mapping<std::dextents<int, 3>> m(
+ std::dextents<int, 3>(100, 100, 100), std::array<int, 3>{1, 100, 10000});
+
+ TEST_LIBCPP_ASSERT_FAILURE(m.stride(4), "layout_stride::mapping::stride(): invalid rank index");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.conversion.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
new file mode 100644
index 0000000000000..53aec7bb714ea
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
@@ -0,0 +1,66 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class OtherElementType, class OtherExtents,
+// class OtherLayoutPolicy, class OtherAccessor>
+// constexpr explicit(see below)
+// mdspan(const mdspan<OtherElementType, OtherExtents,
+// OtherLayoutPolicy, OtherAccessor>& other);
+//
+// Constraints:
+// - is_constructible_v<mapping_type, const OtherLayoutPolicy::template mapping<OtherExtents>&> is true, and
+// - is_constructible_v<accessor_type, const OtherAccessor&> is true.
+// Mandates:
+// - is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&> is
+// - is_constructible_v<extents_type, OtherExtents> is true.
+//
+// Preconditions:
+// - For each rank index r of extents_type, static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r) is true.
+// - [0, map_.required_span_size()) is an accessible range of ptr_ and acc_ for values of ptr_, map_, and acc_ after the invocation of this constructor.
+//
+// Effects:
+// - Direct-non-list-initializes ptr_ with other.ptr_,
+// - direct-non-list-initializes map_ with other.map_, and
+// - direct-non-list-initializes acc_ with other.acc_.
+//
+// Remarks: The expression inside explicit is equivalent to:
+// !is_convertible_v<const OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type>
+// || !is_convertible_v<const OtherAccessor&, accessor_type>
+
+#include <array>
+#include <cassert>
+#include <mdspan>
+
+#include "check_assertion.h"
+#include "../../../../../std/containers/views/mdspan/CustomTestLayouts.h"
+
+// We use a funky mapping in this test that doesn't check the dynamic/static extents mismatch itself
+int main(int, char**) {
+ constexpr size_t D = std::dynamic_extent;
+ std::array<float, 10> data;
+ layout_wrapping_integral<4>::mapping<std::dextents<int, 2>> src_map(
+ std::dextents<int, 2>(5, 2), not_extents_constructible_tag());
+ std::mdspan<float, std::dextents<int, 2>, layout_wrapping_integral<4>> arg(data.data(), src_map);
+
+ // working case
+ {
+ [[maybe_unused]] std::mdspan<float, std::extents<size_t, D, 2>, layout_wrapping_integral<4>> m(arg); // should work
+ }
+ // mismatch of static extent
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ([=] { std::mdspan<float, std::extents<size_t, D, 3>, layout_wrapping_integral<4>> m(arg); }()),
+ "mdspan: conversion mismatch of source dynamic extents with static extents");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
new file mode 100644
index 0000000000000..9dd957986f14d
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// template<class... OtherIndexTypes>
+// constexpr reference operator[](OtherIndexTypes... indices) const;
+// Constraints:
+// - (is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
+// - (is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and
+// - sizeof...(OtherIndexTypes) == rank() is true.
+//
+// Let I be extents_type::index-cast(std::move(indices)).
+//
+// Preconditions: I is a multidimensional index in extents().
+// Note 1: This implies that map_(I) < map_.required_span_size() is true.
+//
+// Effects: Equivalent to:
+// return acc_.access(ptr_, map_(static_cast<index_type>(std::move(indices))...));
+
+#include <mdspan>
+#include <cassert>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ float data[1024];
+ // value out of range
+ {
+ std::mdspan m(data, std::extents<unsigned char, 5>());
+ TEST_LIBCPP_ASSERT_FAILURE(m[-1], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[-130], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[5], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[1000], "mdspan: operator[] out of bounds access");
+ }
+ {
+ std::mdspan m(data, std::extents<signed char, 5>());
+ TEST_LIBCPP_ASSERT_FAILURE(m[-1], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[-130], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[5], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[1000], "mdspan: operator[] out of bounds access");
+ }
+ {
+ std::mdspan m(data, std::dextents<unsigned char, 1>(5));
+ TEST_LIBCPP_ASSERT_FAILURE(m[-1], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[-130], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[5], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[1000], "mdspan: operator[] out of bounds access");
+ }
+ {
+ std::mdspan m(data, std::dextents<signed char, 1>(5));
+ TEST_LIBCPP_ASSERT_FAILURE(m[-1], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[-130], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[5], "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE(m[1000], "mdspan: operator[] out of bounds access");
+ }
+ {
+ std::mdspan m(data, std::dextents<int, 3>(5, 7, 9));
+ TEST_LIBCPP_ASSERT_FAILURE((m[-1, -1, -1]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[-1, 0, 0]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[0, -1, 0]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[0, 0, -1]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[5, 3, 3]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[3, 7, 3]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[3, 3, 9]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[5, 7, 9]), "mdspan: operator[] out of bounds access");
+ }
+ {
+ std::mdspan m(data, std::dextents<unsigned, 3>(5, 7, 9));
+ TEST_LIBCPP_ASSERT_FAILURE((m[-1, -1, -1]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[-1, 0, 0]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[0, -1, 0]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[0, 0, -1]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[5, 3, 3]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[3, 7, 3]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[3, 3, 9]), "mdspan: operator[] out of bounds access");
+ TEST_LIBCPP_ASSERT_FAILURE((m[5, 7, 9]), "mdspan: operator[] out of bounds access");
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.size.pass.cpp b/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.size.pass.cpp
new file mode 100644
index 0000000000000..9af82701cd4be
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/mdspan/mdspan/assert.size.pass.cpp
@@ -0,0 +1,50 @@
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <mdspan>
+
+// constexpr size_type size() const noexcept;
+//
+// Preconditions: The size of the multidimensional index space extents() is representable as a value of type size_type ([basic.fundamental]).
+//
+// Returns: extents().fwd-prod-of-extents(rank()).
+
+#include <array>
+#include <cassert>
+#include <mdspan>
+
+#include "check_assertion.h"
+#include "../../../../../std/containers/views/mdspan/CustomTestLayouts.h"
+
+// We use a funky mapping in this test where required_span_size is much smaller than the size of the index space
+int main(int, char**) {
+ std::array<float, 10> data;
+ // make sure we are not failing because of using index_type instead of size_type
+ {
+ layout_wrapping_integral<4>::mapping<std::dextents<signed char, 2>> map(
+ std::dextents<signed char, 2>(100, 2), not_extents_constructible_tag());
+ std::mdspan<float, std::dextents<signed char, 2>, layout_wrapping_integral<4>> mds(data.data(), map);
+ assert(map.required_span_size() == static_cast<signed char>(8));
+ assert((static_cast<unsigned char>(200) == mds.size()));
+ }
+ {
+ layout_wrapping_integral<4>::mapping<std::dextents<signed char, 2>> map(
+ std::dextents<signed char, 2>(100, 3), not_extents_constructible_tag());
+ std::mdspan<float, std::dextents<signed char, 2>, layout_wrapping_integral<4>> mds(data.data(), map);
+ // sanity check
+ assert(map.required_span_size() == static_cast<signed char>(12));
+ // 100 x 3 exceeds 256
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(([=] { mds.size(); }()), "mdspan: size() is not representable as size_type");
+ }
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/assert.iterator-indexing.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/assert.iterator-indexing.pass.cpp
new file mode 100644
index 0000000000000..d4dacb1f2f1c7
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/assert.iterator-indexing.pass.cpp
@@ -0,0 +1,174 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Make sure that std::span's iterators check for OOB accesses when the debug mode is enabled.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators
+// UNSUPPORTED: libcpp-hardening-mode=none
+
+#include <span>
+
+#include "check_assertion.h"
+
+struct Foo {
+ int x;
+};
+
+template <typename Iter>
+void test_iterator(Iter begin, Iter end, bool reverse) {
+ std::ptrdiff_t distance = std::distance(begin, end);
+
+ // Dereferencing an iterator at the end.
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *end,
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
+#if _LIBCPP_STD_VER >= 20
+ // In C++20 mode, std::reverse_iterator implements operator->, but not operator*, with
+ // std::prev instead of operator--. std::prev ultimately calls operator+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ end->x,
+ reverse ? "__bounded_iter::operator+=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
+#else
+ TEST_LIBCPP_ASSERT_FAILURE(
+ end->x,
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
+#endif
+ }
+
+ // Incrementing an iterator past the end.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator++: Attempt to advance an iterator past the end";
+ auto it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it++, msg);
+ TEST_LIBCPP_ASSERT_FAILURE(++it, msg);
+ }
+
+ // Decrementing an iterator past the start.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator++: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator--: Attempt to rewind an iterator past the start";
+ auto it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it--, msg);
+ TEST_LIBCPP_ASSERT_FAILURE(--it, msg);
+ }
+
+ // Advancing past the end with operator+= and operator+.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator+=: Attempt to advance an iterator past the end";
+ auto it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it += 1, msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end + 1, msg);
+ it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it += (distance + 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin + (distance + 1), msg);
+ }
+
+ // Advancing past the end with operator-= and operator-.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator+=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator-=: Attempt to advance an iterator past the end";
+ auto it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= (-1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end - (-1), msg);
+ it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= (-distance - 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin - (-distance - 1), msg);
+ }
+
+ // Rewinding past the start with operator+= and operator+.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator+=: Attempt to rewind an iterator past the start";
+ auto it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it += (-1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin + (-1), msg);
+ it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it += (-distance - 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end + (-distance - 1), msg);
+ }
+
+ // Rewinding past the start with operator-= and operator-.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator+=: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator-=: Attempt to rewind an iterator past the start";
+ auto it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= 1, msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin - 1, msg);
+ it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= (distance + 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end - (distance + 1), msg);
+ }
+
+ // Out-of-bounds operator[].
+ {
+ [[maybe_unused]] const char* end_msg =
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator[]: Attempt to index an iterator at or past the end";
+ [[maybe_unused]] const char* past_end_msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator[]: Attempt to index an iterator at or past the end";
+ [[maybe_unused]] const char* past_start_msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator[]: Attempt to index an iterator past the start";
+ TEST_LIBCPP_ASSERT_FAILURE(begin[distance], end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin[distance + 1], past_end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin[-1], past_start_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin[-99], past_start_msg);
+
+ auto it = begin + 1;
+ TEST_LIBCPP_ASSERT_FAILURE(it[distance - 1], end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(it[distance], past_end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(it[-2], past_start_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(it[-99], past_start_msg);
+ }
+}
+
+int main(int, char**) {
+ // span<T>::iterator
+ {
+ Foo array[] = {{0}, {1}, {2}};
+ std::span<Foo> const span(array, 3);
+ test_iterator(span.begin(), span.end(), /*reverse=*/false);
+ }
+
+ // span<T, N>::iterator
+ {
+ Foo array[] = {{0}, {1}, {2}};
+ std::span<Foo, 3> const span(array, 3);
+ test_iterator(span.begin(), span.end(), /*reverse=*/false);
+ }
+
+ // span<T>::reverse_iterator
+ {
+ Foo array[] = {{0}, {1}, {2}};
+ std::span<Foo> const span(array, 3);
+ test_iterator(span.rbegin(), span.rend(), /*reverse=*/true);
+ }
+
+ // span<T, N>::reverse_iterator
+ {
+ Foo array[] = {{0}, {1}, {2}};
+ std::span<Foo, 3> const span(array, 3);
+ test_iterator(span.rbegin(), span.rend(), /*reverse=*/true);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_sent.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_sent.pass.cpp
new file mode 100644
index 0000000000000..64e3cc8750cd1
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_sent.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
+
+// <span>
+//
+// constexpr span<T, Extent>::span(Iterator it, Sentinel sent);
+//
+// Check that we ensure `Extent == sent - it` and also that `[it, sent)` is a valid range.
+//
+//
+// constexpr span<T, dynamic_extent>::span(Iterator it, Sentinel sent);
+//
+// Check that we ensure that `[it, sent)` is a valid range.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::array<int, 3> array{0, 1, 2};
+
+ auto invalid_range = [&] {
+ std::span<int> const s(array.end(), array.begin());
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(invalid_range(), "invalid range in span's constructor (iterator, sentinel)");
+ }
+ {
+ std::array<int, 3> array{0, 1, 2};
+
+ auto invalid_range = [&] {
+ std::span<int, 3> const s(array.end(), array.begin());
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(invalid_range(), "invalid range in span's constructor (iterator, sentinel)");
+
+ auto invalid_size = [&] {
+ std::span<int, 3> const s(array.begin(), array.begin() + 2);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(
+ invalid_size(), "invalid range in span's constructor (iterator, sentinel): last - first != extent");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_size.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_size.pass.cpp
new file mode 100644
index 0000000000000..c8c6e3743bd21
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.iter_size.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
+
+// <span>
+//
+// constexpr span<T, Extent>::span(Iterator, size_type);
+//
+// Check that the passed size is equal to the statically known extent.
+// Note that it doesn't make sense to validate the incoming size in the
+// dynamic_extent version.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::array<int, 3> array{0, 1, 2};
+
+ // Input range too large (exceeds the span extent)
+ {
+ auto f = [&] {
+ std::span<int, 3> const s(array.data(), 4);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "size mismatch in span's constructor (iterator, len)");
+ }
+
+ // Input range too small (doesn't fill the span)
+ {
+ auto f = [&] {
+ std::span<int, 3> const s(array.data(), 2);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "size mismatch in span's constructor (iterator, len)");
+ }
+
+ // Input range is non-empty but starts with a null pointer
+ {
+ // static extent
+ {
+ auto f = [&] {
+ int* p = nullptr;
+ std::span<int, 3> const s(p, 3);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "passed nullptr with non-zero length in span's constructor (iterator, len)");
+ }
+
+ // dynamic extent
+ {
+ auto f = [&] {
+ int* p = nullptr;
+ std::span<int, std::dynamic_extent> const s(p, 1);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "passed nullptr with non-zero length in span's constructor (iterator, len)");
+ }
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.other_span.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.other_span.pass.cpp
new file mode 100644
index 0000000000000..9a4e65b0af903
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.other_span.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <span>
+//
+// constexpr span<T, Extent>::span(const span<U, dynamic_extent>& other);
+//
+// Check that we ensure `other.size() == Extent`.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int> other(array.data(), 3);
+
+ auto invalid_source = [&] {
+ std::span<int, 2> const s(other);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(invalid_source(), "size mismatch in span's constructor (other span)");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.range.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.range.pass.cpp
new file mode 100644
index 0000000000000..5e36e9a0418ae
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.cons/assert.range.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <span>
+//
+// constexpr span<T, Extent>::span(Range&& r);
+//
+// Check that we ensure `size(r) == Extent`.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <span>
+#include <vector>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::vector<int> vec{
+ 0,
+ 1,
+ 2}; // must use std::vector instead of std::array, because std::span has a special constructor from std::array
+
+ auto invalid_size = [&] {
+ std::span<int, 2> const s(vec);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(invalid_size(), "size mismatch in span's constructor (range)");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.back.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.back.pass.cpp
new file mode 100644
index 0000000000000..7e656b7f0b6e9
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.back.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
+
+// <span>
+//
+// constexpr reference back() const noexcept;
+
+// Make sure that accessing a span out-of-bounds triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int> const s(array.data(), 0);
+ TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span<T>::back() on empty span");
+ }
+
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int, 0> const s(array.data(), 0);
+ TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span<T, N>::back() on empty span");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.front.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.front.pass.cpp
new file mode 100644
index 0000000000000..0068aad8cc346
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.front.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
+
+// <span>
+//
+// constexpr reference front() const noexcept;
+
+// Make sure that accessing a span out-of-bounds triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int> const s(array.data(), 0);
+ TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span<T>::front() on empty span");
+ }
+
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int, 0> const s(array.data(), 0);
+ TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span<T, N>::front() on empty span");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.op_idx.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.op_idx.pass.cpp
new file mode 100644
index 0000000000000..501067f740788
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.elem/assert.op_idx.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
+
+// <span>
+//
+// constexpr reference operator[](size_type idx) const;
+
+// Make sure that accessing a span out-of-bounds triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s[3], "span<T>::operator[](index): index out of range");
+ }
+
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int, 3> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s[3], "span<T, N>::operator[](index): index out of range");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.first.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.first.pass.cpp
new file mode 100644
index 0000000000000..f241f2a5aadf2
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.first.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <span>
+//
+// constexpr span<element_type, dynamic_extent> first(size_type count) const;
+
+// Make sure that creating a sub-span with an incorrect number of elements triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s.first(4), "span<T>::first(count): count out of range");
+ TEST_LIBCPP_ASSERT_FAILURE(s.first<4>(), "span<T>::first<Count>(): Count out of range");
+ }
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int, 3> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s.first(4), "span<T, N>::first(count): count out of range");
+ // s.first<4>() caught at compile-time (tested elsewhere)
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.last.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.last.pass.cpp
new file mode 100644
index 0000000000000..032df689b1b88
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.last.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <span>
+//
+// constexpr span<element_type, dynamic_extent> last(size_type count) const;
+
+// Make sure that creating a sub-span with an incorrect number of elements triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s.last(4), "span<T>::last(count): count out of range");
+ TEST_LIBCPP_ASSERT_FAILURE(s.last<4>(), "span<T>::last<Count>(): Count out of range");
+ }
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int, 3> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s.last(4), "span<T, N>::last(count): count out of range");
+ // s.last<4>() caught at compile-time (tested elsewhere)
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.subspan.pass.cpp b/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.subspan.pass.cpp
new file mode 100644
index 0000000000000..5dd0fa0530189
--- /dev/null
+++ b/libcxx/test/libcxx-03/containers/views/views.span/span.sub/assert.subspan.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <span>
+//
+// template<size_t Offset, size_t Count = dynamic_extent>
+// constexpr span<element_type, see-below> subspan() const;
+//
+// Requires: Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset)
+//
+// constexpr span<element_type, dynamic_extent> subspan(
+// size_type offset, size_type count = dynamic_extent) const;
+//
+// Requires: offset <= size() && (count == dynamic_extent || count <= size() - offset)
+
+// Make sure that creating a sub-span with an incorrect number of elements triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <array>
+#include <span>
+#include <cstddef>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s.subspan(4), "span<T>::subspan(offset, count): offset out of range");
+ TEST_LIBCPP_ASSERT_FAILURE(s.subspan<4>(), "span<T>::subspan<Offset, Count>(): Offset out of range");
+
+ TEST_LIBCPP_ASSERT_FAILURE(s.subspan(0, 4), "span<T>::subspan(offset, count): offset + count out of range");
+ TEST_LIBCPP_ASSERT_FAILURE((s.subspan<0, 4>()), "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
+
+ TEST_LIBCPP_ASSERT_FAILURE(s.subspan(1, 3), "span<T>::subspan(offset, count): offset + count out of range");
+ TEST_LIBCPP_ASSERT_FAILURE((s.subspan<1, 3>()), "span<T>::subspan<Offset, Count>(): Offset + Count out of range");
+ }
+ {
+ std::array<int, 3> array{0, 1, 2};
+ std::span<int, 3> const s(array.data(), array.size());
+ TEST_LIBCPP_ASSERT_FAILURE(s.subspan(4), "span<T, N>::subspan(offset, count): offset out of range");
+ // s.subspan<4>() caught at compile-time (tested in libcxx/test/std/containers/views/views.span/span.sub/subspan.verify.cpp)
+
+ TEST_LIBCPP_ASSERT_FAILURE(s.subspan(0, 4), "span<T, N>::subspan(offset, count): offset + count out of range");
+ // s.subspan<0, 4>() caught at compile-time (tested in libcxx/test/std/containers/views/views.span/span.sub/subspan.verify.cpp)
+
+ TEST_LIBCPP_ASSERT_FAILURE(s.subspan(1, 3), "span<T, N>::subspan(offset, count): offset + count out of range");
+ // s.subspan<1, 3>() caught at compile-time (tested in libcxx/test/std/containers/views/views.span/span.sub/subspan.verify.cpp)
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/debug/containers.multithread.pass.cpp b/libcxx/test/libcxx-03/debug/containers.multithread.pass.cpp
new file mode 100644
index 0000000000000..974da65acebed
--- /dev/null
+++ b/libcxx/test/libcxx-03/debug/containers.multithread.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++11, c++14
+// UNSUPPORTED: no-threads
+
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+// test multithreaded container debugging
+
+#include <cassert>
+#include <cstddef>
+#include <deque>
+#include <list>
+#include <thread>
+#include <vector>
+
+template <typename Container>
+Container makeContainer(int size) {
+ Container c;
+ typedef typename Container::value_type ValueType;
+ for (int i = 0; i < size; ++i)
+ c.insert(c.end(), ValueType(i));
+ assert(c.size() == static_cast<std::size_t>(size));
+ return c;
+}
+
+template <typename Container>
+void ThreadUseIter() {
+ const std::size_t maxRounds = 7;
+ struct TestRunner{
+ void operator()() {
+ for (std::size_t count = 0; count < maxRounds; count++) {
+ const std::size_t containerCount = 11;
+ std::vector<Container> containers;
+ std::vector<typename Container::iterator> iterators;
+ for (std::size_t containerIndex = 0; containerIndex < containerCount; containerIndex++) {
+ containers.push_back(makeContainer<Container>(3));
+ Container& c = containers.back();
+ iterators.push_back(c.begin());
+ iterators.push_back(c.end());
+ }
+ }
+ }
+ };
+
+ TestRunner r;
+ const std::size_t threadCount = 4;
+ std::vector<std::thread> threads;
+ for (std::size_t count = 0; count < threadCount; count++)
+ threads.emplace_back(r);
+ r();
+ for (std::size_t count = 0; count < threadCount; count++)
+ threads[count].join();
+}
+
+int main(int, char**) {
+ ThreadUseIter<std::vector<int> >();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/debug/containers/sequence_container_iterators.pass.cpp b/libcxx/test/libcxx-03/debug/containers/sequence_container_iterators.pass.cpp
new file mode 100644
index 0000000000000..c456ff1282d4b
--- /dev/null
+++ b/libcxx/test/libcxx-03/debug/containers/sequence_container_iterators.pass.cpp
@@ -0,0 +1,333 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03, c++11, c++14
+
+// test container debugging
+
+#include <forward_list>
+#include <list>
+#include <vector>
+#include <deque>
+#include "check_assertion.h"
+#include "container_debug_tests.h"
+#include "test_macros.h"
+
+using namespace IteratorDebugChecks;
+
+template <class Container, ContainerType CT>
+struct SequenceContainerChecks : BasicContainerChecks<Container, CT> {
+ using Base = BasicContainerChecks<Container, CT>;
+ using value_type = typename Container::value_type;
+ using allocator_type = typename Container::allocator_type;
+ using iterator = typename Container::iterator;
+ using const_iterator = typename Container::const_iterator;
+
+ using Base::makeContainer;
+ using Base::makeValueType;
+public:
+ static void run() {
+ Base::run();
+ SanityTest();
+ FrontOnEmptyContainer();
+
+ if constexpr(CT != CT_ForwardList) {
+ AssignInvalidates();
+ BackOnEmptyContainer();
+ InsertIterValue();
+ InsertIterSizeValue();
+ InsertIterIterIter();
+ EmplaceIterValue();
+ EraseIterIter();
+ }
+ else {
+ SpliceFirstElemAfter();
+ }
+ if constexpr (CT == CT_Vector || CT == CT_Deque || CT == CT_List) {
+ PopBack();
+ }
+ if constexpr (CT == CT_List || CT == CT_Deque) {
+ PopFront(); // FIXME: Run with forward list as well
+ }
+ if constexpr (CT == CT_List || CT == CT_ForwardList) {
+ RemoveFirstElem();
+ }
+ if constexpr (CT == CT_List) {
+ SpliceFirstElem();
+ SpliceSameContainer();
+ }
+ }
+
+private:
+ static void SanityTest() {
+ // sanity test
+ Container C = {1, 1, 1, 1};
+ ::DoNotOptimize(&C);
+ }
+
+ static void RemoveFirstElem() {
+ // See llvm.org/PR35564
+ // remove(<first-elem>)
+ {
+ Container C = makeContainer(1);
+ auto FirstVal = *(C.begin());
+ C.remove(FirstVal);
+ assert(C.empty());
+ }
+ {
+ Container C = {1, 1, 1, 1};
+ auto FirstVal = *(C.begin());
+ C.remove(FirstVal);
+ assert(C.empty());
+ }
+ }
+
+ static void SpliceFirstElem() {
+ // See llvm.org/PR35564
+ // splice(<first-elem>)
+ {
+ Container C = makeContainer(1);
+ Container C2;
+ C2.splice(C2.end(), C, C.begin(), ++C.begin());
+ }
+ {
+ Container C = makeContainer(1);
+ Container C2;
+ C2.splice(C2.end(), C, C.begin());
+ }
+ }
+
+ static void SpliceSameContainer() {
+ // splice(<same-container>)
+ Container C = {1, 1};
+ C.splice(C.end(), C, C.begin());
+ }
+
+ static void SpliceFirstElemAfter() {
+ // See llvm.org/PR35564
+ // splice(<first-elem>)
+ {
+ Container C = makeContainer(1);
+ Container C2;
+ C2.splice_after(C2.begin(), C, C.begin(), ++C.begin());
+ }
+ {
+ Container C = makeContainer(1);
+ Container C2;
+ C2.splice_after(C2.begin(), C, C.begin());
+ }
+ }
+
+ static void AssignInvalidates() {
+ // assign(Size, Value)
+ Container C(allocator_type{});
+ iterator it1, it2, it3;
+ auto reset = [&]() {
+ C = makeContainer(3);
+ it1 = C.begin();
+ it2 = ++C.begin();
+ it3 = C.end();
+ };
+ auto check = [&]() {
+ EXPECT_DEATH( C.erase(it1) );
+ EXPECT_DEATH( C.erase(it2) );
+ EXPECT_DEATH( C.erase(it3, C.end()) );
+ };
+ reset();
+ C.assign(2, makeValueType(4));
+ check();
+ reset();
+ // assign(Iter, Iter)
+ std::vector<value_type> V = {
+ makeValueType(1),
+ makeValueType(2),
+ makeValueType(3)
+ };
+ C.assign(V.begin(), V.end());
+ check();
+ reset();
+ // assign(initializer_list)
+ C.assign({makeValueType(1), makeValueType(2), makeValueType(3)});
+ check();
+ }
+
+ static void BackOnEmptyContainer() {
+ // testing back on empty
+ Container C = makeContainer(1);
+ Container const& CC = C;
+ (void)C.back();
+ (void)CC.back();
+ C.clear();
+ EXPECT_DEATH( C.back() );
+ EXPECT_DEATH( CC.back() );
+ }
+
+ static void FrontOnEmptyContainer() {
+ // testing front on empty
+ Container C = makeContainer(1);
+ Container const& CC = C;
+ (void)C.front();
+ (void)CC.front();
+ C.clear();
+ EXPECT_DEATH( C.front() );
+ EXPECT_DEATH( CC.front() );
+ }
+
+ static void EraseIterIter() {
+ // testing erase iter iter invalidation
+ Container C1 = makeContainer(3);
+ iterator it1 = C1.begin();
+ iterator it1_next = ++C1.begin();
+ iterator it1_after_next = ++C1.begin();
+ ++it1_after_next;
+ iterator it1_back = --C1.end();
+ assert(it1_next != it1_back);
+ if (CT == CT_Vector) {
+ EXPECT_DEATH( C1.erase(it1_next, it1) ); // bad range
+ }
+ C1.erase(it1, it1_after_next);
+ EXPECT_DEATH( C1.erase(it1) );
+ EXPECT_DEATH( C1.erase(it1_next) );
+ if (CT == CT_List) {
+ C1.erase(it1_back);
+ } else {
+ EXPECT_DEATH( C1.erase(it1_back) );
+ }
+ }
+
+ static void PopBack() {
+ // testing pop_back() invalidation
+ Container C1 = makeContainer(2);
+ iterator it1 = C1.end();
+ --it1;
+ C1.pop_back();
+ EXPECT_DEATH( C1.erase(it1) );
+ C1.erase(C1.begin());
+ assert(C1.size() == 0);
+ EXPECT_DEATH( C1.pop_back() );
+ }
+
+ static void PopFront() {
+ // testing pop_front() invalidation
+ Container C1 = makeContainer(2);
+ iterator it1 = C1.begin();
+ C1.pop_front();
+ EXPECT_DEATH( C1.erase(it1) );
+ C1.erase(C1.begin());
+ assert(C1.size() == 0);
+ EXPECT_DEATH( C1.pop_front() );
+ }
+
+ static void InsertIterValue() {
+ // testing insert(iter, value)
+ Container C1 = makeContainer(2);
+ iterator it1 = C1.begin();
+ iterator it1_next = it1;
+ ++it1_next;
+ Container C2 = C1;
+ const value_type value = makeValueType(3);
+ value_type rvalue = makeValueType(3);
+ EXPECT_DEATH( C2.insert(it1, value) ); // wrong container
+ EXPECT_DEATH( C2.insert(it1, std::move(rvalue)) ); // wrong container
+ C1.insert(it1_next, value);
+ if (CT == CT_List) {
+ C1.insert(it1_next, value);
+ C1.insert(it1, value);
+ C1.insert(it1_next, std::move(rvalue));
+ C1.insert(it1, std::move(rvalue));
+ } else {
+ EXPECT_DEATH( C1.insert(it1_next, value) ); // invalidated iterator
+ EXPECT_DEATH( C1.insert(it1, value) ); // invalidated iterator
+ EXPECT_DEATH( C1.insert(it1_next, std::move(rvalue)) ); // invalidated iterator
+ EXPECT_DEATH( C1.insert(it1, std::move(rvalue)) ); // invalidated iterator
+ }
+ }
+
+ static void EmplaceIterValue() {
+ // testing emplace(iter, value)
+ Container C1 = makeContainer(2);
+ iterator it1 = C1.begin();
+ iterator it1_next = it1;
+ ++it1_next;
+ Container C2 = C1;
+ const value_type value = makeValueType(3);
+ EXPECT_DEATH( C2.emplace(it1, value) ); // wrong container
+ EXPECT_DEATH( C2.emplace(it1, makeValueType(4)) ); // wrong container
+ C1.emplace(it1_next, value);
+ if (CT == CT_List) {
+ C1.emplace(it1_next, value);
+ C1.emplace(it1, value);
+ } else {
+ EXPECT_DEATH( C1.emplace(it1_next, value) ); // invalidated iterator
+ EXPECT_DEATH( C1.emplace(it1, value) ); // invalidated iterator
+ }
+ }
+
+ static void InsertIterSizeValue() {
+ // testing insert(iter, size, value)
+ Container C1 = makeContainer(2);
+ iterator it1 = C1.begin();
+ iterator it1_next = it1;
+ ++it1_next;
+ Container C2 = C1;
+ const value_type value = makeValueType(3);
+ EXPECT_DEATH( C2.insert(it1, 1, value) ); // wrong container
+ C1.insert(it1_next, 2, value);
+ if (CT == CT_List) {
+ C1.insert(it1_next, 3, value);
+ C1.insert(it1, 1, value);
+ } else {
+ EXPECT_DEATH( C1.insert(it1_next, 1, value) ); // invalidated iterator
+ EXPECT_DEATH( C1.insert(it1, 1, value) ); // invalidated iterator
+ }
+ }
+
+ static void InsertIterIterIter() {
+ // testing insert(iter, iter, iter)
+ Container C1 = makeContainer(2);
+ iterator it1 = C1.begin();
+ iterator it1_next = it1;
+ ++it1_next;
+ Container C2 = C1;
+ std::vector<value_type> V = {
+ makeValueType(1),
+ makeValueType(2),
+ makeValueType(3)
+ };
+ EXPECT_DEATH( C2.insert(it1, V.begin(), V.end()) ); // wrong container
+ C1.insert(it1_next, V.begin(), V.end());
+ if (CT == CT_List) {
+ C1.insert(it1_next, V.begin(), V.end());
+ C1.insert(it1, V.begin(), V.end());
+ } else {
+ EXPECT_DEATH( C1.insert(it1_next, V.begin(), V.end()) ); // invalidated iterator
+ EXPECT_DEATH( C1.insert(it1, V.begin(), V.end()) ); // invalidated iterator
+ }
+ }
+};
+
+int main(int, char**)
+{
+ using Alloc = test_allocator<int>;
+ {
+ SequenceContainerChecks<std::list<int, Alloc>, CT_List>::run();
+ SequenceContainerChecks<std::vector<int, Alloc>, CT_Vector>::run();
+ }
+ // FIXME these containers don't support iterator debugging
+ if ((false)) {
+ SequenceContainerChecks<
+ std::vector<bool, test_allocator<bool>>, CT_VectorBool>::run();
+ SequenceContainerChecks<
+ std::forward_list<int, Alloc>, CT_ForwardList>::run();
+ SequenceContainerChecks<
+ std::deque<int, Alloc>, CT_Deque>::run();
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/debug/containers/string.pass.cpp b/libcxx/test/libcxx-03/debug/containers/string.pass.cpp
new file mode 100644
index 0000000000000..d1508e91d3179
--- /dev/null
+++ b/libcxx/test/libcxx-03/debug/containers/string.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03, c++11, c++14
+
+// test container debugging
+
+#include <string>
+#include <vector>
+
+#include "test_macros.h"
+#include "check_assertion.h"
+#include "container_debug_tests.h"
+
+using namespace IteratorDebugChecks;
+
+typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> StringType;
+
+template <class Container = StringType, ContainerType CT = CT_String>
+struct StringContainerChecks : BasicContainerChecks<Container, CT> {
+ using Base = BasicContainerChecks<Container, CT_String>;
+ using value_type = typename Container::value_type;
+ using allocator_type = typename Container::allocator_type;
+ using iterator = typename Container::iterator;
+ using const_iterator = typename Container::const_iterator;
+
+ using Base::makeContainer;
+ using Base::makeValueType;
+
+public:
+ static void run() {
+ Base::run_iterator_tests();
+ Base::run_allocator_aware_tests();
+
+ for (int N : {3, 128}) {
+ FrontOnEmptyContainer(N);
+ BackOnEmptyContainer(N);
+ PopBack(N);
+ }
+ }
+
+private:
+ static void BackOnEmptyContainer(int N) {
+ // testing back on empty
+ Container C = makeContainer(N);
+ Container const& CC = C;
+ iterator it = --C.end();
+ (void)C.back();
+ (void)CC.back();
+ C.pop_back();
+ EXPECT_DEATH( C.erase(it) );
+ C.clear();
+ EXPECT_DEATH( C.back() );
+ EXPECT_DEATH( CC.back() );
+ }
+
+ static void FrontOnEmptyContainer(int N) {
+ // testing front on empty
+ Container C = makeContainer(N);
+ Container const& CC = C;
+ (void)C.front();
+ (void)CC.front();
+ C.clear();
+ EXPECT_DEATH( C.front() );
+ EXPECT_DEATH( CC.front() );
+ }
+
+ static void PopBack(int N) {
+ // testing pop_back() invalidation
+ Container C1 = makeContainer(N);
+ iterator it1 = C1.end();
+ --it1;
+ C1.pop_back();
+ EXPECT_DEATH( C1.erase(it1) );
+ C1.erase(C1.begin(), C1.end());
+ assert(C1.size() == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(C1.pop_back(), "string::pop_back(): string is already empty");
+ }
+};
+
+int main(int, char**)
+{
+ StringContainerChecks<>::run();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/debug/containers/unord_containers.pass.cpp b/libcxx/test/libcxx-03/debug/containers/unord_containers.pass.cpp
new file mode 100644
index 0000000000000..b4e439d4a7313
--- /dev/null
+++ b/libcxx/test/libcxx-03/debug/containers/unord_containers.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03, c++11, c++14
+
+// test container debugging
+
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <cassert>
+#include "check_assertion.h"
+#include "container_debug_tests.h"
+#include "test_macros.h"
+
+using namespace IteratorDebugChecks;
+
+template <class Container, ContainerType CT>
+struct UnorderedContainerChecks : BasicContainerChecks<Container, CT> {
+ using Base = BasicContainerChecks<Container, CT>;
+ using value_type = typename Container::value_type;
+ using iterator = typename Container::iterator;
+ using const_iterator = typename Container::const_iterator;
+ using traits = std::iterator_traits<iterator>;
+ using category = typename traits::iterator_category;
+
+ using Base::makeContainer;
+public:
+ static void run() {
+ Base::run();
+ }
+private:
+
+};
+
+int main(int, char**)
+{
+ using SetAlloc = test_allocator<int>;
+ using MapAlloc = test_allocator<std::pair<const int, int>>;
+ {
+ UnorderedContainerChecks<
+ std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, MapAlloc>,
+ CT_UnorderedMap>::run();
+ UnorderedContainerChecks<
+ std::unordered_set<int, std::hash<int>, std::equal_to<int>, SetAlloc>,
+ CT_UnorderedSet>::run();
+ UnorderedContainerChecks<
+ std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>, MapAlloc>,
+ CT_UnorderedMultiMap>::run();
+ UnorderedContainerChecks<
+ std::unordered_multiset<int, std::hash<int>, std::equal_to<int>, SetAlloc>,
+ CT_UnorderedMultiSet>::run();
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.cxx1z.pass.cpp b/libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.cxx1z.pass.cpp
new file mode 100644
index 0000000000000..cad0bd8b304ed
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.cxx1z.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class X>
+// class auto_ptr;
+//
+// In C++17, auto_ptr has been removed.
+// However, for backwards compatibility, if _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
+// is defined before including <memory>, then auto_ptr will be restored.
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <type_traits>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ std::auto_ptr<int> p;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.verify.cpp b/libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.verify.cpp
new file mode 100644
index 0000000000000..3fe7ced3f1d89
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.auto.ptr/auto.ptr/auto_ptr.depr_in_cxx11.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+//
+// template <class X>
+// class auto_ptr;
+//
+// class auto_ptr<void>;
+//
+// template <class X>
+// class auto_ptr_ref;
+//
+// Deprecated in C++11
+
+// UNSUPPORTED: c++03
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR
+
+#include <memory>
+#include "test_macros.h"
+
+typedef std::auto_ptr<int> AP; // expected-warning {{'auto_ptr<int>' is deprecated}}
+typedef std::auto_ptr<void> APV; // expected-warning {{'auto_ptr<void>' is deprecated}}
+typedef std::auto_ptr_ref<int> APR; // expected-warning {{'auto_ptr_ref<int>' is deprecated}}
diff --git a/libcxx/test/libcxx-03/depr/depr.c.headers/extern_c.pass.cpp b/libcxx/test/libcxx-03/depr/depr.c.headers/extern_c.pass.cpp
new file mode 100644
index 0000000000000..f756aacbc1cd5
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.c.headers/extern_c.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
+//
+//===----------------------------------------------------------------------===//
+
+// When building with modules, including headers inside extern "C" is an anti-pattern
+// that we don't want to support and can't support with LSV enabled.
+// UNSUPPORTED: clang-modules-build
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// Sometimes C++'s <foo.h> headers get included within extern "C" contexts. This
+// is ill-formed (no diagnostic required), per [using.headers]p3, but we permit
+// it as an extension.
+
+#include <__config>
+
+extern "C" {
+#include <assert.h>
+// complex.h is not supported in extern "C".
+#include <ctype.h>
+#include <errno.h>
+#include <fenv.h>
+#include <float.h>
+#include <inttypes.h>
+#include <iso646.h>
+#include <limits.h>
+#include <math.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdalign.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+// tgmath.h is not supported in extern "C".
+#include <time.h>
+// FIXME: #include <uchar.h>
+#if _LIBCPP_HAS_WIDE_CHARACTERS
+# include <wchar.h>
+# include <wctype.h>
+#endif
+}
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.c.headers/math_h.compile.pass.cpp b/libcxx/test/libcxx-03/depr/depr.c.headers/math_h.compile.pass.cpp
new file mode 100644
index 0000000000000..045745b5ff95c
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.c.headers/math_h.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Code on Windows expects to be able to do:
+//
+// #define _USE_MATH_DEFINES
+// #include <math.h>
+//
+// and receive the definitions of mathematical constants, even if <math.h>
+// has previously been included. Make sure that works.
+//
+
+#ifdef _MSC_VER
+# include <math.h>
+# define _USE_MATH_DEFINES
+# include <math.h>
+
+# ifndef M_PI
+# error M_PI not defined
+# endif
+#endif
diff --git a/libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.std_types_t.compile.pass.cpp b/libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.std_types_t.compile.pass.cpp
new file mode 100644
index 0000000000000..3485ce755f976
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.std_types_t.compile.pass.cpp
@@ -0,0 +1,263 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// AIX system headers need <stdint.h> to be re-enterable when macro _STD_TYPES_T
+// is defined. This test case checks that after defining _STD_TYPES_T, including
+// <stdint.h>, and undefining _STD_TYPES_T, <stdint.h> can be re-entered to get
+// to macros like UINT32_MAX.
+//
+// https://reviews.llvm.org/D59253
+
+#define _STD_TYPES_T
+# include <stdint.h>
+#undef _STD_TYPES_T
+#include <stdint.h>
+
+#ifndef INT8_MIN
+#error INT8_MIN not defined
+#endif
+
+#ifndef INT16_MIN
+#error INT16_MIN not defined
+#endif
+
+#ifndef INT32_MIN
+#error INT32_MIN not defined
+#endif
+
+#ifndef INT64_MIN
+#error INT64_MIN not defined
+#endif
+
+#ifndef INT8_MAX
+#error INT8_MAX not defined
+#endif
+
+#ifndef INT16_MAX
+#error INT16_MAX not defined
+#endif
+
+#ifndef INT32_MAX
+#error INT32_MAX not defined
+#endif
+
+#ifndef INT64_MAX
+#error INT64_MAX not defined
+#endif
+
+#ifndef UINT8_MAX
+#error UINT8_MAX not defined
+#endif
+
+#ifndef UINT16_MAX
+#error UINT16_MAX not defined
+#endif
+
+#ifndef UINT32_MAX
+#error UINT32_MAX not defined
+#endif
+
+#ifndef UINT64_MAX
+#error UINT64_MAX not defined
+#endif
+
+#ifndef INT_LEAST8_MIN
+#error INT_LEAST8_MIN not defined
+#endif
+
+#ifndef INT_LEAST16_MIN
+#error INT_LEAST16_MIN not defined
+#endif
+
+#ifndef INT_LEAST32_MIN
+#error INT_LEAST32_MIN not defined
+#endif
+
+#ifndef INT_LEAST64_MIN
+#error INT_LEAST64_MIN not defined
+#endif
+
+#ifndef INT_LEAST8_MAX
+#error INT_LEAST8_MAX not defined
+#endif
+
+#ifndef INT_LEAST16_MAX
+#error INT_LEAST16_MAX not defined
+#endif
+
+#ifndef INT_LEAST32_MAX
+#error INT_LEAST32_MAX not defined
+#endif
+
+#ifndef INT_LEAST64_MAX
+#error INT_LEAST64_MAX not defined
+#endif
+
+#ifndef UINT_LEAST8_MAX
+#error UINT_LEAST8_MAX not defined
+#endif
+
+#ifndef UINT_LEAST16_MAX
+#error UINT_LEAST16_MAX not defined
+#endif
+
+#ifndef UINT_LEAST32_MAX
+#error UINT_LEAST32_MAX not defined
+#endif
+
+#ifndef UINT_LEAST64_MAX
+#error UINT_LEAST64_MAX not defined
+#endif
+
+#ifndef INT_FAST8_MIN
+#error INT_FAST8_MIN not defined
+#endif
+
+#ifndef INT_FAST16_MIN
+#error INT_FAST16_MIN not defined
+#endif
+
+#ifndef INT_FAST32_MIN
+#error INT_FAST32_MIN not defined
+#endif
+
+#ifndef INT_FAST64_MIN
+#error INT_FAST64_MIN not defined
+#endif
+
+#ifndef INT_FAST8_MAX
+#error INT_FAST8_MAX not defined
+#endif
+
+#ifndef INT_FAST16_MAX
+#error INT_FAST16_MAX not defined
+#endif
+
+#ifndef INT_FAST32_MAX
+#error INT_FAST32_MAX not defined
+#endif
+
+#ifndef INT_FAST64_MAX
+#error INT_FAST64_MAX not defined
+#endif
+
+#ifndef UINT_FAST8_MAX
+#error UINT_FAST8_MAX not defined
+#endif
+
+#ifndef UINT_FAST16_MAX
+#error UINT_FAST16_MAX not defined
+#endif
+
+#ifndef UINT_FAST32_MAX
+#error UINT_FAST32_MAX not defined
+#endif
+
+#ifndef UINT_FAST64_MAX
+#error UINT_FAST64_MAX not defined
+#endif
+
+#ifndef INTPTR_MIN
+#error INTPTR_MIN not defined
+#endif
+
+#ifndef INTPTR_MAX
+#error INTPTR_MAX not defined
+#endif
+
+#ifndef UINTPTR_MAX
+#error UINTPTR_MAX not defined
+#endif
+
+#ifndef INTMAX_MIN
+#error INTMAX_MIN not defined
+#endif
+
+#ifndef INTMAX_MAX
+#error INTMAX_MAX not defined
+#endif
+
+#ifndef UINTMAX_MAX
+#error UINTMAX_MAX not defined
+#endif
+
+#ifndef PTRDIFF_MIN
+#error PTRDIFF_MIN not defined
+#endif
+
+#ifndef PTRDIFF_MAX
+#error PTRDIFF_MAX not defined
+#endif
+
+#ifndef SIG_ATOMIC_MIN
+#error SIG_ATOMIC_MIN not defined
+#endif
+
+#ifndef SIG_ATOMIC_MAX
+#error SIG_ATOMIC_MAX not defined
+#endif
+
+#ifndef SIZE_MAX
+#error SIZE_MAX not defined
+#endif
+
+#ifndef WCHAR_MIN
+#error WCHAR_MIN not defined
+#endif
+
+#ifndef WCHAR_MAX
+#error WCHAR_MAX not defined
+#endif
+
+#ifndef WINT_MIN
+#error WINT_MIN not defined
+#endif
+
+#ifndef WINT_MAX
+#error WINT_MAX not defined
+#endif
+
+#ifndef INT8_C
+#error INT8_C not defined
+#endif
+
+#ifndef INT16_C
+#error INT16_C not defined
+#endif
+
+#ifndef INT32_C
+#error INT32_C not defined
+#endif
+
+#ifndef INT64_C
+#error INT64_C not defined
+#endif
+
+#ifndef UINT8_C
+#error UINT8_C not defined
+#endif
+
+#ifndef UINT16_C
+#error UINT16_C not defined
+#endif
+
+#ifndef UINT32_C
+#error UINT32_C not defined
+#endif
+
+#ifndef UINT64_C
+#error UINT64_C not defined
+#endif
+
+#ifndef INTMAX_C
+#error INTMAX_C not defined
+#endif
+
+#ifndef UINTMAX_C
+#error UINTMAX_C not defined
+#endif
diff --git a/libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.xopen_source.compile.pass.cpp b/libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.xopen_source.compile.pass.cpp
new file mode 100644
index 0000000000000..75a4ab908ce21
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.c.headers/stdint_h.xopen_source.compile.pass.cpp
@@ -0,0 +1,263 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test breaks when enabling LSV.
+// UNSUPPORTED: clang-modules-build
+
+// Test that limits macros are available when <stdint.h> is included
+// with or without macro _XOPEN_SOURCE=700.
+//
+// https://reviews.llvm.org/D59253
+
+// ADDITIONAL_COMPILE_FLAGS: -D_XOPEN_SOURCE=700
+
+#include <stdint.h>
+
+#ifndef INT8_MIN
+#error INT8_MIN not defined
+#endif
+
+#ifndef INT16_MIN
+#error INT16_MIN not defined
+#endif
+
+#ifndef INT32_MIN
+#error INT32_MIN not defined
+#endif
+
+#ifndef INT64_MIN
+#error INT64_MIN not defined
+#endif
+
+#ifndef INT8_MAX
+#error INT8_MAX not defined
+#endif
+
+#ifndef INT16_MAX
+#error INT16_MAX not defined
+#endif
+
+#ifndef INT32_MAX
+#error INT32_MAX not defined
+#endif
+
+#ifndef INT64_MAX
+#error INT64_MAX not defined
+#endif
+
+#ifndef UINT8_MAX
+#error UINT8_MAX not defined
+#endif
+
+#ifndef UINT16_MAX
+#error UINT16_MAX not defined
+#endif
+
+#ifndef UINT32_MAX
+#error UINT32_MAX not defined
+#endif
+
+#ifndef UINT64_MAX
+#error UINT64_MAX not defined
+#endif
+
+#ifndef INT_LEAST8_MIN
+#error INT_LEAST8_MIN not defined
+#endif
+
+#ifndef INT_LEAST16_MIN
+#error INT_LEAST16_MIN not defined
+#endif
+
+#ifndef INT_LEAST32_MIN
+#error INT_LEAST32_MIN not defined
+#endif
+
+#ifndef INT_LEAST64_MIN
+#error INT_LEAST64_MIN not defined
+#endif
+
+#ifndef INT_LEAST8_MAX
+#error INT_LEAST8_MAX not defined
+#endif
+
+#ifndef INT_LEAST16_MAX
+#error INT_LEAST16_MAX not defined
+#endif
+
+#ifndef INT_LEAST32_MAX
+#error INT_LEAST32_MAX not defined
+#endif
+
+#ifndef INT_LEAST64_MAX
+#error INT_LEAST64_MAX not defined
+#endif
+
+#ifndef UINT_LEAST8_MAX
+#error UINT_LEAST8_MAX not defined
+#endif
+
+#ifndef UINT_LEAST16_MAX
+#error UINT_LEAST16_MAX not defined
+#endif
+
+#ifndef UINT_LEAST32_MAX
+#error UINT_LEAST32_MAX not defined
+#endif
+
+#ifndef UINT_LEAST64_MAX
+#error UINT_LEAST64_MAX not defined
+#endif
+
+#ifndef INT_FAST8_MIN
+#error INT_FAST8_MIN not defined
+#endif
+
+#ifndef INT_FAST16_MIN
+#error INT_FAST16_MIN not defined
+#endif
+
+#ifndef INT_FAST32_MIN
+#error INT_FAST32_MIN not defined
+#endif
+
+#ifndef INT_FAST64_MIN
+#error INT_FAST64_MIN not defined
+#endif
+
+#ifndef INT_FAST8_MAX
+#error INT_FAST8_MAX not defined
+#endif
+
+#ifndef INT_FAST16_MAX
+#error INT_FAST16_MAX not defined
+#endif
+
+#ifndef INT_FAST32_MAX
+#error INT_FAST32_MAX not defined
+#endif
+
+#ifndef INT_FAST64_MAX
+#error INT_FAST64_MAX not defined
+#endif
+
+#ifndef UINT_FAST8_MAX
+#error UINT_FAST8_MAX not defined
+#endif
+
+#ifndef UINT_FAST16_MAX
+#error UINT_FAST16_MAX not defined
+#endif
+
+#ifndef UINT_FAST32_MAX
+#error UINT_FAST32_MAX not defined
+#endif
+
+#ifndef UINT_FAST64_MAX
+#error UINT_FAST64_MAX not defined
+#endif
+
+#ifndef INTPTR_MIN
+#error INTPTR_MIN not defined
+#endif
+
+#ifndef INTPTR_MAX
+#error INTPTR_MAX not defined
+#endif
+
+#ifndef UINTPTR_MAX
+#error UINTPTR_MAX not defined
+#endif
+
+#ifndef INTMAX_MIN
+#error INTMAX_MIN not defined
+#endif
+
+#ifndef INTMAX_MAX
+#error INTMAX_MAX not defined
+#endif
+
+#ifndef UINTMAX_MAX
+#error UINTMAX_MAX not defined
+#endif
+
+#ifndef PTRDIFF_MIN
+#error PTRDIFF_MIN not defined
+#endif
+
+#ifndef PTRDIFF_MAX
+#error PTRDIFF_MAX not defined
+#endif
+
+#ifndef SIG_ATOMIC_MIN
+#error SIG_ATOMIC_MIN not defined
+#endif
+
+#ifndef SIG_ATOMIC_MAX
+#error SIG_ATOMIC_MAX not defined
+#endif
+
+#ifndef SIZE_MAX
+#error SIZE_MAX not defined
+#endif
+
+#ifndef WCHAR_MIN
+#error WCHAR_MIN not defined
+#endif
+
+#ifndef WCHAR_MAX
+#error WCHAR_MAX not defined
+#endif
+
+#ifndef WINT_MIN
+#error WINT_MIN not defined
+#endif
+
+#ifndef WINT_MAX
+#error WINT_MAX not defined
+#endif
+
+#ifndef INT8_C
+#error INT8_C not defined
+#endif
+
+#ifndef INT16_C
+#error INT16_C not defined
+#endif
+
+#ifndef INT32_C
+#error INT32_C not defined
+#endif
+
+#ifndef INT64_C
+#error INT64_C not defined
+#endif
+
+#ifndef UINT8_C
+#error UINT8_C not defined
+#endif
+
+#ifndef UINT16_C
+#error UINT16_C not defined
+#endif
+
+#ifndef UINT32_C
+#error UINT32_C not defined
+#endif
+
+#ifndef UINT64_C
+#error UINT64_C not defined
+#endif
+
+#ifndef INTMAX_C
+#error INTMAX_C not defined
+#endif
+
+#ifndef UINTMAX_C
+#error UINTMAX_C not defined
+#endif
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.pass.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.pass.cpp
new file mode 100644
index 0000000000000..d9a65eee4c130
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// pointer address(reference x) const;
+// const_pointer address(const_reference x) const;
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+void test_address() {
+ T* tp = new T();
+ const T* ctp = tp;
+ const std::allocator<T> a;
+ assert(a.address(*tp) == tp);
+ assert(a.address(*ctp) == tp);
+ delete tp;
+}
+
+struct A {
+ void operator&() const {}
+};
+
+int main(int, char**) {
+ test_address<int>();
+ test_address<A>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.verify.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.verify.cpp
new file mode 100644
index 0000000000000..21fd4d23449b5
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.cxx20.verify.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// pointer address(reference x) const;
+// const_pointer address(const_reference x) const;
+
+// In C++20, parts of std::allocator<T> have been removed.
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+void test_address() {
+ T* tp = new T();
+ const T* ctp = tp;
+ const std::allocator<T> a;
+ assert(a.address(*tp) == tp); // expected-error 2 {{no member}}
+ assert(a.address(*ctp) == tp); // expected-error 2 {{no member}}
+ delete tp;
+}
+
+struct A {
+ void operator&() const {}
+};
+
+int main(int, char**) {
+ test_address<int>();
+ test_address<A>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp
new file mode 100644
index 0000000000000..4098bdb2ee925
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// pointer address(reference x) const;
+// const_pointer address(const_reference x) const;
+
+// Deprecated in C++17
+
+// REQUIRES: c++17
+
+#include <memory>
+
+void f() {
+ int x = 0;
+ std::allocator<int> a;
+
+ (void)a.address(x); // expected-warning {{'address' is deprecated}}
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.pass.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.pass.cpp
new file mode 100644
index 0000000000000..8fc6628ebfba2
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// T* allocate(size_t n, const void* hint);
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <cassert>
+#include <cstddef> // for std::max_align_t
+
+#include "test_macros.h"
+#include "count_new.h"
+
+#ifdef TEST_HAS_NO_ALIGNED_ALLOCATION
+static const bool UsingAlignedNew = false;
+#else
+static const bool UsingAlignedNew = true;
+#endif
+
+#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+static const std::size_t MaxAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
+#else
+static const std::size_t MaxAligned = std::alignment_of<std::max_align_t>::value;
+#endif
+
+static const std::size_t OverAligned = MaxAligned * 2;
+
+template <std::size_t Align>
+struct TEST_ALIGNAS(Align) AlignedType {
+ char data;
+ static int constructed;
+ AlignedType() { ++constructed; }
+ AlignedType(AlignedType const&) { ++constructed; }
+ ~AlignedType() { --constructed; }
+};
+template <std::size_t Align>
+int AlignedType<Align>::constructed = 0;
+
+template <std::size_t Align>
+void test_aligned() {
+ typedef AlignedType<Align> T;
+ T::constructed = 0;
+ globalMemCounter.reset();
+ std::allocator<T> a;
+ const bool IsOverAlignedType = Align > MaxAligned;
+ const bool ExpectAligned = IsOverAlignedType && UsingAlignedNew;
+ {
+ globalMemCounter.last_new_size = 0;
+ globalMemCounter.last_new_align = 0;
+ T* ap2 = a.allocate(11, (const void*)5);
+ DoNotOptimize(ap2);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(globalMemCounter.checkNewCalledEq(1));
+ assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
+ assert(globalMemCounter.checkLastNewSizeEq(11 * sizeof(T)));
+ assert(globalMemCounter.checkLastNewAlignEq(ExpectAligned ? Align : 0));
+ assert(T::constructed == 0);
+ globalMemCounter.last_delete_align = 0;
+ a.deallocate(ap2, 11);
+ DoNotOptimize(ap2);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(globalMemCounter.checkDeleteCalledEq(1));
+ assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned));
+ assert(globalMemCounter.checkLastDeleteAlignEq(ExpectAligned ? Align : 0));
+ assert(T::constructed == 0);
+ }
+}
+
+int main(int, char**) {
+ test_aligned<1>();
+ test_aligned<2>();
+ test_aligned<4>();
+ test_aligned<8>();
+ test_aligned<16>();
+ test_aligned<MaxAligned>();
+ test_aligned<OverAligned>();
+ test_aligned<OverAligned * 2>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.verify.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.verify.cpp
new file mode 100644
index 0000000000000..bf02c7570d39a
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.cxx20.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <memory>
+
+// allocator:
+// T* allocate(size_t n, const void* hint);
+
+// Removed in C++20.
+
+#include <memory>
+
+void f() {
+ std::allocator<int> a;
+ a.allocate(3, nullptr); // expected-error {{too many arguments to function call}}
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp
new file mode 100644
index 0000000000000..8629df3c41645
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// T* allocate(size_t n, const void* hint);
+
+// Deprecated in C++17
+
+// REQUIRES: c++17
+
+#include <memory>
+
+#include "test_macros.h"
+
+void f() {
+ std::allocator<int> a;
+ TEST_IGNORE_NODISCARD a.allocate(3, nullptr); // expected-warning {{'allocate' is deprecated}}
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
new file mode 100644
index 0000000000000..9a37cf8af8e69
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// template <class... Args> void construct(pointer p, Args&&... args);
+
+// In C++20, parts of std::allocator<T> have been removed.
+// In C++17, they were deprecated.
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.h"
+
+int A_constructed = 0;
+
+struct A {
+ int data;
+ A() { ++A_constructed; }
+
+ A(const A&) { ++A_constructed; }
+
+ explicit A(int) { ++A_constructed; }
+ A(int, int*) { ++A_constructed; }
+
+ ~A() { --A_constructed; }
+};
+
+int move_only_constructed = 0;
+
+#if TEST_STD_VER >= 11
+class move_only {
+ move_only(const move_only&) = delete;
+ move_only& operator=(const move_only&) = delete;
+
+public:
+ move_only(move_only&&) { ++move_only_constructed; }
+ move_only& operator=(move_only&&) { return *this; }
+
+ move_only() { ++move_only_constructed; }
+ ~move_only() { --move_only_constructed; }
+
+public:
+ int data; // unused other than to make sizeof(move_only) == sizeof(int).
+ // but public to suppress "-Wunused-private-field"
+};
+#endif // TEST_STD_VER >= 11
+
+int main(int, char**) {
+ globalMemCounter.reset();
+ {
+ std::allocator<A> a;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(A_constructed == 0);
+
+ globalMemCounter.last_new_size = 0;
+ A* ap = a.allocate(3);
+ DoNotOptimize(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
+ assert(A_constructed == 0);
+
+ a.construct(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 1);
+
+ a.destroy(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 0);
+
+ a.construct(ap, A());
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 1);
+
+ a.destroy(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 0);
+
+ a.construct(ap, 5);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 1);
+
+ a.destroy(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 0);
+
+ a.construct(ap, 5, (int*)0);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 1);
+
+ a.destroy(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(A_constructed == 0);
+
+ a.deallocate(ap, 3);
+ DoNotOptimize(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(A_constructed == 0);
+ }
+#if TEST_STD_VER >= 11
+ {
+ std::allocator<move_only> a;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(move_only_constructed == 0);
+
+ globalMemCounter.last_new_size = 0;
+ move_only* ap = a.allocate(3);
+ DoNotOptimize(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
+ assert(move_only_constructed == 0);
+
+ a.construct(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(move_only_constructed == 1);
+
+ a.destroy(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(move_only_constructed == 0);
+
+ a.construct(ap, move_only());
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(move_only_constructed == 1);
+
+ a.destroy(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(move_only_constructed == 0);
+
+ a.deallocate(ap, 3);
+ DoNotOptimize(ap);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(move_only_constructed == 0);
+ }
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.verify.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.verify.cpp
new file mode 100644
index 0000000000000..b39f9d918c959
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/construct.cxx20.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// template <class... Args> void construct(pointer p, Args&&... args);
+
+// Removed in C++20.
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <memory>
+#include <cassert>
+
+int A_constructed = 0;
+
+struct A {
+ int data;
+ A() { ++A_constructed; }
+
+ A(const A&) { ++A_constructed; }
+
+ explicit A(int) { ++A_constructed; }
+ A(int, int*) { ++A_constructed; }
+
+ ~A() { --A_constructed; }
+};
+
+int move_only_constructed = 0;
+
+class move_only {
+ move_only(const move_only&) = delete;
+ move_only& operator=(const move_only&) = delete;
+
+public:
+ move_only(move_only&&) { ++move_only_constructed; }
+ move_only& operator=(move_only&&) { return *this; }
+
+ move_only() { ++move_only_constructed; }
+ ~move_only() { --move_only_constructed; }
+
+public:
+ int data; // unused other than to make sizeof(move_only) == sizeof(int).
+ // but public to suppress "-Wunused-private-field"
+};
+
+int main(int, char**) {
+ {
+ std::allocator<A> a;
+ A* ap = a.allocate(3);
+ a.construct(ap); // expected-error {{no member}}
+ a.destroy(ap); // expected-error {{no member}}
+ a.construct(ap, A()); // expected-error {{no member}}
+ a.destroy(ap); // expected-error {{no member}}
+ a.construct(ap, 5); // expected-error {{no member}}
+ a.destroy(ap); // expected-error {{no member}}
+ a.construct(ap, 5, (int*)0); // expected-error {{no member}}
+ a.destroy(ap); // expected-error {{no member}}
+ a.deallocate(ap, 3);
+ }
+ {
+ std::allocator<move_only> a;
+ move_only* ap = a.allocate(3);
+ a.construct(ap); // expected-error {{no member}}
+ a.destroy(ap); // expected-error {{no member}}
+ a.construct(ap, move_only()); // expected-error {{no member}}
+ a.destroy(ap); // expected-error {{no member}}
+ a.deallocate(ap, 3);
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.pass.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.pass.cpp
new file mode 100644
index 0000000000000..92e3b919b0f76
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// size_type max_size() const throw();
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <limits>
+#include <cstddef>
+#include <cassert>
+
+#include "test_macros.h"
+
+int new_called = 0;
+
+int main(int, char**) {
+ const std::allocator<int> a;
+ std::size_t M = a.max_size();
+ assert(M > 0xFFFF && M <= (std::numeric_limits<std::size_t>::max() / sizeof(int)));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.verify.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.verify.cpp
new file mode 100644
index 0000000000000..0e0f3c3f4aa45
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator.members/max_size.cxx20.verify.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// size_type max_size() const throw();
+
+// In C++20, parts of std::allocator<T> have been removed.
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <memory>
+#include <limits>
+#include <cstddef>
+#include <cassert>
+
+#include "test_macros.h"
+
+int new_called = 0;
+
+int main(int, char**) {
+ const std::allocator<int> a;
+ std::size_t M = a.max_size(); // expected-error {{no member}}
+ assert(M > 0xFFFF && M <= (std::numeric_limits<std::size_t>::max() / sizeof(int)));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator_types.cxx20.pass.cpp b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator_types.cxx20.pass.cpp
new file mode 100644
index 0000000000000..e462e07d896c5
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.default.allocator/allocator_types.cxx20.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Check that the following types are provided regardless of the Standard when
+// we request them from libc++.
+
+// template <class T>
+// class allocator
+// {
+// public:
+// typedef size_t size_type;
+// typedef ptrdiff_t difference_type;
+// typedef T* pointer;
+// typedef const T* const_pointer;
+// typedef typename add_lvalue_reference<T>::type reference;
+// typedef typename add_lvalue_reference<const T>::type const_reference;
+//
+// template <class U> struct rebind {typedef allocator<U> other;};
+// ...
+// };
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <type_traits>
+#include <cstddef>
+
+template <class T>
+void test() {
+ static_assert((std::is_same<typename std::allocator<T>::size_type, std::size_t>::value), "");
+ static_assert((std::is_same<typename std::allocator<T>::difference_type, std::ptrdiff_t>::value), "");
+ static_assert((std::is_same<typename std::allocator<T>::pointer, T*>::value), "");
+ static_assert((std::is_same<typename std::allocator<T>::const_pointer, const T*>::value), "");
+ static_assert((std::is_same<typename std::allocator<T>::reference, T&>::value), "");
+ static_assert((std::is_same<typename std::allocator<T>::const_reference, const T&>::value), "");
+ static_assert(
+ (std::is_same<typename std::allocator<T>::template rebind<int>::other, std::allocator<int> >::value), "");
+}
+
+int main(int, char**) {
+ test<char>();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.func.adaptor.typedefs/typedefs.depr_in_cxx17.verify.cpp b/libcxx/test/libcxx-03/depr/depr.func.adaptor.typedefs/typedefs.depr_in_cxx17.verify.cpp
new file mode 100644
index 0000000000000..422f405042208
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.func.adaptor.typedefs/typedefs.depr_in_cxx17.verify.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <optional>
+#include <utility>
+#include "test_macros.h"
+
+void test_functional()
+{
+ {
+ using T = std::plus<int>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::first_argument_type b; // expected-warning {{is deprecated}}
+ T::second_argument_type c; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ (void)c;
+ }
+ {
+ using T = std::less<int>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::first_argument_type b; // expected-warning {{is deprecated}}
+ T::second_argument_type c; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ (void)c;
+ }
+ {
+ using T = std::logical_not<int>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::argument_type b; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ }
+}
+
+void test_owner_less()
+{
+ {
+ using T = std::owner_less<std::shared_ptr<int>>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::first_argument_type b; // expected-warning {{is deprecated}}
+ T::second_argument_type c; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ (void)c;
+ }
+ {
+ using T = std::owner_less<std::weak_ptr<int>>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::first_argument_type b; // expected-warning {{is deprecated}}
+ T::second_argument_type c; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ (void)c;
+ }
+}
+
+void test_hash()
+{
+ {
+ using T = std::hash<int>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::argument_type b; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ }
+ {
+ using T = std::hash<std::shared_ptr<int>>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::argument_type b; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ }
+ {
+ using T = std::hash<std::unique_ptr<int>>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::argument_type b; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ }
+ {
+ using T = std::hash<std::optional<int>>;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::argument_type b; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ }
+}
+
+void test_map()
+{
+ {
+ using T = std::map<int, int>::value_compare;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::first_argument_type b; // expected-warning {{is deprecated}}
+ T::second_argument_type c; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ (void)c;
+ }
+ {
+ using T = std::multimap<int, int>::value_compare;
+ T::result_type a; // expected-warning {{is deprecated}}
+ T::first_argument_type b; // expected-warning {{is deprecated}}
+ T::second_argument_type c; // expected-warning {{is deprecated}}
+ (void)a;
+ (void)b;
+ (void)c;
+ }
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.function.objects/adaptors.depr_in_cxx11.verify.cpp b/libcxx/test/libcxx-03/depr/depr.function.objects/adaptors.depr_in_cxx11.verify.cpp
new file mode 100644
index 0000000000000..87d81d00ebaec
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.function.objects/adaptors.depr_in_cxx11.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// UNSUPPORTED: c++03
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+
+#include <functional>
+#include <cassert>
+
+int identity(int v) { return v; }
+int sum(int a, int b) { return a + b; }
+
+struct Foo {
+ int const_zero() const { return 0; }
+ int const_identity(int v) const { return v; }
+ int zero() { return 0; }
+ int identity(int v) { return v; }
+};
+
+void f() {
+ typedef std::pointer_to_unary_function<int, int> PUF; // expected-warning {{'pointer_to_unary_function<int, int>' is deprecated}}
+ typedef std::pointer_to_binary_function<int, int, int> PBF; // expected-warning {{'pointer_to_binary_function<int, int, int>' is deprecated}}
+ std::ptr_fun<int, int>(identity); // expected-warning {{'ptr_fun<int, int>' is deprecated}}
+ std::ptr_fun<int, int, int>(sum); // expected-warning {{'ptr_fun<int, int, int>' is deprecated}}
+
+ typedef std::mem_fun_t<int, Foo> MFT0; // expected-warning {{'mem_fun_t<int, Foo>' is deprecated}}
+ typedef std::mem_fun1_t<int, Foo, int> MFT1; // expected-warning {{'mem_fun1_t<int, Foo, int>' is deprecated}}
+ typedef std::const_mem_fun_t<int, Foo> CMFT0; // expected-warning {{'const_mem_fun_t<int, Foo>' is deprecated}}
+ typedef std::const_mem_fun1_t<int, Foo, int> CMFT1; // expected-warning {{'const_mem_fun1_t<int, Foo, int>' is deprecated}}
+ std::mem_fun<int, Foo>(&Foo::zero); // expected-warning {{'mem_fun<int, Foo>' is deprecated}}
+ std::mem_fun<int, Foo, int>(&Foo::identity); // expected-warning {{'mem_fun<int, Foo, int>' is deprecated}}
+ std::mem_fun<int, Foo>(&Foo::const_zero); // expected-warning {{'mem_fun<int, Foo>' is deprecated}}
+ std::mem_fun<int, Foo, int>(&Foo::const_identity); // expected-warning {{'mem_fun<int, Foo, int>' is deprecated}}
+
+ typedef std::mem_fun_ref_t<int, Foo> MFR0; // expected-warning {{'mem_fun_ref_t<int, Foo>' is deprecated}}
+ typedef std::mem_fun1_ref_t<int, Foo, int> MFR1; // expected-warning {{'mem_fun1_ref_t<int, Foo, int>' is deprecated}}
+ typedef std::const_mem_fun_ref_t<int, Foo> CMFR0; // expected-warning {{'const_mem_fun_ref_t<int, Foo>' is deprecated}}
+ typedef std::const_mem_fun1_ref_t<int, Foo, int> CMFR1; // expected-warning {{'const_mem_fun1_ref_t<int, Foo, int>' is deprecated}}
+ std::mem_fun_ref<int, Foo>(&Foo::zero); // expected-warning {{'mem_fun_ref<int, Foo>' is deprecated}}
+ std::mem_fun_ref<int, Foo, int>(&Foo::identity); // expected-warning {{'mem_fun_ref<int, Foo, int>' is deprecated}}
+ std::mem_fun_ref<int, Foo>(&Foo::const_zero); // expected-warning {{'mem_fun_ref<int, Foo>' is deprecated}}
+ std::mem_fun_ref<int, Foo, int>(&Foo::const_identity); // expected-warning {{'mem_fun_ref<int, Foo, int>' is deprecated}}
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp b/libcxx/test/libcxx-03/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
new file mode 100644
index 0000000000000..d212f36bb1ab4
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.function.objects/depr.adaptors.cxx1z.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+
+// In C++17, the function adapters mem_fun/mem_fun_ref, etc have been removed.
+// However, for backwards compatibility, if _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+// is defined before including <functional>, then they will be restored.
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <functional>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+
+int identity(int v) { return v; }
+int sum(int a, int b) { return a + b; }
+
+struct Foo {
+ int zero() { return 0; }
+ int zero_const() const { return 1; }
+
+ int identity(int v) const { return v; }
+ int sum(int a, int b) const { return a + b; }
+};
+
+int main(int, char**)
+{
+ typedef std::pointer_to_unary_function<int, int> PUF;
+ typedef std::pointer_to_binary_function<int, int, int> PBF;
+
+ static_assert(
+ (std::is_same<PUF, decltype((std::ptr_fun<int, int>(identity)))>::value),
+ "");
+ static_assert(
+ (std::is_same<PBF, decltype((std::ptr_fun<int, int, int>(sum)))>::value),
+ "");
+
+ assert((std::ptr_fun<int, int>(identity)(4) == 4));
+ assert((std::ptr_fun<int, int, int>(sum)(4, 5) == 9));
+
+ Foo f;
+ assert((std::mem_fn(&Foo::identity)(f, 5) == 5));
+ assert((std::mem_fn(&Foo::sum)(f, 5, 6) == 11));
+
+ typedef std::mem_fun_ref_t<int, Foo> MFR;
+ typedef std::const_mem_fun_ref_t<int, Foo> CMFR;
+
+ static_assert(
+ (std::is_same<MFR, decltype((std::mem_fun_ref(&Foo::zero)))>::value), "");
+ static_assert((std::is_same<CMFR, decltype((std::mem_fun_ref(
+ &Foo::zero_const)))>::value),
+ "");
+
+ assert((std::mem_fun_ref(&Foo::zero)(f) == 0));
+ assert((std::mem_fun_ref(&Foo::identity)(f, 5) == 5));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/depr.rel_ops/rel_ops.depr_in_cxx20.verify.cpp b/libcxx/test/libcxx-03/depr/depr.rel_ops/rel_ops.depr_in_cxx20.verify.cpp
new file mode 100644
index 0000000000000..35457f65fe2eb
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/depr.rel_ops/rel_ops.depr_in_cxx20.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <utility>
+#include <cassert>
+
+struct A {
+ int data_ = 0;
+};
+
+inline bool operator==(const A& x, const A& y) { return x.data_ == y.data_; }
+
+inline bool operator<(const A& x, const A& y) { return x.data_ < y.data_; }
+
+void test() {
+ using namespace std::rel_ops;
+ A a1{1};
+ A a2{2};
+ (void)(a1 == a1);
+ (void)(a1 != a2); // note not deprecated message, due to compiler generated operator.
+ std::rel_ops::operator!=(a1, a2); // expected-warning {{is deprecated}}
+ (void)(a1 < a2);
+ (void)(a1 > a2); // expected-warning 2 {{is deprecated}}
+ (void)(a1 <= a2); // expected-warning 2 {{is deprecated}}
+ (void)(a1 >= a2); // expected-warning 2 {{is deprecated}}
+}
diff --git a/libcxx/test/libcxx-03/depr/exception.unexpected/get_unexpected.pass.cpp b/libcxx/test/libcxx-03/depr/exception.unexpected/get_unexpected.pass.cpp
new file mode 100644
index 0000000000000..e4533a01c5bfd
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/exception.unexpected/get_unexpected.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// test get_unexpected
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
+
+#include <exception>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+
+void f1() {}
+void f2() {}
+
+void f3()
+{
+ std::exit(0);
+}
+
+int main(int, char**)
+{
+
+ std::unexpected_handler old = std::get_unexpected();
+ // verify there is a previous unexpected handler
+ assert(old);
+ std::set_unexpected(f1);
+ assert(std::get_unexpected() == f1);
+ // verify f1 was replace with f2
+ std::set_unexpected(f2);
+ assert(std::get_unexpected() == f2);
+ // verify calling original unexpected handler calls terminate
+ std::set_terminate(f3);
+ (*old)();
+ assert(0);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/exception.unexpected/set_unexpected.pass.cpp b/libcxx/test/libcxx-03/depr/exception.unexpected/set_unexpected.pass.cpp
new file mode 100644
index 0000000000000..f428790f6cc96
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/exception.unexpected/set_unexpected.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// test set_unexpected
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
+
+#include <exception>
+#include <cassert>
+#include <cstdlib>
+
+#include "test_macros.h"
+
+void f1() {}
+void f2() {}
+
+void f3()
+{
+ std::exit(0);
+}
+
+int main(int, char**)
+{
+ std::unexpected_handler old = std::set_unexpected(f1);
+ // verify there is a previous unexpected handler
+ assert(old);
+ // verify f1 was replace with f2
+ assert(std::set_unexpected(f2) == f1);
+ // verify calling original unexpected handler calls terminate
+ std::set_terminate(f3);
+ (*old)();
+ assert(0);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/exception.unexpected/unexpected.pass.cpp b/libcxx/test/libcxx-03/depr/exception.unexpected/unexpected.pass.cpp
new file mode 100644
index 0000000000000..6ab1147b912eb
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/exception.unexpected/unexpected.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// test unexpected
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
+
+#include <exception>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+
+void fexit()
+{
+ std::exit(0);
+}
+
+int main(int, char**)
+{
+ std::set_unexpected(fexit);
+ std::unexpected();
+ assert(false);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/depr/exception.unexpected/unexpected_disabled_cpp17.verify.cpp b/libcxx/test/libcxx-03/depr/exception.unexpected/unexpected_disabled_cpp17.verify.cpp
new file mode 100644
index 0000000000000..299cb123fbda3
--- /dev/null
+++ b/libcxx/test/libcxx-03/depr/exception.unexpected/unexpected_disabled_cpp17.verify.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, c++11, c++14
+
+// test unexpected
+
+#include <exception>
+
+void f() {}
+
+int main(int, char**) {
+ using T = std::unexpected_handler; // expected-error {{no type named 'unexpected_handler' in namespace 'std'}}
+ std::unexpected(); // expected-error {{no member named 'unexpected' in namespace 'std'}}
+ std::get_unexpected(); // expected-error {{no member named 'get_unexpected' in namespace 'std'}}
+ std::set_unexpected(f); // expected-error {{no type named 'set_unexpected' in namespace 'std'}}
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/algorithm.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/algorithm.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..14febc12a8a2d
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/algorithm.nodiscard.verify.cpp
@@ -0,0 +1,396 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <algorithm> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <algorithm>
+#include <functional>
+#include <iterator>
+
+#include "test_macros.h"
+
+struct P {
+ bool operator()(int) const { return false; }
+};
+
+void test() {
+ int arr[1] = { 1 };
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::adjacent_find(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::adjacent_find(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::all_of(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::any_of(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::binary_search(std::begin(arr), std::end(arr), 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::binary_search(std::begin(arr), std::end(arr), 1, std::greater<int>());
+
+#if TEST_STD_VER >= 17
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::clamp(2, 1, 3);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::clamp(2, 1, 3, std::greater<int>());
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::count_if(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::count(std::begin(arr), std::end(arr), 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::equal_range(std::begin(arr), std::end(arr), 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::equal_range(std::begin(arr), std::end(arr), 1, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::equal(std::begin(arr), std::end(arr), std::begin(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::equal(std::begin(arr), std::end(arr), std::begin(arr),
+ std::greater<int>());
+
+#if TEST_STD_VER >= 14
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::equal(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::equal(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
+ std::greater<int>());
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_end(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_end(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
+ std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_first_of(std::begin(arr), std::end(arr), std::begin(arr),
+ std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_first_of(std::begin(arr), std::end(arr), std::begin(arr),
+ std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_if_not(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find_if(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::find(std::begin(arr), std::end(arr), 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::includes(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::includes(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
+ std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_heap_until(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_heap_until(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_heap(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_heap(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_partitioned(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
+ std::greater<int>());
+
+#if TEST_STD_VER >= 14
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
+ std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_permutation(std::begin(arr), std::end(arr), std::begin(arr),
+ std::end(arr), std::greater<int>());
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_sorted_until(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_sorted_until(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_sorted(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_sorted(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lexicographical_compare(std::begin(arr), std::end(arr), std::begin(arr),
+ std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lexicographical_compare(std::begin(arr), std::end(arr), std::begin(arr),
+ std::end(arr), std::greater<int>());
+
+#if TEST_STD_VER >= 20
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lexicographical_compare_three_way(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lexicographical_compare_three_way(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr), std::compare_three_way());
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lower_bound(std::begin(arr), std::end(arr), 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::lower_bound(std::begin(arr), std::end(arr), 1, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::max_element(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::max_element(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::max(1, 2);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::max(1, 2, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::max({1, 2, 3});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::max({1, 2, 3}, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::min_element(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::min_element(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::min(1, 2);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::min(1, 2, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::min({1, 2, 3});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::min({1, 2, 3}, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::minmax_element(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::minmax_element(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::minmax(1, 2);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::minmax(1, 2, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::minmax({1, 2, 3});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::minmax({1, 2, 3}, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::mismatch(std::begin(arr), std::end(arr), std::begin(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::mismatch(std::begin(arr), std::end(arr), std::begin(arr),
+ std::greater<int>());
+
+#if TEST_STD_VER >= 14
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::mismatch(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::mismatch(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
+ std::greater<int>());
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::none_of(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::remove_if(std::begin(arr), std::end(arr), P());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::remove(std::begin(arr), std::end(arr), 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::search_n(std::begin(arr), std::end(arr), 1, 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::search_n(std::begin(arr), std::end(arr), 1, 1, std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::search(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::search(std::begin(arr), std::end(arr), std::begin(arr), std::end(arr),
+ std::greater<int>());
+
+#if TEST_STD_VER >= 17
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::search(std::begin(arr), std::end(arr),
+ std::default_searcher(std::begin(arr), std::end(arr)));
+#endif
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::unique(std::begin(arr), std::end(arr));
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::unique(std::begin(arr), std::end(arr), std::greater<int>());
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::upper_bound(std::begin(arr), std::end(arr), 1);
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::upper_bound(std::begin(arr), std::end(arr), 1, std::greater<int>());
+
+#if TEST_STD_VER >= 20
+ int range[1];
+ int* iter = range;
+ auto pred = [](auto...) { return true; };
+ std::ranges::adjacent_find(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::adjacent_find(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::all_of(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::all_of(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::any_of(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::any_of(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::binary_search(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::binary_search(iter, iter, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::clamp(1, 2, 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::count_if(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::count_if(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::count(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::count(iter, iter, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::equal_range(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::equal_range(iter, iter, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::equal(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::equal(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_end(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_end(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_first_of(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_first_of(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_if_not(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_if_not(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_if(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_if(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find(iter, iter, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::includes(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::includes(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_heap_until(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_heap_until(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_heap(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_heap(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_partitioned(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_partitioned(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_permutation(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_permutation(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_sorted_until(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_sorted_until(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_sorted(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::is_sorted(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::lexicographical_compare(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::lexicographical_compare(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::lower_bound(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::lower_bound(iter, iter, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::max_element(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::max_element(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::max(1, 2); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::max({1, 2, 3}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::max(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::minmax_element(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::minmax_element(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::minmax(1, 2); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::minmax({1, 2, 3}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::minmax(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::mismatch(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::mismatch(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::none_of(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::none_of(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::remove_if(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::remove_if(iter, iter, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::remove(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::remove(iter, iter, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::search_n(range, 1, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::search_n(iter, iter, 1, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::search(range, range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::search(iter, iter, iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::unique(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::unique(iter, iter); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::upper_bound(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::upper_bound(iter, iter, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+#if TEST_STD_VER >= 23
+ std::ranges::contains(range, 1);
+ // expected-warning at -1{{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::contains(iter, iter, 1);
+ // expected-warning at -1{{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::contains_subrange(range, range);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::contains_subrange(iter, iter, iter, iter);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_last_if_not(iter, iter, pred);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_last_if_not(range, pred);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_last_if(iter, iter, pred);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_last_if(range, pred);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_last(iter, iter, 1);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::find_last(range, 1);
+ // expected-warning at -1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::fold_left(range, 0, std::plus());
+ // expected-warning at -1{{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::fold_left(iter, iter, 0, std::plus());
+ // expected-warning at -1{{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::fold_left_with_iter(range, 0, std::plus());
+ // expected-warning at -1{{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::fold_left_with_iter(iter, iter, 0, std::plus());
+ // expected-warning at -1{{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/array.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/array.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..25a2f80b48f02
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/array.nodiscard.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <array> functions are marked [[nodiscard]]
+
+#include <array>
+
+void array_test() {
+ std::array<int, 1> array;
+ array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void empty_array_test() {
+ std::array<int, 0> array;
+ array.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/bit.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/bit.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..b172d515cf2fe
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/bit.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// check that <bit> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <bit>
+
+#include "test_macros.h"
+
+void func() {
+ std::bit_cast<unsigned int>(42); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::bit_ceil(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::bit_floor(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::bit_width(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 23
+ std::byteswap(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+ std::countl_zero(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::countl_one(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::countr_zero(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::countr_one(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::has_single_bit(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::popcount(0u); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/chrono.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..4e7380b863993
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/chrono.nodiscard.verify.cpp
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 format functions are marked [[nodiscard]] as a conforming extension
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+#include <chrono>
+
+#include "test_macros.h"
+
+// These types have "private" constructors.
+void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chrono::leap_second leap) {
+ std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
+ list.front(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ list.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ list.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ list.cbegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ list.cend(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ {
+ const std::chrono::tzdb& t = list.front();
+ t.locate_zone("name"); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ t.current_zone(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+ namespace crno = std::chrono;
+ crno::get_tzdb_list(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ crno::get_tzdb(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ crno::locate_zone("n"); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ crno::current_zone(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ crno::remote_version(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ {
+ std::chrono::sys_seconds s{};
+ std::chrono::local_seconds l{};
+ std::chrono::choose z = std::chrono::choose::earliest;
+ tz.name(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ tz.get_info(s); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ tz.get_info(l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ tz.to_sys(l); // not nodiscard
+ tz.to_sys(l, z); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ operator==(tz, tz); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ operator<=>(tz, tz); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+ {
+ link.name(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ link.target(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ operator==(link, link);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ operator<=>(link, link);
+ }
+
+ {
+ leap.date(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ leap.value(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+ {
+ using t = std::chrono::zoned_traits<const std::chrono::time_zone*>;
+ t::default_zone(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ t::locate_zone(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+ { // [time.clock.utc]
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::utc_clock::now();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::utc_clock::to_sys(std::chrono::utc_seconds{});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::utc_clock::from_sys(std::chrono::sys_seconds{});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::get_leap_second_info(std::chrono::utc_seconds{});
+ }
+
+ {
+ std::chrono::zoned_time<std::chrono::seconds> zt;
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ static_cast<std::chrono::sys_seconds>(zt);
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ static_cast<std::chrono::local_seconds>(zt);
+
+ zt.get_time_zone(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ zt.get_local_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ zt.get_sys_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ zt.get_info(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ }
+
+ { // [time.clock.tai]
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::tai_clock::now();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::tai_clock::to_utc(std::chrono::tai_seconds{});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::tai_clock::from_utc(std::chrono::utc_seconds{});
+ }
+
+ { // [time.clock.gps]
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::gps_clock::now();
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::gps_clock::to_utc(std::chrono::gps_seconds{});
+
+ // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::gps_clock::from_utc(std::chrono::utc_seconds{});
+ }
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/cmath.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/cmath.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..14d1935bd5030
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/cmath.nodiscard.verify.cpp
@@ -0,0 +1,167 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// We don't control the implementation of the math.h functions on windows
+// UNSUPPORTED: windows
+
+// Check that functions from `<cmath>` that Clang marks with the `[[gnu::const]]` attribute are declared
+// `[[nodiscard]]`.
+
+// clang-format off
+
+#include <cmath>
+#include "test_macros.h"
+
+void test() {
+ // These tests rely on Clang's behaviour of adding `[[gnu::const]]` to the double overload of most of the functions
+ // below.
+ // Without that attribute being added implicitly, this test can't be checked consistently because its result depends
+ // on whether we're getting libc++'s own `std::foo(double)` or the underlying C library's `foo(double)`.
+#ifdef TEST_COMPILER_CLANG
+ std::ceil(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fabs(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::floor(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::cbrt(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::copysign(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fmax(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::fmin(0., 0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::nearbyint(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::rint(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::round(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+ std::trunc(0.); // expected-warning-re {{ignoring return value of function declared with {{.*}} attribute}}
+#endif
+
+ std::signbit(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::signbit(0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::signbit(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::signbit(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::signbit(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::fpclassify(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fpclassify(0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fpclassify(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fpclassify(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fpclassify(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isfinite(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isfinite(0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isfinite(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isfinite(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isfinite(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isinf(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isinf(0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isinf(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isinf(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isinf(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isnan(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnan(0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnan(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnan(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnan(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isnormal(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnormal(0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnormal(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnormal(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isnormal(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isgreater(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreater(0., 0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreater(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreater(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreater(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isgreaterequal(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreaterequal(0., 0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreaterequal(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreaterequal(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isgreaterequal(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isless(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isless(0., 0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isless(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isless(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isless(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::islessequal(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessequal(0., 0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessequal(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessequal(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessequal(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::islessgreater(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessgreater(0., 0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessgreater(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessgreater(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::islessgreater(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::isunordered(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isunordered(0., 0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isunordered(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isunordered(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::isunordered(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::ceil(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ceil(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ceil(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ceil(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::fabs(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fabs(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fabs(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fabs(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::floor(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::floor(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::floor(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::floor(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::cbrt(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cbrt(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cbrt(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::cbrt(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::copysign(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::copysign(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::copysign(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::copysign(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::fmax(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmax(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmax(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmax(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::fmin(0.f, 0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmin(0.l, 0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmin(0, 0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::fmin(0U, 0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::nearbyint(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::nearbyint(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::nearbyint(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::nearbyint(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::rint(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::rint(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::rint(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::rint(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::round(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::round(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::round(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::round(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::trunc(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::trunc(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::trunc(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::trunc(0U); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/cstddef.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/cstddef.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..a588ffab47bca
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/cstddef.nodiscard.verify.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
+
+// check that <cstddef> functions are marked [[nodiscard]]
+
+#include <cstddef>
+
+#include "test_macros.h"
+
+void test() {
+ std::byte b{42};
+ std::to_integer<int>(b); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/cstdlib.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/cstdlib.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..d3c809f22816b
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/cstdlib.nodiscard.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// We don't control the implementation of the stdlib.h functions on windows
+// UNSUPPORTED: windows
+
+// check that <cstdlib> functions are marked [[nodiscard]]
+
+#include <cmath>
+#include "test_macros.h"
+
+void test() {
+ std::abs(0l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::abs(0ll); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::abs(0.f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::abs(0.); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::abs(0.l); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/deque.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/deque.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..e8dda09567613
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/deque.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <deque> functions are marked [[nodiscard]]
+
+#include <deque>
+
+void test() {
+ std::deque<int> deque;
+ deque.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/filesystem.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/filesystem.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..830d8e394dd7f
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/filesystem.nodiscard.verify.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, c++11, c++14
+// UNSUPPORTED: availability-filesystem-missing
+
+// check that <filesystem> functions are marked [[nodiscard]]
+
+#include <filesystem>
+
+void test() {
+ std::filesystem::path path;
+ path.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/flat_map.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/flat_map.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..79b943b790d04
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/flat_map.nodiscard.verify.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, c++20
+
+// <flat_map>
+
+// [[nodiscard]] bool empty() const noexcept;
+
+#include <flat_map>
+
+void f() {
+ std::flat_map<int, int> c;
+ c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/flat_multimap.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/flat_multimap.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..9b7b827c9bec8
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/flat_multimap.nodiscard.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <flat_map>
+
+// class flat_multimap
+
+// [[nodiscard]] bool empty() const noexcept;
+
+#include <flat_map>
+
+void f() {
+ std::flat_multimap<int, int> c;
+ c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/flat_multiset.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/flat_multiset.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..a271a293e94e7
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/flat_multiset.nodiscard.verify.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, c++20
+
+// <flat_set>
+
+// [[nodiscard]] bool empty() const noexcept;
+
+#include <flat_set>
+
+void f() {
+ std::flat_multiset<int> c;
+ c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/flat_set.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/flat_set.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..161fe533eabac
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/flat_set.nodiscard.verify.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, c++20
+
+// <flat_set>
+
+// [[nodiscard]] bool empty() const noexcept;
+
+#include <flat_set>
+
+void f() {
+ std::flat_set<int> c;
+ c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/format.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/format.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..ede6988f8bb4e
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/format.nodiscard.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that format functions are marked [[nodiscard]] as a conforming extension
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <format>
+
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+# include <locale>
+#endif
+
+void test() {
+ // clang-format off
+ std::format(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::vformat("", std::make_format_args()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::formatted_size(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_format_args(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ std::format(L""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::vformat(L"", std::make_wformat_args()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::formatted_size(L""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::make_wformat_args(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif // TEST_HAS_NO_WIDE_CHARACTERS
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+ std::format(std::locale::classic(), ""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::vformat(std::locale::classic(), "", std::make_format_args()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::formatted_size(std::locale::classic(), ""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ std::format(std::locale::classic(), L""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::vformat(std::locale::classic(), L"", std::make_wformat_args()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::formatted_size(std::locale::classic(), L""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+# endif // TEST_HAS_NO_WIDE_CHARACTERS
+#endif // TEST_HAS_NO_LOCALIZATION
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/forward_list.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/forward_list.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..7594a1d299a50
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/forward_list.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <forward_list> functions are marked [[nodiscard]]
+
+#include <forward_list>
+
+void test() {
+ std::forward_list<int> forward_list;
+ forward_list.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/functional.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/functional.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..4307976e9e442
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/functional.nodiscard.verify.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
+
+// check that <functional> functions are marked [[nodiscard]]
+
+#include <functional>
+
+#include "test_macros.h"
+
+void test() {
+ int i = 0;
+ std::identity()(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/future.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/future.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..cc5c6135d109b
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/future.nodiscard.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// UNSUPPORTED: no-threads
+
+// check that <future> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <future>
+
+void test() {
+ std::async([]() {}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::async(std::launch::any, []() {}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/iterator.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/iterator.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..c7cd2f5ce5767
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/iterator.nodiscard.verify.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <iterator> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <iterator>
+#include <vector>
+
+#include "test_macros.h"
+
+void test() {
+ std::vector<int> container;
+ int c_array[] = {1, 2, 3};
+ std::initializer_list<int> initializer_list;
+
+ std::empty(container); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::empty(c_array); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::empty(initializer_list); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::prev(c_array); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::next(c_array); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER >= 20
+ std::ranges::prev(c_array); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::prev(container.end(), 2); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::next(container.end(), 2, container.begin()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::next(c_array); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::next(container.begin(), 2); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::next(container.end(), 1, container.end()); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/limits.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/limits.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..7a81b84378c52
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/limits.nodiscard.verify.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
+
+// check that <limits> functions are marked [[nodiscard]]
+
+#include <limits>
+
+#include "test_macros.h"
+
+void func() {
+ // clang-format off
+ // arithmetic
+ std::numeric_limits<int>::min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::lowest(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::epsilon(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::round_error(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::infinity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::quiet_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::signaling_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<int>::denorm_min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // bool
+ std::numeric_limits<bool>::min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::lowest(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::epsilon(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::round_error(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::infinity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::quiet_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::signaling_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<bool>::denorm_min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // float
+ std::numeric_limits<float>::min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::lowest(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::epsilon(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::round_error(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::infinity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::quiet_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::signaling_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<float>::denorm_min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // double
+ std::numeric_limits<double>::min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::lowest(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::epsilon(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::round_error(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::infinity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::quiet_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::signaling_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<double>::denorm_min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // long double
+ std::numeric_limits<long double>::min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::max(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::lowest(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::epsilon(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::round_error(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::infinity(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::quiet_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::signaling_NaN(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::numeric_limits<long double>::denorm_min(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ // clang-format on
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/list.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/list.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..f19224a71f5cc
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/list.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <list> functions are marked [[nodiscard]]
+
+#include <list>
+
+void test() {
+ std::list<int> list;
+ list.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/map.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/map.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..78a8dd78f98a7
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/map.nodiscard.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <map> functions are marked [[nodiscard]]
+
+#include <map>
+
+void map_test() {
+ std::map<int, int> map;
+ map.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void multimap_test() {
+ std::multimap<int, int> multimap;
+ multimap.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/memory.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/memory.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..6410c84e926aa
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/memory.nodiscard.verify.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <memory> functions are marked [[nodiscard]]
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+// clang-format off
+
+#include <memory>
+
+#include "test_macros.h"
+
+void test() {
+ std::get_temporary_buffer<int>(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void test_allocator_traits() {
+ std::allocator<int> allocator;
+ std::allocator_traits<std::allocator<int>> allocator_traits;
+ allocator_traits.allocate(allocator, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ allocator_traits.allocate(allocator, 1, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void test_allocator() {
+ std::allocator<int> allocator;
+ allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if TEST_STD_VER <= 17
+ allocator.allocate(1, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+#if TEST_STD_VER >= 23
+ allocator.allocate_at_least(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/memory_resource.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/memory_resource.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..57c3823ba3fdc
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/memory_resource.nodiscard.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <memory_resource> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <memory_resource>
+
+#include "test_macros.h"
+
+void test() {
+ std::pmr::memory_resource* resource = std::pmr::null_memory_resource();
+ resource->allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::pmr::polymorphic_allocator<int> polymorphic_allocator;
+ polymorphic_allocator.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/mutex.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/mutex.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..b9890ced55bb1
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/mutex.nodiscard.verify.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
+
+// UNSUPPORTED: no-threads
+
+// check that <mutex> functions are marked [[nodiscard]]
+
+#include <mutex>
+#include <chrono>
+#include <utility>
+
+#include "test_macros.h"
+
+void test() {
+ // std::scoped_lock
+ {
+#if TEST_STD_VER >= 17
+ using M = std::mutex;
+ M m0, m1, m2;
+ // clang-format off
+ std::scoped_lock<>{}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::scoped_lock<M>{m0}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::scoped_lock<M, M>{m0, m1}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::scoped_lock<M, M, M>{m0, m1, m2}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+
+ std::scoped_lock<>{std::adopt_lock}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::scoped_lock<M>{std::adopt_lock, m0}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::scoped_lock<M, M>{std::adopt_lock, m0, m1}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::scoped_lock<M, M, M>{std::adopt_lock, m0, m1, m2}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ // clang-format on
+#endif
+ }
+
+ // std::unique_lock
+ {
+ using M = std::timed_mutex; // necessary for the time_point and duration constructors
+ M m;
+ std::chrono::time_point<std::chrono::steady_clock> time_point;
+ std::chrono::milliseconds duration;
+ std::unique_lock<M> other;
+
+ // clang-format off
+ std::unique_lock<M>{}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::unique_lock<M>{m}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::unique_lock<M>{m, std::defer_lock}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::unique_lock<M>{m, std::try_to_lock}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::unique_lock<M>{m, std::adopt_lock}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::unique_lock<M>{m, time_point}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::unique_lock<M>{m, duration}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::unique_lock<M>(std::move(other)); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ // clang-format on
+ }
+
+ // std::lock_guard
+ {
+ std::mutex m;
+ // clang-format off
+ std::lock_guard<std::mutex>{m}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ std::lock_guard<std::mutex>{m, std::adopt_lock}; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
+ // clang-format on
+ }
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/new.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/new.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..505618c0b88d7
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/new.nodiscard.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <array> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <new>
+
+#include "test_macros.h"
+
+void test() {
+ ::operator new(0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(0, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#if _LIBCPP_HAS_ALIGNED_ALLOCATION
+ ::operator new(0, std::align_val_t{1}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new(0, std::align_val_t{1}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0, std::align_val_t{1}); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ ::operator new[](0, std::align_val_t{1}, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif // _LIBCPP_HAS_ALIGNED_ALLOCATION
+
+#if TEST_STD_VER >= 17
+ int* ptr = nullptr;
+ std::launder(ptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/node_handle.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/node_handle.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..84aeafeaa279e
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/node_handle.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// check that <__node_handle> functions are marked [[nodiscard]]
+
+#include <set>
+
+void func() {
+ std::set<int> set;
+ set.extract(0).empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/pstl.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/pstl.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..a16e07168f700
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/pstl.nodiscard.verify.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 PSTL algorithms are marked [[nodiscard]] as a conforming extension
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// clang-format off
+
+#include <algorithm>
+#include <execution>
+#include <iterator>
+
+void test() {
+ int a[] = {1};
+ auto pred = [](auto) { return false; };
+ std::all_of(std::execution::par, std::begin(a), std::end(a), pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::any_of(std::execution::par, std::begin(a), std::end(a), pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::none_of(std::execution::par, std::begin(a), std::end(a), pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::is_partitioned(std::execution::par, std::begin(a), std::end(a), pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/queue.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/queue.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..77d3367cc2f4a
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/queue.nodiscard.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <queue> functions are marked [[nodiscard]]
+
+#include <queue>
+
+void test_queue() {
+ std::queue<int> queue;
+ queue.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void test_priority_queue() {
+ std::priority_queue<int> priority_queue;
+ priority_queue.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/ranges.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/ranges.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..03b4df735edb5
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/ranges.nodiscard.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that ranges are marked [[nodiscard]] as a conforming extension
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// clang-format off
+
+#include <ranges>
+#include <functional>
+#include <vector>
+
+#include "test_macros.h"
+
+void test() {
+ std::vector<int> range;
+ std::ranges::less_equal pred;
+
+ std::views::drop(pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::views::split(range, 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::split(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::views::take(range, 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::take(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 23
+ std::views::drop(std::views::repeat(1)); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::views::repeat(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::repeat(1, std::unreachable_sentinel); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ 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}}
+
+ std::views::chunk_by(pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::chunk_by(range, pred); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::views::take(std::views::repeat(3), 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::take(std::views::repeat(3, std::unreachable_sentinel), 3); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ std::allocator<int> alloc;
+
+ std::ranges::to<std::vector<int>>(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::to<std::vector<int>>(range, alloc); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::to<std::vector>(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::ranges::to<std::vector>(range, alloc); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::ranges::to<std::vector<int>>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::ranges::to<std::vector<int>>(alloc); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::ranges::to<std::vector>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::ranges::to<std::vector>(alloc); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif // TEST_STD_VER >= 23
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/regex.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/regex.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..0959ec5e26bd6
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/regex.nodiscard.verify.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
+
+// UNSUPPORTED: no-localization
+
+// check that <regex> functions are marked [[nodiscard]]
+
+#include <regex>
+
+void test() {
+ std::cmatch match_result;
+ match_result.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/scoped_allocator.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/scoped_allocator.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..5c5360c412089
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/scoped_allocator.nodiscard.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <scoped_allocator> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <memory>
+#include <scoped_allocator>
+
+void test() {
+ std::scoped_allocator_adaptor<std::allocator<int>> alloc;
+ alloc.allocate(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ alloc.allocate(1, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/set.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/set.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..cc6fb55854dac
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/set.nodiscard.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <set> functions are marked [[nodiscard]]
+
+#include <set>
+
+void set_test() {
+ std::set<int> set;
+ set.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void multiset_test() {
+ std::multiset<int> multiset;
+ multiset.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/stack.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/stack.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..861852ae07247
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/stack.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <stack> functions are marked [[nodiscard]]
+
+#include <stack>
+
+void test() {
+ std::stack<int> stack;
+ stack.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/string.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/string.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..746ae633fff44
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/string.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <string> functions are marked [[nodiscard]]
+
+#include <string>
+
+void test() {
+ std::string string;
+ string.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/string_view.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/string_view.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..b5548bc34fddc
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/string_view.nodiscard.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <string_view> functions are marked [[nodiscard]]
+
+#include <string_view>
+
+void test() {
+ std::string_view string_view;
+ string_view.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/system_error_win_codes.pass.cpp b/libcxx/test/libcxx-03/diagnostics/system_error_win_codes.pass.cpp
new file mode 100644
index 0000000000000..799a5b5c0b086
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/system_error_win_codes.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: windows
+
+// Validate that system_error on windows accepts Windows' System Error Codes (as
+// used by win32 APIs and reported by GetLastError), and that they are properly
+// translated to generic conditions.
+
+#include <windows.h>
+#include <system_error>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ LIBCPP_ASSERT(std::error_code(ERROR_ACCESS_DENIED, std::system_category()) == std::errc::permission_denied);
+ LIBCPP_ASSERT(std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()) == std::errc::no_such_file_or_directory);
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/unordered_map.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/unordered_map.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..a5d347e36d80f
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/unordered_map.nodiscard.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <unordered_map> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <unordered_map>
+
+void unordered_map_test() {
+ std::unordered_map<int, int> unordered_map;
+ unordered_map.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void unordered_multimap_test() {
+ std::unordered_multimap<int, int> unordered_multimap;
+ unordered_multimap.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/unordered_set.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/unordered_set.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..5d35cf00c5f5f
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/unordered_set.nodiscard.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <unordered_set> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <unordered_set>
+
+void unordered_set_test() {
+ std::unordered_set<int> unordered_set;
+ unordered_set.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void unordered_multiset_test() {
+ std::unordered_multiset<int> unordered_multiset;
+ unordered_multiset.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/utility.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/utility.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..524be96736bad
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/utility.nodiscard.verify.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <utility> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <utility>
+
+#include "test_macros.h"
+
+void test() {
+ int i = 0;
+
+ std::forward<int>(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::forward<int>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::move_if_noexcept(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 17
+ std::as_const(i); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+
+#if TEST_STD_VER >= 23
+ enum E { Apple, Orange } e = Apple;
+ std::to_underlying(e); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}
diff --git a/libcxx/test/libcxx-03/diagnostics/vector.nodiscard.verify.cpp b/libcxx/test/libcxx-03/diagnostics/vector.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..51e90af941895
--- /dev/null
+++ b/libcxx/test/libcxx-03/diagnostics/vector.nodiscard.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that <vector> functions are marked [[nodiscard]]
+
+#include <vector>
+
+void test_vector() {
+ std::vector<int> vector;
+ vector.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
+
+void test_vector_bool() {
+ std::vector<bool> vector;
+ vector.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/double_include.gen.py b/libcxx/test/libcxx-03/double_include.gen.py
new file mode 100644
index 0000000000000..f58e72f94a353
--- /dev/null
+++ b/libcxx/test/libcxx-03/double_include.gen.py
@@ -0,0 +1,42 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that we can include each header in two TU's and link them together.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+# Block Lit from interpreting a RUN/XFAIL/etc inside the generation script.
+# END.
+
+import sys
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+ lit_header_restrictions,
+ lit_header_undeprecations,
+ public_headers,
+)
+
+for header in public_headers:
+ print(
+ f"""\
+//--- {header}.sh.cpp
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+// RUN: %{{cxx}} -c %s -o %t.first.o %{{flags}} %{{compile_flags}}
+// RUN: %{{cxx}} -c %s -o %t.second.o -DWITH_MAIN %{{flags}} %{{compile_flags}}
+// RUN: %{{cxx}} -o %t.exe %t.first.o %t.second.o %{{flags}} %{{link_flags}}
+// RUN: %{{run}}
+
+#include <{header}>
+
+#if defined(WITH_MAIN)
+int main(int, char**) {{ return 0; }}
+#endif
+"""
+ )
diff --git a/libcxx/test/libcxx-03/experimental/fexperimental-library.compile.pass.cpp b/libcxx/test/libcxx-03/experimental/fexperimental-library.compile.pass.cpp
new file mode 100644
index 0000000000000..3cf497da233fb
--- /dev/null
+++ b/libcxx/test/libcxx-03/experimental/fexperimental-library.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that passing `-fexperimental-library` results in experimental
+// library features being enabled.
+
+// GCC does not support the -fexperimental-library flag
+// UNSUPPORTED: gcc
+
+// ADDITIONAL_COMPILE_FLAGS: -fexperimental-library
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <version>
+
+#if !_LIBCPP_HAS_EXPERIMENTAL_PSTL
+# error "-fexperimental-library should enable the PSTL"
+#endif
+
+#if !_LIBCPP_HAS_EXPERIMENTAL_TZDB
+# error "-fexperimental-library should enable the chrono TZDB"
+#endif
+
+#if !_LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM
+# error "-fexperimental-library should enable the syncstream header"
+#endif
diff --git a/libcxx/test/libcxx-03/extensions/hash/specializations.compile.fail.cpp b/libcxx/test/libcxx-03/extensions/hash/specializations.compile.fail.cpp
new file mode 100644
index 0000000000000..f81ec5dacb91e
--- /dev/null
+++ b/libcxx/test/libcxx-03/extensions/hash/specializations.compile.fail.cpp
@@ -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 <assert.h>
+#include <ext/hash_map>
+#include <string>
+
+int main(int, char**)
+{
+ assert(__gnu_cxx::hash<std::string>()(std::string()) == 0); // error
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/extensions/hash/specializations.pass.cpp b/libcxx/test/libcxx-03/extensions/hash/specializations.pass.cpp
new file mode 100644
index 0000000000000..345a2721dc035
--- /dev/null
+++ b/libcxx/test/libcxx-03/extensions/hash/specializations.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: clang-modules-build
+
+// Prevent <ext/hash_set> from generating deprecated warnings for this test.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
+#include <assert.h>
+#include <ext/hash_map>
+#include <string>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ char str[] = "test";
+ assert(__gnu_cxx::hash<const char *>()("test") ==
+ std::hash<std::string>()("test"));
+ assert(__gnu_cxx::hash<char *>()(str) == std::hash<std::string>()("test"));
+ assert(__gnu_cxx::hash<char>()(42) == 42);
+ assert(__gnu_cxx::hash<signed char>()(42) == 42);
+ assert(__gnu_cxx::hash<unsigned char>()(42) == 42);
+ assert(__gnu_cxx::hash<short>()(42) == 42);
+ assert(__gnu_cxx::hash<unsigned short>()(42) == 42);
+ assert(__gnu_cxx::hash<int>()(42) == 42);
+ assert(__gnu_cxx::hash<unsigned int>()(42) == 42);
+ assert(__gnu_cxx::hash<long>()(42) == 42);
+ assert(__gnu_cxx::hash<unsigned long>()(42) == 42);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/extensions/hash_map/const_iterator.compile.fail.cpp b/libcxx/test/libcxx-03/extensions/hash_map/const_iterator.compile.fail.cpp
new file mode 100644
index 0000000000000..db09e40801a1f
--- /dev/null
+++ b/libcxx/test/libcxx-03/extensions/hash_map/const_iterator.compile.fail.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
+//
+//===----------------------------------------------------------------------===//
+
+#include <ext/hash_map>
+
+int main(int, char**)
+{
+ __gnu_cxx::hash_map<int, int> m;
+ m[1] = 1;
+ const __gnu_cxx::hash_map<int, int> &cm = m;
+ cm.find(1)->second = 2; // error
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/feature_test_macro/ftm_metadata.sh.py b/libcxx/test/libcxx-03/feature_test_macro/ftm_metadata.sh.py
new file mode 100644
index 0000000000000..f727f9a2d9e0e
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/ftm_metadata.sh.py
@@ -0,0 +1,82 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros, Metadata
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementation(self):
+ expected = {
+ "__cpp_lib_any": Metadata(
+ headers=["any"],
+ available_since="c++17",
+ test_suite_guard=None,
+ libcxx_guard=None,
+ ),
+ "__cpp_lib_barrier": Metadata(
+ headers=["barrier"],
+ available_since="c++20",
+ test_suite_guard="!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)",
+ libcxx_guard="_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
+ ),
+ "__cpp_lib_clamp": Metadata(
+ headers=["algorithm"],
+ available_since="c++17",
+ test_suite_guard=None,
+ libcxx_guard=None,
+ ),
+ "__cpp_lib_format": Metadata(
+ headers=["format"],
+ available_since="c++20",
+ test_suite_guard=None,
+ libcxx_guard=None,
+ ),
+ "__cpp_lib_parallel_algorithm": Metadata(
+ headers=["algorithm", "numeric"],
+ available_since="c++17",
+ test_suite_guard=None,
+ libcxx_guard=None,
+ ),
+ "__cpp_lib_to_chars": Metadata(
+ headers=["charconv"],
+ available_since="c++17",
+ test_suite_guard=None,
+ libcxx_guard=None,
+ ),
+ "__cpp_lib_variant": Metadata(
+ headers=["variant"],
+ available_since="c++17",
+ test_suite_guard=None,
+ libcxx_guard=None,
+ ),
+ "__cpp_lib_zz_missing_FTM_in_older_standard": Metadata(
+ headers=[],
+ available_since="c++17",
+ test_suite_guard=None,
+ libcxx_guard=None,
+ ),
+ }
+ self.assertEqual(self.ftm.ftm_metadata, expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/generate_header_test.sh.py b/libcxx/test/libcxx-03/feature_test_macro/generate_header_test.sh.py
new file mode 100644
index 0000000000000..789a0bc25a87b
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/generate_header_test.sh.py
@@ -0,0 +1,637 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json %t/tests
+# END.
+
+import os
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+OUTPUT_PATH = sys.argv[3]
+del sys.argv[1:4]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ self.expected = dict(
+ {
+ "algorithm": """\
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <algorithm>
+
+// Test the feature test macros defined by <algorithm>
+
+// clang-format off
+
+#include <algorithm>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+# ifdef __cpp_lib_clamp
+# error "__cpp_lib_clamp should not be defined before c++17"
+# endif
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++17"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++17"
+# endif
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++17"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++20"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++20"
+# endif
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++20"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20"
+# endif
+
+#elif TEST_STD_VER == 23
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++23"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++23"
+# endif
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++23"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23"
+# endif
+
+#elif TEST_STD_VER > 23
+
+# ifndef __cpp_lib_clamp
+# error "__cpp_lib_clamp should be defined in c++26"
+# endif
+# if __cpp_lib_clamp != 201603L
+# error "__cpp_lib_clamp should have the value 201603L in c++26"
+# endif
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++26"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26"
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+ "any": """\
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <any>
+
+// Test the feature test macros defined by <any>
+
+// clang-format off
+
+#include <any>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+# ifdef __cpp_lib_any
+# error "__cpp_lib_any should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++17"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++17"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++20"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++20"
+# endif
+
+#elif TEST_STD_VER == 23
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++23"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++23"
+# endif
+
+#elif TEST_STD_VER > 23
+
+# ifndef __cpp_lib_any
+# error "__cpp_lib_any should be defined in c++26"
+# endif
+# if __cpp_lib_any != 201606L
+# error "__cpp_lib_any should have the value 201606L in c++26"
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+ "barrier": """\
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// UNSUPPORTED: no-threads
+
+// <barrier>
+
+// Test the feature test macros defined by <barrier>
+
+// clang-format off
+
+#include <barrier>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+# ifdef __cpp_lib_barrier
+# error "__cpp_lib_barrier should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_barrier
+# error "__cpp_lib_barrier should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)
+# ifndef __cpp_lib_barrier
+# error "__cpp_lib_barrier should be defined in c++20"
+# endif
+# if __cpp_lib_barrier != 201907L
+# error "__cpp_lib_barrier should have the value 201907L in c++20"
+# endif
+# else
+# ifdef __cpp_lib_barrier
+# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!"
+# endif
+# endif
+
+#elif TEST_STD_VER == 23
+
+# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)
+# ifndef __cpp_lib_barrier
+# error "__cpp_lib_barrier should be defined in c++23"
+# endif
+# if __cpp_lib_barrier != 201907L
+# error "__cpp_lib_barrier should have the value 201907L in c++23"
+# endif
+# else
+# ifdef __cpp_lib_barrier
+# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!"
+# endif
+# endif
+
+#elif TEST_STD_VER > 23
+
+# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)
+# ifndef __cpp_lib_barrier
+# error "__cpp_lib_barrier should be defined in c++26"
+# endif
+# if __cpp_lib_barrier != 299900L
+# error "__cpp_lib_barrier should have the value 299900L in c++26"
+# endif
+# else
+# ifdef __cpp_lib_barrier
+# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+ "charconv": """\
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <charconv>
+
+// Test the feature test macros defined by <charconv>
+
+// clang-format off
+
+#if !defined(_WIN32) && __has_include(<charconv>)
+# include <charconv>
+#endif
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++17"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++17"
+# endif
+# else
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER == 20
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++20"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++20"
+# endif
+# else
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER == 23
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++23"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++23"
+# endif
+# else
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER > 23
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should be defined in c++26"
+# endif
+# if __cpp_lib_to_chars != 201611L
+# error "__cpp_lib_to_chars should have the value 201611L in c++26"
+# endif
+# else
+# ifdef __cpp_lib_to_chars
+# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+ "format": """\
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <format>
+
+// Test the feature test macros defined by <format>
+
+// clang-format off
+
+#include <format>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+# ifdef __cpp_lib_format
+# error "__cpp_lib_format should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_format
+# error "__cpp_lib_format should not be defined before c++20"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_format
+# error "__cpp_lib_format should be defined in c++20"
+# endif
+# if __cpp_lib_format != 202110L
+# error "__cpp_lib_format should have the value 202110L in c++20"
+# endif
+# else
+# ifdef __cpp_lib_format
+# error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER == 23
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_format
+# error "__cpp_lib_format should be defined in c++23"
+# endif
+# if __cpp_lib_format != 202207L
+# error "__cpp_lib_format should have the value 202207L in c++23"
+# endif
+# else
+# ifdef __cpp_lib_format
+# error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER > 23
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_format
+# error "__cpp_lib_format should be defined in c++26"
+# endif
+# if __cpp_lib_format != 202311L
+# error "__cpp_lib_format should have the value 202311L in c++26"
+# endif
+# else
+# ifdef __cpp_lib_format
+# error "__cpp_lib_format should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+ "numeric": """\
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <numeric>
+
+// Test the feature test macros defined by <numeric>
+
+// clang-format off
+
+#include <numeric>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+# ifdef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++17"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++20"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20"
+# endif
+
+#elif TEST_STD_VER == 23
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++23"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23"
+# endif
+
+#elif TEST_STD_VER > 23
+
+# ifndef __cpp_lib_parallel_algorithm
+# error "__cpp_lib_parallel_algorithm should be defined in c++26"
+# endif
+# if __cpp_lib_parallel_algorithm != 201603L
+# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26"
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+ "variant": """\
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <variant>
+
+// Test the feature test macros defined by <variant>
+
+// clang-format off
+
+#include <variant>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 17
+
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined before c++17"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++17"
+# endif
+# if __cpp_lib_variant != 202102L
+# error "__cpp_lib_variant should have the value 202102L in c++17"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++20"
+# endif
+# if __cpp_lib_variant != 202106L
+# error "__cpp_lib_variant should have the value 202106L in c++20"
+# endif
+# else
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER == 23
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++23"
+# endif
+# if __cpp_lib_variant != 202106L
+# error "__cpp_lib_variant should have the value 202106L in c++23"
+# endif
+# else
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#elif TEST_STD_VER > 23
+
+# if !defined(_LIBCPP_VERSION)
+# ifndef __cpp_lib_variant
+# error "__cpp_lib_variant should be defined in c++26"
+# endif
+# if __cpp_lib_variant != 202306L
+# error "__cpp_lib_variant should have the value 202306L in c++26"
+# endif
+# else
+# ifdef __cpp_lib_variant
+# error "__cpp_lib_variant should not be defined because it is unimplemented in libc++!"
+# endif
+# endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
+
+""",
+ }
+ )
+
+ def test_implementation(self):
+ # Generate the output
+ self.ftm.generate_header_test_directory(OUTPUT_PATH)
+
+ for key, value in self.expected.items():
+ # Test whether the per header generate function generates the proper output.
+ self.assertEqual(self.ftm.generate_header_test_file(key), value)
+
+ # Test whether all header generate function generates the proper output.
+ with open(
+ os.path.join(OUTPUT_PATH, f"{key}.version.compile.pass.cpp"),
+ "r",
+ newline="\n",
+ ) as f:
+ self.assertEqual(f.read(), value)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/implemented_ftms.sh.py b/libcxx/test/libcxx-03/feature_test_macro/implemented_ftms.sh.py
new file mode 100644
index 0000000000000..2ca639e95e986
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/implemented_ftms.sh.py
@@ -0,0 +1,68 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementation(self):
+
+ expected = {
+ "__cpp_lib_any": {
+ "c++17": "201606L",
+ "c++20": "201606L",
+ "c++23": "201606L",
+ "c++26": "201606L",
+ },
+ "__cpp_lib_barrier": {
+ "c++20": "201907L",
+ "c++23": "201907L",
+ "c++26": "299900L",
+ },
+ "__cpp_lib_clamp": {
+ "c++17": "201603L",
+ "c++20": "201603L",
+ "c++23": "201603L",
+ "c++26": "201603L",
+ },
+ "__cpp_lib_format": {},
+ "__cpp_lib_parallel_algorithm": {
+ "c++17": "201603L",
+ "c++20": "201603L",
+ "c++23": "201603L",
+ "c++26": "201603L",
+ },
+ "__cpp_lib_to_chars": {},
+ "__cpp_lib_variant": {
+ "c++17": "202102L",
+ "c++20": "202102L",
+ "c++23": "202102L",
+ "c++26": "202102L",
+ },
+ "__cpp_lib_zz_missing_FTM_in_older_standard": {},
+ }
+
+ self.assertEqual(self.ftm.implemented_ftms, expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/invalid.sh.py b/libcxx/test/libcxx-03/feature_test_macro/invalid.sh.py
new file mode 100644
index 0000000000000..4488af3244dd9
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/invalid.sh.py
@@ -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
+#
+# ===----------------------------------------------------------------------===##
+
+# RUN: %{python} %s %{libcxx-dir}/utils %t
+
+import sys
+import json
+
+sys.path.append(sys.argv[1])
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+def test(output, expected):
+ assert output == expected, f"expected\n{expected}\n\noutput\n{output}"
+
+
+def test_error(data, type, message):
+ tmp = sys.argv[2]
+ with open(tmp, "w") as file:
+ file.write(json.dumps(data))
+ ftm = FeatureTestMacros(tmp, ["charconv"])
+ try:
+ ftm.implemented_ftms
+ except type as error:
+ test(str(error), message)
+ else:
+ assert False, "no exception was thrown"
+
+
+test_error(
+ [
+ {
+ "values": {
+ "c++17": {
+ "197001": [
+ {
+ "implemented": False,
+ },
+ ],
+ },
+ },
+ "headers": [],
+ },
+ ],
+ KeyError,
+ "'name'",
+)
+
+test_error(
+ [
+ {
+ "name": "a",
+ "headers": [],
+ },
+ ],
+ KeyError,
+ "'values'",
+)
+
+test_error(
+ [
+ {
+ "name": "a",
+ "values": {},
+ "headers": [],
+ },
+ ],
+ AssertionError,
+ "'values' is empty",
+)
+
+
+test_error(
+ [
+ {
+ "name": "a",
+ "values": {
+ "c++17": {},
+ },
+ "headers": [],
+ },
+ ],
+ AssertionError,
+ "a[c++17] has no entries",
+)
+
+test_error(
+ [
+ {
+ "name": "a",
+ "values": {
+ "c++17": {
+ "197001": [
+ {},
+ ],
+ },
+ },
+ "headers": [],
+ },
+ ],
+ KeyError,
+ "'implemented'",
+)
diff --git a/libcxx/test/libcxx-03/feature_test_macro/is_implemented.sh.py b/libcxx/test/libcxx-03/feature_test_macro/is_implemented.sh.py
new file mode 100644
index 0000000000000..1ccba5ea74ec4
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/is_implemented.sh.py
@@ -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
+#
+# ===----------------------------------------------------------------------===##
+
+# RUN: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros, Metadata
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementation(self):
+ # FTM not available in C++14.
+ self.assertEqual(self.ftm.is_implemented("__cpp_lib_any", "c++14"), False)
+ self.assertEqual(self.ftm.is_implemented("__cpp_lib_any", "c++17"), True)
+
+ self.assertEqual(self.ftm.is_implemented("__cpp_lib_format", "c++20"), False)
+
+ # FTM C++20 202106L, libc++ has 202102L
+ self.assertEqual(self.ftm.is_implemented("__cpp_lib_variant", "c++20"), False)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/standard_ftms.sh.py b/libcxx/test/libcxx-03/feature_test_macro/standard_ftms.sh.py
new file mode 100644
index 0000000000000..1a8d4437faa0a
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/standard_ftms.sh.py
@@ -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
+#
+# ===----------------------------------------------------------------------===##
+
+# RUN: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementation(self):
+ expected = {
+ "__cpp_lib_any": {
+ "c++17": "201606L",
+ "c++20": "201606L",
+ "c++23": "201606L",
+ "c++26": "201606L",
+ },
+ "__cpp_lib_barrier": {
+ "c++20": "201907L",
+ "c++23": "201907L",
+ "c++26": "299900L",
+ },
+ "__cpp_lib_clamp": {
+ "c++17": "201603L",
+ "c++20": "201603L",
+ "c++23": "201603L",
+ "c++26": "201603L",
+ },
+ "__cpp_lib_format": {
+ "c++20": "202110L",
+ "c++23": "202207L",
+ "c++26": "202311L",
+ },
+ "__cpp_lib_parallel_algorithm": {
+ "c++17": "201603L",
+ "c++20": "201603L",
+ "c++23": "201603L",
+ "c++26": "201603L",
+ },
+ "__cpp_lib_to_chars": {
+ "c++17": "201611L",
+ "c++20": "201611L",
+ "c++23": "201611L",
+ "c++26": "201611L",
+ },
+ "__cpp_lib_variant": {
+ "c++17": "202102L",
+ "c++20": "202106L",
+ "c++23": "202106L",
+ "c++26": "202306L",
+ },
+ "__cpp_lib_zz_missing_FTM_in_older_standard": {
+ "c++17": "2017L",
+ "c++20": "2020L",
+ "c++23": "2020L",
+ "c++26": "2026L",
+ },
+ }
+
+ self.assertEqual(self.ftm.standard_ftms, expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/standard_library_headers.sh.py b/libcxx/test/libcxx-03/feature_test_macro/standard_library_headers.sh.py
new file mode 100644
index 0000000000000..27a2953a2e321
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/standard_library_headers.sh.py
@@ -0,0 +1,44 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros, Metadata
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementation(self):
+ self.assertEqual(
+ sorted(self.ftm.standard_library_headers),
+ [
+ "algorithm",
+ "any",
+ "barrier",
+ "charconv",
+ "format",
+ "numeric",
+ "variant",
+ ],
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/std_dialects.sh.py b/libcxx/test/libcxx-03/feature_test_macro/std_dialects.sh.py
new file mode 100644
index 0000000000000..f01dcb2f3c45c
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/std_dialects.sh.py
@@ -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
+#
+# ===----------------------------------------------------------------------===##
+
+# RUN: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementation(self):
+ expected = [
+ "c++17",
+ "c++20",
+ "c++23",
+ "c++26",
+ ]
+
+ self.assertEqual(self.ftm.std_dialects, expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/test_data.json b/libcxx/test/libcxx-03/feature_test_macro/test_data.json
new file mode 100644
index 0000000000000..b0122163f714f
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/test_data.json
@@ -0,0 +1,213 @@
+[
+ {
+ "name": "__cpp_lib_any",
+ "values": {
+ "c++17": {
+ "201606": [
+ {
+ "implemented": true
+ }
+ ]
+ }
+ },
+ "headers": [
+ "any"
+ ]
+ },
+ {
+ "name": "__cpp_lib_barrier",
+ "values": {
+ "c++20": {
+ "201907": [
+ {
+ "implemented": true
+ }
+ ]
+ },
+ "c++26": {
+ "299900": [
+ {
+ "implemented": true
+ }
+ ]
+ }
+ },
+ "headers": [
+ "barrier"
+ ],
+ "test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)",
+ "libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC"
+ },
+ {
+ "name": "__cpp_lib_clamp",
+ "values": {
+ "c++17": {
+ "201603": [
+ {
+ "implemented": true
+ }
+ ]
+ }
+ },
+ "headers": ["algorithm"]
+ },
+ {
+ "name": "__cpp_lib_format",
+ "values": {
+ "c++20": {
+ "201907": [
+ {
+ "number": "P0645R10",
+ "title": "Text Formatting",
+ "implemented": true
+ },
+ {
+ "number": "P1361R2",
+ "title": "Integration of chrono with text formatting",
+ "implemented": false
+ }
+ ],
+ "202106": [
+ {
+ "number": "P2216R3",
+ "title": "std::format improvements",
+ "implemented": true
+ }
+ ],
+ "202110": [
+ {
+ "number": "P2372R3",
+ "title": "Fixing locale handling in chrono formatters",
+ "implemented": false
+ },
+ {
+ "number": "P2418R2",
+ "title": "FAdd support for std::generator-like types to std::format",
+ "implemented": true
+ }
+ ]
+ },
+ "c++23": {
+ "202207": [
+ {
+ "number": "P2419R2",
+ "title": "Clarify handling of encodings in localized formatting of chrono types",
+ "implemented": false
+ }
+ ]
+ },
+ "c++26": {
+ "202306": [
+ {
+ "number": "P2637R3",
+ "title": "Member Visit",
+ "implemented": true
+ }
+ ],
+ "202311": [
+ {
+ "number": "P2918R2",
+ "title": "Runtime format strings II",
+ "implemented": true
+ }
+ ]
+ }
+ },
+ "headers": [
+ "format"
+ ]
+ },
+ {
+ "name": "__cpp_lib_parallel_algorithm",
+ "values": {
+ "c++17": {
+ "201603": [
+ {
+ "implemented": true
+ }
+ ]
+ }
+ },
+ "headers": [
+ "algorithm",
+ "numeric"
+ ]
+ },
+ {
+ "name": "__cpp_lib_to_chars",
+ "values": {
+ "c++17": {
+ "201611": [
+ {
+ "implemented": false
+ }
+ ]
+ }
+ },
+ "headers": ["charconv"]
+ },
+ {
+ "name": "__cpp_lib_variant",
+ "values": {
+ "c++17": {
+ "202102": [
+ {
+ "title": "``std::visit`` for classes derived from ``std::variant``",
+ "implemented": true
+ }
+ ]
+ },
+ "c++20": {
+ "202106": [
+ {
+ "number": "",
+ "title": "Fully constexpr ``std::variant``",
+ "implemented": false
+ }
+ ]
+ },
+ "c++26": {
+ "202306": [
+ {
+ "number": "",
+ "title": "Member visit",
+ "implemented": true
+ }
+ ]
+ }
+ },
+ "headers": [
+ "variant"
+ ]
+ },
+ {
+ "name": "__cpp_lib_zz_missing_FTM_in_older_standard",
+ "values": {
+ "c++17": {
+ "2017": [
+ {
+ "title": "Some FTM missing a paper in an older Standard mode, which should result in the FTM never being defined.",
+ "implemented": false
+ }
+ ]
+ },
+ "c++20": {
+ "2020": [
+ {
+ "title": "",
+ "implemented": true
+ }
+ ]
+ },
+ "c++26": {
+ "2026": [
+ {
+ "title": "",
+ "implemented": true
+ }
+ ]
+ }
+ },
+ "headers": []
+ }
+]
diff --git a/libcxx/test/libcxx-03/feature_test_macro/version_header.sh.py b/libcxx/test/libcxx-03/feature_test_macro/version_header.sh.py
new file mode 100644
index 0000000000000..fa645c735f0bc
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/version_header.sh.py
@@ -0,0 +1,84 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementeation(self):
+ expected = """// -*- 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_VERSIONH
+#define _LIBCPP_VERSIONH
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+# define __cpp_lib_any 201606L
+# define __cpp_lib_clamp 201603L
+# define __cpp_lib_parallel_algorithm 201603L
+// define __cpp_lib_to_chars 201611L
+# define __cpp_lib_variant 202102L
+// define __cpp_lib_zz_missing_FTM_in_older_standard 2017L
+#endif // _LIBCPP_STD_VER >= 17
+
+#if _LIBCPP_STD_VER >= 20
+# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC
+# define __cpp_lib_barrier 201907L
+# endif
+// define __cpp_lib_format 202110L
+// define __cpp_lib_variant 202106L
+// define __cpp_lib_zz_missing_FTM_in_older_standard 2020L
+#endif // _LIBCPP_STD_VER >= 20
+
+#if _LIBCPP_STD_VER >= 23
+// define __cpp_lib_format 202207L
+#endif // _LIBCPP_STD_VER >= 23
+
+#if _LIBCPP_STD_VER >= 26
+# if _LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC
+# undef __cpp_lib_barrier
+# define __cpp_lib_barrier 299900L
+# endif
+// define __cpp_lib_format 202311L
+// define __cpp_lib_variant 202306L
+// define __cpp_lib_zz_missing_FTM_in_older_standard 2026L
+#endif // _LIBCPP_STD_VER >= 26
+
+#endif // _LIBCPP_VERSIONH
+"""
+ self.assertEqual(self.ftm.version_header, expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/feature_test_macro/version_header_implementation.sh.py b/libcxx/test/libcxx-03/feature_test_macro/version_header_implementation.sh.py
new file mode 100644
index 0000000000000..6118a65b78357
--- /dev/null
+++ b/libcxx/test/libcxx-03/feature_test_macro/version_header_implementation.sh.py
@@ -0,0 +1,163 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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: %{python} %s %{libcxx-dir}/utils %{libcxx-dir}/test/libcxx/feature_test_macro/test_data.json
+
+import sys
+import unittest
+
+UTILS = sys.argv[1]
+TEST_DATA = sys.argv[2]
+del sys.argv[1:3]
+
+sys.path.append(UTILS)
+from generate_feature_test_macro_components import FeatureTestMacros, VersionHeader
+
+
+class Test(unittest.TestCase):
+ def setUp(self):
+ self.ftm = FeatureTestMacros(TEST_DATA, ["charconv"])
+ self.maxDiff = None # This causes the diff to be printed when the test fails
+
+ def test_implementation(self):
+ expected = {
+ "17": [
+ {
+ "__cpp_lib_any": VersionHeader(
+ value="201606L",
+ implemented=True,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_clamp": VersionHeader(
+ value="201603L",
+ implemented=True,
+ need_undef=False,
+ condition=None,
+ )
+ },
+ {
+ "__cpp_lib_parallel_algorithm": VersionHeader(
+ value="201603L",
+ implemented=True,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_to_chars": VersionHeader(
+ value="201611L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_variant": VersionHeader(
+ value="202102L",
+ implemented=True,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_zz_missing_FTM_in_older_standard": VersionHeader(
+ value="2017L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ ],
+ "20": [
+ {
+ "__cpp_lib_barrier": VersionHeader(
+ value="201907L",
+ implemented=True,
+ need_undef=False,
+ condition="_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
+ ),
+ },
+ {
+ "__cpp_lib_format": VersionHeader(
+ value="202110L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_variant": VersionHeader(
+ value="202106L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_zz_missing_FTM_in_older_standard": VersionHeader(
+ value="2020L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ ],
+ "23": [
+ {
+ "__cpp_lib_format": VersionHeader(
+ value="202207L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ ],
+ "26": [
+ {
+ "__cpp_lib_barrier": VersionHeader(
+ value="299900L",
+ implemented=True,
+ need_undef=True,
+ condition="_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
+ ),
+ },
+ {
+ "__cpp_lib_format": VersionHeader(
+ value="202311L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_variant": VersionHeader(
+ value="202306L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ {
+ "__cpp_lib_zz_missing_FTM_in_older_standard": VersionHeader(
+ value="2026L",
+ implemented=False,
+ need_undef=False,
+ condition=None,
+ ),
+ },
+ ],
+ }
+
+ self.assertEqual(self.ftm.version_header_implementation, expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/libcxx/test/libcxx-03/fuzzing/format_no_args.pass.cpp b/libcxx/test/libcxx-03/fuzzing/format_no_args.pass.cpp
new file mode 100644
index 0000000000000..2faf27eda98c5
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/format_no_args.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-exceptions
+
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// XFAIL: availability-fp_to_chars-missing
+
+#include <cstdint>
+#include <format>
+#include <string_view>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size) {
+ try {
+ [[maybe_unused]] auto result = std::vformat(std::string_view{(const char*)(data), size}, std::make_format_args());
+ } catch (std::format_error const&) {
+ // If the fuzzing input isn't a valid thing we can format and we detect it, it's okay. We are looking for crashes.
+ return 0;
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/fuzz.h b/libcxx/test/libcxx-03/fuzzing/fuzz.h
new file mode 100644
index 0000000000000..5e70d0afdb468
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/fuzz.h
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_LIBCXX_FUZZING_FUZZ_H
+#define TEST_LIBCXX_FUZZING_FUZZ_H
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring> // std::strlen
+#include <iterator>
+#include <type_traits>
+#include <utility> // std::swap
+
+
+// This is a struct we can use to test the stable_XXX algorithms.
+// Perform the operation on the key, then check the order of the payload.
+struct ByteWithPayload {
+ std::uint8_t key;
+ std::size_t payload;
+
+ ByteWithPayload(std::uint8_t k) : key(k), payload(0) { }
+ ByteWithPayload(std::uint8_t k, std::size_t p) : key(k), payload(p) { }
+
+ friend bool operator==(ByteWithPayload const& x, ByteWithPayload const& y) {
+ return x.key == y.key && x.payload == y.payload;
+ }
+
+ friend bool operator!=(ByteWithPayload const& x, ByteWithPayload const& y) {
+ return !(x == y);
+ }
+
+ struct key_less {
+ bool operator()(ByteWithPayload const& x, ByteWithPayload const& y) const
+ { return x.key < y.key; }
+ };
+
+ struct payload_less {
+ bool operator()(ByteWithPayload const& x, ByteWithPayload const& y) const
+ { return x.payload < y.payload; }
+ };
+
+ struct total_less {
+ bool operator()(ByteWithPayload const& x, ByteWithPayload const& y) const {
+ return x.key == y.key ? x.payload < y.payload : x.key < y.key;
+ }
+ };
+
+ friend void swap(ByteWithPayload& lhs, ByteWithPayload& rhs) {
+ std::swap(lhs.key, rhs.key);
+ std::swap(lhs.payload, rhs.payload);
+ }
+};
+
+// Faster version of std::is_permutation
+//
+// Builds a set of buckets for each of the key values, and sums all the payloads.
+// Not 100% perfect, but _way_ faster.
+template <typename Iter1, typename Iter2, typename = typename std::enable_if<
+ std::is_same<typename std::iterator_traits<Iter1>::value_type, ByteWithPayload>::value &&
+ std::is_same<typename std::iterator_traits<Iter2>::value_type, ByteWithPayload>::value
+>::type>
+bool fast_is_permutation(Iter1 first1, Iter1 last1, Iter2 first2) {
+ std::size_t xBuckets[256] = {0};
+ std::size_t xPayloads[256] = {0};
+ std::size_t yBuckets[256] = {0};
+ std::size_t yPayloads[256] = {0};
+
+ for (; first1 != last1; ++first1, ++first2) {
+ xBuckets[first1->key]++;
+ xPayloads[first1->key] += first1->payload;
+
+ yBuckets[first2->key]++;
+ yPayloads[first2->key] += first2->payload;
+ }
+
+ for (std::size_t i = 0; i < 256; ++i) {
+ if (xBuckets[i] != yBuckets[i])
+ return false;
+ if (xPayloads[i] != yPayloads[i])
+ return false;
+ }
+
+ return true;
+}
+
+template <typename Iter1, typename Iter2, typename = void, typename = typename std::enable_if<
+ std::is_same<typename std::iterator_traits<Iter1>::value_type, std::uint8_t>::value &&
+ std::is_same<typename std::iterator_traits<Iter2>::value_type, std::uint8_t>::value
+>::type>
+bool fast_is_permutation(Iter1 first1, Iter1 last1, Iter2 first2) {
+ std::size_t xBuckets[256] = {0};
+ std::size_t yBuckets[256] = {0};
+
+ for (; first1 != last1; ++first1, ++first2) {
+ xBuckets[*first1]++;
+ yBuckets[*first2]++;
+ }
+
+ for (std::size_t i = 0; i < 256; ++i)
+ if (xBuckets[i] != yBuckets[i])
+ return false;
+
+ return true;
+}
+
+// When running inside OSS-Fuzz, we link against a fuzzing library that defines
+// main() and calls LLVMFuzzerTestOneInput.
+//
+// Otherwise, when e.g. running the Lit tests, we define main() to run fuzzing
+// tests on a few inputs.
+#if !defined(LIBCPP_OSS_FUZZ)
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t*, std::size_t);
+
+int main(int, char**) {
+ const char* test_cases[] = {
+ "",
+ "s",
+ "bac",
+ "bacasf",
+ "lkajseravea",
+ "adsfkajdsfjkas;lnc441324513,34535r34525234",
+ "b*c",
+ "ba?sf",
+ "lka*ea",
+ "adsf*kas;lnc441[0-9]1r34525234"
+ };
+
+ for (const char* tc : test_cases) {
+ const std::size_t size = std::strlen(tc);
+ const std::uint8_t* data = reinterpret_cast<const std::uint8_t*>(tc);
+ int result = LLVMFuzzerTestOneInput(data, size);
+ assert(result == 0);
+ }
+
+ return 0;
+}
+#endif // !LIBCPP_OSS_FUZZ
+
+#endif // TEST_LIBCXX_FUZZING_FUZZ_H
diff --git a/libcxx/test/libcxx-03/fuzzing/make_heap.pass.cpp b/libcxx/test/libcxx-03/fuzzing/make_heap.pass.cpp
new file mode 100644
index 0000000000000..ede82c288b062
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/make_heap.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ std::vector<std::uint8_t> working(data, data + size);
+ std::make_heap(working.begin(), working.end());
+
+ if (!std::is_heap(working.begin(), working.end()))
+ return 1;
+ if (!fast_is_permutation(data, data + size, working.cbegin()))
+ return 99;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/nth_element.pass.cpp b/libcxx/test/libcxx-03/fuzzing/nth_element.pass.cpp
new file mode 100644
index 0000000000000..45f4aed6fa412
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/nth_element.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+// Use the first element as a position into the data
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ if (size <= 1) return 0;
+ const std::size_t partition_point = data[0] % size;
+ std::vector<std::uint8_t> working(data + 1, data + size);
+ const auto partition_iter = working.begin() + partition_point;
+ std::nth_element(working.begin(), partition_iter, working.end());
+
+ // nth may be the end iterator, in this case nth_element has no effect.
+ if (partition_iter == working.end()) {
+ if (!std::equal(data + 1, data + size, working.begin()))
+ return 98;
+ }
+ else {
+ const std::uint8_t nth = *partition_iter;
+ if (!std::all_of(working.begin(), partition_iter, [=](std::uint8_t v) { return v <= nth; }))
+ return 1;
+ if (!std::all_of(partition_iter, working.end(), [=](std::uint8_t v) { return v >= nth; }))
+ return 2;
+ if (!fast_is_permutation(data + 1, data + size, working.cbegin()))
+ return 99;
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/partial_sort.pass.cpp b/libcxx/test/libcxx-03/fuzzing/partial_sort.pass.cpp
new file mode 100644
index 0000000000000..c179846b6ff68
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/partial_sort.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+// Use the first element as a position into the data
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ if (size <= 1)
+ return 0;
+ const std::size_t sort_point = data[0] % size;
+ std::vector<std::uint8_t> working(data + 1, data + size);
+ const auto sort_iter = working.begin() + sort_point;
+ std::partial_sort(working.begin(), sort_iter, working.end());
+
+ if (sort_iter != working.end()) {
+ const std::uint8_t nth = *std::min_element(sort_iter, working.end());
+ if (!std::all_of(working.begin(), sort_iter, [=](std::uint8_t v) { return v <= nth; }))
+ return 1;
+ if (!std::all_of(sort_iter, working.end(), [=](std::uint8_t v) { return v >= nth; }))
+ return 2;
+ }
+ if (!std::is_sorted(working.begin(), sort_iter))
+ return 3;
+ if (!fast_is_permutation(data + 1, data + size, working.cbegin()))
+ return 99;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/partial_sort_copy.pass.cpp b/libcxx/test/libcxx-03/fuzzing/partial_sort_copy.pass.cpp
new file mode 100644
index 0000000000000..530ab0d162c40
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/partial_sort_copy.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+// Use the first element as a count
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ if (size <= 1)
+ return 0;
+ const std::size_t num_results = data[0] % size;
+ std::vector<std::uint8_t> results(num_results);
+ (void)std::partial_sort_copy(data + 1, data + size, results.begin(), results.end());
+
+ // The results have to be sorted
+ if (!std::is_sorted(results.begin(), results.end()))
+ return 1;
+ // All the values in results have to be in the original data
+ for (auto v: results)
+ if (std::find(data + 1, data + size, v) == data + size)
+ return 2;
+
+ // The things in results have to be the smallest N in the original data
+ std::vector<std::uint8_t> sorted(data + 1, data + size);
+ std::sort(sorted.begin(), sorted.end());
+ if (!std::equal(results.begin(), results.end(), sorted.begin()))
+ return 3;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/partition.pass.cpp b/libcxx/test/libcxx-03/fuzzing/partition.pass.cpp
new file mode 100644
index 0000000000000..203e45bb8bdd8
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/partition.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ auto is_even = [](auto x) { return x % 2 == 0; };
+ std::vector<std::uint8_t> working(data, data + size);
+ auto iter = std::partition(working.begin(), working.end(), is_even);
+
+ if (!std::all_of(working.begin(), iter, is_even))
+ return 1;
+ if (!std::none_of(iter, working.end(), is_even))
+ return 2;
+ if (!fast_is_permutation(data, data + size, working.cbegin()))
+ return 99;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/partition_copy.pass.cpp b/libcxx/test/libcxx-03/fuzzing/partition_copy.pass.cpp
new file mode 100644
index 0000000000000..ac37c2ef24275
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/partition_copy.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ auto is_even = [](auto t) {
+ return t % 2 == 0;
+ };
+
+ std::vector<std::uint8_t> v1, v2;
+ auto iter = std::partition_copy(data, data + size,
+ std::back_inserter<std::vector<std::uint8_t>>(v1),
+ std::back_inserter<std::vector<std::uint8_t>>(v2),
+ is_even);
+ ((void)iter);
+ // The two vectors should add up to the original size
+ if (v1.size() + v2.size() != size)
+ return 1;
+
+ // All of the even values should be in the first vector, and none in the second
+ if (!std::all_of(v1.begin(), v1.end(), is_even))
+ return 2;
+ if (!std::none_of(v2.begin(), v2.end(), is_even))
+ return 3;
+
+ // Every value in both vectors has to be in the original
+
+ // Make a copy of the input, and sort it
+ std::vector<std::uint8_t> v0{data, data + size};
+ std::sort(v0.begin(), v0.end());
+
+ // Sort each vector and ensure that all of the elements appear in the original input
+ std::sort(v1.begin(), v1.end());
+ if (!std::includes(v0.begin(), v0.end(), v1.begin(), v1.end()))
+ return 4;
+
+ std::sort(v2.begin(), v2.end());
+ if (!std::includes(v0.begin(), v0.end(), v2.begin(), v2.end()))
+ return 5;
+
+ // This, while simple, is really slow - 20 seconds on a 500K element input.
+ // for (auto v: v1)
+ // if (std::find(data, data + size, v) == data + size)
+ // return 4;
+ //
+ // for (auto v: v2)
+ // if (std::find(data, data + size, v) == data + size)
+ // return 5;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/pop_heap.pass.cpp b/libcxx/test/libcxx-03/fuzzing/pop_heap.pass.cpp
new file mode 100644
index 0000000000000..e54eedec36441
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/pop_heap.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ if (size < 2)
+ return 0;
+ std::vector<std::uint8_t> working(data, data + size);
+ std::make_heap(working.begin(), working.end());
+
+ // Pop things off, one at a time
+ auto iter = --working.end();
+ while (iter != working.begin()) {
+ std::pop_heap(working.begin(), iter);
+ if (!std::is_heap(working.begin(), --iter))
+ return 2;
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/push_heap.pass.cpp b/libcxx/test/libcxx-03/fuzzing/push_heap.pass.cpp
new file mode 100644
index 0000000000000..ce67176039752
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/push_heap.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ if (size < 2)
+ return 0;
+
+ // Make a heap from the first half of the data
+ std::vector<std::uint8_t> working(data, data + size);
+ auto iter = working.begin() + (size / 2);
+ std::make_heap(working.begin(), iter);
+ if (!std::is_heap(working.begin(), iter))
+ return 1;
+
+ // Now push the rest onto the heap, one at a time
+ ++iter;
+ for (; iter != working.end(); ++iter) {
+ std::push_heap(working.begin(), iter);
+ if (!std::is_heap(working.begin(), iter))
+ return 2;
+ }
+
+ if (!fast_is_permutation(data, data + size, working.cbegin()))
+ return 99;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/random.pass.cpp b/libcxx/test/libcxx-03/fuzzing/random.pass.cpp
new file mode 100644
index 0000000000000..cb074bd60fdc8
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/random.pass.cpp
@@ -0,0 +1,198 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test fails because Clang no longer enables -fdelayed-template-parsing
+// by default on Windows with C++20 (#69431).
+// XFAIL: msvc && (clang-18 || clang-19 || clang-20 || clang-21)
+
+// UNSUPPORTED: c++03, c++11
+
+#include <cassert>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <random>
+#include <type_traits>
+#include <vector>
+
+#include "fuzz.h"
+
+template <class IntT>
+std::vector<IntT> GetValues(const std::uint8_t *data, std::size_t size) {
+ std::vector<IntT> result;
+ while (size >= sizeof(IntT)) {
+ IntT tmp;
+ std::memcpy(&tmp, data, sizeof(IntT));
+ size -= sizeof(IntT);
+ data += sizeof(IntT);
+ result.push_back(tmp);
+ }
+ return result;
+}
+
+template <class Dist>
+struct ParamTypeHelper {
+ using ParamT = typename Dist::param_type;
+ using ResultT = typename Dist::result_type;
+ static_assert(std::is_same<ResultT, typename ParamT::distribution_type::result_type>::value, "");
+
+ static ParamT Create(const std::uint8_t* data, std::size_t size, bool &OK) {
+ constexpr bool select_vector_result = std::is_constructible<ParamT, ResultT*, ResultT*, ResultT*>::value;
+ constexpr bool select_vector_double = std::is_constructible<ParamT, double*, double*>::value;
+ constexpr int selector = select_vector_result ? 0 : (select_vector_double ? 1 : 2);
+ return DispatchAndCreate(std::integral_constant<int, selector>{}, data, size, OK);
+ }
+
+ // Vector result
+ static ParamT DispatchAndCreate(std::integral_constant<int, 0>, const std::uint8_t *data, std::size_t size, bool &OK) {
+ auto Input = GetValues<ResultT>(data, size);
+ OK = false;
+ if (Input.size() < 10)
+ return ParamT{};
+ OK = true;
+ auto Beg = Input.begin();
+ auto End = Input.end();
+ auto Mid = Beg + ((End - Beg) / 2);
+
+ assert(Mid - Beg <= (End - Mid));
+ ParamT p(Beg, Mid, Mid);
+ return p;
+ }
+
+ // Vector double
+ static ParamT DispatchAndCreate(std::integral_constant<int, 1>, const std::uint8_t *data, std::size_t size, bool &OK) {
+ auto Input = GetValues<double>(data, size);
+
+ OK = true;
+ auto Beg = Input.begin();
+ auto End = Input.end();
+
+ ParamT p(Beg, End);
+ return p;
+ }
+
+ // Default
+ static ParamT DispatchAndCreate(std::integral_constant<int, 2>, const std::uint8_t *data, std::size_t size, bool &OK) {
+ OK = false;
+ if (size < sizeof(ParamT))
+ return ParamT{};
+ OK = true;
+ ParamT input;
+ std::memcpy(&input, data, sizeof(ParamT));
+ return input;
+ }
+};
+
+template <class IntT>
+struct ParamTypeHelper<std::poisson_distribution<IntT>> {
+ using Dist = std::poisson_distribution<IntT>;
+ using ParamT = typename Dist::param_type;
+ using ResultT = typename Dist::result_type;
+
+ static ParamT Create(const std::uint8_t *data, std::size_t size, bool& OK) {
+ OK = false;
+ auto vals = GetValues<double>(data, size);
+ if (vals.empty() || std::isnan(vals[0]) || std::isnan(std::abs(vals[0])) || vals[0] < 0)
+ return ParamT{};
+ OK = true;
+ return ParamT{vals[0]};
+ }
+};
+
+template <class IntT>
+struct ParamTypeHelper<std::geometric_distribution<IntT>> {
+ using Dist = std::geometric_distribution<IntT>;
+ using ParamT = typename Dist::param_type;
+ using ResultT = typename Dist::result_type;
+
+ static ParamT Create(const std::uint8_t *data, std::size_t size, bool& OK) {
+ OK = false;
+ auto vals = GetValues<double>(data, size);
+ if (vals.empty() || std::isnan(vals[0]) || vals[0] < 0 )
+ return ParamT{};
+ OK = true;
+ return ParamT{vals[0]};
+ }
+};
+
+template <class IntT>
+struct ParamTypeHelper<std::lognormal_distribution<IntT>> {
+ using Dist = std::lognormal_distribution<IntT>;
+ using ParamT = typename Dist::param_type;
+ using ResultT = typename Dist::result_type;
+
+ static ParamT Create(const std::uint8_t *data, std::size_t size, bool& OK) {
+ OK = false;
+ auto vals = GetValues<ResultT>(data, size);
+ if (vals.size() < 2 )
+ return ParamT{};
+ OK = true;
+ return ParamT{vals[0], vals[1]};
+ }
+};
+
+template <>
+struct ParamTypeHelper<std::bernoulli_distribution> {
+ using Dist = std::bernoulli_distribution;
+ using ParamT = Dist::param_type;
+ using ResultT = Dist::result_type;
+
+ static ParamT Create(const std::uint8_t *data, std::size_t size, bool& OK) {
+ OK = false;
+ auto vals = GetValues<double>(data, size);
+ if (vals.empty())
+ return ParamT{};
+ OK = true;
+ return ParamT{vals[0]};
+ }
+};
+
+template <class Distribution>
+int helper(const std::uint8_t *data, std::size_t size) {
+ std::mt19937 engine;
+ using ParamT = typename Distribution::param_type;
+ bool OK;
+ ParamT p = ParamTypeHelper<Distribution>::Create(data, size, OK);
+ if (!OK)
+ return 0;
+ Distribution d(p);
+ volatile auto res = d(engine);
+ if (std::isnan(res)) {
+ // FIXME(llvm.org/PR44289):
+ // Investigate why these distributions are returning NaN and decide
+ // if that's what we want them to be doing.
+ //
+ // Make this assert false (or return non-zero).
+ return 0;
+ }
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ return helper<std::uniform_int_distribution<std::int16_t>>(data, size) ||
+ helper<std::uniform_real_distribution<float>>(data, size) ||
+ helper<std::bernoulli_distribution>(data, size) ||
+ helper<std::poisson_distribution<std::int16_t>>(data, size) ||
+ helper<std::geometric_distribution<std::int16_t>>(data, size) ||
+ helper<std::binomial_distribution<std::int16_t>>(data, size) ||
+ helper<std::negative_binomial_distribution<std::int16_t>>(data, size) ||
+ helper<std::exponential_distribution<float>>(data, size) ||
+ helper<std::gamma_distribution<float>>(data, size) ||
+ helper<std::weibull_distribution<float>>(data, size) ||
+ helper<std::extreme_value_distribution<float>>(data, size) ||
+ helper<std::normal_distribution<float>>(data, size) ||
+ helper<std::lognormal_distribution<float>>(data, size) ||
+ helper<std::chi_squared_distribution<float>>(data, size) ||
+ helper<std::cauchy_distribution<float>>(data, size) ||
+ helper<std::fisher_f_distribution<float>>(data, size) ||
+ helper<std::student_t_distribution<float>>(data, size) ||
+ helper<std::discrete_distribution<std::int16_t>>(data, size) ||
+ helper<std::piecewise_constant_distribution<float>>(data, size) ||
+ helper<std::piecewise_linear_distribution<float>>(data, size);
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/regex.pass.cpp b/libcxx/test/libcxx-03/fuzzing/regex.pass.cpp
new file mode 100644
index 0000000000000..7e3b362fd6161
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/regex.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: no-exceptions
+// UNSUPPORTED: no-localization
+
+#include <cstddef>
+#include <cstdint>
+#include <regex>
+#include <string>
+
+#include "fuzz.h"
+
+template <std::regex_constants::syntax_option_type Syntax>
+static int regex_test(const std::uint8_t *data, std::size_t size) {
+ if (size == 0)
+ return 0;
+
+ std::string s((const char *)data, size);
+ std::regex re;
+ try {
+ re.assign(s, Syntax);
+ } catch (std::regex_error &) {
+ // the data represents an invalid regex, ignore this test case
+ return 0;
+ }
+
+ auto match = std::regex_match(s, re);
+ (void)match;
+ return 0; // always pretend we succeeded -- we're only looking for crashes
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ return regex_test<std::regex_constants::awk>(data, size) ||
+ regex_test<std::regex_constants::basic>(data, size) ||
+ regex_test<std::regex_constants::ECMAScript>(data, size) ||
+ regex_test<std::regex_constants::egrep>(data, size) ||
+ regex_test<std::regex_constants::extended>(data, size) ||
+ regex_test<std::regex_constants::grep>(data, size);
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/search.pass.cpp b/libcxx/test/libcxx-03/fuzzing/search.pass.cpp
new file mode 100644
index 0000000000000..e20fad2ea7e9b
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/search.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ if (size < 2)
+ return 0;
+
+ const std::size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
+ assert(pat_size <= size - 1);
+ const std::uint8_t *pat_begin = data + 1;
+ const std::uint8_t *pat_end = pat_begin + pat_size;
+ const std::uint8_t *data_end = data + size;
+ assert(pat_end <= data_end);
+
+ auto it = std::search(pat_end, data_end, pat_begin, pat_end);
+ if (it != data_end) // not found
+ if (!std::equal(pat_begin, pat_end, it))
+ return 1;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/sort.pass.cpp b/libcxx/test/libcxx-03/fuzzing/sort.pass.cpp
new file mode 100644
index 0000000000000..e11889713a39e
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/sort.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ std::vector<std::uint8_t> working(data, data + size);
+ std::sort(working.begin(), working.end());
+
+ if (!std::is_sorted(working.begin(), working.end()))
+ return 1;
+ if (!fast_is_permutation(data, data + size, working.cbegin()))
+ return 99;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/stable_partition.pass.cpp b/libcxx/test/libcxx-03/fuzzing/stable_partition.pass.cpp
new file mode 100644
index 0000000000000..2a1799dc3b851
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/stable_partition.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ auto is_even = [](auto b) { return b.key % 2 == 0; };
+
+ std::vector<ByteWithPayload> input;
+ for (std::size_t i = 0; i < size; ++i)
+ input.push_back(ByteWithPayload(data[i], i));
+ std::vector<ByteWithPayload> working = input;
+ auto iter = std::stable_partition(working.begin(), working.end(), is_even);
+
+ if (!std::all_of(working.begin(), iter, is_even))
+ return 1;
+ if (!std::none_of(iter, working.end(), is_even))
+ return 2;
+ if (!std::is_sorted(working.begin(), iter, ByteWithPayload::payload_less()))
+ return 3;
+ if (!std::is_sorted(iter, working.end(), ByteWithPayload::payload_less()))
+ return 4;
+ if (!fast_is_permutation(input.cbegin(), input.cend(), working.cbegin()))
+ return 99;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/stable_sort.pass.cpp b/libcxx/test/libcxx-03/fuzzing/stable_sort.pass.cpp
new file mode 100644
index 0000000000000..b493691035d78
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/stable_sort.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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ std::vector<ByteWithPayload> input;
+ for (std::size_t i = 0; i < size; ++i)
+ input.push_back(ByteWithPayload(data[i], i));
+
+ std::vector<ByteWithPayload> working = input;
+ std::stable_sort(working.begin(), working.end(), ByteWithPayload::key_less());
+
+ if (!std::is_sorted(working.begin(), working.end(), ByteWithPayload::key_less()))
+ return 1;
+
+ auto iter = working.begin();
+ while (iter != working.end()) {
+ auto range = std::equal_range(iter, working.end(), *iter, ByteWithPayload::key_less());
+ if (!std::is_sorted(range.first, range.second, ByteWithPayload::total_less()))
+ return 2;
+ iter = range.second;
+ }
+ if (!fast_is_permutation(input.cbegin(), input.cend(), working.cbegin()))
+ return 99;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/unique.pass.cpp b/libcxx/test/libcxx-03/fuzzing/unique.pass.cpp
new file mode 100644
index 0000000000000..e95c617111896
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/unique.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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ std::vector<std::uint8_t> working(data, data + size);
+ std::sort(working.begin(), working.end());
+ std::vector<std::uint8_t> results = working;
+ std::vector<std::uint8_t>::iterator new_end = std::unique(results.begin(), results.end());
+ std::vector<std::uint8_t>::iterator it; // scratch iterator
+
+ // Check the size of the unique'd sequence.
+ // it should only be zero if the input sequence was empty.
+ if (results.begin() == new_end)
+ return working.size() == 0 ? 0 : 1;
+
+ // 'results' is sorted
+ if (!std::is_sorted(results.begin(), new_end))
+ return 2;
+
+ // All the elements in 'results' must be different
+ it = results.begin();
+ std::uint8_t prev_value = *it++;
+ for (; it != new_end; ++it) {
+ if (*it == prev_value)
+ return 3;
+ prev_value = *it;
+ }
+
+ // Every element in 'results' must be in 'working'
+ for (it = results.begin(); it != new_end; ++it)
+ if (std::find(working.begin(), working.end(), *it) == working.end())
+ return 4;
+
+ // Every element in 'working' must be in 'results'
+ for (auto v : working)
+ if (std::find(results.begin(), new_end, v) == new_end)
+ return 5;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/fuzzing/unique_copy.pass.cpp b/libcxx/test/libcxx-03/fuzzing/unique_copy.pass.cpp
new file mode 100644
index 0000000000000..dfaaa19932f8c
--- /dev/null
+++ b/libcxx/test/libcxx-03/fuzzing/unique_copy.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <vector>
+
+#include "fuzz.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) {
+ std::vector<std::uint8_t> working(data, data + size);
+ std::sort(working.begin(), working.end());
+ std::vector<std::uint8_t> results;
+ (void)std::unique_copy(working.begin(), working.end(),
+ std::back_inserter<std::vector<std::uint8_t>>(results));
+ std::vector<std::uint8_t>::iterator it; // scratch iterator
+
+ // Check the size of the unique'd sequence.
+ // it should only be zero if the input sequence was empty.
+ if (results.size() == 0)
+ return working.size() == 0 ? 0 : 1;
+
+ // 'results' is sorted
+ if (!std::is_sorted(results.begin(), results.end()))
+ return 2;
+
+ // All the elements in 'results' must be different
+ it = results.begin();
+ std::uint8_t prev_value = *it++;
+ for (; it != results.end(); ++it) {
+ if (*it == prev_value)
+ return 3;
+ prev_value = *it;
+ }
+
+ // Every element in 'results' must be in 'working'
+ for (auto v : results)
+ if (std::find(working.begin(), working.end(), v) == working.end())
+ return 4;
+
+ // Every element in 'working' must be in 'results'
+ for (auto v : working)
+ if (std::find(results.begin(), results.end(), v) == results.end())
+ return 5;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.py b/libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.py
new file mode 100644
index 0000000000000..da09092b690c4
--- /dev/null
+++ b/libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.py
@@ -0,0 +1,162 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+"""Commands used to automate testing gdb pretty printers.
+
+This script is part of a larger framework to test gdb pretty printers. It
+runs the program, detects test cases, checks them, and prints results.
+
+See gdb_pretty_printer_test.sh.cpp on how to write a test case.
+
+"""
+
+from __future__ import print_function
+import json
+import re
+import gdb
+import sys
+
+test_failures = 0
+# Sometimes the inital run command can fail to trace the process.
+# (e.g. you don't have ptrace permissions)
+# In these cases gdb still sends us an exited event so we cannot
+# see what "run" printed to check for a warning message, since
+# we get taken to our exit handler before we can look.
+# Instead check that at least one test has been run by the time
+# we exit.
+has_run_tests = False
+
+has_execute_mi = getattr(gdb, "execute_mi", None) is not None
+
+
+class CheckResult(gdb.Command):
+ def __init__(self):
+ super(CheckResult, self).__init__("print_and_compare", gdb.COMMAND_DATA)
+
+ def invoke(self, arg, from_tty):
+ global has_run_tests
+
+ try:
+ has_run_tests = True
+
+ # Stack frame is:
+ # 0. StopForDebugger
+ # 1. CompareListChildrenToChars, ComparePrettyPrintToChars or ComparePrettyPrintToRegex
+ # 2. TestCase
+ compare_frame = gdb.newest_frame().older()
+ testcase_frame = compare_frame.older()
+ test_loc = testcase_frame.find_sal()
+ test_loc_str = test_loc.symtab.filename + ":" + str(test_loc.line)
+ # Use interactive commands in the correct context to get the pretty
+ # printed version
+
+ frame_name = compare_frame.name()
+ if frame_name.startswith("CompareListChildren"):
+ if has_execute_mi:
+ value = self._get_children(compare_frame)
+ else:
+ print("SKIPPED: " + test_loc_str)
+ return
+ else:
+ value = self._get_value(compare_frame, testcase_frame)
+
+ gdb.newest_frame().select()
+ expectation_val = compare_frame.read_var("expectation")
+ check_literal = expectation_val.string(encoding="utf-8")
+ if "PrettyPrintToRegex" in frame_name:
+ test_fails = not re.search(check_literal, value)
+ else:
+ test_fails = value != check_literal
+
+ if test_fails:
+ global test_failures
+ print("FAIL: " + test_loc_str)
+ print("GDB printed:")
+ print(" " + repr(value))
+ print("Value should match:")
+ print(" " + repr(check_literal))
+ test_failures += 1
+ else:
+ print("PASS: " + test_loc_str)
+
+ except RuntimeError as e:
+ # At this point, lots of different things could be wrong, so don't try to
+ # recover or figure it out. Don't exit either, because then it's
+ # impossible to debug the framework itself.
+ print("FAIL: Something is wrong in the test framework.")
+ print(str(e))
+ test_failures += 1
+
+ def _get_children(self, compare_frame):
+ compare_frame.select()
+ gdb.execute_mi("-var-create", "value", "*", "value")
+ r = gdb.execute_mi("-var-list-children", "--simple-values", "value")
+ gdb.execute_mi("-var-delete", "value")
+ children = r["children"]
+ if r["displayhint"] == "map":
+ r = [
+ {
+ "key": json.loads(children[2 * i]["value"]),
+ "value": json.loads(children[2 * i + 1]["value"]),
+ }
+ for i in range(len(children) // 2)
+ ]
+ else:
+ r = [json.loads(el["value"]) for el in children]
+ return json.dumps(r, sort_keys=True)
+
+ def _get_value(self, compare_frame, testcase_frame):
+ compare_frame.select()
+ frame_name = compare_frame.name()
+ if frame_name.startswith("ComparePrettyPrint"):
+ s = gdb.execute("p value", to_string=True)
+ else:
+ value_str = str(compare_frame.read_var("value"))
+ clean_expression_str = value_str.strip("'\"")
+ testcase_frame.select()
+ s = gdb.execute("p " + clean_expression_str, to_string=True)
+ if sys.version_info.major == 2:
+ s = s.decode("utf-8")
+
+ # Ignore the convenience variable name and newline
+ return s[s.find("= ") + 2 : -1]
+
+
+def exit_handler(event=None):
+ global test_failures
+ global has_run_tests
+
+ if not has_run_tests:
+ print("FAILED test program did not run correctly, check gdb warnings")
+ test_failures = -1
+ elif test_failures:
+ print("FAILED %d cases" % test_failures)
+ exit(test_failures)
+
+
+# Start code executed at load time
+
+# Disable terminal paging
+gdb.execute("set height 0")
+gdb.execute("set python print-stack full")
+
+if has_execute_mi:
+ gdb.execute_mi("-enable-pretty-printing")
+
+test_failures = 0
+CheckResult()
+test_bp = gdb.Breakpoint("StopForDebugger")
+test_bp.enabled = True
+test_bp.silent = True
+test_bp.commands = "print_and_compare\ncontinue"
+# "run" won't return if the program exits; ensure the script regains control.
+gdb.events.exited.connect(exit_handler)
+gdb.execute("run")
+# If the program didn't exit, something went wrong, but we don't
+# know what. Fail on exit.
+test_failures += 1
+exit_handler(None)
diff --git a/libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.sh.cpp b/libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.sh.cpp
new file mode 100644
index 0000000000000..f125cc9adc491
--- /dev/null
+++ b/libcxx/test/libcxx-03/gdb/gdb_pretty_printer_test.sh.cpp
@@ -0,0 +1,722 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: host-has-gdb-with-python
+// REQUIRES: locale.en_US.UTF-8
+// REQUIRES: optimization=none
+// UNSUPPORTED: no-localization
+// UNSUPPORTED: c++03
+
+// TODO: Investigate why this fails on the arm bots
+// UNSUPPORTED: target=arm{{.*}}
+
+// The Android libc++ tests are run on a non-Android host, connected to an
+// Android device over adb. gdb needs special support to make this work (e.g.
+// gdbclient.py, ndk-gdb.py, gdbserver), and the Android organization doesn't
+// support gdb anymore, favoring lldb instead.
+// UNSUPPORTED: android
+
+// This test doesn't work as such on Windows.
+// UNSUPPORTED: windows
+
+// RUN: %{cxx} %{flags} %s -o %t.exe %{compile_flags} -g %{link_flags}
+// Ensure locale-independence for unicode tests.
+// RUN: env LANG=en_US.UTF-8 %{gdb} -nx -batch -iex "set autoload off" -ex "source %S/../../../utils/gdb/libcxx/printers.py" -ex "python register_libcxx_printer_loader()" -ex "source %S/gdb_pretty_printer_test.py" %t.exe
+
+#include <bitset>
+#include <deque>
+#include <list>
+#include <map>
+#include <memory>
+#include <queue>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <string>
+#include <tuple>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "test_macros.h"
+
+// To write a pretty-printer test:
+//
+// 1. Declare a variable of the type you want to test
+//
+// 2. Set its value to something which will test the pretty printer in an
+// interesting way.
+//
+// 3. Call ComparePrettyPrintToChars with that variable, and a "const char*"
+// value to compare to the printer's output.
+//
+// Or
+//
+// Call ComparePrettyPrintToRegex with that variable, and a "const char*"
+// *python* regular expression to match against the printer's output.
+// The set of special characters in a Python regular expression overlaps
+// with a lot of things the pretty printers print--brackets, for
+// example--so take care to escape appropriately.
+//
+// Alternatively, construct a string that gdb can parse as an expression,
+// so that printing the value of the expression will test the pretty printer
+// in an interesting way. Then, call CompareExpressionPrettyPrintToChars or
+// CompareExpressionPrettyPrintToRegex to compare the printer's output.
+
+// Avoids setting a breakpoint in every-single instantiation of
+// ComparePrettyPrintTo*. Also, make sure neither it, nor the
+// variables we need present in the Compare functions are optimized
+// away.
+#ifdef TEST_COMPILER_GCC
+#define OPT_NONE __attribute__((noinline))
+#else
+#define OPT_NONE __attribute__((optnone))
+#endif
+void StopForDebugger(void *, void *) OPT_NONE;
+void StopForDebugger(void *, void *) {}
+
+
+// Prevents the compiler optimizing away the parameter in the caller function.
+template <typename Type>
+void MarkAsLive(Type &&) OPT_NONE;
+template <typename Type>
+void MarkAsLive(Type &&) {}
+
+// In all of the Compare(Expression)PrettyPrintTo(Regex/Chars) functions below,
+// the python script sets a breakpoint just before the call to StopForDebugger,
+// compares the result to the expectation.
+//
+// The expectation is a literal string to be matched exactly in
+// *PrettyPrintToChars functions, and is a python regular expression in
+// *PrettyPrintToRegex functions.
+//
+// In ComparePrettyPrint* functions, the value is a variable of any type. In
+// CompareExpressionPrettyPrint functions, the value is a string expression that
+// gdb will parse and print the result.
+//
+// The python script will print either "PASS", or a detailed failure explanation
+// along with the line that has invoke the function. The testing will continue
+// in either case.
+
+template <typename TypeToPrint> void ComparePrettyPrintToChars(
+ TypeToPrint value,
+ const char *expectation) {
+ MarkAsLive(value);
+ StopForDebugger(&value, &expectation);
+}
+
+template <typename TypeToPrint> void ComparePrettyPrintToRegex(
+ TypeToPrint value,
+ const char *expectation) {
+ MarkAsLive(value);
+ StopForDebugger(&value, &expectation);
+}
+
+void CompareExpressionPrettyPrintToChars(
+ std::string value,
+ const char *expectation) {
+ MarkAsLive(value);
+ StopForDebugger(&value, &expectation);
+}
+
+void CompareExpressionPrettyPrintToRegex(
+ std::string value,
+ const char *expectation) {
+ MarkAsLive(value);
+ StopForDebugger(&value, &expectation);
+}
+
+template <typename TypeToPrint>
+void CompareListChildrenToChars(TypeToPrint value, const char* expectation) {
+ MarkAsLive(value);
+ StopForDebugger(&value, &expectation);
+}
+
+namespace example {
+ struct example_struct {
+ int a = 0;
+ int arr[1000];
+ };
+}
+
+// If enabled, the self test will "fail"--because we want to be sure it properly
+// diagnoses tests that *should* fail. Evaluate the output by hand.
+void framework_self_test() {
+#ifdef FRAMEWORK_SELF_TEST
+ // Use the most simple data structure we can.
+ const char a = 'a';
+
+ // Tests that should pass
+ ComparePrettyPrintToChars(a, "97 'a'");
+ ComparePrettyPrintToRegex(a, ".*");
+
+ // Tests that should fail.
+ ComparePrettyPrintToChars(a, "b");
+ ComparePrettyPrintToRegex(a, "b");
+#endif
+}
+
+// A simple pass-through allocator to check that we handle CompressedPair
+// correctly.
+template <typename T> class UncompressibleAllocator : public std::allocator<T> {
+ public:
+ char X;
+
+ template <class U>
+ struct rebind {
+ using other = UncompressibleAllocator<U>;
+ };
+};
+
+void string_test() {
+ std::string short_string("kdjflskdjf");
+ // The display_hint "string" adds quotes the printed result.
+ ComparePrettyPrintToChars(short_string, "\"kdjflskdjf\"");
+
+ std::basic_string<char, std::char_traits<char>, UncompressibleAllocator<char>>
+ long_string("mehmet bizim dostumuz agzi kirik testimiz");
+ ComparePrettyPrintToChars(long_string,
+ "\"mehmet bizim dostumuz agzi kirik testimiz\"");
+}
+
+namespace a_namespace {
+// To test name-lookup in the presence of using inside a namespace. Inside this
+// namespace, unqualified string_view variables will appear in the debug info as
+// "a_namespace::string_view, rather than "std::string_view".
+//
+// There is nothing special here about string_view; it's just the data structure
+// where lookup with using inside a namespace wasn't always working.
+
+using string_view = std::string_view;
+
+void string_view_test() {
+ std::string_view i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "\"\"");
+
+ std::string source_string("to be or not to be");
+ std::string_view to_be(source_string);
+ ComparePrettyPrintToChars(to_be, "\"to be or not to be\"");
+
+ const char char_arr[] = "what a wonderful world";
+ std::string_view wonderful(&char_arr[7], 9);
+ ComparePrettyPrintToChars(wonderful, "\"wonderful\"");
+
+ const char char_arr1[] = "namespace_stringview";
+ string_view namespace_stringview(&char_arr1[10], 10);
+ ComparePrettyPrintToChars(namespace_stringview, "\"stringview\"");
+}
+}
+
+void u16string_test() {
+ std::u16string test0 = u"Hello World";
+ ComparePrettyPrintToChars(test0, "u\"Hello World\"");
+ std::u16string test1 = u"\U00010196\u20AC\u00A3\u0024";
+ ComparePrettyPrintToChars(test1, "u\"\U00010196\u20AC\u00A3\u0024\"");
+ std::u16string test2 = u"\u0024\u0025\u0026\u0027";
+ ComparePrettyPrintToChars(test2, "u\"\u0024\u0025\u0026\u0027\"");
+ std::u16string test3 = u"mehmet bizim dostumuz agzi kirik testimiz";
+ ComparePrettyPrintToChars(test3,
+ ("u\"mehmet bizim dostumuz agzi kirik testimiz\""));
+}
+
+void u32string_test() {
+ std::u32string test0 = U"Hello World";
+ ComparePrettyPrintToChars(test0, "U\"Hello World\"");
+ std::u32string test1 =
+ U"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557";
+ ComparePrettyPrintToChars(
+ test1,
+ ("U\"\U0001d552\U0001d553\U0001d554\U0001d555\U0001d556\U0001d557\""));
+ std::u32string test2 = U"\U00004f60\U0000597d";
+ ComparePrettyPrintToChars(test2, ("U\"\U00004f60\U0000597d\""));
+ std::u32string test3 = U"mehmet bizim dostumuz agzi kirik testimiz";
+ ComparePrettyPrintToChars(test3, ("U\"mehmet bizim dostumuz agzi kirik testimiz\""));
+}
+
+void tuple_test() {
+ std::tuple<int, int, int> test0(2, 3, 4);
+ ComparePrettyPrintToChars(test0, "std::tuple containing = {[0] = 2, [1] = 3, [2] = 4}");
+
+ std::tuple<> test1;
+ ComparePrettyPrintToChars(
+ test1,
+ "empty std::tuple");
+}
+
+void unique_ptr_test() {
+ std::unique_ptr<std::string> matilda(new std::string("Matilda"));
+ ComparePrettyPrintToRegex(
+ std::move(matilda),
+ R"(std::unique_ptr<std::string> containing = {__ptr_ = 0x[a-f0-9]+})");
+ std::unique_ptr<int> forty_two(new int(42));
+ ComparePrettyPrintToRegex(std::move(forty_two),
+ R"(std::unique_ptr<int> containing = {__ptr_ = 0x[a-f0-9]+})");
+
+ std::unique_ptr<int> this_is_null;
+ ComparePrettyPrintToChars(std::move(this_is_null),
+ R"(std::unique_ptr is nullptr)");
+}
+
+void bitset_test() {
+ std::bitset<258> i_am_empty(0);
+ ComparePrettyPrintToRegex(i_am_empty, "std::bitset<258(u|ul)?>");
+
+ std::bitset<0> very_empty;
+ ComparePrettyPrintToRegex(very_empty, "std::bitset<0(u|ul)?>");
+
+ std::bitset<15> b_000001111111100(1020);
+ ComparePrettyPrintToRegex(b_000001111111100,
+ R"(std::bitset<15(u|ul)?> = {\[2\] = 1, \[3\] = 1, \[4\] = 1, \[5\] = 1, \[6\] = 1, )"
+ R"(\[7\] = 1, \[8\] = 1, \[9\] = 1})");
+
+ std::bitset<258> b_0_129_132(0);
+ b_0_129_132[0] = true;
+ b_0_129_132[129] = true;
+ b_0_129_132[132] = true;
+ ComparePrettyPrintToRegex(b_0_129_132,
+ R"(std::bitset<258(u|ul)?> = {\[0\] = 1, \[129\] = 1, \[132\] = 1})");
+}
+
+void list_test() {
+ std::list<int> i_am_empty{};
+ ComparePrettyPrintToChars(i_am_empty, "std::list is empty");
+
+ std::list<int> one_two_three {1, 2, 3};
+ ComparePrettyPrintToChars(one_two_three,
+ "std::list with 3 elements = {1, 2, 3}");
+
+ std::list<std::string> colors {"red", "blue", "green"};
+ ComparePrettyPrintToChars(colors,
+ R"(std::list with 3 elements = {"red", "blue", "green"})");
+}
+
+void deque_test() {
+ std::deque<int> i_am_empty{};
+ ComparePrettyPrintToChars(i_am_empty, "std::deque is empty");
+
+ std::deque<int> one_two_three {1, 2, 3};
+ ComparePrettyPrintToChars(one_two_three,
+ "std::deque with 3 elements = {1, 2, 3}");
+
+ std::deque<example::example_struct> bfg;
+ for (int i = 0; i < 10; ++i) {
+ example::example_struct current;
+ current.a = i;
+ bfg.push_back(current);
+ }
+ for (int i = 0; i < 3; ++i) {
+ bfg.pop_front();
+ }
+ for (int i = 0; i < 3; ++i) {
+ bfg.pop_back();
+ }
+ ComparePrettyPrintToRegex(bfg,
+ "std::deque with 4 elements = {"
+ "{a = 3, arr = {[^}]+}}, "
+ "{a = 4, arr = {[^}]+}}, "
+ "{a = 5, arr = {[^}]+}}, "
+ "{a = 6, arr = {[^}]+}}}");
+}
+
+void map_test() {
+ std::map<int, int> i_am_empty{};
+ ComparePrettyPrintToChars(i_am_empty, "std::map is empty");
+
+ std::map<int, std::string> one_two_three;
+ one_two_three.insert({1, "one"});
+ one_two_three.insert({2, "two"});
+ one_two_three.insert({3, "three"});
+ ComparePrettyPrintToChars(one_two_three,
+ "std::map with 3 elements = "
+ R"({[1] = "one", [2] = "two", [3] = "three"})");
+
+ std::map<int, example::example_struct> bfg;
+ for (int i = 0; i < 4; ++i) {
+ example::example_struct current;
+ current.a = 17 * i;
+ bfg.insert({i, current});
+ }
+ ComparePrettyPrintToRegex(bfg,
+ R"(std::map with 4 elements = {)"
+ R"(\[0\] = {a = 0, arr = {[^}]+}}, )"
+ R"(\[1\] = {a = 17, arr = {[^}]+}}, )"
+ R"(\[2\] = {a = 34, arr = {[^}]+}}, )"
+ R"(\[3\] = {a = 51, arr = {[^}]+}}})");
+}
+
+void multimap_test() {
+ std::multimap<int, int> i_am_empty{};
+ ComparePrettyPrintToChars(i_am_empty, "std::multimap is empty");
+
+ std::multimap<int, std::string> one_two_three;
+ one_two_three.insert({1, "one"});
+ one_two_three.insert({3, "three"});
+ one_two_three.insert({1, "ein"});
+ one_two_three.insert({2, "two"});
+ one_two_three.insert({2, "zwei"});
+ one_two_three.insert({1, "bir"});
+
+ ComparePrettyPrintToChars(one_two_three,
+ "std::multimap with 6 elements = "
+ R"({[1] = "one", [1] = "ein", [1] = "bir", )"
+ R"([2] = "two", [2] = "zwei", [3] = "three"})");
+}
+
+void queue_test() {
+ std::queue<int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::queue wrapping: std::deque is empty");
+
+ std::queue<int> one_two_three(std::deque<int>{1, 2, 3});
+ ComparePrettyPrintToChars(
+ one_two_three,
+ "std::queue wrapping: "
+ "std::deque with 3 elements = {1, 2, 3}");
+}
+
+void priority_queue_test() {
+ std::priority_queue<int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::priority_queue wrapping: std::vector of length 0, capacity 0");
+
+ std::priority_queue<int> one_two_three;
+ one_two_three.push(11111);
+ one_two_three.push(22222);
+ one_two_three.push(33333);
+
+ ComparePrettyPrintToRegex(
+ one_two_three,
+ R"(std::priority_queue wrapping: )"
+ R"(std::vector of length 3, capacity 3 = {33333)");
+
+ ComparePrettyPrintToRegex(one_two_three, ".*11111.*");
+ ComparePrettyPrintToRegex(one_two_three, ".*22222.*");
+}
+
+void set_test() {
+ std::set<int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::set is empty");
+
+ std::set<int> one_two_three {3, 1, 2};
+ ComparePrettyPrintToChars(one_two_three,
+ "std::set with 3 elements = {1, 2, 3}");
+
+ std::set<std::pair<int, int>> prime_pairs {
+ std::make_pair(3, 5), std::make_pair(5, 7), std::make_pair(3, 5)};
+
+ ComparePrettyPrintToChars(prime_pairs,
+ "std::set with 2 elements = {"
+ "{first = 3, second = 5}, {first = 5, second = 7}}");
+
+ using using_set = std::set<int>;
+ using_set other{1, 2, 3};
+ ComparePrettyPrintToChars(other, "std::set with 3 elements = {1, 2, 3}");
+}
+
+void stack_test() {
+ std::stack<int> test0;
+ ComparePrettyPrintToChars(test0, "std::stack wrapping: std::deque is empty");
+ test0.push(5);
+ test0.push(6);
+ ComparePrettyPrintToChars(test0, "std::stack wrapping: std::deque with 2 elements = {5, 6}");
+ std::stack<bool> test1;
+ test1.push(true);
+ test1.push(false);
+ ComparePrettyPrintToChars(test1, "std::stack wrapping: std::deque with 2 elements = {true, false}");
+
+ std::stack<std::string> test2;
+ test2.push("Hello");
+ test2.push("World");
+ ComparePrettyPrintToChars(
+ test2,
+ "std::stack wrapping: std::deque with 2 elements "
+ "= {\"Hello\", \"World\"}");
+}
+
+void multiset_test() {
+ std::multiset<int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::multiset is empty");
+
+ std::multiset<std::string> one_two_three {"1:one", "2:two", "3:three", "1:one"};
+ ComparePrettyPrintToChars(one_two_three,
+ "std::multiset with 4 elements = {"
+ R"("1:one", "1:one", "2:two", "3:three"})");
+}
+
+void vector_test() {
+ std::vector<bool> test0 = {true, false};
+ ComparePrettyPrintToRegex(test0,
+ "std::vector<bool> of "
+ "length 2, capacity (32|64) = {1, 0}");
+ for (int i = 0; i < 31; ++i) {
+ test0.push_back(true);
+ test0.push_back(false);
+ }
+ ComparePrettyPrintToRegex(
+ test0,
+ "std::vector<bool> of length 64, "
+ "capacity 64 = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
+ "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
+ "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}");
+ test0.push_back(true);
+ ComparePrettyPrintToRegex(
+ test0,
+ "std::vector<bool> of length 65, "
+ "capacity (96|128) = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
+ "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, "
+ "0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}");
+
+ std::vector<int> test1;
+ ComparePrettyPrintToChars(test1, "std::vector of length 0, capacity 0");
+
+ std::vector<int> test2 = {5, 6, 7};
+ ComparePrettyPrintToChars(test2,
+ "std::vector of length "
+ "3, capacity 3 = {5, 6, 7}");
+
+ std::vector<int, UncompressibleAllocator<int>> test3({7, 8});
+ ComparePrettyPrintToChars(std::move(test3),
+ "std::vector of length "
+ "2, capacity 2 = {7, 8}");
+}
+
+void set_iterator_test() {
+ std::set<int> one_two_three {1111, 2222, 3333};
+ auto it = one_two_three.find(2222);
+ MarkAsLive(it);
+ CompareExpressionPrettyPrintToRegex("it",
+ R"(std::__tree_const_iterator = {\[0x[a-f0-9]+\] = 2222})");
+
+ auto not_found = one_two_three.find(1234);
+ MarkAsLive(not_found);
+ // Because the end_node is not easily detected, just be sure it doesn't crash.
+ CompareExpressionPrettyPrintToRegex("not_found",
+ R"(std::__tree_const_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
+}
+
+void map_iterator_test() {
+ std::map<int, std::string> one_two_three;
+ one_two_three.insert({1, "one"});
+ one_two_three.insert({2, "two"});
+ one_two_three.insert({3, "three"});
+ auto it = one_two_three.begin();
+ MarkAsLive(it);
+ CompareExpressionPrettyPrintToRegex("it",
+ R"(std::__map_iterator = )"
+ R"({\[0x[a-f0-9]+\] = {first = 1, second = "one"}})");
+
+ auto not_found = one_two_three.find(7);
+ MarkAsLive(not_found);
+ // Because the end_node is not easily detected, just be sure it doesn't crash.
+ CompareExpressionPrettyPrintToRegex(
+ "not_found", R"(std::__map_iterator ( = {\[0x[a-f0-9]+\] = .*}|<error reading variable:.*>))");
+}
+
+void unordered_set_test() {
+ std::unordered_set<int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::unordered_set is empty");
+
+ std::unordered_set<int> numbers {12345, 67890, 222333, 12345};
+ numbers.erase(numbers.find(222333));
+ ComparePrettyPrintToRegex(numbers, "std::unordered_set with 2 elements = ");
+ ComparePrettyPrintToRegex(numbers, ".*12345.*");
+ ComparePrettyPrintToRegex(numbers, ".*67890.*");
+
+ std::unordered_set<std::string> colors {"red", "blue", "green"};
+ ComparePrettyPrintToRegex(colors, "std::unordered_set with 3 elements = ");
+ ComparePrettyPrintToRegex(colors, R"(.*"red".*)");
+ ComparePrettyPrintToRegex(colors, R"(.*"blue".*)");
+ ComparePrettyPrintToRegex(colors, R"(.*"green".*)");
+}
+
+void unordered_multiset_test() {
+ std::unordered_multiset<int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::unordered_multiset is empty");
+
+ std::unordered_multiset<int> numbers {12345, 67890, 222333, 12345};
+ ComparePrettyPrintToRegex(numbers,
+ "std::unordered_multiset with 4 elements = ");
+ ComparePrettyPrintToRegex(numbers, ".*12345.*12345.*");
+ ComparePrettyPrintToRegex(numbers, ".*67890.*");
+ ComparePrettyPrintToRegex(numbers, ".*222333.*");
+
+ std::unordered_multiset<std::string> colors {"red", "blue", "green", "red"};
+ ComparePrettyPrintToRegex(colors,
+ "std::unordered_multiset with 4 elements = ");
+ ComparePrettyPrintToRegex(colors, R"(.*"red".*"red".*)");
+ ComparePrettyPrintToRegex(colors, R"(.*"blue".*)");
+ ComparePrettyPrintToRegex(colors, R"(.*"green".*)");
+}
+
+void unordered_map_test() {
+ std::unordered_map<int, int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::unordered_map is empty");
+
+ std::unordered_map<int, std::string> one_two_three;
+ one_two_three.insert({1, "one"});
+ one_two_three.insert({2, "two"});
+ one_two_three.insert({3, "three"});
+ ComparePrettyPrintToRegex(one_two_three,
+ "std::unordered_map with 3 elements = ");
+ ComparePrettyPrintToRegex(one_two_three, R"(.*\[1\] = "one".*)");
+ ComparePrettyPrintToRegex(one_two_three, R"(.*\[2\] = "two".*)");
+ ComparePrettyPrintToRegex(one_two_three, R"(.*\[3\] = "three".*)");
+}
+
+void unordered_multimap_test() {
+ std::unordered_multimap<int, int> i_am_empty;
+ ComparePrettyPrintToChars(i_am_empty, "std::unordered_multimap is empty");
+
+ std::unordered_multimap<int, std::string> one_two_three;
+ one_two_three.insert({1, "one"});
+ one_two_three.insert({2, "two"});
+ one_two_three.insert({3, "three"});
+ one_two_three.insert({2, "two"});
+ ComparePrettyPrintToRegex(one_two_three,
+ "std::unordered_multimap with 4 elements = ");
+ ComparePrettyPrintToRegex(one_two_three, R"(.*\[1\] = "one".*)");
+ ComparePrettyPrintToRegex(one_two_three, R"(.*\[2\] = "two".*\[2\] = "two")");
+ ComparePrettyPrintToRegex(one_two_three, R"(.*\[3\] = "three".*)");
+}
+
+void unordered_map_iterator_test() {
+ std::unordered_map<int, int> ones_to_eights;
+ ones_to_eights.insert({1, 8});
+ ones_to_eights.insert({11, 88});
+ ones_to_eights.insert({111, 888});
+
+ auto ones_to_eights_begin = ones_to_eights.begin();
+ MarkAsLive(ones_to_eights_begin);
+ CompareExpressionPrettyPrintToRegex("ones_to_eights_begin",
+ R"(std::__hash_map_iterator = {\[1+\] = 8+})");
+
+ auto not_found = ones_to_eights.find(5);
+ MarkAsLive(not_found);
+ CompareExpressionPrettyPrintToRegex("not_found",
+ R"(std::__hash_map_iterator = end\(\))");
+}
+
+void unordered_set_iterator_test() {
+ std::unordered_set<int> ones;
+ ones.insert(111);
+ ones.insert(1111);
+ ones.insert(11111);
+
+ auto ones_begin = ones.begin();
+ MarkAsLive(ones_begin);
+ CompareExpressionPrettyPrintToRegex("ones_begin",
+ R"(std::__hash_const_iterator = {1+})");
+
+ auto not_found = ones.find(5);
+ MarkAsLive(not_found);
+ CompareExpressionPrettyPrintToRegex("not_found",
+ R"(std::__hash_const_iterator = end\(\))");
+}
+
+// Check that libc++ pretty printers do not handle pointers.
+void pointer_negative_test() {
+ int abc = 123;
+ int *int_ptr = &abc;
+ // Check that the result is equivalent to "p/r int_ptr" command.
+ ComparePrettyPrintToRegex(int_ptr, R"(\(int \*\) 0x[a-f0-9]+)");
+}
+
+void shared_ptr_test() {
+ // Shared ptr tests while using test framework call another function
+ // due to which there is one more count for the pointer. Hence, all the
+ // following tests are testing with expected count plus 1.
+ std::shared_ptr<const int> test0 = std::make_shared<const int>(5);
+ // The python regular expression matcher treats newlines as significant, so
+ // these regular expressions should be on one line.
+ ComparePrettyPrintToRegex(
+ test0,
+ R"(std::shared_ptr<int> count [2\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
+
+ std::shared_ptr<const int> test1(test0);
+ ComparePrettyPrintToRegex(
+ test1,
+ R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
+
+ {
+ std::weak_ptr<const int> test2 = test1;
+ ComparePrettyPrintToRegex(
+ test0,
+ R"(std::shared_ptr<int> count [3\?], weak [1\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
+ }
+
+ ComparePrettyPrintToRegex(
+ test0,
+ R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
+
+ std::shared_ptr<const int> test3;
+ ComparePrettyPrintToChars(test3, "std::shared_ptr is nullptr");
+}
+
+void streampos_test() {
+ std::streampos test0 = 67;
+ ComparePrettyPrintToRegex(test0, "^std::fpos with stream offset:67( with state: {count:0 value:0})?$");
+ std::istringstream input("testing the input stream here");
+ std::streampos test1 = input.tellg();
+ ComparePrettyPrintToRegex(test1, "^std::fpos with stream offset:0( with state: {count:0 value:0})?$");
+ std::unique_ptr<char[]> buffer(new char[5]);
+ input.read(buffer.get(), 5);
+ test1 = input.tellg();
+ ComparePrettyPrintToRegex(test1, "^std::fpos with stream offset:5( with state: {count:0 value:0})?$");
+}
+
+void mi_mode_test() {
+ std::map<int, std::string> one_two_three_map;
+ one_two_three_map.insert({1, "one"});
+ one_two_three_map.insert({2, "two"});
+ one_two_three_map.insert({3, "three"});
+ CompareListChildrenToChars(
+ one_two_three_map, R"([{"key": 1, "value": "one"}, {"key": 2, "value": "two"}, {"key": 3, "value": "three"}])");
+
+ std::unordered_map<int, std::string> one_two_three_umap;
+ one_two_three_umap.insert({3, "three"});
+ one_two_three_umap.insert({2, "two"});
+ one_two_three_umap.insert({1, "one"});
+ CompareListChildrenToChars(
+ one_two_three_umap, R"([{"key": 3, "value": "three"}, {"key": 2, "value": "two"}, {"key": 1, "value": "one"}])");
+
+ std::deque<int> one_two_three_deque{1, 2, 3};
+ CompareListChildrenToChars(one_two_three_deque, "[1, 2, 3]");
+}
+
+int main(int, char**) {
+ framework_self_test();
+
+ string_test();
+ a_namespace::string_view_test();
+
+ //u16string_test();
+ u32string_test();
+ tuple_test();
+ unique_ptr_test();
+ shared_ptr_test();
+ bitset_test();
+ list_test();
+ deque_test();
+ map_test();
+ multimap_test();
+ queue_test();
+ priority_queue_test();
+ stack_test();
+ set_test();
+ multiset_test();
+ vector_test();
+ set_iterator_test();
+ map_iterator_test();
+ unordered_set_test();
+ unordered_multiset_test();
+ unordered_map_test();
+ unordered_multimap_test();
+ unordered_map_iterator_test();
+ unordered_set_iterator_test();
+ pointer_negative_test();
+ streampos_test();
+ mi_mode_test();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/header_inclusions.gen.py b/libcxx/test/libcxx-03/header_inclusions.gen.py
new file mode 100644
index 0000000000000..e00cf180d17ad
--- /dev/null
+++ b/libcxx/test/libcxx-03/header_inclusions.gen.py
@@ -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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that all headers include all the other headers they're supposed to, as
+# prescribed by the Standard.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+# END.
+
+import sys
+
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+ lit_header_restrictions,
+ lit_header_undeprecations,
+ public_headers,
+ mandatory_inclusions,
+)
+
+for header in public_headers:
+ header_guard = (
+ lambda h: f"_LIBCPP_{str(h).upper().replace('.', '_').replace('/', '_')}"
+ )
+
+ # <cassert> has no header guards
+ if header == "cassert":
+ checks = ""
+ else:
+ checks = f"""
+#ifndef {header_guard(header)}
+# error <{header}> was expected to define a header guard {header_guard(header)}
+#endif
+"""
+ for includee in mandatory_inclusions.get(header, []):
+ checks += f"""
+#ifndef {header_guard(includee)}
+# error <{header}> was expected to include <{includee}>
+#endif
+"""
+
+ print(
+ f"""\
+//--- {header}.compile.pass.cpp
+// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
+
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+#include <{header}>
+{checks}
+"""
+ )
diff --git a/libcxx/test/libcxx-03/headers_in_modulemap.sh.py b/libcxx/test/libcxx-03/headers_in_modulemap.sh.py
new file mode 100644
index 0000000000000..d4a18a20c8926
--- /dev/null
+++ b/libcxx/test/libcxx-03/headers_in_modulemap.sh.py
@@ -0,0 +1,20 @@
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+import sys
+sys.path.append(sys.argv[1])
+from libcxx.header_information import all_headers, libcxx_include
+
+with open(libcxx_include / "module.modulemap.in") as f:
+ modulemap = f.read()
+
+isHeaderMissing = False
+for header in all_headers:
+ if not header.is_in_modulemap():
+ continue
+
+ if not str(header) in modulemap:
+ print(f"Header {header} seems to be missing from the modulemap!")
+ isHeaderMissing = True
+
+if isHeaderMissing:
+ exit(1)
diff --git a/libcxx/test/libcxx-03/include_as_c.sh.cpp b/libcxx/test/libcxx-03/include_as_c.sh.cpp
new file mode 100644
index 0000000000000..635c7e3aa4f5f
--- /dev/null
+++ b/libcxx/test/libcxx-03/include_as_c.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// We're building as C, so this test doesn't work when building with modules.
+// UNSUPPORTED: clang-modules-build
+
+// GCC complains about unrecognized arguments because we're compiling the
+// file as C, but we're passing C++ flags on the command-line.
+// UNSUPPORTED: gcc
+
+// Test that the C wrapper headers can be included when compiling them as C.
+
+// NOTE: It's not common or recommended to have libc++ in the header search
+// path when compiling C files, but it does happen often enough.
+
+// RUN: %{cxx} -c -xc %s -fsyntax-only %{flags} %{compile_flags} -std=c99
+
+#include <__config>
+
+#include <complex.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fenv.h>
+#include <float.h>
+#include <inttypes.h>
+#include <limits.h>
+#if _LIBCPP_HAS_LOCALIZATION
+# include <locale.h>
+#endif
+#include <math.h>
+#include <setjmp.h>
+#include <stdalign.h>
+#include <stdatomic.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+// The clang-shipped tgmath.h header doesn't work with MSVC/UCRT's complex
+// headers in C mode, see PR46207.
+#ifndef _MSC_VER
+# include <tgmath.h>
+#endif
+#if _LIBCPP_HAS_WIDE_CHARACTERS
+# include <wchar.h>
+# include <wctype.h>
+#endif
+
+int main(int argc, char** argv) {
+ (void)argc;
+ (void)argv;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp
new file mode 100644
index 0000000000000..455c9979ae57d
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/filebuf/traits_mismatch.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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_filebuf;
+//
+// The char type of the stream and the char_type of the traits have to match
+
+// UNSUPPORTED: no-wide-characters
+
+#include <fstream>
+
+std::basic_filebuf<char, std::char_traits<wchar_t> > f;
+// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
+// expected-error@*:* 9 {{only virtual member functions can be marked 'override'}}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.close.pass.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.close.pass.cpp
new file mode 100644
index 0000000000000..d77d5370f2c49
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.close.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_fstream
+
+// close();
+
+// Inspired by PR#38052 - std::fstream still good after closing and updating content
+
+#include <fstream>
+#include <cassert>
+#include "test_macros.h"
+#include "platform_support.h"
+
+int main(int, char**)
+{
+ std::string temp = get_temp_file_name();
+
+ std::fstream ofs(temp, std::ios::out | std::ios::trunc);
+ ofs << "Hello, World!\n";
+ assert( ofs.good());
+ ofs.close();
+ assert( ofs.good());
+ ofs << "Hello, World!\n";
+ assert(!ofs.good());
+
+ std::remove(temp.c_str());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.cons/wchar_pointer.pass.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.cons/wchar_pointer.pass.cpp
new file mode 100644
index 0000000000000..652783fc65134
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.cons/wchar_pointer.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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_fstream
+
+// explicit basic_fstream(const wchar_t* s, ios_base::openmode mode = ios_base::in | ios_base::out);
+
+// This extension is only provided on Windows.
+// REQUIRES: windows
+// UNSUPPORTED: no-wide-characters
+
+// TODO: This should not be necessary
+// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT
+
+#include <fstream>
+#include <cassert>
+#include "test_macros.h"
+#include "wide_temp_file.h"
+
+int main(int, char**) {
+ std::wstring temp = get_wide_temp_file_name();
+ {
+ std::fstream fs(temp.c_str(), std::ios_base::in | std::ios_base::out
+ | std::ios_base::trunc);
+ double x = 0;
+ fs << 3.25;
+ fs.seekg(0);
+ fs >> x;
+ assert(x == 3.25);
+ }
+ _wremove(temp.c_str());
+ {
+ std::wfstream fs(temp.c_str(), std::ios_base::in | std::ios_base::out
+ | std::ios_base::trunc);
+ double x = 0;
+ fs << 3.25;
+ fs.seekg(0);
+ fs >> x;
+ assert(x == 3.25);
+ }
+ _wremove(temp.c_str());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.members/open_wchar_pointer.pass.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.members/open_wchar_pointer.pass.cpp
new file mode 100644
index 0000000000000..b592492f84830
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/fstream.members/open_wchar_pointer.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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_fstream
+
+// void open(const wchar_t* s, ios_base::openmode mode = ios_base::in|ios_base::out);
+
+// This extension is only provided on Windows.
+// REQUIRES: windows
+// UNSUPPORTED: no-wide-characters
+
+// TODO: This should not be necessary
+// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT
+
+#include <fstream>
+#include <cassert>
+#include "test_macros.h"
+#include "wide_temp_file.h"
+
+int main(int, char**) {
+ std::wstring temp = get_wide_temp_file_name();
+ {
+ std::fstream fs;
+ assert(!fs.is_open());
+ fs.open(temp.c_str(), std::ios_base::in | std::ios_base::out
+ | std::ios_base::trunc);
+ assert(fs.is_open());
+ double x = 0;
+ fs << 3.25;
+ fs.seekg(0);
+ fs >> x;
+ assert(x == 3.25);
+ }
+ _wremove(temp.c_str());
+ {
+ std::wfstream fs;
+ assert(!fs.is_open());
+ fs.open(temp.c_str(), std::ios_base::in | std::ios_base::out
+ | std::ios_base::trunc);
+ assert(fs.is_open());
+ double x = 0;
+ fs << 3.25;
+ fs.seekg(0);
+ fs >> x;
+ assert(x == 3.25);
+ }
+ _wremove(temp.c_str());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/test.dat b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/test.dat
new file mode 100644
index 0000000000000..64064d34a8e3e
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/test.dat
@@ -0,0 +1 @@
+3.25
\ No newline at end of file
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/wchar_pointer.pass.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/wchar_pointer.pass.cpp
new file mode 100644
index 0000000000000..18e9b2910d872
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.cons/wchar_pointer.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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_ifstream
+
+// explicit basic_ifstream(const wchar_t* s, ios_base::openmode mode = ios_base::in);
+
+// This extension is only provided on Windows.
+// REQUIRES: windows
+// UNSUPPORTED: no-wide-characters
+
+// FILE_DEPENDENCIES: test.dat
+
+#include <fstream>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ {
+ std::ifstream fs(L"test.dat");
+ double x = 0;
+ fs >> x;
+ assert(x == 3.25);
+ }
+ // std::ifstream(const wchar_t*, std::ios_base::openmode) is tested in
+ // test/libcxx/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp
+ // which creates writable files.
+ {
+ std::wifstream fs(L"test.dat");
+ double x = 0;
+ fs >> x;
+ assert(x == 3.25);
+ }
+ // std::wifstream(const wchar_t*, std::ios_base::openmode) is tested in
+ // test/libcxx/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp
+ // which creates writable files.
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/open_wchar_pointer.pass.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/open_wchar_pointer.pass.cpp
new file mode 100644
index 0000000000000..3fa8a29e2995a
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/open_wchar_pointer.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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_ifstream
+
+// void open(const wchar_t* s, ios_base::openmode mode = ios_base::in);
+
+// This extension is only provided on Windows.
+// REQUIRES: windows
+// UNSUPPORTED: no-wide-characters
+
+// FILE_DEPENDENCIES: test.dat
+
+#include <fstream>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ {
+ std::ifstream fs;
+ assert(!fs.is_open());
+ char c = 'a';
+ fs >> c;
+ assert(fs.fail());
+ assert(c == 'a');
+ fs.open(L"test.dat");
+ assert(fs.is_open());
+ fs >> c;
+ assert(c == 'r');
+ }
+ {
+ std::wifstream fs;
+ assert(!fs.is_open());
+ wchar_t c = L'a';
+ fs >> c;
+ assert(fs.fail());
+ assert(c == L'a');
+ fs.open(L"test.dat");
+ assert(fs.is_open());
+ fs >> c;
+ assert(c == L'r');
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/test.dat b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/test.dat
new file mode 100644
index 0000000000000..1d2f01491f783
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ifstream.members/test.dat
@@ -0,0 +1 @@
+r
\ No newline at end of file
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp
new file mode 100644
index 0000000000000..3730e73648d30
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.cons/wchar_pointer.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_ofstream
+
+// explicit basic_ofstream(const wchar_t* s, ios_base::openmode mode = ios_base::out);
+
+// This extension is only provided on Windows.
+// REQUIRES: windows
+// UNSUPPORTED: no-wide-characters
+
+// TODO: This should not be necessary
+// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT
+
+#include <fstream>
+#include <cassert>
+#include "test_macros.h"
+#include "wide_temp_file.h"
+
+int main(int, char**) {
+ std::wstring temp = get_wide_temp_file_name();
+ {
+ std::ofstream fs(temp.c_str());
+ fs << 3.25;
+ }
+ {
+ std::ifstream fs(temp.c_str());
+ double x = 0;
+ fs >> x;
+ assert(x == 3.25);
+ }
+ {
+ std::ifstream fs(temp.c_str(), std::ios_base::out);
+ double x = 0;
+ fs >> x;
+ assert(x == 3.25);
+ }
+ _wremove(temp.c_str());
+ {
+ std::wofstream fs(temp.c_str());
+ fs << 3.25;
+ }
+ {
+ std::wifstream fs(temp.c_str());
+ double x = 0;
+ fs >> x;
+ assert(x == 3.25);
+ }
+ {
+ std::wifstream fs(temp.c_str(), std::ios_base::out);
+ double x = 0;
+ fs >> x;
+ assert(x == 3.25);
+ }
+ _wremove(temp.c_str());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.members/open_wchar_pointer.pass.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.members/open_wchar_pointer.pass.cpp
new file mode 100644
index 0000000000000..bfbbd5322161f
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/ofstream.members/open_wchar_pointer.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_ofstream
+
+// void open(const wchar_t* s, ios_base::openmode mode = ios_base::out);
+
+// This extension is only provided on Windows.
+// REQUIRES: windows
+// UNSUPPORTED: no-wide-characters
+
+// TODO: This should not be necessary
+// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT
+
+#include <fstream>
+#include <cassert>
+#include "test_macros.h"
+#include "wide_temp_file.h"
+
+int main(int, char**) {
+ std::wstring temp = get_wide_temp_file_name();
+ {
+ std::ofstream fs;
+ assert(!fs.is_open());
+ char c = 'a';
+ fs << c;
+ assert(fs.fail());
+ fs.open(temp.c_str());
+ assert(fs.is_open());
+ fs << c;
+ }
+ {
+ std::ifstream fs(temp.c_str());
+ char c = 0;
+ fs >> c;
+ assert(c == 'a');
+ }
+ _wremove(temp.c_str());
+ {
+ std::wofstream fs;
+ assert(!fs.is_open());
+ wchar_t c = L'a';
+ fs << c;
+ assert(fs.fail());
+ fs.open(temp.c_str());
+ assert(fs.is_open());
+ fs << c;
+ }
+ {
+ std::wifstream fs(temp.c_str());
+ wchar_t c = 0;
+ fs >> c;
+ assert(c == L'a');
+ }
+ _wremove(temp.c_str());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/fstreams/traits_mismatch.verify.cpp b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/traits_mismatch.verify.cpp
new file mode 100644
index 0000000000000..cc52cc119d50e
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/fstreams/traits_mismatch.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_fstream
+
+// The char type of the stream and the char_type of the traits have to match
+
+// UNSUPPORTED: no-wide-characters
+
+#include <fstream>
+
+std::basic_fstream<char, std::char_traits<wchar_t> > f;
+// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
+// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
+
+// expected-error@*:* 11 {{only virtual member functions can be marked 'override'}}
+
+// FIXME: As of commit r324062 Clang incorrectly generates a diagnostic about mismatching
+// exception specifications for types which are already invalid for one reason or another.
+// For now we tolerate this diagnostic.
+// expected-error@*:* 0-1 {{exception specification of overriding function is more lax than base version}}
diff --git a/libcxx/test/libcxx-03/input.output/file.streams/lit.local.cfg b/libcxx/test/libcxx-03/input.output/file.streams/lit.local.cfg
new file mode 100644
index 0000000000000..ac628161afe73
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/file.streams/lit.local.cfg
@@ -0,0 +1,7 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+
+inLibcxx = os.path.join("libcxx", "test", "libcxx-03")
+inStd = os.path.join("libcxx", "test", "std")
+localConfig = os.path.normpath(os.path.realpath(__file__)).replace(inLibcxx, inStd)
+config.load_from_path(localConfig, lit_config)
diff --git a/libcxx/test/libcxx-03/input.output/filesystems/class.directory_entry/directory_entry.mods/last_write_time.pass.cpp b/libcxx/test/libcxx-03/input.output/filesystems/class.directory_entry/directory_entry.mods/last_write_time.pass.cpp
new file mode 100644
index 0000000000000..1acbed55d2b51
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/filesystems/class.directory_entry/directory_entry.mods/last_write_time.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: availability-filesystem-missing
+// UNSUPPORTED: no-filesystem
+// ADDITIONAL_COMPILE_FLAGS: -I %{libcxx-dir}/src
+
+// This test relies on calling functions from the libcxx internal headers
+// of <filesystem>; the Windows implementation uses different
+// internals and doesn't provide the same set_file_times function as for
+// other platforms.
+// UNSUPPORTED: windows
+
+// This test assumes that time is stored as a 64 bit value when on MVS it is stored as 32 bit
+// XFAIL: target={{.+}}-zos{{.*}}
+
+// <filesystem>
+
+// class directory_entry
+
+#include <filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "assert_macros.h"
+#include "test_macros.h"
+#include "filesystem_test_helper.h"
+
+#include "filesystem/time_utils.h"
+
+namespace fs = std::filesystem;
+using namespace fs::detail;
+
+static void last_write_time_not_representable_error() {
+ using namespace fs;
+ using namespace std::chrono;
+ scoped_test_env env;
+ const path dir = env.create_dir("dir");
+ const path file = env.create_file("dir/file", 42);
+
+ TimeSpec ToTime;
+ ToTime.tv_sec = std::numeric_limits<decltype(ToTime.tv_sec)>::max();
+ ToTime.tv_nsec = duration_cast<nanoseconds>(seconds(1)).count() - 1;
+
+ std::array<TimeSpec, 2> TS = {ToTime, ToTime};
+
+ file_time_type old_time = last_write_time(file);
+ directory_entry ent(file);
+
+ file_time_type start_time = file_time_type::clock::now() - hours(1);
+ last_write_time(file, start_time);
+
+ assert(ent.last_write_time() == old_time);
+
+ bool IsRepresentable = true;
+ file_time_type rep_value;
+ {
+ std::error_code ec;
+ assert(!set_file_times(file, TS, ec));
+ ec.clear();
+ rep_value = last_write_time(file, ec);
+ IsRepresentable = !bool(ec);
+ }
+
+ if (!IsRepresentable) {
+ std::error_code rec = GetTestEC();
+ ent.refresh(rec);
+ assert(!rec);
+
+ const std::errc expected_err = std::errc::value_too_large;
+
+ std::error_code ec = GetTestEC();
+ assert(ent.last_write_time(ec) == file_time_type::min());
+ assert(ErrorIs(ec, expected_err));
+
+ ec = GetTestEC();
+ assert(last_write_time(file, ec) == file_time_type::min());
+ assert(ErrorIs(ec, expected_err));
+
+ ExceptionChecker CheckExcept(file, expected_err,
+ "directory_entry::last_write_time");
+ TEST_VALIDATE_EXCEPTION(filesystem_error, CheckExcept,
+ ent.last_write_time());
+
+ } else {
+ ent.refresh();
+
+ std::error_code ec = GetTestEC();
+ assert(ent.last_write_time(ec) == rep_value);
+ assert(!ec);
+ }
+}
+
+int main(int, char**) {
+ last_write_time_not_representable_error();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.itr/assert.iterator.pass.cpp b/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.itr/assert.iterator.pass.cpp
new file mode 100644
index 0000000000000..38047957de8e5
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.itr/assert.iterator.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <filesystem>
+
+// class path
+
+#include <filesystem>
+#include <iterator>
+#include <type_traits>
+#include <cassert>
+
+#include "check_assertion.h"
+namespace fs = std::filesystem;
+
+int main(int, char**) {
+ // Test incrementing/decrementing a singular iterator
+ {
+ fs::path::iterator singular;
+ TEST_LIBCPP_ASSERT_FAILURE(++singular, "attempting to increment a singular iterator");
+ TEST_LIBCPP_ASSERT_FAILURE(--singular, "attempting to decrement a singular iterator");
+ }
+
+ // Test incrementing the end iterator
+ {
+ fs::path p("foo/bar");
+ auto it = p.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(--it, "attempting to decrement the begin iterator");
+ }
+
+ // Test incrementing the end iterator
+ {
+ fs::path p("foo/bar");
+ auto it = p.end();
+ TEST_LIBCPP_ASSERT_FAILURE(++it, "attempting to increment the end iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp b/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.pass.cpp
new file mode 100644
index 0000000000000..8a443b955d129
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.member/path.native.obs/string_alloc.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
+// UNSUPPORTED: availability-filesystem-missing
+
+// These tests require locale for non-char paths
+// UNSUPPORTED: no-localization
+
+// <filesystem>
+
+// class path
+
+// template <class ECharT, class Traits = char_traits<ECharT>,
+// class Allocator = allocator<ECharT>>
+// basic_string<ECharT, Traits, Allocator>
+// string(const Allocator& a = Allocator()) const;
+
+#include <filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "count_new.h"
+#include "make_string.h"
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+namespace fs = std::filesystem;
+
+// the SSO is always triggered for strings of size 2.
+MultiStringType shortString = MKSTR("a");
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+template <class CharT>
+void doShortStringTest(MultiStringType const& MS) {
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ using Alloc = std::allocator<CharT>;
+ Ptr value = MS;
+ const path p((const char*)MS);
+#ifdef _WIN32
+ // On Windows, charset conversions cause allocations outside of the
+ // provided allocator, but accessing the native type should work without
+ // extra allocations.
+ bool DisableAllocations = std::is_same<CharT, path::value_type>::value;
+#else
+ // On other platforms, these methods only use the provided allocator, and
+ // no extra allocations should be done.
+ bool DisableAllocations = true;
+#endif
+ {
+ DisableAllocationGuard g(DisableAllocations);
+ Str s = p.string<CharT>();
+ assert(s == value);
+ Str s2 = p.string<CharT>(Alloc{});
+ assert(s2 == value);
+ }
+ using MAlloc = malloc_allocator<CharT>;
+ MAlloc::reset();
+ {
+ using Traits = std::char_traits<CharT>;
+ using AStr = std::basic_string<CharT, Traits, MAlloc>;
+ DisableAllocationGuard g(DisableAllocations);
+ AStr s = p.string<CharT, Traits, MAlloc>();
+ assert(s == value);
+ assert(MAlloc::alloc_count == 0);
+ assert(MAlloc::outstanding_alloc() == 0);
+ }
+ MAlloc::reset();
+ { // Other allocator - provided copy
+ using Traits = std::char_traits<CharT>;
+ using AStr = std::basic_string<CharT, Traits, MAlloc>;
+ DisableAllocationGuard g(DisableAllocations);
+ MAlloc a;
+ // don't allow another allocator to be default constructed.
+ MAlloc::disable_default_constructor = true;
+ AStr s = p.string<CharT, Traits, MAlloc>(a);
+ assert(s == value);
+ assert(MAlloc::alloc_count == 0);
+ assert(MAlloc::outstanding_alloc() == 0);
+ }
+ MAlloc::reset();
+}
+
+template <class CharT>
+void doLongStringTest(MultiStringType const& MS) {
+ using namespace fs;
+ using Ptr = CharT const*;
+ using Str = std::basic_string<CharT>;
+ Ptr value = MS;
+ const path p((const char*)MS);
+ { // Default allocator
+ using Alloc = std::allocator<CharT>;
+ Str s = p.string<CharT>();
+ assert(s == value);
+ Str s2 = p.string<CharT>(Alloc{});
+ assert(s2 == value);
+ }
+ using MAlloc = malloc_allocator<CharT>;
+ MAlloc::reset();
+#ifdef _WIN32
+ // On Windows, charset conversions cause allocations outside of the
+ // provided allocator, but accessing the native type should work without
+ // extra allocations.
+ bool DisableAllocations = std::is_same<CharT, path::value_type>::value;
+#else
+ // On other platforms, these methods only use the provided allocator, and
+ // no extra allocations should be done.
+ bool DisableAllocations = true;
+#endif
+
+ { // Other allocator - default construct
+ using Traits = std::char_traits<CharT>;
+ using AStr = std::basic_string<CharT, Traits, MAlloc>;
+ DisableAllocationGuard g(DisableAllocations);
+ AStr s = p.string<CharT, Traits, MAlloc>();
+ assert(s == value);
+ assert(MAlloc::alloc_count > 0);
+ assert(MAlloc::outstanding_alloc() == 1);
+ }
+ MAlloc::reset();
+ { // Other allocator - provided copy
+ using Traits = std::char_traits<CharT>;
+ using AStr = std::basic_string<CharT, Traits, MAlloc>;
+ DisableAllocationGuard g(DisableAllocations);
+ MAlloc a;
+ // don't allow another allocator to be default constructed.
+ MAlloc::disable_default_constructor = true;
+ AStr s = p.string<CharT, Traits, MAlloc>(a);
+ assert(s == value);
+ assert(MAlloc::alloc_count > 0);
+ assert(MAlloc::outstanding_alloc() == 1);
+ }
+ MAlloc::reset();
+ /////////////////////////////////////////////////////////////////////////////
+}
+
+int main(int, char**)
+{
+ using namespace fs;
+ {
+ auto const& S = shortString;
+ doShortStringTest<char>(S);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ doShortStringTest<wchar_t>(S);
+#endif
+ doShortStringTest<char16_t>(S);
+ doShortStringTest<char32_t>(S);
+#if TEST_STD_VER > 17 && defined(__cpp_lib_char8_t)
+ doShortStringTest<char8_t>(S);
+#endif
+ }
+ {
+ auto const& S = longString;
+ doLongStringTest<char>(S);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ doLongStringTest<wchar_t>(S);
+#endif
+ doLongStringTest<char16_t>(S);
+ doLongStringTest<char32_t>(S);
+#if TEST_STD_VER > 17 && defined(__cpp_lib_char8_t)
+ doLongStringTest<char8_t>(S);
+#endif
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.req/is_pathable.pass.cpp b/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.req/is_pathable.pass.cpp
new file mode 100644
index 0000000000000..e095d7598f189
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/filesystems/class.path/path.req/is_pathable.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <filesystem>
+
+// template <class Tp> struct __is_pathable
+
+// [path.req]
+// In addition to the requirements (5), function template parameters named
+// `Source` shall be one of:
+// * basic_string<_ECharT, _Traits, _Alloc>
+// * InputIterator with a value_type of _ECharT
+// * A character array, which points to a NTCTS after array-to-pointer decay.
+
+#include <filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "min_allocator.h"
+#include "constexpr_char_traits.h"
+namespace fs = std::filesystem;
+
+using fs::__is_pathable;
+
+template <class Tp>
+struct Identity { typedef Tp type; };
+
+template <class Source>
+Identity<Source> CheckSourceType(Source const&);
+
+template <class Tp>
+using GetSourceType = typename decltype(CheckSourceType(std::declval<Tp>()))::type;
+
+template <class Tp, class Exp,
+ class ExpQual = typename std::remove_const<Exp>::type>
+using CheckPass = std::is_same<ExpQual, GetSourceType<Tp>>;
+
+template <class Source>
+using CheckPassSource = std::integral_constant<bool,
+ CheckPass<Source&, Source>::value &&
+ CheckPass<Source const&, Source>::value &&
+ CheckPass<Source&&, Source>::value &&
+ CheckPass<Source const&&, Source>::value
+ >;
+
+template <class CharT>
+struct MakeTestType {
+ using value_type = CharT;
+ using string_type = std::basic_string<CharT>;
+ using string_type2 = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>;
+ using string_view_type = std::basic_string_view<CharT>;
+ using string_view_type2 = std::basic_string_view<CharT, constexpr_char_traits<CharT>>;
+ using cstr_type = CharT* const;
+ using const_cstr_type = const CharT*;
+ using array_type = CharT[25];
+ using const_array_type = const CharT[25];
+ using iter_type = cpp17_input_iterator<CharT*>;
+ using bad_iter_type = cpp17_input_iterator<signed char*>;
+
+ template <class TestT>
+ static void AssertPathable() {
+ static_assert(__is_pathable<TestT>::value, "");
+ static_assert(CheckPassSource<TestT>::value, "cannot pass as Source const&");
+ ASSERT_SAME_TYPE(CharT, typename __is_pathable<TestT>::__char_type);
+ }
+
+ template <class TestT>
+ static void AssertNotPathable() {
+ static_assert(!__is_pathable<TestT>::value, "");
+ }
+
+ static void Test() {
+ AssertPathable<string_type>();
+ AssertPathable<string_type2>();
+ AssertPathable<string_view_type>();
+ AssertPathable<string_view_type2>();
+ AssertPathable<cstr_type>();
+ AssertPathable<const_cstr_type>();
+ AssertPathable<array_type>();
+ AssertPathable<const_array_type>();
+ AssertPathable<iter_type>();
+
+ AssertNotPathable<CharT>();
+ AssertNotPathable<bad_iter_type>();
+ AssertNotPathable<signed char*>();
+ }
+};
+
+int main(int, char**) {
+ MakeTestType<char>::Test();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ MakeTestType<wchar_t>::Test();
+#endif
+ MakeTestType<char16_t>::Test();
+ MakeTestType<char32_t>::Test();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/filesystems/convert_file_time.pass.cpp b/libcxx/test/libcxx-03/input.output/filesystems/convert_file_time.pass.cpp
new file mode 100644
index 0000000000000..c501969c31167
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/filesystems/convert_file_time.pass.cpp
@@ -0,0 +1,309 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: availability-filesystem-missing
+
+// <filesystem>
+
+// typedef TrivialClock file_time_type;
+
+// ADDITIONAL_COMPILE_FLAGS: -I %{libcxx-dir}/src -Wno-macro-redefined
+
+#include <cassert>
+#include <chrono>
+#include <cstddef>
+#include <filesystem>
+#include <limits>
+#include <string>
+#include <type_traits>
+
+#include "filesystem/time_utils.h"
+
+#ifndef __SIZEOF_INT128__
+#define TEST_HAS_NO_INT128_T
+#endif
+
+using namespace std::chrono;
+namespace fs = std::filesystem;
+using fs::file_time_type;
+using fs::detail::time_util;
+
+#ifdef TEST_HAS_NO_INT128_T
+static_assert(sizeof(fs::file_time_type::rep) <= 8, "");
+#endif
+
+enum TestKind { TK_128Bit, TK_64Bit, TK_32Bit, TK_FloatingPoint };
+
+template <class TimeT>
+constexpr TestKind getTimeTTestKind() {
+ if (sizeof(TimeT) == 8 && !std::is_floating_point<TimeT>::value)
+ return TK_64Bit;
+ else if (sizeof(TimeT) == 4 && !std::is_floating_point<TimeT>::value)
+ return TK_32Bit;
+ else if (std::is_floating_point<TimeT>::value)
+ return TK_FloatingPoint;
+ else
+ assert(false && "test kind not supported");
+}
+template <class FileTimeT>
+constexpr TestKind getFileTimeTestKind() {
+ using Rep = typename FileTimeT::rep;
+ if (std::is_floating_point<Rep>::value)
+ return TK_FloatingPoint;
+ else if (sizeof(Rep) == 16)
+ return TK_128Bit;
+ else if (sizeof(Rep) == 8)
+ return TK_64Bit;
+ else
+ assert(false && "test kind not supported");
+}
+
+template <class FileTimeT, class TimeT, class TimeSpecT,
+ class Base = time_util<FileTimeT, TimeT, TimeSpecT>,
+ TestKind = getTimeTTestKind<TimeT>(),
+ TestKind = getFileTimeTestKind<FileTimeT>()>
+struct test_case;
+
+template <class FileTimeT, class TimeT, class TimeSpecT, class Base>
+struct test_case<FileTimeT, TimeT, TimeSpecT, Base, TK_64Bit, TK_128Bit>
+ : public Base {
+
+ using Base::convert_from_timespec;
+ using Base::convert_to_timespec;
+ using Base::is_representable;
+ using Base::max_nsec;
+ using Base::max_seconds;
+ using Base::min_nsec_timespec;
+ using Base::min_seconds;
+
+ static constexpr auto max_time_t = std::numeric_limits<TimeT>::max();
+ static constexpr auto min_time_t = std::numeric_limits<TimeT>::min();
+
+ static constexpr bool test_timespec() {
+ static_assert(is_representable(TimeSpecT{max_time_t, 0}), "");
+ static_assert(is_representable(TimeSpecT{max_time_t, 999999999}), "");
+ static_assert(is_representable(TimeSpecT{max_time_t, 1000000000}), "");
+ static_assert(is_representable(TimeSpecT{max_time_t, max_nsec}), "");
+
+ static_assert(is_representable(TimeSpecT{min_time_t, 0}), "");
+ static_assert(is_representable(TimeSpecT{min_time_t, 999999999}), "");
+ static_assert(is_representable(TimeSpecT{min_time_t, 1000000000}), "");
+ static_assert(is_representable(TimeSpecT{min_time_t, min_nsec_timespec}),
+ "");
+
+ return true;
+ }
+
+ static constexpr bool test_file_time_type() {
+ // This kinda sucks. Oh well.
+ static_assert(!Base::is_representable(FileTimeT::max()), "");
+ static_assert(!Base::is_representable(FileTimeT::min()), "");
+ return true;
+ }
+
+ static constexpr bool check_round_trip(TimeSpecT orig) {
+ TimeSpecT new_ts = {};
+ FileTimeT out = convert_from_timespec(orig);
+ assert(convert_to_timespec(new_ts, out));
+ return new_ts.tv_sec == orig.tv_sec && new_ts.tv_nsec == orig.tv_nsec;
+ }
+
+ static constexpr bool test_convert_timespec() {
+ static_assert(check_round_trip({0, 0}), "");
+ static_assert(check_round_trip({0, 1}), "");
+ static_assert(check_round_trip({1, 1}), "");
+ static_assert(check_round_trip({-1, 1}), "");
+ static_assert(check_round_trip({max_time_t, max_nsec}), "");
+ static_assert(check_round_trip({max_time_t, 123}), "");
+ static_assert(check_round_trip({min_time_t, min_nsec_timespec}), "");
+ static_assert(check_round_trip({min_time_t, 123}), "");
+ return true;
+ }
+
+ static bool test() {
+ static_assert(test_timespec(), "");
+ static_assert(test_file_time_type(), "");
+ static_assert(test_convert_timespec(), "");
+ return true;
+ }
+};
+
+template <class FileTimeT, class TimeT, class TimeSpecT, class Base>
+struct test_case<FileTimeT, TimeT, TimeSpecT, Base, TK_32Bit, TK_128Bit>
+ : public test_case<FileTimeT, TimeT, TimeSpecT, Base, TK_64Bit, TK_128Bit> {
+
+};
+
+template <class FileTimeT, class TimeT, class TimeSpecT, class Base>
+struct test_case<FileTimeT, TimeT, TimeSpecT, Base, TK_64Bit, TK_64Bit>
+ : public Base {
+
+ using Base::convert_from_timespec;
+ using Base::is_representable;
+ using Base::max_nsec;
+ using Base::max_seconds;
+ using Base::min_nsec_timespec;
+ using Base::min_seconds;
+
+ static constexpr auto max_time_t = std::numeric_limits<TimeT>::max();
+ static constexpr auto min_time_t = std::numeric_limits<TimeT>::min();
+
+ static constexpr bool test_timespec() {
+ static_assert(is_representable(TimeSpecT{max_seconds, max_nsec}), "");
+ static_assert(!is_representable(TimeSpecT{max_seconds + 1, 0}), "");
+ static_assert(!is_representable(TimeSpecT{max_seconds, max_nsec + 1}), "");
+ static_assert(!is_representable(TimeSpecT{max_time_t, 0}), "");
+ static_assert(is_representable(TimeSpecT{min_seconds, 0}), "");
+ static_assert(
+ is_representable(TimeSpecT{min_seconds - 1, min_nsec_timespec}), "");
+ static_assert(
+ is_representable(TimeSpecT{min_seconds - 1, min_nsec_timespec + 1}),
+ "");
+ static_assert(
+ !is_representable(TimeSpecT{min_seconds - 1, min_nsec_timespec - 1}),
+ "");
+ static_assert(!is_representable(TimeSpecT{min_time_t, 999999999}), "");
+ return true;
+ }
+
+ static constexpr bool test_file_time_type() {
+ static_assert(Base::is_representable(FileTimeT::max()), "");
+ static_assert(Base::is_representable(FileTimeT::min()), "");
+ return true;
+ }
+
+ static constexpr bool test_convert_timespec() {
+ static_assert(convert_from_timespec(TimeSpecT{max_seconds, max_nsec}) ==
+ FileTimeT::max(),
+ "");
+ static_assert(convert_from_timespec(TimeSpecT{max_seconds, max_nsec - 1}) <
+ FileTimeT::max(),
+ "");
+ static_assert(convert_from_timespec(TimeSpecT{max_seconds - 1, 999999999}) <
+ FileTimeT::max(),
+ "");
+ static_assert(convert_from_timespec(TimeSpecT{
+ min_seconds - 1, min_nsec_timespec}) == FileTimeT::min(),
+ "");
+ static_assert(convert_from_timespec(
+ TimeSpecT{min_seconds - 1, min_nsec_timespec + 1}) >
+ FileTimeT::min(),
+ "");
+ static_assert(convert_from_timespec(TimeSpecT{min_seconds, 0}) >
+ FileTimeT::min(),
+ "");
+ return true;
+ }
+
+ static bool test() {
+ static_assert(test_timespec(), "");
+ static_assert(test_file_time_type(), "");
+ static_assert(test_convert_timespec(), "");
+ return true;
+ }
+};
+
+template <class FileTimeT, class TimeT, class TimeSpecT, class Base>
+struct test_case<FileTimeT, TimeT, TimeSpecT, Base, TK_32Bit, TK_64Bit>
+ : public Base {
+ static constexpr auto max_time_t = std::numeric_limits<TimeT>::max();
+ static constexpr auto min_time_t = std::numeric_limits<TimeT>::min();
+
+ using Base::convert_from_timespec;
+ using Base::is_representable;
+ using Base::max_nsec;
+ using Base::max_seconds;
+ using Base::min_nsec_timespec;
+ using Base::min_seconds;
+
+ static constexpr bool test_timespec() {
+ static_assert(is_representable(TimeSpecT{max_time_t, 999999999}), "");
+ static_assert(is_representable(TimeSpecT{max_time_t, 1000000000}), "");
+ static_assert(is_representable(TimeSpecT{min_time_t, 0}), "");
+ return true;
+ }
+
+ static constexpr bool test_file_time_type() {
+ static_assert(!is_representable(FileTimeT::max()), "");
+ static_assert(!is_representable(FileTimeT::min()), "");
+ static_assert(is_representable(FileTimeT(seconds(max_time_t))), "");
+ static_assert(is_representable(FileTimeT(seconds(min_time_t))), "");
+ return true;
+ }
+
+ static constexpr bool test_convert_timespec() {
+ // FIXME add tests for 32 bit builds
+ return true;
+ }
+
+ static bool test() {
+ static_assert(test_timespec(), "");
+ static_assert(test_file_time_type(), "");
+ static_assert(test_convert_timespec(), "");
+ return true;
+ }
+};
+
+template <class FileTimeT, class TimeT, class TimeSpec, class Base,
+ TestKind FileTimeTKind>
+struct test_case<FileTimeT, TimeT, TimeSpec, Base, TK_FloatingPoint,
+ FileTimeTKind> : public Base {
+
+ static bool test() { return true; }
+};
+
+template <class TimeT, class NSecT = long>
+struct TestTimeSpec {
+ TimeT tv_sec;
+ NSecT tv_nsec;
+};
+
+template <class Dur>
+struct TestClock {
+ typedef Dur duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+ typedef std::chrono::time_point<TestClock> time_point;
+ static constexpr const bool is_steady = false;
+
+ static time_point now() noexcept { return {}; }
+};
+
+template <class IntType, class Period = std::micro>
+using TestFileTimeT = time_point<TestClock<duration<IntType, Period> > >;
+
+int main(int, char**) {
+ { assert((test_case<file_time_type, time_t, struct timespec>::test())); }
+ {
+ assert((test_case<TestFileTimeT<std::int64_t>, std::int64_t,
+ TestTimeSpec<std::int64_t, long> >::test()));
+ }
+ {
+ assert((test_case<TestFileTimeT<long long>, std::int32_t,
+ TestTimeSpec<std::int32_t, std::int32_t> >::test()));
+ }
+ {
+ // Test that insane platforms like ppc64 linux, which use long double as time_t,
+ // at least compile.
+ assert((test_case<TestFileTimeT<long double>, double,
+ TestTimeSpec<long double, long> >::test()));
+ }
+#ifndef TEST_HAS_NO_INT128_T
+ {
+ assert((test_case<TestFileTimeT<__int128_t, std::nano>, std::int64_t,
+ TestTimeSpec<std::int64_t, long> >::test()));
+ }
+ {
+ assert((test_case<TestFileTimeT<__int128_t, std::nano>, std::int32_t,
+ TestTimeSpec<std::int32_t, std::int32_t> >::test()));
+ }
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/input.streams/traits_mismatch.verify.cpp b/libcxx/test/libcxx-03/input.output/iostream.format/input.streams/traits_mismatch.verify.cpp
new file mode 100644
index 0000000000000..a03aed123c03c
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/input.streams/traits_mismatch.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <istream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_istream;
+
+// The char type of the stream and the char_type of the traits have to match
+
+// UNSUPPORTED: no-wide-characters
+
+#include <istream>
+#include <string>
+
+struct test_istream
+ : public std::basic_istream<char, std::char_traits<wchar_t> > {};
+
+// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
+// expected-error@*:* {{only virtual member functions can be marked 'override'}}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/lit.local.cfg b/libcxx/test/libcxx-03/input.output/iostream.format/lit.local.cfg
new file mode 100644
index 0000000000000..ac628161afe73
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/lit.local.cfg
@@ -0,0 +1,7 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+
+inLibcxx = os.path.join("libcxx", "test", "libcxx-03")
+inStd = os.path.join("libcxx", "test", "std")
+localConfig = os.path.normpath(os.path.realpath(__file__)).replace(inLibcxx, inStd)
+config.load_from_path(localConfig, lit_config)
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp b/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp
new file mode 100644
index 0000000000000..52d8500f7fa3a
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-rtti
+// UNSUPPORTED: libcpp-has-no-unicode
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// XFAIL: availability-fp_to_chars-missing
+
+// When std::print is unavailable, we don't rely on an implementation of
+// std::__is_terminal and we always assume a non-unicode and non-terminal
+// output.
+// XFAIL: availability-print-missing
+
+// Clang modules do not work with the definiton of _LIBCPP_TESTING_PRINT_IS_TERMINAL
+// XFAIL: clang-modules-build
+// <ostream>
+
+// Tests the implementation of
+// void __vprint_unicode(ostream& os, string_view fmt,
+// format_args args, bool write_nl);
+
+// In the library when std::cout is redirected to a file it is no longer
+// considered a terminal and the special terminal handling is no longer
+// executed. By testing this function we can "force" emulate a terminal.
+// Note write_nl is tested by the public API.
+
+#include <cstdio>
+bool is_terminal(FILE*);
+#define _LIBCPP_TESTING_PRINT_IS_TERMINAL ::is_terminal
+
+#include "filesystem_test_helper.h"
+#include <cassert>
+#include <fstream>
+#include <iostream>
+#include <ostream>
+#include <sstream>
+
+#include "test_macros.h"
+
+scoped_test_env env;
+std::string filename = env.create_file("output.txt");
+
+int is_terminal_calls = 0;
+bool is_terminal_result = false;
+bool is_terminal(FILE*) {
+ ++is_terminal_calls;
+ return is_terminal_result;
+}
+
+// When the stream is not a file stream, cout, clog, or cerr the stream does not
+// considered to be backed by a FILE*. Then the stream should never check
+// whether it's a terminal.
+static void test_is_terminal_not_a_file_stream() {
+ is_terminal_calls = 0;
+ is_terminal_result = false;
+ {
+ std::stringstream stream;
+ std::print(stream, "test");
+ }
+ {
+ std::ostringstream stream;
+ std::print(stream, "test");
+ }
+ assert(is_terminal_calls == 0);
+}
+
+// When the stream is a file stream, its FILE* may be a terminal. Validate this
+// is tested.
+static void test_is_terminal_file_stream() {
+ is_terminal_calls = 0;
+ is_terminal_result = false;
+ {
+ std::fstream stream(filename);
+ assert(stream.is_open());
+ assert(stream.good());
+ std::print(stream, "test");
+ assert(is_terminal_calls == 1);
+ }
+ {
+ std::ofstream stream(filename);
+ assert(stream.is_open());
+ assert(stream.good());
+ std::print(stream, "test");
+ assert(is_terminal_calls == 2);
+ }
+}
+
+// The same as above, but this time test for derived classes.
+static void test_is_terminal_rdbuf_derived_from_filebuf() {
+ struct my_filebuf : public std::filebuf {};
+
+ is_terminal_calls = 0;
+ is_terminal_result = false;
+
+ my_filebuf buf;
+ buf.open(filename, std::ios_base::out);
+ assert(buf.is_open());
+
+ std::ostream stream(&buf);
+ std::print(stream, "test");
+ assert(is_terminal_calls == 1);
+}
+
+// When the stream is cout, clog, or cerr, its FILE* may be a terminal. Validate
+// this is tested.
+static void test_is_terminal_std_cout_cerr_clog() {
+ is_terminal_calls = 0;
+ is_terminal_result = false;
+ {
+ std::print(std::cout, "test");
+ assert(is_terminal_calls == 1);
+ }
+ {
+ std::print(std::cerr, "test");
+ assert(is_terminal_calls == 2);
+ }
+ {
+ std::print(std::clog, "test");
+ assert(is_terminal_calls == 3);
+ }
+}
+
+// When the stream's FILE* is a terminal the contents need to be flushed before
+// writing to the stream.
+static void test_is_terminal_is_flushed() {
+ struct sync_counter : public std::filebuf {
+ sync_counter() {
+ open(filename, std::ios_base::out);
+ assert(is_open());
+ }
+ int sync_calls = 0;
+
+ protected:
+ int virtual sync() {
+ ++sync_calls;
+ return std::basic_streambuf<char>::sync();
+ }
+ };
+
+ is_terminal_result = false;
+
+ sync_counter buf;
+ std::ostream stream(&buf);
+
+ // Not a terminal sync is not called.
+ std::print(stream, "");
+ assert(buf.sync_calls == 0);
+
+ // A terminal sync is called.
+ is_terminal_result = true;
+ std::print(stream, "");
+ assert(buf.sync_calls == 1); // only called from the destructor of the sentry
+}
+
+int main(int, char**) {
+ test_is_terminal_not_a_file_stream();
+ test_is_terminal_file_stream();
+ test_is_terminal_rdbuf_derived_from_filebuf();
+ test_is_terminal_std_cout_cerr_clog();
+
+ test_is_terminal_is_flushed();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.syn/includes.compile.pass.cpp b/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.syn/includes.compile.pass.cpp
new file mode 100644
index 0000000000000..7a5bfb9926482
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/ostream.syn/includes.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// XFAIL: availability-fp_to_chars-missing
+
+// <ostream>
+
+// The Standard does indirectly require that <ostream> includes <format>.
+// However using the granularized headers so it's possible to implement
+// <ostream> without <format>. This would be a non-conforming implementation.
+//
+// See https://github.com/llvm/llvm-project/issues/71925
+
+#include <ostream>
+#include <vector>
+
+extern std::ostream& os;
+
+void test() {
+ std::vector<int> v{1, 2, 3};
+ std::print(os, "{} {}", 42, v);
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/traits_mismatch.verify.cpp b/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/traits_mismatch.verify.cpp
new file mode 100644
index 0000000000000..9e7bc998eb91c
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/output.streams/traits_mismatch.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <ostream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_ostream;
+
+// The char type of the stream and the char_type of the traits have to match
+
+// UNSUPPORTED: no-wide-characters
+
+#include <ostream>
+#include <string>
+
+struct test_ostream
+ : public std::basic_ostream<char, std::char_traits<wchar_t> > {};
+
+// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
+// expected-error@*:* {{only virtual member functions can be marked 'override'}}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/transcoding.pass.cpp b/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/transcoding.pass.cpp
new file mode 100644
index 0000000000000..225e4124d351e
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/transcoding.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem
+// UNSUPPORTED: libcpp-has-no-unicode
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=9000000
+
+// <print>
+
+// Tests the UTF-8 to UTF-16/32 encoding.
+// UTF-16 is used on Windows to write to the Unicode API.
+// UTF-32 is used to test the Windows behaviour on Linux using 32-bit wchar_t.
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <print>
+#include <string_view>
+
+#include "test_macros.h"
+#include "make_string.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+constexpr void test(std::basic_string_view<CharT> expected, std::string_view input) {
+ assert(expected.size() < 1024);
+ std::array<CharT, 1024> buffer;
+ std::ranges::fill(buffer, CharT('*'));
+
+ auto out = std::__unicode::__transcode(input.begin(), input.end(), buffer.begin());
+
+ assert(std::basic_string_view<CharT>(buffer.begin(), out) == expected);
+
+ out = std::find_if(out, buffer.end(), [](CharT c) { return c != CharT('*'); });
+ assert(out == buffer.end());
+}
+
+template <class CharT>
+constexpr void test() {
+ // *** Test valid UTF-8 ***
+#define TEST(S) test(SV(S), S)
+ TEST("hello world");
+ // copied from benchmarks/std_format_spec_string_unicode.bench.cpp
+ TEST("Lorem ipsum dolor sit amet, ne sensibus evertitur aliquando his. Iuvaret fabulas qui ex.");
+ TEST("Lōrem ipsūm dolor sīt æmeÞ, ea vel nostrud feuġǣit, muciūs tēmporiȝusrefērrēnÞur no mel.");
+ TEST("Лорем ипсум долор сит амет, еу диам тамяуам принципес вис, еяуидем цонцептам диспутандо");
+ TEST("入ト年媛ろ舗学ラロ準募ケカ社金スノ屋検れう策他セヲシ引口ぎ集7独ぱクふ出車ぽでぱ円輪ルノ受打わ。");
+ TEST("\U0001f636\u200d\U0001f32b\ufe0f");
+#undef TEST
+
+ // *** Test invalid UTF-8 ***
+ test(SV("\ufffd"), "\xc3");
+ test(SV("\ufffd("), "\xc3\x28");
+
+ // Surrogate range
+ test(SV("\ufffd"), "\xed\xa0\x80"); // U+D800
+ test(SV("\ufffd"), "\xed\xaf\xbf"); // U+DBFF
+ test(SV("\ufffd"), "\xed\xbf\x80"); // U+DC00
+ test(SV("\ufffd"), "\xed\xbf\xbf"); // U+DFFF
+
+ // Beyond valid values
+ test(SV("\ufffd"), "\xf4\x90\x80\x80"); // U+110000
+ test(SV("\ufffd"), "\xf4\xbf\xbf\xbf"); // U+11FFFF
+
+ // Validates http://unicode.org/review/pr-121.html option 3.
+ test(SV("\u0061\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0062"), "\x61\xF1\x80\x80\xE1\x80\xC2\x62");
+}
+
+constexpr bool test() {
+ test<char16_t>();
+ test<char32_t>();
+#if !defined(TEST_HAS_NO_WIDE_CHARACTERS)
+ test<wchar_t>();
+#endif
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_posix.pass.cpp b/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_posix.pass.cpp
new file mode 100644
index 0000000000000..b89d02ba99425
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_posix.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, c++20
+// UNSUPPORTED: no-filesystem
+// UNSUPPORTED: libcpp-has-no-unicode
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// XFAIL: availability-fp_to_chars-missing
+
+// fmemopen is available starting in Android M (API 23)
+// XFAIL: target={{.+}}-android{{(eabi)?(21|22)}}
+
+// REQUIRES: has-unix-headers
+
+// <print>
+
+// Tests the implementation of
+// void __print::__vprint_unicode_posix(FILE* __stream, string_view __fmt,
+// format_args __args, bool __write_nl,
+// bool __is_terminal);
+//
+// In the library when the stdout is redirected to a file it is no
+// longer considered a terminal and the special terminal handling is no
+// longer executed. By testing this function we can "force" emulate a
+// terminal.
+// Note __write_nl is tested by the public API.
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <cstdio>
+#include <print>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::array<char, 100> buffer;
+ std::ranges::fill(buffer, '*');
+
+ FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
+ assert(file);
+
+ // Test the file is buffered.
+ std::fprintf(file, "Hello");
+ assert(std::ftell(file) == 5);
+#if defined(TEST_HAS_GLIBC) && \
+ !(__has_feature(address_sanitizer) || __has_feature(thread_sanitizer) || __has_feature(memory_sanitizer))
+ assert(std::ranges::all_of(buffer, [](char c) { return c == '*'; }));
+#endif
+
+ // Test writing to a "non-terminal" stream does not flush.
+ std::__print::__vprint_unicode_posix(file, " world", std::make_format_args(), false, false);
+ assert(std::ftell(file) == 11);
+#if defined(TEST_HAS_GLIBC) && \
+ !(__has_feature(address_sanitizer) || __has_feature(thread_sanitizer) || __has_feature(memory_sanitizer))
+ assert(std::ranges::all_of(buffer, [](char c) { return c == '*'; }));
+#endif
+
+ // Test writing to a "terminal" stream flushes before writing.
+ std::__print::__vprint_unicode_posix(file, "!", std::make_format_args(), false, true);
+ assert(std::ftell(file) == 12);
+ assert(std::string_view(buffer.data(), buffer.data() + 11) == "Hello world");
+#if defined(TEST_HAS_GLIBC)
+ // glibc does not flush after a write.
+ assert(buffer[11] != '!');
+#endif
+
+ // Test everything is written when closing the stream.
+ std::fclose(file);
+ assert(std::string_view(buffer.data(), buffer.data() + 12) == "Hello world!");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_windows.pass.cpp b/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_windows.pass.cpp
new file mode 100644
index 0000000000000..bcd1d05a3aeeb
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.format/print.fun/vprint_unicode_windows.pass.cpp
@@ -0,0 +1,135 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem
+// UNSUPPORTED: no-wide-characters
+// UNSUPPORTED: libcpp-has-no-unicode
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// Clang modules do not work with the definiton of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION
+// XFAIL: clang-modules-build
+
+// XFAIL: availability-fp_to_chars-missing
+
+// <print>
+
+// Tests the implementation of
+// void __print::__vprint_unicode_windows(FILE* __stream, string_view __fmt,
+// format_args __args, bool __write_nl,
+// bool __is_terminal);
+//
+// In the library when the stdout is redirected to a file it is no
+// longer considered a terminal and the special terminal handling is no
+// longer executed. By testing this function we can "force" emulate a
+// terminal.
+// Note __write_nl is tested by the public API.
+
+#include <string_view>
+#include <cstdio>
+#include <algorithm>
+#include <cassert>
+
+void write_to_console(FILE*, std::wstring_view data);
+#define _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION ::write_to_console
+#include <print>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.h"
+#include "make_string.h"
+
+TEST_GCC_DIAGNOSTIC_IGNORED("-Wuse-after-free")
+
+#define SV(S) MAKE_STRING_VIEW(wchar_t, S)
+
+bool calling = false;
+std::wstring_view expected = L" world";
+
+void write_to_console(FILE*, std::wstring_view data) {
+ assert(calling);
+ assert(data == expected);
+}
+
+scoped_test_env env;
+std::string filename = env.create_file("output.txt");
+
+static void test_basics() {
+ FILE* file = std::fopen(filename.c_str(), "wb");
+ assert(file);
+
+ // Test writing to a "non-terminal" stream does not call WriteConsoleW.
+ std::__print::__vprint_unicode_windows(file, "Hello", std::make_format_args(), false, false);
+ assert(std::ftell(file) == 5);
+
+ // It's not possible to reliably test whether writing to a "terminal" stream
+ // flushes before writing. Testing flushing a closed stream worked on some
+ // platforms, but was unreliable.
+ calling = true;
+ std::__print::__vprint_unicode_windows(file, " world", std::make_format_args(), false, true);
+}
+
+// When the output is a file the data is written as-is.
+// When the output is a "terminal" invalid UTF-8 input is flagged.
+static void test(std::wstring_view output, std::string_view input) {
+ // *** File ***
+ FILE* file = std::fopen(filename.c_str(), "wb");
+ assert(file);
+
+ std::__print::__vprint_unicode_windows(file, input, std::make_format_args(), false, false);
+ assert(std::ftell(file) == static_cast<long>(input.size()));
+ std::fclose(file);
+
+ file = std::fopen(filename.c_str(), "rb");
+ assert(file);
+
+ std::vector<char> buffer(input.size());
+ size_t read = fread(buffer.data(), 1, buffer.size(), file);
+ assert(read == input.size());
+ assert(input == std::string_view(buffer.begin(), buffer.end()));
+ std::fclose(file);
+
+ // *** Terminal ***
+ expected = output;
+ std::__print::__vprint_unicode_windows(file, input, std::make_format_args(), false, true);
+}
+
+static void test() {
+ // *** Test valid UTF-8 ***
+#define TEST(S) test(SV(S), S)
+ TEST("hello world");
+
+ // copied from benchmarks/std_format_spec_string_unicode.bench.cpp
+ TEST("Lorem ipsum dolor sit amet, ne sensibus evertitur aliquando his. Iuvaret fabulas qui ex.");
+ TEST("Lōrem ipsūm dolor sīt æmeÞ, ea vel nostrud feuġǣit, muciūs tēmporiȝusrefērrēnÞur no mel.");
+ TEST("Лорем ипсум долор сит амет, еу диам тамяуам принципес вис, еяуидем цонцептам диспутандо");
+ TEST("入ト年媛ろ舗学ラロ準募ケカ社金スノ屋検れう策他セヲシ引口ぎ集7独ぱクふ出車ぽでぱ円輪ルノ受打わ。");
+ TEST("\U0001f636\u200d\U0001f32b\ufe0f");
+#undef TEST
+
+ // *** Test invalid utf-8 ***
+ test(SV("\ufffd"), "\xc3");
+ test(SV("\ufffd("), "\xc3\x28");
+
+ // surrogate range
+ test(SV("\ufffd"), "\xed\xa0\x80"); // U+D800
+ test(SV("\ufffd"), "\xed\xaf\xbf"); // U+DBFF
+ test(SV("\ufffd"), "\xed\xbf\x80"); // U+DC00
+ test(SV("\ufffd"), "\xed\xbf\xbf"); // U+DFFF
+
+ // beyond valid values
+ test(SV("\ufffd"), "\xf4\x90\x80\x80"); // U+110000
+ test(SV("\ufffd"), "\xf4\xbf\xbf\xbf"); // U+11FFFF
+
+ // Validates http://unicode.org/review/pr-121.html option 3.
+ test(SV("\u0061\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\u0062"), "\x61\xf1\x80\x80\xe1\x80\xc2\x62");
+}
+
+int main(int, char**) {
+ test_basics();
+ test();
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostream.objects/lit.local.cfg b/libcxx/test/libcxx-03/input.output/iostream.objects/lit.local.cfg
new file mode 100644
index 0000000000000..ac628161afe73
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostream.objects/lit.local.cfg
@@ -0,0 +1,7 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+
+inLibcxx = os.path.join("libcxx", "test", "libcxx-03")
+inStd = os.path.join("libcxx", "test", "std")
+localConfig = os.path.normpath(os.path.realpath(__file__)).replace(inLibcxx, inStd)
+config.load_from_path(localConfig, lit_config)
diff --git a/libcxx/test/libcxx-03/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp b/libcxx/test/libcxx-03/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp
new file mode 100644
index 0000000000000..c04250987e8e2
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostreams.base/ios.base/ios.base.cons/dtor.uninitialized.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// TODO(mordante) Investigate
+// UNSUPPORTED: apple-clang
+
+// UNSUPPORTED: no-exceptions
+
+// The fix for issue 57964 requires an updated dylib due to explicit
+// instantiations. That means Apple backdeployment targets remain broken.
+// XFAIL using-built-library-before-llvm-19
+
+// <ios>
+
+// class ios_base
+
+// ~ios_base()
+//
+// Destroying a constructed ios_base object that has not been
+// initialized by basic_ios::init is undefined behaviour. This can
+// happen in practice, make sure the undefined behaviour is handled
+// gracefully.
+//
+//
+// [ios.base.cons]/1
+//
+// ios_base();
+// Effects: Each ios_base member has an indeterminate value after construction.
+// The object's members shall be initialized by calling basic_ios::init before
+// the object's first use or before it is destroyed, whichever comes first;
+// otherwise the behavior is undefined.
+//
+// [basic.ios.cons]/2
+//
+// basic_ios();
+// Effects: Leaves its member objects uninitialized. The object shall be
+// initialized by calling basic_ios::init before its first use or before it is
+// destroyed, whichever comes first; otherwise the behavior is undefined.
+//
+// ostream and friends have a basic_ios virtual base.
+// [class.base.init]/13
+// In a non-delegating constructor, initialization proceeds in the
+// following order:
+// - First, and only for the constructor of the most derived class
+// ([intro.object]), virtual base classes are initialized ...
+//
+// So in this example
+// struct Foo : AlwaysThrows, std::ostream {
+// Foo() : AlwaysThrows{}, std::ostream{nullptr} {}
+// };
+//
+// Here
+// - the ios_base object is constructed
+// - the AlwaysThrows object is constructed and throws an exception
+// - the AlwaysThrows object is destrodyed
+// - the ios_base object is destroyed
+//
+// The ios_base object is destroyed before it has been initialized and runs
+// into undefined behavior. By using __loc_ as a sentinel we can avoid
+// accessing uninitialized memory in the destructor.
+
+#include <ostream>
+
+struct AlwaysThrows {
+ AlwaysThrows() { throw 1; }
+};
+
+struct Foo : AlwaysThrows, std::ostream {
+ Foo() : AlwaysThrows(), std::ostream(nullptr) {}
+};
+
+int main(int, char**) {
+ try {
+ Foo foo;
+ } catch (...) {
+ };
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostreams.base/ios/iostate.flags/clear.abort.pass.cpp b/libcxx/test/libcxx-03/input.output/iostreams.base/ios/iostate.flags/clear.abort.pass.cpp
new file mode 100644
index 0000000000000..8f0f5a6d78b13
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostreams.base/ios/iostate.flags/clear.abort.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
+//
+//===----------------------------------------------------------------------===//
+
+// <ios>
+
+// template <class charT, class traits> class basic_ios
+
+// void clear(iostate state);
+
+// Make sure that we abort() when exceptions are disabled and the exception
+// flag is set for the iostate we pass to clear().
+
+// REQUIRES: no-exceptions
+
+#include <csignal>
+#include <cstdlib>
+#include <ios>
+#include <streambuf>
+
+#include "test_macros.h"
+
+
+void exit_success(int) {
+ std::_Exit(EXIT_SUCCESS);
+}
+
+struct testbuf : public std::streambuf {};
+
+int main(int, char**) {
+ std::signal(SIGABRT, exit_success);
+
+ testbuf buf;
+ std::ios ios(&buf);
+ ios.exceptions(std::ios::badbit);
+ ios.clear(std::ios::badbit);
+
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/input.output/iostreams.base/lit.local.cfg b/libcxx/test/libcxx-03/input.output/iostreams.base/lit.local.cfg
new file mode 100644
index 0000000000000..ac628161afe73
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/iostreams.base/lit.local.cfg
@@ -0,0 +1,7 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+
+inLibcxx = os.path.join("libcxx", "test", "libcxx-03")
+inStd = os.path.join("libcxx", "test", "std")
+localConfig = os.path.normpath(os.path.realpath(__file__)).replace(inLibcxx, inStd)
+config.load_from_path(localConfig, lit_config)
diff --git a/libcxx/test/libcxx-03/input.output/stream.buffers/lit.local.cfg b/libcxx/test/libcxx-03/input.output/stream.buffers/lit.local.cfg
new file mode 100644
index 0000000000000..ac628161afe73
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/stream.buffers/lit.local.cfg
@@ -0,0 +1,7 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+
+inLibcxx = os.path.join("libcxx", "test", "libcxx-03")
+inStd = os.path.join("libcxx", "test", "std")
+localConfig = os.path.normpath(os.path.realpath(__file__)).replace(inLibcxx, inStd)
+config.load_from_path(localConfig, lit_config)
diff --git a/libcxx/test/libcxx-03/input.output/string.streams/lit.local.cfg b/libcxx/test/libcxx-03/input.output/string.streams/lit.local.cfg
new file mode 100644
index 0000000000000..ac628161afe73
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/string.streams/lit.local.cfg
@@ -0,0 +1,7 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+
+inLibcxx = os.path.join("libcxx", "test", "libcxx-03")
+inStd = os.path.join("libcxx", "test", "std")
+localConfig = os.path.normpath(os.path.realpath(__file__)).replace(inLibcxx, inStd)
+config.load_from_path(localConfig, lit_config)
diff --git a/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp
new file mode 100644
index 0000000000000..2b6c3802a56b6
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/string.streams/stringbuf/const_sso_buffer.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <sstream>
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// How the constructors of basic_stringbuf initialize the buffer pointers is
+// not specified. For some constructors it's implementation defined whether the
+// pointers are set to nullptr. Libc++'s implementation directly uses the SSO
+// buffer of a std::string as the initial size. This test validates that
+// behaviour.
+//
+// This behaviour is allowed by LWG2995.
+
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+template <class CharT>
+struct test_buf : public std::basic_stringbuf<CharT> {
+ typedef std::basic_streambuf<CharT> base;
+ typedef typename base::char_type char_type;
+ typedef typename base::int_type int_type;
+ typedef typename base::traits_type traits_type;
+
+ char_type* pbase() const { return base::pbase(); }
+ char_type* pptr() const { return base::pptr(); }
+ char_type* epptr() const { return base::epptr(); }
+ void gbump(int n) { base::gbump(n); }
+
+ virtual int_type overflow(int_type c = traits_type::eof()) { return base::overflow(c); }
+
+ test_buf() = default;
+ explicit test_buf(std::ios_base::openmode which) : std::basic_stringbuf<CharT>(which) {}
+
+ explicit test_buf(const std::basic_string<CharT>& s) : std::basic_stringbuf<CharT>(s) {}
+#if TEST_STD_VER >= 20
+ explicit test_buf(const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(a) {}
+ test_buf(std::ios_base::openmode which, const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(which, a) {}
+ explicit test_buf(std::basic_string<CharT>&& s)
+ : std::basic_stringbuf<CharT>(std::forward<std::basic_string<CharT>>(s)) {}
+
+ test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s,
+ const std::allocator<CharT>& a)
+ : std::basic_stringbuf<CharT>(s, a) {}
+ test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s,
+ std::ios_base::openmode which,
+ const std::allocator<CharT>& a)
+ : std::basic_stringbuf<CharT>(s, which, a) {}
+ test_buf(const std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>& s)
+ : std::basic_stringbuf<CharT>(s) {}
+#endif // TEST_STD_VER >= 20
+
+#if TEST_STD_VER >= 26
+ test_buf(std::basic_string_view<CharT> s) : std::basic_stringbuf<CharT>(s) {}
+ test_buf(std::basic_string_view<CharT> s, const std::allocator<CharT>& a) : std::basic_stringbuf<CharT>(s, a) {}
+ test_buf(std::basic_string_view<CharT> s, std::ios_base::openmode which, const std::allocator<CharT>& a)
+ : std::basic_stringbuf<CharT>(s, which, a) {}
+#endif // TEST_STD_VER >= 26
+};
+
+template <class CharT>
+static void test() {
+ std::size_t size = std::basic_string<CharT>().capacity(); // SSO buffer size.
+ {
+ test_buf<CharT> b;
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size);
+ }
+ {
+ test_buf<CharT> b(std::ios_base::out);
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size);
+ }
+ {
+ std::basic_string<CharT> s;
+ s.reserve(1024);
+ test_buf<CharT> b(s);
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size); // copy so uses size
+ }
+#if TEST_STD_VER >= 20
+ {
+ test_buf<CharT> b = test_buf<CharT>(std::allocator<CharT>());
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size);
+ }
+ {
+ test_buf<CharT> b = test_buf<CharT>(std::ios_base::out, std::allocator<CharT>());
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size);
+ }
+ {
+ std::basic_string<CharT> s;
+ s.reserve(1024);
+ std::size_t capacity = s.capacity();
+ test_buf<CharT> b = test_buf<CharT>(std::move(s));
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() >= b.pbase() + capacity); // move so uses s.capacity()
+ }
+ {
+ std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s;
+ s.reserve(1024);
+ test_buf<CharT> b = test_buf<CharT>(s, std::allocator<CharT>());
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size); // copy so uses size
+ }
+ {
+ std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s;
+ s.reserve(1024);
+ test_buf<CharT> b = test_buf<CharT>(s, std::ios_base::out, std::allocator<CharT>());
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size); // copy so uses size
+ }
+ {
+ std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>> s;
+ s.reserve(1024);
+ test_buf<CharT> b = test_buf<CharT>(s);
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size); // copy so uses size
+ }
+#endif // TEST_STD_VER >= 20
+#if TEST_STD_VER >= 26
+ {
+ std::basic_string_view<CharT> s;
+ test_buf<CharT> b = test_buf<CharT>(s);
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size);
+ }
+ {
+ std::basic_string_view<CharT> s;
+ test_buf<CharT> b = test_buf<CharT>(s, std::allocator<CharT>());
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size);
+ }
+ {
+ std::basic_string_view<CharT> s;
+ test_buf<CharT> b = test_buf<CharT>(s, std::ios_base::out, std::allocator<CharT>());
+ assert(b.pbase() != nullptr);
+ assert(b.pptr() == b.pbase());
+ assert(b.epptr() == b.pbase() + size);
+ }
+#endif // TEST_STD_VER >= 26
+}
+
+int main(int, char**) {
+ test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/input.output/string.streams/traits_mismatch.verify.cpp b/libcxx/test/libcxx-03/input.output/string.streams/traits_mismatch.verify.cpp
new file mode 100644
index 0000000000000..36f3222c3a7ac
--- /dev/null
+++ b/libcxx/test/libcxx-03/input.output/string.streams/traits_mismatch.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <sstream>
+
+// template<class charT, class traits = char_traits<charT>,
+// class Allocator = allocator<charT>>
+// class basic_stringbuf;
+//
+// The char type of the stream and the char_type of the traits have to match
+
+// UNSUPPORTED: no-wide-characters
+
+#include <sstream>
+
+std::basic_stringbuf<char, std::char_traits<wchar_t> > sb;
+// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
+// expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}}
+
+// expected-error@*:* 5 {{only virtual member functions can be marked 'override'}}
diff --git a/libcxx/test/libcxx-03/iterators/aliasing_iterator.pass.cpp b/libcxx/test/libcxx-03/iterators/aliasing_iterator.pass.cpp
new file mode 100644
index 0000000000000..33774578e2337
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/aliasing_iterator.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
+//
+//===----------------------------------------------------------------------===//
+
+// ADDITIONAL_COMPILE_FLAGS(clang): -Wprivate-header
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__iterator/aliasing_iterator.h>
+#include <cassert>
+
+struct NonTrivial {
+ int i_;
+
+ NonTrivial(int i) : i_(i) {}
+ NonTrivial(const NonTrivial& other) : i_(other.i_) {}
+
+ NonTrivial& operator=(const NonTrivial& other) {
+ i_ = other.i_;
+ return *this;
+ }
+
+ ~NonTrivial() {}
+};
+
+int main(int, char**) {
+ {
+ NonTrivial arr[] = {1, 2, 3, 4};
+ std::__aliasing_iterator<NonTrivial*, int> iter(arr);
+
+ assert(*iter == 1);
+ assert(iter[0] == 1);
+ assert(iter[1] == 2);
+ ++iter;
+ assert(*iter == 2);
+ assert(iter[-1] == 1);
+ assert(iter.__base() == arr + 1);
+ assert(iter == iter);
+ assert(iter != (iter + 1));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/assert.advance.pass.cpp b/libcxx/test/libcxx-03/iterators/assert.advance.pass.cpp
new file mode 100644
index 0000000000000..a7e8878b933b2
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/assert.advance.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <list>
+
+// Call advance(non-bidi iterator, -1)
+
+#include <iterator>
+
+#include "check_assertion.h"
+#include "test_iterators.h"
+
+int main(int, char**) {
+ int a[] = {1, 2, 3};
+
+ bidirectional_iterator<int *> bidi(a+1);
+ std::advance(bidi, 1); // should work fine
+ std::advance(bidi, 0); // should work fine
+ std::advance(bidi, -1); // should work fine
+
+ forward_iterator<int *> it(a+1);
+ std::advance(it, 1); // should work fine
+ std::advance(it, 0); // should work fine
+ TEST_LIBCPP_ASSERT_FAILURE(std::advance(it, -1), "std::advance: Can only pass a negative `n` with a bidirectional_iterator.");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/assert.next.pass.cpp b/libcxx/test/libcxx-03/iterators/assert.next.pass.cpp
new file mode 100644
index 0000000000000..2e0296b72d124
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/assert.next.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <list>
+
+// Call next(non-bidi iterator, -1)
+
+#include <iterator>
+
+#include "check_assertion.h"
+#include "test_iterators.h"
+
+int main(int, char**) {
+ int a[] = {1, 2, 3};
+ forward_iterator<int *> it(a+1);
+ (void)std::next(it, 1); // should work fine
+ (void)std::next(it, 0); // should work fine
+ TEST_LIBCPP_ASSERT_FAILURE(std::next(it, -1), "std::advance: Can only pass a negative `n` with a bidirectional_iterator.");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/assert.prev.pass.cpp b/libcxx/test/libcxx-03/iterators/assert.prev.pass.cpp
new file mode 100644
index 0000000000000..deac1edf59e06
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/assert.prev.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <list>
+
+// Call prev(forward_iterator, -1)
+
+#include <iterator>
+
+#include "check_assertion.h"
+#include "test_iterators.h"
+
+int main(int, char**) {
+ int a[] = {1, 2, 3};
+
+ bidirectional_iterator<int *> bidi(a+1);
+ (void)std::prev(bidi, -1); // should work fine
+ (void)std::prev(bidi, 0); // should work fine
+ (void)std::prev(bidi, 1); // should work fine
+
+ forward_iterator<int *> it(a+1);
+ (void)std::prev(it, -1); // should work fine
+ (void)std::prev(it, 0); // should work fine
+ TEST_LIBCPP_ASSERT_FAILURE(std::prev(it, 1), "std::advance: Can only pass a negative `n` with a bidirectional_iterator.");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.pass.cpp
new file mode 100644
index 0000000000000..3fc735b441676
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/arithmetic.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
+//
+//===----------------------------------------------------------------------===//
+
+// template <class _Iterator>
+// struct __bounded_iter;
+//
+// Arithmetic operators
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__iterator/bounded_iter.h>
+#include <cstddef>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+TEST_CONSTEXPR_CXX14 bool tests() {
+ int array[] = {40, 41, 42, 43, 44};
+ int* b = array + 0;
+ int* e = array + 5;
+
+ // ++it
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter>& result = ++iter;
+ assert(&result == &iter);
+ assert(*iter == 41);
+ }
+ // it++
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> result = iter++;
+ assert(*result == 40);
+ assert(*iter == 41);
+ }
+ // --it
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
+ std::__bounded_iter<Iter>& result = --iter;
+ assert(&result == &iter);
+ assert(*iter == 42);
+ }
+ // it--
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> result = iter--;
+ assert(*result == 43);
+ assert(*iter == 42);
+ }
+ // it += n
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter>& result = (iter += 3);
+ assert(&result == &iter);
+ assert(*iter == 43);
+ }
+ // it + n
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> result = iter + 3;
+ assert(*iter == 40);
+ assert(*result == 43);
+ }
+ // n + it
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> result = 3 + iter;
+ assert(*iter == 40);
+ assert(*result == 43);
+ }
+ // it -= n
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
+ std::__bounded_iter<Iter>& result = (iter -= 3);
+ assert(&result == &iter);
+ assert(*iter == 40);
+ }
+ // it - n
+ {
+ std::__bounded_iter<Iter> iter = std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> result = iter - 3;
+ assert(*iter == 43);
+ assert(*result == 40);
+ }
+ // it - it
+ {
+ std::__bounded_iter<Iter> iter1 = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> iter2 = std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
+ std::ptrdiff_t result = iter2 - iter1;
+ assert(result == 5);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ tests<int*>();
+#if TEST_STD_VER > 11
+ static_assert(tests<int*>(), "");
+#endif
+
+#if TEST_STD_VER > 17
+ tests<contiguous_iterator<int*> >();
+ static_assert(tests<contiguous_iterator<int*> >(), "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp
new file mode 100644
index 0000000000000..a12b77afa0db0
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/comparison.pass.cpp
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// template <class _Iterator>
+// struct __bounded_iter;
+//
+// Comparison operators
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <concepts>
+#include <__iterator/bounded_iter.h>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+TEST_CONSTEXPR_CXX14 bool tests() {
+ int array[] = {0, 1, 2, 3, 4};
+ int* b = array + 0;
+ int* e = array + 5;
+ std::__bounded_iter<Iter> const iter1 = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> const iter2 = std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
+
+ // operator==
+ {
+ assert(iter1 == iter1);
+ assert(!(iter1 == iter2));
+ }
+ // operator!=
+ {
+ assert(iter1 != iter2);
+ assert(!(iter1 != iter1));
+ }
+ // operator<
+ {
+ assert(iter1 < iter2);
+ assert(!(iter2 < iter1));
+ assert(!(iter1 < iter1));
+ }
+ // operator>
+ {
+ assert(iter2 > iter1);
+ assert(!(iter1 > iter2));
+ assert(!(iter1 > iter1));
+ }
+ // operator<=
+ {
+ assert(iter1 <= iter2);
+ assert(!(iter2 <= iter1));
+ assert(iter1 <= iter1);
+ }
+ // operator>=
+ {
+ assert(iter2 >= iter1);
+ assert(!(iter1 >= iter2));
+ assert(iter1 >= iter1);
+ }
+
+#if TEST_STD_VER >= 20
+ // P1614
+ std::same_as<std::strong_ordering> decltype(auto) r1 = iter1 <=> iter2;
+ assert(r1 == std::strong_ordering::less);
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ tests<int*>();
+#if TEST_STD_VER > 11
+ static_assert(tests<int*>(), "");
+#endif
+
+#if TEST_STD_VER > 17
+ tests<contiguous_iterator<int*>>();
+ static_assert(tests<contiguous_iterator<int*>>());
+
+ tests<three_way_contiguous_iterator<int*>>();
+ static_assert(tests<three_way_contiguous_iterator<int*>>());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/dereference.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/dereference.pass.cpp
new file mode 100644
index 0000000000000..7e3a59a49ffd4
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/dereference.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
+//
+//===----------------------------------------------------------------------===//
+
+// template <class _Iterator>
+// struct __bounded_iter;
+//
+// Dereference and indexing operators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <__iterator/bounded_iter.h>
+
+#include "check_assertion.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+struct Foo {
+ int x;
+ TEST_CONSTEXPR bool operator==(Foo const& other) const { return x == other.x; }
+};
+
+template <class Iter>
+TEST_CONSTEXPR_CXX14 bool tests() {
+ Foo array[] = {Foo{40}, Foo{41}, Foo{42}, Foo{43}, Foo{44}};
+ Foo* b = array + 0;
+ Foo* e = array + 5;
+ std::__bounded_iter<Iter> const iter1 = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> const iter2 = std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
+
+ // operator*
+ assert(*iter1 == Foo{40});
+ // operator->
+ assert(iter1->x == 40);
+ // operator[]
+ assert(iter1[0] == Foo{40});
+ assert(iter1[1] == Foo{41});
+ assert(iter1[2] == Foo{42});
+ assert(iter2[-1] == Foo{44});
+ assert(iter2[-2] == Foo{43});
+
+ return true;
+}
+
+template <class Iter>
+void test_death() {
+ Foo array[] = {Foo{0}, Foo{1}, Foo{2}, Foo{3}, Foo{4}};
+ Foo* b = array + 0;
+ Foo* e = array + 5;
+ std::__bounded_iter<Iter> const iter = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> const oob = std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
+
+ // operator*
+ TEST_LIBCPP_ASSERT_FAILURE(*oob, "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
+ // operator->
+ TEST_LIBCPP_ASSERT_FAILURE(oob->x, "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
+ // operator[]
+ TEST_LIBCPP_ASSERT_FAILURE(iter[-1], "__bounded_iter::operator[]: Attempt to index an iterator past the start");
+ TEST_LIBCPP_ASSERT_FAILURE(iter[5], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ TEST_LIBCPP_ASSERT_FAILURE(oob[0], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ TEST_LIBCPP_ASSERT_FAILURE(oob[1], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ TEST_LIBCPP_ASSERT_FAILURE(oob[-6], "__bounded_iter::operator[]: Attempt to index an iterator past the start");
+}
+
+int main(int, char**) {
+ tests<Foo*>();
+ test_death<Foo*>();
+#if TEST_STD_VER > 11
+ static_assert(tests<Foo*>(), "");
+#endif
+
+#if TEST_STD_VER > 17
+ tests<contiguous_iterator<Foo*> >();
+ test_death<contiguous_iterator<Foo*> >();
+ static_assert(tests<contiguous_iterator<Foo*> >(), "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp
new file mode 100644
index 0000000000000..22ad8c6706d6f
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/pointer_traits.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// template <class _Iterator>
+// struct __bounded_iter;
+//
+// std::pointer_traits specialization
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__iterator/bounded_iter.h>
+#include <cassert>
+#include <cstddef>
+#include <memory>
+#include <type_traits>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+TEST_CONSTEXPR_CXX14 bool tests() {
+ using BoundedIter = std::__bounded_iter<Iter>;
+ using PointerTraits = std::pointer_traits<BoundedIter>;
+ using BasePointerTraits = std::pointer_traits<Iter>;
+ static_assert(std::is_same<typename PointerTraits::pointer, BoundedIter>::value, "");
+ static_assert(std::is_same<typename PointerTraits::element_type, typename BasePointerTraits::element_type>::value, "");
+ static_assert(std::is_same<typename PointerTraits::difference_type, typename BasePointerTraits::difference_type>::value, "");
+
+ {
+ int array[] = {0, 1, 2, 3, 4};
+ int* b = array + 0;
+ int* e = array + 5;
+ std::__bounded_iter<Iter> const iter1 = std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
+ std::__bounded_iter<Iter> const iter2 = std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
+ assert(std::__to_address(iter1) == b); // in-bounds iterator
+ assert(std::__to_address(iter2) == e); // out-of-bounds iterator
+#if TEST_STD_VER > 17
+ assert(std::to_address(iter1) == b); // in-bounds iterator
+ assert(std::to_address(iter2) == e); // out-of-bounds iterator
+#endif
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ tests<int*>();
+#if TEST_STD_VER > 11
+ static_assert(tests<int*>(), "");
+#endif
+
+#if TEST_STD_VER > 17
+ tests<contiguous_iterator<int*> >();
+ static_assert(tests<contiguous_iterator<int*> >(), "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/bounded_iter/types.compile.pass.cpp
new file mode 100644
index 0000000000000..d205c5b03ee3f
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/bounded_iter/types.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
+//
+//===----------------------------------------------------------------------===//
+
+// template <class _Iterator>
+// struct __bounded_iter;
+//
+// Nested types
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__iterator/bounded_iter.h>
+#include <cstddef>
+#include <iterator>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER > 17
+struct Iterator {
+ struct value_type {};
+ using difference_type = int;
+ struct pointer {};
+ using reference = value_type&;
+ struct iterator_category : std::random_access_iterator_tag {};
+ using iterator_concept = std::contiguous_iterator_tag;
+};
+
+using BoundedIter1 = std::__bounded_iter<Iterator>;
+static_assert(std::is_same<BoundedIter1::value_type, Iterator::value_type>::value, "");
+static_assert(std::is_same<BoundedIter1::difference_type, Iterator::difference_type>::value, "");
+static_assert(std::is_same<BoundedIter1::pointer, Iterator::pointer>::value, "");
+static_assert(std::is_same<BoundedIter1::reference, Iterator::reference>::value, "");
+static_assert(std::is_same<BoundedIter1::iterator_category, Iterator::iterator_category>::value, "");
+static_assert(std::is_same<BoundedIter1::iterator_concept, Iterator::iterator_concept>::value, "");
+#endif
+
+
+using BoundedIter2 = std::__bounded_iter<int*>;
+static_assert(std::is_same<BoundedIter2::value_type, int>::value, "");
+static_assert(std::is_same<BoundedIter2::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<BoundedIter2::pointer, int*>::value, "");
+static_assert(std::is_same<BoundedIter2::reference, int&>::value, "");
+static_assert(std::is_same<BoundedIter2::iterator_category, std::random_access_iterator_tag>::value, "");
+#if TEST_STD_VER > 17
+static_assert(std::is_same<BoundedIter2::iterator_concept, std::contiguous_iterator_tag>::value, "");
+#endif
diff --git a/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp
new file mode 100644
index 0000000000000..4d3690953070f
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/contiguous_iterators.conv.compile.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <iterator>
+
+// __bounded_iter<_Iter>
+// __static_bounded_iter<_Iter>
+// __wrap_iter<_Iter>
+
+// Verify that libc++-wrapped iterators do not permit slicing conversion or construction.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <array>
+#include <span>
+#include <type_traits>
+#include <vector>
+
+#include "test_macros.h"
+
+struct Base {};
+struct Derived : Base {};
+
+template <class B, class D, bool = std::is_pointer<typename std::array<B, 1>::iterator>::value>
+struct test_array_helper : std::true_type {
+ typedef typename std::array<B, 1>::iterator BaseIter;
+ typedef typename std::array<D, 1>::iterator DerivedIter;
+ typedef typename std::array<B, 1>::const_iterator BaseConstIter;
+ typedef typename std::array<D, 1>::const_iterator DerivedConstIter;
+
+ static_assert(!std::is_convertible<DerivedIter, BaseIter>::value, "");
+ static_assert(!std::is_convertible<DerivedIter, BaseConstIter>::value, "");
+ static_assert(!std::is_convertible<DerivedConstIter, BaseConstIter>::value, "");
+ static_assert(!std::is_constructible<BaseIter, DerivedIter>::value, "");
+ static_assert(!std::is_constructible<BaseConstIter, DerivedIter>::value, "");
+ static_assert(!std::is_constructible<BaseConstIter, DerivedConstIter>::value, "");
+};
+
+template <class B, class D>
+struct test_array_helper<B, D, true> : std::true_type {};
+
+static_assert(test_array_helper<Base, Derived>::value, "");
+
+static_assert(!std::is_convertible<std::vector<Derived>::iterator, std::vector<Base>::iterator>::value, "");
+static_assert(!std::is_convertible<std::vector<Derived>::iterator, std::vector<Base>::const_iterator>::value, "");
+static_assert(!std::is_convertible<std::vector<Derived>::const_iterator, std::vector<Base>::const_iterator>::value, "");
+static_assert(!std::is_constructible<std::vector<Base>::iterator, std::vector<Derived>::iterator>::value, "");
+static_assert(!std::is_constructible<std::vector<Base>::const_iterator, std::vector<Derived>::iterator>::value, "");
+static_assert(!std::is_constructible<std::vector<Base>::const_iterator, std::vector<Derived>::const_iterator>::value,
+ "");
+
+#if TEST_STD_VER >= 20
+static_assert(!std::is_convertible_v<std::span<Derived>::iterator, std::span<Base>::iterator>);
+static_assert(!std::is_convertible_v<std::span<Derived>::iterator, std::span<const Base>::iterator>);
+static_assert(!std::is_convertible_v<std::span<const Derived>::iterator, std::span<Base>::iterator>);
+static_assert(!std::is_constructible_v<std::span<Base>::iterator, std::span<Derived>::iterator>);
+static_assert(!std::is_constructible_v<std::span<Base>::iterator, std::span<const Derived>::iterator>);
+static_assert(!std::is_constructible_v<std::span<const Base>::iterator, std::span<const Derived>::iterator>);
+#endif
diff --git a/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp b/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp
new file mode 100644
index 0000000000000..f00ca4e879403
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/contiguous_iterators.pass.cpp
@@ -0,0 +1,265 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <iterator>
+
+// __libcpp_is_contiguous_iterator<_Tp>
+
+// __libcpp_is_contiguous_iterator determines if an iterator is contiguous,
+// either because it advertises itself as such (in C++20) or because it
+// is a pointer type or a known trivial wrapper around a pointer type,
+// such as __wrap_iter<T*>.
+//
+
+#include <cassert>
+#include <deque>
+#include <initializer_list>
+#include <iterator>
+#include <string>
+#include <vector>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+#if TEST_STD_VER >= 17
+#include <string_view>
+#endif
+
+#if TEST_STD_VER >= 20
+#include <span>
+#endif
+
+class T; // incomplete
+
+class my_input_iterator
+{
+ struct tag : std::input_iterator_tag {};
+ typedef my_input_iterator Self;
+ int *state_;
+public:
+ typedef tag iterator_category;
+ typedef int value_type;
+ typedef int difference_type;
+ typedef int* pointer;
+ typedef int& reference;
+
+ my_input_iterator();
+ reference operator*() const;
+ pointer operator->() const;
+
+ Self& operator++();
+ Self operator++(int);
+ friend bool operator==(const Self&, const Self&);
+ friend bool operator!=(const Self&, const Self&);
+};
+
+class my_random_access_iterator
+{
+ struct tag : std::random_access_iterator_tag {};
+ typedef my_random_access_iterator Self;
+ int *state_;
+public:
+ typedef tag iterator_category;
+ typedef int value_type;
+ typedef int difference_type;
+ typedef int* pointer;
+ typedef int& reference;
+
+ my_random_access_iterator();
+ reference operator*() const;
+ pointer operator->() const;
+ reference operator[](difference_type) const;
+
+ Self& operator++();
+ Self operator++(int);
+ Self& operator--();
+ Self operator--(int);
+ friend Self& operator+=(Self&, difference_type);
+ friend Self& operator-=(Self&, difference_type);
+ friend Self operator+(Self, difference_type);
+ friend Self operator+(difference_type, Self);
+ friend Self operator-(Self, difference_type);
+ friend difference_type operator-(Self, Self);
+ friend bool operator==(const Self&, const Self&);
+ friend bool operator!=(const Self&, const Self&);
+ friend bool operator<(const Self&, const Self&);
+ friend bool operator>(const Self&, const Self&);
+ friend bool operator<=(const Self&, const Self&);
+ friend bool operator>=(const Self&, const Self&);
+};
+
+#if TEST_STD_VER >= 20
+class my_contiguous_iterator
+{
+ struct tag : std::contiguous_iterator_tag {};
+ typedef my_contiguous_iterator Self;
+ int *state_;
+public:
+ typedef tag iterator_category;
+ typedef int value_type;
+ typedef int difference_type;
+ typedef int* pointer;
+ typedef int& reference;
+ typedef int element_type; // enable to_address via pointer_traits
+
+ my_contiguous_iterator();
+ reference operator*() const;
+ pointer operator->() const;
+ reference operator[](difference_type) const;
+
+ Self& operator++();
+ Self operator++(int);
+ Self& operator--();
+ Self operator--(int);
+ friend Self& operator+=(Self&, difference_type);
+ friend Self& operator-=(Self&, difference_type);
+ friend Self operator+(Self, difference_type);
+ friend Self operator+(difference_type, Self);
+ friend Self operator-(Self, difference_type);
+ friend difference_type operator-(Self, Self);
+ friend bool operator==(const Self&, const Self&);
+ friend bool operator!=(const Self&, const Self&);
+ friend bool operator<(const Self&, const Self&);
+ friend bool operator>(const Self&, const Self&);
+ friend bool operator<=(const Self&, const Self&);
+ friend bool operator>=(const Self&, const Self&);
+};
+#endif
+
+struct fake_deque_iterator : std::deque<int>::iterator {
+ using element_type = int;
+};
+static_assert(std::__has_random_access_iterator_category<fake_deque_iterator>::value, "");
+static_assert(!std::__libcpp_is_contiguous_iterator<fake_deque_iterator>::value, "");
+
+#if TEST_STD_VER >= 20
+struct fake2_deque_iterator : std::deque<int>::iterator {
+ using iterator_concept = std::contiguous_iterator_tag;
+ using element_type = int;
+};
+static_assert(std::__has_random_access_iterator_category<fake2_deque_iterator>::value, "");
+static_assert(std::__libcpp_is_contiguous_iterator<fake2_deque_iterator>::value, "");
+#endif
+
+int main(int, char**)
+{
+// basic tests
+ static_assert(( std::__libcpp_is_contiguous_iterator<char *>::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<const char *>::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<int *>::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<int **>::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<T *>::value), "");
+
+ static_assert((!std::__libcpp_is_contiguous_iterator<my_input_iterator>::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<my_random_access_iterator>::value), "");
+#if TEST_STD_VER >= 20
+ static_assert(( std::__libcpp_is_contiguous_iterator<my_contiguous_iterator>::value), "");
+#endif
+
+ // move_iterator changes value category, which makes it pretty sketchy to use in optimized codepaths
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<const char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<int *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<T *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_random_access_iterator> >::value), "");
+#if TEST_STD_VER >= 20
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::move_iterator<my_contiguous_iterator> >::value), "");
+#endif
+
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<const char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<int *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<T *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_random_access_iterator> >::value), "");
+#if TEST_STD_VER >= 20
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::reverse_iterator<my_contiguous_iterator> >::value), "");
+#endif
+
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<char *> >::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<const char *> >::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<int *> >::value), "");
+
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<T *> >::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<T *> > >::value), "");
+
+ // Here my_random_access_iterator is standing in for some user's fancy pointer type, written pre-C++20.
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_random_access_iterator> >::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_random_access_iterator> > >::value), "");
+
+#if TEST_STD_VER >= 20
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<my_contiguous_iterator> >::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::__wrap_iter<my_contiguous_iterator> > >::value), "");
+#endif
+
+// iterators in the libc++ test suite
+ static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_output_iterator <char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<cpp17_input_iterator <char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<forward_iterator <char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<bidirectional_iterator<char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<random_access_iterator<char *> >::value), "");
+#if TEST_STD_VER >= 20
+ static_assert(( std::__libcpp_is_contiguous_iterator<contiguous_iterator <char *> >::value), "");
+#endif
+ static_assert((!std::__libcpp_is_contiguous_iterator<ThrowingIterator <char *> >::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<NonThrowingIterator <char *> >::value), "");
+
+//
+// iterators from libc++'s containers
+//
+
+// vector
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::vector<int>::iterator> ::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::vector<int>::const_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<int>::reverse_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<int>::const_reverse_iterator> ::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::__wrap_iter<std::vector<int>::iterator> >::value), "");
+
+// string
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::string::iterator> ::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::string::const_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::string::reverse_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::string::const_reverse_iterator>::value), "");
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::wstring::iterator> ::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::wstring::const_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::wstring::reverse_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::wstring::const_reverse_iterator>::value), "");
+#endif
+
+// deque is random-access but not contiguous
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::const_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::reverse_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::deque<int>::const_reverse_iterator> ::value), "");
+
+// vector<bool> is random-access but not contiguous
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::reverse_iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::vector<bool>::const_reverse_iterator> ::value), "");
+
+#if TEST_STD_VER >= 11
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::iterator> ::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::initializer_list<int>::const_iterator>::value), "");
+#endif
+
+#if TEST_STD_VER >= 17
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::iterator> ::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::string_view::const_iterator>::value), "");
+#endif
+
+#if TEST_STD_VER >= 20
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::span< int>::iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::span< int>::reverse_iterator>::value), "");
+ static_assert(( std::__libcpp_is_contiguous_iterator<std::span<const int>::iterator> ::value), "");
+ static_assert((!std::__libcpp_is_contiguous_iterator<std::span<const int>::reverse_iterator>::value), "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/contiguous_iterators.verify.cpp b/libcxx/test/libcxx-03/iterators/contiguous_iterators.verify.cpp
new file mode 100644
index 0000000000000..ba2697c78986c
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/contiguous_iterators.verify.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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <iterator>
+
+// __bounded_iter<_Iter>
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// Verify that __bounded_iter does not accept non-contiguous iterators as determined by __libcpp_is_contiguous_iterator.
+// static_assert should be used, see https://github.com/llvm/llvm-project/issues/115002.
+// __wrap_iter cannot be so handled because it may directly wrap user-defined fancy pointers in libc++'s vector.
+
+#include <deque>
+#include <vector>
+#include <array>
+
+// expected-error-re@*:* {{static assertion failed due to requirement {{.*}}Only contiguous iterators can be adapted by __bounded_iter.}}
+std::__bounded_iter<std::deque<int>::iterator> bounded_iter;
+// expected-error-re@*:* {{static assertion failed due to requirement {{.*}}Only contiguous iterators can be adapted by __static_bounded_iter.}}
+std::__static_bounded_iter<std::deque<int>::iterator, 42> statically_bounded_iter;
diff --git a/libcxx/test/libcxx-03/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp
new file mode 100644
index 0000000000000..601f60bcc02c4
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.concepts/iterator.concept.random.access/subsumption.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
+
+// template<class T>
+// concept random_access_iterator;
+
+#include <iterator>
+
+#include <concepts>
+
+template<std::bidirectional_iterator I>
+requires std::derived_from<std::_ITER_CONCEPT<I>, std::random_access_iterator_tag>
+constexpr bool check_subsumption() {
+ return false;
+}
+
+template<std::random_access_iterator>
+constexpr bool check_subsumption() {
+ return true;
+}
+
+static_assert(check_subsumption<int*>());
diff --git a/libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp b/libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp
new file mode 100644
index 0000000000000..ffef687723983
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// std::prev
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <iterator>
+#include "test_iterators.h"
+
+void test() {
+ int arr[] = {1, 2};
+ cpp17_input_iterator<int*> it(&arr[0]);
+ it = std::prev(it);
+ // expected-error-re@*:* {{static assertion failed due to requirement {{.*}}: Attempt to prev(it) with a non-bidirectional iterator}}
+}
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..e8b5a0cc361e9
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// This test uses iterator types from std::filesystem
+// XFAIL: availability-filesystem-missing
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_bidirectional_iterator;
+
+#include "test_macros.h"
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef TEST_HAS_NO_FILESYSTEM
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef TEST_HAS_NO_FILESYSTEM
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::filesystem::directory_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::forward_list<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::back_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::front_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::insert_iterator<std::vector<int>>>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::move_iterator<int*>>);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int (S::*)()>);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..9e36cfafc73f5
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// This test uses iterator types from std::filesystem
+// XFAIL: availability-filesystem-missing
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_forward_iterator;
+
+#include "test_macros.h"
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef TEST_HAS_NO_FILESYSTEM
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef TEST_HAS_NO_FILESYSTEM
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::filesystem::directory_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::forward_list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::back_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::front_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::insert_iterator<std::vector<int>>>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::move_iterator<int*>>);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int (S::*)()>);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..69a639122b59d
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// This test uses iterator types from std::filesystem
+// XFAIL: availability-filesystem-missing
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_input_iterator;
+
+#include "test_macros.h"
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef TEST_HAS_NO_FILESYSTEM
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef TEST_HAS_NO_FILESYSTEM
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::filesystem::directory_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::forward_list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::back_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::front_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::insert_iterator<std::vector<int>>>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::move_iterator<int*>>);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int (S::*)()>);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..54e9d7bf99dfc
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// This test uses iterator types from std::filesystem
+// XFAIL: availability-filesystem-missing
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_iterator;
+
+#include "test_macros.h"
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef TEST_HAS_NO_FILESYSTEM
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef TEST_HAS_NO_FILESYSTEM
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::filesystem::directory_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::forward_list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::back_insert_iterator<std::vector<int>>>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::front_insert_iterator<std::vector<int>>>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::insert_iterator<std::vector<int>>>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::move_iterator<int*>>);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int (S::*)()>);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..053215145fb16
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// This test uses iterator types from std::filesystem
+// XFAIL: availability-filesystem-missing
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_random_access_iterator;
+
+#include "test_macros.h"
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef TEST_HAS_NO_FILESYSTEM
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef TEST_HAS_NO_FILESYSTEM
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::filesystem::directory_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::forward_list<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::back_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::front_insert_iterator<std::vector<int>>>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::insert_iterator<std::vector<int>>>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::move_iterator<int*>>);
+
+// <list>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::reverse_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::reverse_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int (S::*)()>);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp
new file mode 100644
index 0000000000000..683a2dcc79a02
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-localization
+
+#include <iterator>
+
+#include <istream>
+#include <ostream>
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+// This is because the legacy iterator concepts don't care about iterator_category
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::istream_iterator<int, std::istream> >);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(
+ !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::ostreambuf_iterator<int, std::ostream> >);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.compile.pass.cpp
new file mode 100644
index 0000000000000..ffe473c97fedc
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.compile.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// ITER_TRAITS(I)
+
+// -- If the qualified-id ITER_TRAITS(I)::iterator_concept is valid and names a
+// type, then ITER_CONCEPT(I) denotes that type.
+// (1.2) -- Otherwise, if the qualified-id ITER_TRAITS(I)::iterator_category is
+// valid and names a type, then ITER_CONCEPT(I) denotes that type.
+// (1.3) -- Otherwise, if iterator_traits<I> names a specialization generated
+// from the primary template, then ITER_CONCEPT(I) denotes
+// random_access_iterator_tag.
+// (1.4) -- Otherwise, ITER_CONCEPT(I) does not denote a type.
+
+#include <__iterator/concepts.h>
+#include <__type_traits/is_valid_expansion.h>
+#include <cstddef>
+#include <iterator>
+
+#include "test_macros.h"
+
+struct OtherTag : std::input_iterator_tag {};
+struct OtherTagTwo : std::output_iterator_tag {};
+
+struct MyIter {
+ using iterator_category = std::random_access_iterator_tag;
+ using iterator_concept = int;
+ using value_type = char;
+ using difference_type = std::ptrdiff_t;
+ using pointer = char*;
+ using reference = char&;
+};
+
+struct MyIter2 {
+ using iterator_category = OtherTag;
+ using value_type = char;
+ using difference_type = std::ptrdiff_t;
+ using pointer = char*;
+ using reference = char&;
+};
+
+struct MyIter3 {};
+
+struct Empty {};
+struct EmptyWithSpecial {};
+template <>
+struct std::iterator_traits<MyIter3> {
+ using iterator_category = OtherTagTwo;
+ using value_type = char;
+ using difference_type = std::ptrdiff_t;
+ using pointer = char*;
+ using reference = char&;
+};
+
+template <>
+struct std::iterator_traits<EmptyWithSpecial> {
+ // empty non-default.
+};
+
+// If the qualified-id ITER_TRAITS(I)::iterator_concept is valid and names a type,
+// then ITER_CONCEPT(I) denotes that type.
+ASSERT_SAME_TYPE(std::_ITER_CONCEPT<char*>, std::contiguous_iterator_tag);
+ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter>, int);
+
+// Otherwise, if the qualified-id ITER_TRAITS(I)::iterator_category is valid
+// and names a type, then ITER_CONCEPT(I) denotes that type.
+ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter2>, OtherTag);
+ASSERT_SAME_TYPE(std::_ITER_CONCEPT<MyIter3>, OtherTagTwo);
+
+// FIXME - This requirement makes no sense to me. Why does an empty type with
+// an empty default iterator_traits get a category of random?
+ASSERT_SAME_TYPE(std::_ITER_CONCEPT<Empty>, std::random_access_iterator_tag);
+
+static_assert(!std::_IsValidExpansion<std::_ITER_CONCEPT, EmptyWithSpecial>::value);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp
new file mode 100644
index 0000000000000..066587d68cd3b
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// ITER_TRAITS(I)
+
+// For a type I, let ITER_TRAITS(I) denote the type I if iterator_traits<I> names
+// a specialization generated from the primary template. Otherwise,
+// ITER_TRAITS(I) denotes iterator_traits<I>.
+
+#include <__iterator/concepts.h>
+#include <type_traits>
+
+#include "test_iterators.h"
+
+struct A : random_access_iterator<int*> {};
+struct B : random_access_iterator<int*> {};
+struct C : random_access_iterator<int*> {};
+struct D : random_access_iterator<int*> {};
+template<> struct std::iterator_traits<B> {};
+template<> struct std::iterator_traits<C> : std::iterator_traits<A> {};
+template<> struct std::iterator_traits<D> : std::iterator_traits<int*> {};
+
+static_assert(std::is_same<std::_ITER_TRAITS<int*>, std::iterator_traits<int*>>::value);
+static_assert(std::is_same<std::_ITER_TRAITS<A>, A>::value);
+static_assert(std::is_same<std::_ITER_TRAITS<B>, std::iterator_traits<B>>::value);
+static_assert(std::is_same<std::_ITER_TRAITS<C>, std::iterator_traits<C>>::value);
+static_assert(std::is_same<std::_ITER_TRAITS<D>, std::iterator_traits<D>>::value);
diff --git a/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/integer_like.compile.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/integer_like.compile.pass.cpp
new file mode 100644
index 0000000000000..91b3acf5656d6
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator.requirements/iterator.concepts/integer_like.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
+
+#include <iterator>
+
+#include <concepts>
+
+static_assert(!std::__integer_like<bool>);
+static_assert(std::__integer_like<signed char>);
+static_assert(std::__integer_like<unsigned char>);
+static_assert(std::__integer_like<short>);
+static_assert(std::__integer_like<unsigned short>);
+static_assert(std::__integer_like<int>);
+static_assert(std::__integer_like<unsigned int>);
+static_assert(std::__integer_like<long>);
+static_assert(std::__integer_like<unsigned long>);
+static_assert(std::__integer_like<long long>);
+static_assert(std::__integer_like<unsigned long long>);
+static_assert(std::__integer_like<char>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::__integer_like<wchar_t>);
+#endif
+static_assert(std::__integer_like<char8_t>);
+static_assert(std::__integer_like<char16_t>);
+static_assert(std::__integer_like<char32_t>);
+
+static_assert(!std::__signed_integer_like<bool>);
+static_assert(std::__signed_integer_like<signed char>);
+static_assert(std::__signed_integer_like<short>);
+static_assert(std::__signed_integer_like<int>);
+static_assert(std::__signed_integer_like<long>);
+static_assert(std::__signed_integer_like<long long>);
+static_assert(!std::__signed_integer_like<unsigned char>);
+static_assert(!std::__signed_integer_like<unsigned short>);
+static_assert(!std::__signed_integer_like<unsigned int>);
+static_assert(!std::__signed_integer_like<unsigned long>);
+static_assert(!std::__signed_integer_like<unsigned long long>);
+static_assert(std::__signed_integer_like<char> == std::signed_integral<char>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::__signed_integer_like<wchar_t> == std::signed_integral<wchar_t>);
+#endif
+static_assert(std::__signed_integer_like<char8_t> == std::signed_integral<char8_t>);
+static_assert(std::__signed_integer_like<char16_t> == std::signed_integral<char16_t>);
+static_assert(std::__signed_integer_like<char32_t> == std::signed_integral<char32_t>);
diff --git a/libcxx/test/libcxx-03/iterators/iterator_with_data.pass.cpp b/libcxx/test/libcxx-03/iterators/iterator_with_data.pass.cpp
new file mode 100644
index 0000000000000..b2e3ffe0be90e
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/iterator_with_data.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// 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());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/predef.iterators/counted.iterator/assert.pass.cpp b/libcxx/test/libcxx-03/iterators/predef.iterators/counted.iterator/assert.pass.cpp
new file mode 100644
index 0000000000000..2fafe4727185d
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/predef.iterators/counted.iterator/assert.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <iterator>
+
+#include "check_assertion.h"
+#include "test_iterators.h"
+
+int main(int, char**) {
+ using Iter = std::counted_iterator<int*>;
+ int a[] = {1, 2, 3};
+ Iter valid_i(a, 1);
+
+ {
+ Iter i;
+
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Iterator is equal to or past end.");
+ TEST_LIBCPP_ASSERT_FAILURE(i[999], "Subscript argument must be less than size.");
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::iter_move(i), "Iterator must not be past end of range.");
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::iter_swap(i, valid_i), "Iterators must not be past end of range.");
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::iter_swap(valid_i, i), "Iterators must not be past end of range.");
+ std::ranges::iter_swap(valid_i, valid_i); // Ok
+ }
+
+ { // Check the `const` overload of `operator*`.
+ const Iter i;
+
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Iterator is equal to or past end.");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp b/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp
new file mode 100644
index 0000000000000..9f45848e9d3ff
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/get_container.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <iterator>
+
+// back_insert_iterator
+
+// _Container* __get_container(); // constexpr in C++20
+
+#include <iterator>
+#include <vector>
+
+#include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
+
+template <class C>
+TEST_CONSTEXPR_CXX20 bool test(C c) {
+ const std::back_insert_iterator<C> i(c);
+ assert(i.__get_container() == std::addressof(c));
+ return true;
+}
+
+int main(int, char**) {
+ test(std::vector<int>());
+ test(nasty_vector<int>());
+#if TEST_STD_VER >= 20
+ test(ConstexprFixedCapacityDeque<int, 10>());
+ static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/predef.iterators/iterators.common/assert.pass.cpp b/libcxx/test/libcxx-03/iterators/predef.iterators/iterators.common/assert.pass.cpp
new file mode 100644
index 0000000000000..01c0fb4048320
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/predef.iterators/iterators.common/assert.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <iterator>
+
+#include "check_assertion.h"
+#include "test_iterators.h"
+
+int main(int, char**) {
+ using Iter = std::common_iterator<int*, sentinel_wrapper<int*>>;
+ int a[] = {1, 2, 3};
+ sentinel_wrapper<int*> s;
+ Iter valid_i = a;
+
+ {
+ Iter i = s;
+
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable common_iterator");
+
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "Attempted to increment a non-dereferenceable common_iterator");
+ TEST_LIBCPP_ASSERT_FAILURE(i++, "Attempted to increment a non-dereferenceable common_iterator");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::iter_move(i), "Attempted to iter_move a non-dereferenceable common_iterator");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::iter_swap(i, valid_i), "Attempted to iter_swap a non-dereferenceable common_iterator");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::ranges::iter_swap(valid_i, i), "Attempted to iter_swap a non-dereferenceable common_iterator");
+ std::ranges::iter_swap(valid_i, valid_i); // Ok
+ }
+
+ { // Check the `const` overload of `operator*`.
+ const Iter i = s;
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "Attempted to dereference a non-dereferenceable common_iterator");
+ }
+
+ { // Check `operator->`.
+ struct Foo {
+ int x = 0;
+ };
+
+ std::common_iterator<Foo*, sentinel_wrapper<Foo*>> i = sentinel_wrapper<Foo*>();
+ TEST_LIBCPP_ASSERT_FAILURE(i->x, "Attempted to dereference a non-dereferenceable common_iterator");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/predef.iterators/reverse.iterators/bad_template_argument.verify.cpp b/libcxx/test/libcxx-03/iterators/predef.iterators/reverse.iterators/bad_template_argument.verify.cpp
new file mode 100644
index 0000000000000..997e611b95318
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/predef.iterators/reverse.iterators/bad_template_argument.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <iterator>
+
+// reverse_iterator
+
+#include <iterator>
+
+#include "test_iterators.h"
+
+void f() {
+ using BadIter = std::reverse_iterator<forward_iterator<int*>>;
+ BadIter i; //expected-error-re@*:* {{static assertion failed{{.*}}reverse_iterator<It> requires It to be a bidirectional iterator.}}
+}
diff --git a/libcxx/test/libcxx-03/iterators/stream.iterators/ostreambuf.iterator/ostreambuf.iter.ops/failed.pass.cpp b/libcxx/test/libcxx-03/iterators/stream.iterators/ostreambuf.iterator/ostreambuf.iter.ops/failed.pass.cpp
new file mode 100644
index 0000000000000..c856c931f5280
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/stream.iterators/ostreambuf.iterator/ostreambuf.iter.ops/failed.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <iterator>
+
+// class ostreambuf_iterator
+
+// bool failed() const throw();
+//
+// Extension: constructing from NULL is UB; we just make it a failed iterator
+
+#include <iterator>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ {
+ std::ostreambuf_iterator<char> i(nullptr);
+ assert(i.failed());
+ }
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ {
+ std::ostreambuf_iterator<wchar_t> i(nullptr);
+ assert(i.failed());
+ }
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp b/libcxx/test/libcxx-03/iterators/unwrap_iter.pass.cpp
new file mode 100644
index 0000000000000..8ef2be2b01074
--- /dev/null
+++ b/libcxx/test/libcxx-03/iterators/unwrap_iter.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
+//
+//===----------------------------------------------------------------------===//
+
+// check that std::__unwrap_iter() returns the correct type
+
+#include <algorithm>
+#include <cassert>
+#include <string>
+#include <type_traits>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+using UnwrapT = decltype(std::__unwrap_iter(std::declval<Iter>()));
+
+template <class Iter>
+using rev_iter = std::reverse_iterator<Iter>;
+
+template <class Iter>
+using rev_rev_iter = rev_iter<rev_iter<Iter> >;
+
+static_assert(std::is_same<UnwrapT<int*>, int*>::value, "");
+static_assert(std::is_same<UnwrapT<std::__wrap_iter<int*> >, int*>::value, "");
+static_assert(std::is_same<UnwrapT<rev_iter<int*> >, std::reverse_iterator<int*> >::value, "");
+static_assert(std::is_same<UnwrapT<rev_rev_iter<int*> >, int*>::value, "");
+static_assert(std::is_same<UnwrapT<rev_rev_iter<std::__wrap_iter<int*> > >, int*>::value, "");
+static_assert(std::is_same<UnwrapT<rev_rev_iter<rev_iter<std::__wrap_iter<int*> > > >, rev_iter<std::__wrap_iter<int*> > >::value, "");
+
+static_assert(std::is_same<UnwrapT<random_access_iterator<int*> >, random_access_iterator<int*> >::value, "");
+static_assert(std::is_same<UnwrapT<rev_iter<random_access_iterator<int*> > >, rev_iter<random_access_iterator<int*> > >::value, "");
+static_assert(std::is_same<UnwrapT<rev_rev_iter<random_access_iterator<int*> > >, random_access_iterator<int*> >::value, "");
+static_assert(std::is_same<UnwrapT<rev_rev_iter<rev_iter<random_access_iterator<int*> > > >, rev_iter<random_access_iterator<int*> > >::value, "");
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ std::string str = "Banane";
+ using Iter = std::string::iterator;
+
+ assert(std::__unwrap_iter(str.begin()) == str.data());
+ assert(std::__unwrap_iter(str.end()) == str.data() + str.size());
+ assert(std::__unwrap_iter(rev_rev_iter<Iter>(rev_iter<Iter>(str.begin()))) == str.data());
+ assert(std::__unwrap_iter(rev_rev_iter<Iter>(rev_iter<Iter>(str.end()))) == str.data() + str.size());
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/language.support/cxa_deleted_virtual.pass.cpp b/libcxx/test/libcxx-03/language.support/cxa_deleted_virtual.pass.cpp
new file mode 100644
index 0000000000000..883e176b26268
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/cxa_deleted_virtual.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
+
+// Test exporting the symbol: "__cxa_deleted_virtual" in macosx
+// But don't expect the symbol to be exported in previous versions.
+//
+// XFAIL: stdlib=system && target={{.+}}-apple-macosx10.{{13|14}}
+
+struct S { virtual void f() = delete; virtual ~S() {} };
+int main(int, char**) {
+ S *s = new S;
+ delete s;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/language.support/no_specializations.verify.cpp b/libcxx/test/libcxx-03/language.support/no_specializations.verify.cpp
new file mode 100644
index 0000000000000..b7b75b7e9a00d
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/no_specializations.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Check that user-specializations are diagnosed
+// See [cmp.result]/1
+
+#include <compare>
+
+#if !__has_warning("-Winvalid-specialization")
+// expected-no-diagnostics
+#else
+struct S {};
+
+template <>
+struct std::compare_three_way_result<S>; // expected-error {{cannot be specialized}}
+#endif
diff --git a/libcxx/test/libcxx-03/language.support/support.c.headers/support.c.headers.other/math.lerp.verify.cpp b/libcxx/test/libcxx-03/language.support/support.c.headers/support.c.headers.other/math.lerp.verify.cpp
new file mode 100644
index 0000000000000..1b84a9bfe47da
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.c.headers/support.c.headers.other/math.lerp.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// When built with modules, this test gives diagnostics like
+// declaration of 'lerp' must be imported from module 'std.compat.cmath'
+// before it is required
+// therefore disable the test in this configuration.
+// UNSUPPORTED: clang-modules-build
+
+// <math.h>
+
+// [support.c.headers.other]/1
+// ... except for the functions described in [sf.cmath], the
+// std::lerp function overloads ([c.math.lerp]) ...
+
+#include <math.h>
+
+void f() {
+ {
+ float f;
+ ::lerp(f, f, f); // expected-error {{no member named 'lerp' in the global namespace}}
+ std::lerp(f, f, f); // expected-error {{no member named 'lerp' in namespace 'std'}}
+ }
+ {
+ double d;
+ ::lerp(d, d, d); // expected-error {{no member named 'lerp' in the global namespace}}
+ std::lerp(d, d, d); // expected-error {{no member named 'lerp' in namespace 'std'}}
+ }
+ {
+ long double l;
+ ::lerp(l, l, l); // expected-error {{no member named 'lerp' in the global namespace}}
+ std::lerp(l, l, l); // expected-error {{no member named 'lerp' in namespace 'std'}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/language.support/support.dynamic/assert.nothrow_new_not_overridden_fno_exceptions.pass.cpp b/libcxx/test/libcxx-03/language.support/support.dynamic/assert.nothrow_new_not_overridden_fno_exceptions.pass.cpp
new file mode 100644
index 0000000000000..fb26bdf49cc3c
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.dynamic/assert.nothrow_new_not_overridden_fno_exceptions.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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, const std::nothrow_t&);
+// void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&);
+// void* operator new[](std::size_t, const std::nothrow_t&);
+// void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&);
+
+// This test ensures that we catch the case where `new` has been overridden but `new(nothrow)`
+// has not been overridden, and the library is compiled with -fno-exceptions.
+//
+// In that case, it is impossible for libc++ to provide a Standards conforming implementation
+// of `new(nothrow)`, so the only viable option is to terminate the program.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+
+// We only know how to diagnose this on platforms that use the ELF or Mach-O object file formats.
+// XFAIL: target={{.+}}-windows-{{.+}}
+
+// TODO: We currently don't have a way to express that the built library was
+// compiled with -fno-exceptions, so if the library was built with support
+// for exceptions but we run the test suite without exceptions, this will
+// spuriously fail.
+// REQUIRES: no-exceptions
+
+#include <cstddef>
+#include <new>
+
+#include "check_assertion.h"
+
+// Override the throwing versions of operator new, but not the nothrow versions.
+alignas(32) char DummyData[32 * 3];
+void* operator new(std::size_t) { return DummyData; }
+void* operator new(std::size_t, std::align_val_t) { return DummyData; }
+void* operator new[](std::size_t) { return DummyData; }
+void* operator new[](std::size_t, std::align_val_t) { return DummyData; }
+
+void operator delete(void*) noexcept {}
+void operator delete(void*, std::align_val_t) noexcept {}
+void operator delete[](void*) noexcept {}
+void operator delete[](void*, std::align_val_t) noexcept {}
+
+int main(int, char**) {
+ std::size_t size = 3;
+ std::align_val_t align = static_cast<std::align_val_t>(32);
+ EXPECT_ANY_DEATH((void)operator new(size, std::nothrow));
+ EXPECT_ANY_DEATH((void)operator new(size, align, std::nothrow));
+ EXPECT_ANY_DEATH((void)operator new[](size, std::nothrow));
+ EXPECT_ANY_DEATH((void)operator new[](size, align, std::nothrow));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp
new file mode 100644
index 0000000000000..7ead65caf9fda
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -0,0 +1,255 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test libc++'s implementation of align_val_t, and the relevant new/delete
+// overloads in all dialects when -faligned-allocation is present.
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// XFAIL: target={{.+}}-zos{{.*}}
+
+// XFAIL: sanitizer-new-delete && !hwasan
+
+// TODO: Investigate this failure
+// UNSUPPORTED: ubsan
+
+// GCC doesn't support the aligned-allocation flags.
+// XFAIL: gcc
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// RUN: %{build} -faligned-allocation -fsized-deallocation
+// RUN: %{run}
+// RUN: %{build} -faligned-allocation -fno-sized-deallocation -DNO_SIZE
+// RUN: %{run}
+// RUN: %{build} -fno-aligned-allocation -fsized-deallocation -DNO_ALIGN
+// RUN: %{run}
+// RUN: %{build} -fno-aligned-allocation -fno-sized-deallocation -DNO_ALIGN -DNO_SIZE
+// RUN: %{run}
+
+#include <cassert>
+#include <cstdlib>
+#include <new>
+
+#include "test_macros.h"
+
+TEST_DIAGNOSTIC_PUSH
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__memory/aligned_alloc.h>
+TEST_DIAGNOSTIC_POP
+
+struct alloc_stats {
+ alloc_stats() { reset(); }
+
+ int aligned_sized_called;
+ int aligned_called;
+ int sized_called;
+ int plain_called;
+ int last_size;
+ int last_align;
+
+ void reset() {
+ aligned_sized_called = aligned_called = sized_called = plain_called = 0;
+ last_align = last_size = -1;
+ }
+
+ bool expect_plain() const {
+ assert(aligned_sized_called == 0);
+ assert(aligned_called == 0);
+ assert(sized_called == 0);
+ assert(last_size == -1);
+ assert(last_align == -1);
+ return plain_called == 1;
+ }
+
+ bool expect_size(int n) const {
+ assert(plain_called == 0);
+ assert(aligned_sized_called == 0);
+ assert(aligned_called == 0);
+ assert(last_size == n);
+ assert(last_align == -1);
+ return sized_called == 1;
+ }
+
+ bool expect_align(int a) const {
+ assert(plain_called == 0);
+ assert(aligned_sized_called == 0);
+ assert(sized_called == 0);
+ assert(last_size == -1);
+ assert(last_align == a);
+ return aligned_called == 1;
+ }
+
+ bool expect_size_align(int n, int a) const {
+ assert(plain_called == 0);
+ assert(sized_called == 0);
+ assert(aligned_called == 0);
+ assert(last_size == n);
+ assert(last_align == a);
+ return aligned_sized_called == 1;
+ }
+};
+alloc_stats stats;
+
+void operator delete(void* p) TEST_NOEXCEPT {
+ ::free(p);
+ stats.plain_called++;
+ stats.last_size = stats.last_align = -1;
+}
+
+#ifndef NO_SIZE
+void operator delete(void* p, std::size_t n) TEST_NOEXCEPT {
+ ::free(p);
+ stats.sized_called++;
+ stats.last_size = n;
+ stats.last_align = -1;
+}
+#endif
+
+#ifndef NO_ALIGN
+void operator delete(void* p, std::align_val_t a) TEST_NOEXCEPT {
+ std::__libcpp_aligned_free(p);
+ stats.aligned_called++;
+ stats.last_align = static_cast<int>(a);
+ stats.last_size = -1;
+}
+
+void operator delete(void* p, std::size_t n, std::align_val_t a) TEST_NOEXCEPT {
+ std::__libcpp_aligned_free(p);
+ stats.aligned_sized_called++;
+ stats.last_align = static_cast<int>(a);
+ stats.last_size = n;
+}
+#endif
+
+void test_libcpp_dealloc() {
+ void* p = nullptr;
+#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+ std::size_t over_align_val = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2;
+#else
+ std::size_t over_align_val = TEST_ALIGNOF(std::max_align_t) * 2;
+#endif
+ std::size_t under_align_val = TEST_ALIGNOF(int);
+ std::size_t with_size_val = 2;
+
+ {
+ std::__libcpp_deallocate_unsized<char>(static_cast<char*>(p), under_align_val);
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+
+#if defined(NO_SIZE) && defined(NO_ALIGN)
+ {
+ std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val);
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+#elif defined(NO_SIZE)
+ {
+ std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val);
+ assert(stats.expect_align(over_align_val));
+ }
+ stats.reset();
+#elif defined(NO_ALIGN)
+ {
+ std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val);
+ assert(stats.expect_size(with_size_val));
+ }
+ stats.reset();
+#else
+ {
+ std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), over_align_val);
+ assert(stats.expect_size_align(with_size_val, over_align_val));
+ }
+ stats.reset();
+ {
+ std::__libcpp_deallocate_unsized<char>(static_cast<char*>(p), over_align_val);
+ assert(stats.expect_align(over_align_val));
+ }
+ stats.reset();
+ {
+ std::__libcpp_deallocate<char>(static_cast<char*>(p), std::__element_count(with_size_val), under_align_val);
+ assert(stats.expect_size(with_size_val));
+ }
+ stats.reset();
+#endif
+}
+
+struct TEST_ALIGNAS(128) AlignedType {
+ AlignedType() : elem(0) {}
+ TEST_ALIGNAS(128) char elem;
+};
+
+void test_allocator_and_new_match() {
+ stats.reset();
+#if defined(NO_SIZE) && defined(NO_ALIGN)
+ {
+ int* x = DoNotOptimize(new int(42));
+ delete x;
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+ {
+ AlignedType* a = DoNotOptimize(new AlignedType());
+ delete a;
+ assert(stats.expect_plain());
+ }
+ stats.reset();
+#elif defined(NO_SIZE)
+ stats.reset();
+# if TEST_STD_VER >= 11
+ {
+ int* x = DoNotOptimize(new int(42));
+ delete x;
+ assert(stats.expect_plain());
+ }
+# endif
+ stats.reset();
+ {
+ AlignedType* a = DoNotOptimize(new AlignedType());
+ delete a;
+ assert(stats.expect_align(TEST_ALIGNOF(AlignedType)));
+ }
+ stats.reset();
+#elif defined(NO_ALIGN)
+ stats.reset();
+ {
+ int* x = DoNotOptimize(new int(42));
+ delete x;
+ assert(stats.expect_size(sizeof(int)));
+ }
+ stats.reset();
+ {
+ AlignedType* a = DoNotOptimize(new AlignedType());
+ delete a;
+ assert(stats.expect_size(sizeof(AlignedType)));
+ }
+ stats.reset();
+#else
+ stats.reset();
+ {
+ int* x = DoNotOptimize(new int(42));
+ delete x;
+ assert(stats.expect_size(sizeof(int)));
+ }
+ stats.reset();
+ {
+ AlignedType* a = DoNotOptimize(new AlignedType());
+ delete a;
+ assert(stats.expect_size_align(sizeof(AlignedType), TEST_ALIGNOF(AlignedType)));
+ }
+ stats.reset();
+#endif
+}
+
+int main(int, char**) {
+ test_libcpp_dealloc();
+ test_allocator_and_new_match();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/language.support/support.dynamic/new_dont_return_nullptr.pass.cpp b/libcxx/test/libcxx-03/language.support/support.dynamic/new_dont_return_nullptr.pass.cpp
new file mode 100644
index 0000000000000..02b20a8c98b21
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.dynamic/new_dont_return_nullptr.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t);
+// void* operator new(std::size_t, std::align_val_t);
+// void* operator new[](std::size_t);
+// void* operator new[](std::size_t, std::align_val_t);
+
+// This test ensures that we abort the program instead of returning nullptr
+// when we fail to satisfy the allocation request. The throwing versions of
+// `operator new` must never return nullptr on failure to allocate (per the
+// Standard) and the compiler actually relies on that for optimizations.
+// Returning nullptr from the throwing `operator new` can basically result
+// in miscompiles.
+
+// REQUIRES: has-unix-headers
+// REQUIRES: no-exceptions
+// UNSUPPORTED: c++03, c++11, c++14
+
+#include <cstddef>
+#include <limits>
+#include <new>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ EXPECT_ANY_DEATH((void)operator new(std::numeric_limits<std::size_t>::max()));
+ EXPECT_ANY_DEATH((void)operator new(std::numeric_limits<std::size_t>::max(), static_cast<std::align_val_t>(32)));
+ EXPECT_ANY_DEATH((void)operator new[](std::numeric_limits<std::size_t>::max()));
+ EXPECT_ANY_DEATH((void)operator new[](std::numeric_limits<std::size_t>::max(), static_cast<std::align_val_t>(32)));
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.apple.compile.pass.cpp b/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.apple.compile.pass.cpp
new file mode 100644
index 0000000000000..6c6b1d44cc8f1
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.apple.compile.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test makes sure that we use the correct implementation for comparing
+// type_info objects on Apple platforms. See https://llvm.org/PR45549.
+
+// REQUIRES: darwin
+
+#include <typeinfo>
+
+#if !defined(_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION)
+# error "_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION should be defined on Apple platforms"
+#endif
+
+#if defined(__x86_64__) || defined(__ARM_ARCH_7M__)
+# if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION != 1
+# error "_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION should be 1 (assume RTTI is merged) on Apple platforms"
+# endif
+#elif defined(__aarch64__)
+# if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION != 3
+# error "_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION should be 3 (use the special ARM RTTI) on Apple platforms"
+# endif
+#else
+# error "This test should be updated to pin down the RTTI behavior on this ABI."
+#endif
diff --git a/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.merged.sh.cpp b/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.merged.sh.cpp
new file mode 100644
index 0000000000000..da82ea1d2c388
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.merged.sh.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: no-rtti
+
+// In MSVC mode, the two anonymous types have identical type index in both object files.
+// XFAIL: msvc
+
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.tu1.o -DTU1 -D_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=1
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.tu2.o -DTU2 -D_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=1
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.main.o -DMAIN -D_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=1
+// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.main.o %{flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe
+
+#include <cassert>
+#include <typeindex>
+#include <vector>
+
+extern std::vector<std::type_index> registry;
+
+void register1();
+void register2();
+
+#if defined(TU1)
+ namespace { struct A { bool x; }; }
+ void register1() { registry.push_back(std::type_index(typeid(A))); }
+#elif defined(TU2)
+ namespace { struct A { int x, y; }; }
+ void register2() { registry.push_back(std::type_index(typeid(A))); }
+#elif defined(MAIN)
+ std::vector<std::type_index> registry;
+
+ int main(int, char**) {
+ register1();
+ register2();
+
+ assert(registry.size() == 2);
+ assert(registry[0] != registry[1]);
+ return 0;
+ }
+#else
+# error
+#endif
diff --git a/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.unmerged.sh.cpp b/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.unmerged.sh.cpp
new file mode 100644
index 0000000000000..9b94fcbc1c92a
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.rtti/type.info/type_info.comparison.unmerged.sh.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-rtti
+
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.tu1.o -DTU1 -D_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=2
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.tu2.o -DTU2 -D_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=2
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.main.o -DMAIN -D_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=2
+// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.main.o %{flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe
+
+#include <cassert>
+#include <typeindex>
+#include <vector>
+
+extern std::vector<std::type_index> registry;
+
+void register1();
+void register2();
+
+#if defined(TU1)
+ namespace { struct A { bool x; }; }
+ void register1() { registry.push_back(std::type_index(typeid(A))); }
+#elif defined(TU2)
+ namespace { struct A { int x, y; }; }
+ void register2() { registry.push_back(std::type_index(typeid(A))); }
+#elif defined(MAIN)
+ std::vector<std::type_index> registry;
+
+ int main(int, char**) {
+ register1();
+ register2();
+
+ assert(registry.size() == 2);
+ assert(registry[0] == registry[1]);
+ return 0;
+ }
+#else
+# error
+#endif
diff --git a/libcxx/test/libcxx-03/language.support/support.types/cstddef.compile.pass.cpp b/libcxx/test/libcxx-03/language.support/support.types/cstddef.compile.pass.cpp
new file mode 100644
index 0000000000000..514353a103029
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/support.types/cstddef.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure libc++'s <cstddef> defines types like ::nullptr_t in the global namespace.
+// This is a conforming extension to be consistent with other implementations, which all
+// appear to provide that behavior too.
+
+#include <cstddef>
+#include "test_macros.h"
+
+using PtrdiffT = ::ptrdiff_t;
+using SizeT = ::size_t;
+#if TEST_STD_VER >= 11
+using MaxAlignT = ::max_align_t;
+#endif
+
+// Supported in C++03 mode too for backwards compatibility with previous versions of libc++
+using NullptrT = ::nullptr_t;
+
+// Also ensure that we provide std::nullptr_t in C++03 mode, which is an extension too.
+using StdNullptrT = std::nullptr_t;
diff --git a/libcxx/test/libcxx-03/language.support/timespec_get.xopen.compile.pass.cpp b/libcxx/test/libcxx-03/language.support/timespec_get.xopen.compile.pass.cpp
new file mode 100644
index 0000000000000..134978d099ecf
--- /dev/null
+++ b/libcxx/test/libcxx-03/language.support/timespec_get.xopen.compile.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test breaks when enabling LSV.
+// UNSUPPORTED: clang-modules-build
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// Make sure that <ctime> can be included even when _XOPEN_SOURCE is defined.
+// This used to trigger some bug in Apple SDKs, since timespec_get was not
+// defined in <time.h> but we tried using it from <ctime>.
+// See https://llvm.org/PR47208 for details.
+
+// ADDITIONAL_COMPILE_FLAGS: -D_XOPEN_SOURCE=500
+
+#include <ctime>
diff --git a/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp b/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp
new file mode 100644
index 0000000000000..3ae7f7499d796
--- /dev/null
+++ b/libcxx/test/libcxx-03/libcpp_alignof.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Test that _LIBCPP_ALIGNOF acts the same as the C++11 keyword `alignof`, and
+// not as the GNU extension `__alignof`. The former returns the minimal required
+// alignment for a type, whereas the latter returns the preferred alignment.
+//
+// See llvm.org/PR39713
+
+#include <type_traits>
+#include "test_macros.h"
+
+template <class T>
+void test() {
+ static_assert(_LIBCPP_ALIGNOF(T) == std::alignment_of<T>::value, "");
+ static_assert(_LIBCPP_ALIGNOF(T) == TEST_ALIGNOF(T), "");
+#if TEST_STD_VER >= 11
+ static_assert(_LIBCPP_ALIGNOF(T) == alignof(T), "");
+#endif
+#ifdef TEST_COMPILER_CLANG
+ static_assert(_LIBCPP_ALIGNOF(T) == _Alignof(T), "");
+#endif
+}
+
+int main(int, char**) {
+ test<int>();
+ test<long long>();
+ test<double>();
+ test<long double>();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/libcpp_freestanding.sh.cpp b/libcxx/test/libcxx-03/libcpp_freestanding.sh.cpp
new file mode 100644
index 0000000000000..8dd7a8ac85211
--- /dev/null
+++ b/libcxx/test/libcxx-03/libcpp_freestanding.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that _LIBCPP_FREESTANDING is not defined when -ffreestanding is not passed
+// to the compiler but defined when -ffreestanding is passed to the compiler.
+
+// RUN: %{cxx} %{flags} %{compile_flags} -fsyntax-only %s
+// RUN: %{cxx} %{flags} %{compile_flags} -fsyntax-only -ffreestanding -DFREESTANDING %s
+
+#include <__config>
+
+#if defined(FREESTANDING) != defined(_LIBCPP_FREESTANDING)
+#error _LIBCPP_FREESTANDING should be defined in freestanding mode and not \
+ defined in non-freestanding mode
+#endif
diff --git a/libcxx/test/libcxx-03/libcpp_version.gen.py b/libcxx/test/libcxx-03/libcpp_version.gen.py
new file mode 100644
index 0000000000000..b30623fe2c388
--- /dev/null
+++ b/libcxx/test/libcxx-03/libcpp_version.gen.py
@@ -0,0 +1,34 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that all headers define the _LIBCPP_VERSION macro.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+import sys
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+ lit_header_restrictions,
+ lit_header_undeprecations,
+ public_headers,
+)
+
+for header in public_headers:
+ print(
+ f"""\
+//--- {header}.compile.pass.cpp
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+#include <{header}>
+
+#ifndef _LIBCPP_VERSION
+# error <{header}> does not seem to define _LIBCPP_VERSION
+#endif
+"""
+ )
diff --git a/libcxx/test/libcxx-03/lint/lint_cmakelists.sh.py b/libcxx/test/libcxx-03/lint/lint_cmakelists.sh.py
new file mode 100644
index 0000000000000..286508c0d4f6d
--- /dev/null
+++ b/libcxx/test/libcxx-03/lint/lint_cmakelists.sh.py
@@ -0,0 +1,33 @@
+# RUN: %{python} %s
+
+# Verify that libcxx/include/CMakeLists.txt's list of header files
+# is maintained in alphabetical order.
+
+import os
+
+
+if __name__ == "__main__":
+ libcxx_test_libcxx_lint = os.path.dirname(os.path.abspath(__file__))
+ libcxx = os.path.abspath(os.path.join(libcxx_test_libcxx_lint, "../../.."))
+ cmakelists_name = os.path.join(libcxx, "include/CMakeLists.txt")
+ assert os.path.isfile(cmakelists_name)
+
+ with open(cmakelists_name, "r") as f:
+ lines = f.readlines()
+
+ assert lines[0] == "set(files\n"
+
+ okay = True
+ prevline = lines[1]
+ for line in lines[2:]:
+ if line == "\n":
+ continue
+ if line == "# C++03 frozen headers\n":
+ break
+ if line < prevline:
+ okay = False
+ print("LINES OUT OF ORDER in libcxx/include/CMakeLists.txt!")
+ print(prevline)
+ print(line)
+ prevline = line
+ assert okay
diff --git a/libcxx/test/libcxx-03/lint/lint_headers.sh.py b/libcxx/test/libcxx-03/lint/lint_headers.sh.py
new file mode 100644
index 0000000000000..ab237c968da7e
--- /dev/null
+++ b/libcxx/test/libcxx-03/lint/lint_headers.sh.py
@@ -0,0 +1,63 @@
+# RUN: %{python} %s
+
+# Verify that each run of consecutive #include directives
+# in each libcxx/include/ header is maintained in alphabetical order.
+
+import glob
+import os
+import re
+
+
+def exclude_from_consideration(path):
+ return (
+ path.endswith(".txt")
+ or path.endswith(".modulemap.in")
+ or os.path.basename(path) == "__config"
+ or os.path.basename(path) == "__config_site.in"
+ or os.path.basename(path) == "libcxx.imp"
+ or os.path.basename(path).startswith("__pstl")
+ or not os.path.isfile(path) # TODO: Remove once PSTL integration is finished
+ )
+
+
+def check_for_pragma_GCC_system_header(pretty_fname, lines):
+ if pretty_fname not in ["__undef_macros"]:
+ for line in lines:
+ if re.match("# *pragma GCC system_header\n", line):
+ return True
+ print(
+ "FAILED TO FIND # pragma GCC system_header in libcxx/include/%s"
+ % pretty_fname
+ )
+ return False
+ return True
+
+
+if __name__ == "__main__":
+ libcxx_test_libcxx_lint = os.path.dirname(os.path.abspath(__file__))
+ libcxx_include = os.path.abspath(
+ os.path.join(libcxx_test_libcxx_lint, "../../../include")
+ )
+ assert os.path.isdir(libcxx_include)
+
+ def pretty(path):
+ return path[len(libcxx_include) + 1 :]
+
+ all_headers = [
+ p
+ for p in (
+ glob.glob(os.path.join(libcxx_include, "*"))
+ + glob.glob(os.path.join(libcxx_include, "__*/*.h"))
+ )
+ if not exclude_from_consideration(p)
+ ]
+
+ okay = True
+ for fname in all_headers:
+ pretty_fname = pretty(fname)
+ with open(fname, "r") as f:
+ lines = f.readlines()
+
+ okay = check_for_pragma_GCC_system_header(pretty_fname, lines) and okay
+
+ assert okay
diff --git a/libcxx/test/libcxx-03/lit.local.cfg b/libcxx/test/libcxx-03/lit.local.cfg
new file mode 100644
index 0000000000000..abfc900678946
--- /dev/null
+++ b/libcxx/test/libcxx-03/lit.local.cfg
@@ -0,0 +1,9 @@
+# The tests in this directory need to run Python
+import shlex
+import sys
+
+config.substitutions.append(("%{python}", shlex.quote(sys.executable)))
+
+# run libcxx-03 tests only when running against the frozen headers. We have separate tests for non-frozen headers.
+if "FROZEN-CXX03-HEADERS-FIXME" not in config.available_features:
+ config.unsupported = True
diff --git a/libcxx/test/libcxx-03/localization/lit.local.cfg b/libcxx/test/libcxx-03/localization/lit.local.cfg
new file mode 100644
index 0000000000000..ac628161afe73
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/lit.local.cfg
@@ -0,0 +1,7 @@
+# Load the same local configuration as the corresponding one in libcxx/test/std
+import os
+
+inLibcxx = os.path.join("libcxx", "test", "libcxx-03")
+inStd = os.path.join("libcxx", "test", "std")
+localConfig = os.path.normpath(os.path.realpath(__file__)).replace(inLibcxx, inStd)
+config.load_from_path(localConfig, lit_config)
diff --git a/libcxx/test/libcxx-03/localization/locale.categories/__scan_keyword.pass.cpp b/libcxx/test/libcxx-03/localization/locale.categories/__scan_keyword.pass.cpp
new file mode 100644
index 0000000000000..1ecf378de5b61
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locale.categories/__scan_keyword.pass.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// Not a portable test
+
+// __scan_keyword
+// Scans [__b, __e) until a match is found in the basic_strings range
+// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
+// __b will be incremented (visibly), consuming CharT until a match is found
+// or proved to not exist. A keyword may be "", in which will match anything.
+// If one keyword is a prefix of another, and the next CharT in the input
+// might match another keyword, the algorithm will attempt to find the longest
+// matching keyword. If the longer matching keyword ends up not matching, then
+// no keyword match is found. If no keyword match is found, __ke is returned.
+// Else an iterator pointing to the matching keyword is found. If more than
+// one keyword matches, an iterator to the first matching keyword is returned.
+// If on exit __b == __e, eofbit is set in __err. If __case_sensitive is false,
+// __ct is used to force to lower case before comparing characters.
+// Examples:
+// Keywords: "a", "abb"
+// If the input is "a", the first keyword matches and eofbit is set.
+// If the input is "abc", no match is found and "ab" are consumed.
+//
+// template <class _InputIterator, class _ForwardIterator, class _Ctype>
+// _ForwardIterator
+// __scan_keyword(_InputIterator& __b, _InputIterator __e,
+// _ForwardIterator __kb, _ForwardIterator __ke,
+// const _Ctype& __ct, ios_base::iostate& __err,
+// bool __case_sensitive = true);
+
+#include <locale>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ const std::ctype<char>& ct = std::use_facet<std::ctype<char> >(std::locale::classic());
+ std::ios_base::iostate err = std::ios_base::goodbit;
+ {
+ const char input[] = "a";
+ const char* in = input;
+ std::string keys[] = {"a", "abb"};
+ err = std::ios_base::goodbit;
+ std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
+ keys, keys+sizeof(keys)/sizeof(keys[0]),
+ ct, err);
+ assert(k - keys == 0);
+ assert(in == input+1);
+ assert(err == std::ios_base::eofbit);
+ }
+ {
+ const char input[] = "abc";
+ const char* in = input;
+ std::string keys[] = {"a", "abb"};
+ err = std::ios_base::goodbit;
+ std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
+ keys, keys+sizeof(keys)/sizeof(keys[0]),
+ ct, err);
+ assert(k - keys == 2);
+ assert(in == input+2);
+ assert(err == std::ios_base::failbit);
+ }
+ {
+ const char input[] = "abb";
+ const char* in = input;
+ std::string keys[] = {"a", "abb"};
+ err = std::ios_base::goodbit;
+ std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
+ keys, keys+sizeof(keys)/sizeof(keys[0]),
+ ct, err);
+ assert(k - keys == 1);
+ assert(in == input+3);
+ assert(err == std::ios_base::eofbit);
+ }
+ {
+ const char input[] = "Tue ";
+ const char* in = input;
+ std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
+ err = std::ios_base::goodbit;
+ std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
+ keys, keys+sizeof(keys)/sizeof(keys[0]),
+ ct, err);
+ assert(k - keys == 2);
+ assert(in == input+3);
+ assert(err == std::ios_base::goodbit);
+ }
+ {
+ const char input[] = "tue ";
+ const char* in = input;
+ std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
+ err = std::ios_base::goodbit;
+ std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
+ keys, keys+sizeof(keys)/sizeof(keys[0]),
+ ct, err);
+ assert(k - keys == 4);
+ assert(in == input+0);
+ assert(err == std::ios_base::failbit);
+ }
+ {
+ const char input[] = "tue ";
+ const char* in = input;
+ std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
+ err = std::ios_base::goodbit;
+ std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
+ keys, keys+sizeof(keys)/sizeof(keys[0]),
+ ct, err, false);
+ assert(k - keys == 2);
+ assert(in == input+3);
+ assert(err == std::ios_base::goodbit);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/localization/locales/locale.abort.pass.cpp b/libcxx/test/libcxx-03/localization/locales/locale.abort.pass.cpp
new file mode 100644
index 0000000000000..9a47eb8f13c64
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locales/locale.abort.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// class locale;
+
+// explicit locale( const char* std_name );
+
+// REQUIRES: no-exceptions
+
+// Make sure we abort() when we construct a locale with a null name and
+// exceptions are disabled.
+
+#include <csignal>
+#include <cstdlib>
+#include <locale>
+
+#include "test_macros.h"
+
+
+void exit_success(int) {
+ std::_Exit(EXIT_SUCCESS);
+}
+
+int main(int, char**) {
+ std::signal(SIGABRT, exit_success);
+ std::locale loc(NULL);
+ (void)loc;
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/localization/locales/locale.category.abort.pass.cpp b/libcxx/test/libcxx-03/localization/locales/locale.category.abort.pass.cpp
new file mode 100644
index 0000000000000..9b321e6b1fd3e
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locales/locale.category.abort.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// class locale;
+
+// locale(const locale& other, const char* std_name, category cat);
+
+// REQUIRES: no-exceptions
+
+// Make sure we abort() when we construct a locale with a null name and
+// exceptions are disabled.
+
+#include <csignal>
+#include <cstdlib>
+#include <locale>
+
+#include "test_macros.h"
+
+
+void exit_success(int) {
+ std::_Exit(EXIT_SUCCESS);
+}
+
+int main(int, char**) {
+ std::signal(SIGABRT, exit_success);
+ std::locale loc(std::locale(), NULL, std::locale::ctype);
+ (void)loc;
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp b/libcxx/test/libcxx-03/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp
new file mode 100644
index 0000000000000..a536e6e9b04c6
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: no-wide-characters
+
+// UNSUPPORTED: c++03
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT
+
+// <locale>
+
+// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>
+
+// wstring_convert(wstring_convert&& other); // EXTENSION
+
+#include <locale>
+#include <codecvt>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ typedef std::codecvt_utf8<wchar_t> Codecvt;
+ typedef std::wstring_convert<Codecvt> Myconv;
+ // create a converter and perform some conversions to generate some
+ // interesting state.
+ Myconv myconv;
+ myconv.from_bytes("\xEF\xBF\xBD");
+ const auto old_converted = myconv.converted();
+ assert(myconv.converted() == 3);
+ // move construct a new converter and make sure the state is the same.
+ Myconv myconv2(std::move(myconv));
+ assert(myconv2.converted() == old_converted);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp b/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp
new file mode 100644
index 0000000000000..072c85a11d2b8
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/facet.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// class locale::facet
+// {
+// protected:
+// explicit facet(size_t refs = 0);
+// virtual ~facet();
+// facet(const facet&) = delete;
+// void operator=(const facet&) = delete;
+// };
+
+// This test isn't portable
+
+#include <locale>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct my_facet
+ : public std::locale::facet
+{
+ static int count;
+ my_facet(unsigned refs = 0)
+ : std::locale::facet(refs)
+ {++count;}
+
+ ~my_facet() {--count;}
+};
+
+int my_facet::count = 0;
+
+int main(int, char**)
+{
+ my_facet* f = new my_facet;
+ f->__add_shared();
+ assert(my_facet::count == 1);
+ f->__release_shared();
+ assert(my_facet::count == 0);
+ f = new my_facet(1);
+ f->__add_shared();
+ assert(my_facet::count == 1);
+ f->__release_shared();
+ assert(my_facet::count == 1);
+ f->__release_shared();
+ assert(my_facet::count == 0);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp b/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
new file mode 100644
index 0000000000000..6e59b8256ffe7
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// This test verifies that the construction of locale::__imp does not allocate
+// for facets, as it uses __sso_allocator<facet*, N>. It would fail if new
+// facets have been added (using install()) but N hasn't been adjusted to
+// account for them.
+
+#include <cassert>
+
+#include "count_new.h"
+
+int main(int, char**) {
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.id/id.pass.cpp b/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.id/id.pass.cpp
new file mode 100644
index 0000000000000..5e0113474c9d1
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locales/locale/locale.types/locale.id/id.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
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// class locale::id
+// {
+// public:
+// id();
+// void operator=(const id&) = delete;
+// id(const id&) = delete;
+// };
+
+// This test isn't portable
+
+#include <locale>
+#include <cassert>
+
+#include "test_macros.h"
+
+std::locale::id id0;
+std::locale::id id2;
+std::locale::id id1;
+
+int main(int, char**)
+{
+ long id = id0.__get();
+ assert(id0.__get() == id+0);
+ assert(id0.__get() == id+0);
+ assert(id0.__get() == id+0);
+ assert(id1.__get() == id+1);
+ assert(id1.__get() == id+1);
+ assert(id1.__get() == id+1);
+ assert(id2.__get() == id+2);
+ assert(id2.__get() == id+2);
+ assert(id2.__get() == id+2);
+ assert(id0.__get() == id+0);
+ assert(id0.__get() == id+0);
+ assert(id0.__get() == id+0);
+ assert(id1.__get() == id+1);
+ assert(id1.__get() == id+1);
+ assert(id1.__get() == id+1);
+ assert(id2.__get() == id+2);
+ assert(id2.__get() == id+2);
+ assert(id2.__get() == id+2);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/localization/locales/use_facet.abort.pass.cpp b/libcxx/test/libcxx-03/localization/locales/use_facet.abort.pass.cpp
new file mode 100644
index 0000000000000..9b4755a819cb9
--- /dev/null
+++ b/libcxx/test/libcxx-03/localization/locales/use_facet.abort.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
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// template <class Facet> const Facet& use_facet(const locale& loc);
+
+// REQUIRES: no-exceptions
+
+// Make sure we abort() when we pass a facet not associated to the locale to
+// use_facet() and exceptions are disabled.
+
+#include <csignal>
+#include <cstdlib>
+#include <locale>
+
+#include "test_macros.h"
+
+
+struct my_facet : public std::locale::facet {
+ static std::locale::id id;
+};
+
+std::locale::id my_facet::id;
+
+void exit_success(int) {
+ std::_Exit(EXIT_SUCCESS);
+}
+
+int main(int, char**) {
+ std::signal(SIGABRT, exit_success);
+ std::use_facet<my_facet>(std::locale());
+ return EXIT_FAILURE;
+}
diff --git a/libcxx/test/libcxx-03/mem/mem.res/nodiscard.verify.cpp b/libcxx/test/libcxx-03/mem/mem.res/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..9ccdcff34619c
--- /dev/null
+++ b/libcxx/test/libcxx-03/mem/mem.res/nodiscard.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// check that functions are marked [[nodiscard]] as an extension in C++17
+
+// [[nodiscard]] std::pmr::memory_resource::allocate(size_t, size_t);
+// [[nodiscard]] std::pmr::polymorphic_allocator<T>::allocate(size_t, size_t);
+
+#include <memory_resource>
+
+void f() {
+ std::pmr::memory_resource* res = nullptr;
+ res->allocate(0); // expected-warning {{ignoring return value of function}}
+ res->allocate(0, 1); // expected-warning {{ignoring return value of function}}
+
+ std::pmr::polymorphic_allocator<int> poly;
+ poly.allocate(0); // expected-warning {{ignoring return value of function}}
+}
diff --git a/libcxx/test/libcxx-03/memory/aligned_allocation_macro.compile.pass.cpp b/libcxx/test/libcxx-03/memory/aligned_allocation_macro.compile.pass.cpp
new file mode 100644
index 0000000000000..6249c52814781
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/aligned_allocation_macro.compile.pass.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <new>
+
+#include "test_macros.h"
+
+#if !_LIBCPP_HAS_ALIGNED_ALLOCATION
+# error "libc++ should have aligned allocation in C++17 and up when targeting a platform that supports it"
+#endif
diff --git a/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp b/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp
new file mode 100644
index 0000000000000..20c05b381ef0e
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/allocation_guard.pass.cpp
@@ -0,0 +1,194 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <memory>
+
+// To allow checking that self-move works correctly.
+// ADDITIONAL_COMPILE_FLAGS: -Wno-self-move
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// template<class _Alloc>
+// struct __allocation_guard;
+
+#include <__memory/allocation_guard.h>
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+#include "test_allocator.h"
+
+using A = test_allocator<int>;
+
+// A trimmed-down version of `test_allocator` that is copy-assignable (in general allocators don't have to support copy
+// assignment).
+template <class T>
+struct AssignableAllocator {
+ using size_type = unsigned;
+ using difference_type = int;
+ using value_type = T;
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+ using reference = typename std::add_lvalue_reference<value_type>::type;
+ using const_reference = typename std::add_lvalue_reference<const value_type>::type;
+
+ template <class U>
+ struct rebind {
+ using other = test_allocator<U>;
+ };
+
+ test_allocator_statistics* stats_ = nullptr;
+
+ explicit AssignableAllocator(test_allocator_statistics& stats) : stats_(&stats) {
+ ++stats_->count;
+ }
+
+ TEST_CONSTEXPR_CXX14 AssignableAllocator(const AssignableAllocator& rhs) TEST_NOEXCEPT
+ : stats_(rhs.stats_) {
+ if (stats_ != nullptr) {
+ ++stats_->count;
+ ++stats_->copied;
+ }
+ }
+
+ TEST_CONSTEXPR_CXX14 AssignableAllocator& operator=(const AssignableAllocator& rhs) TEST_NOEXCEPT {
+ stats_ = rhs.stats_;
+ if (stats_ != nullptr) {
+ ++stats_->count;
+ ++stats_->copied;
+ }
+
+ return *this;
+ }
+
+ TEST_CONSTEXPR_CXX14 pointer allocate(size_type n, const void* = nullptr) {
+ if (stats_ != nullptr) {
+ ++stats_->alloc_count;
+ }
+ return std::allocator<value_type>().allocate(n);
+ }
+
+ TEST_CONSTEXPR_CXX14 void deallocate(pointer p, size_type s) {
+ if (stats_ != nullptr) {
+ --stats_->alloc_count;
+ }
+ std::allocator<value_type>().deallocate(p, s);
+ }
+
+ TEST_CONSTEXPR size_type max_size() const TEST_NOEXCEPT { return UINT_MAX / sizeof(T); }
+
+ template <class U>
+ TEST_CONSTEXPR_CXX20 void construct(pointer p, U&& val) {
+ if (stats_ != nullptr)
+ ++stats_->construct_count;
+#if TEST_STD_VER > 17
+ std::construct_at(std::to_address(p), std::forward<U>(val));
+#else
+ ::new (static_cast<void*>(p)) T(std::forward<U>(val));
+#endif
+ }
+
+ TEST_CONSTEXPR_CXX14 void destroy(pointer p) {
+ if (stats_ != nullptr) {
+ ++stats_->destroy_count;
+ }
+ p->~T();
+ }
+};
+
+// Move-only.
+static_assert(!std::is_copy_constructible<std::__allocation_guard<A> >::value, "");
+static_assert(std::is_move_constructible<std::__allocation_guard<A> >::value, "");
+static_assert(!std::is_copy_assignable<std::__allocation_guard<A> >::value, "");
+static_assert(std::is_move_assignable<std::__allocation_guard<A> >::value, "");
+
+int main(int, char**) {
+ const int size = 42;
+
+ { // The constructor allocates using the given allocator.
+ test_allocator_statistics stats;
+ std::__allocation_guard<A> guard(A(&stats), size);
+ assert(stats.alloc_count == 1);
+ assert(guard.__get() != nullptr);
+ }
+
+ { // The destructor deallocates using the given allocator.
+ test_allocator_statistics stats;
+ {
+ std::__allocation_guard<A> guard(A(&stats), size);
+ assert(stats.alloc_count == 1);
+ }
+ assert(stats.alloc_count == 0);
+ }
+
+ { // `__release_ptr` prevents deallocation.
+ test_allocator_statistics stats;
+ A alloc(&stats);
+ int* ptr = nullptr;
+ {
+ std::__allocation_guard<A> guard(alloc, size);
+ assert(stats.alloc_count == 1);
+ ptr = guard.__release_ptr();
+ }
+ assert(stats.alloc_count == 1);
+ alloc.deallocate(ptr, size);
+ }
+
+ { // Using the move constructor doesn't lead to double deletion.
+ test_allocator_statistics stats;
+ {
+ std::__allocation_guard<A> guard1(A(&stats), size);
+ assert(stats.alloc_count == 1);
+ auto* ptr1 = guard1.__get();
+
+ std::__allocation_guard<A> guard2 = std::move(guard1);
+ assert(stats.alloc_count == 1);
+ assert(guard1.__get() == nullptr);
+ assert(guard2.__get() == ptr1);
+ }
+ assert(stats.alloc_count == 0);
+ }
+
+ { // Using the move assignment operator doesn't lead to double deletion.
+ using A2 = AssignableAllocator<int>;
+
+ test_allocator_statistics stats;
+ {
+ std::__allocation_guard<A2> guard1(A2(stats), size);
+ assert(stats.alloc_count == 1);
+ std::__allocation_guard<A2> guard2(A2(stats), size);
+ assert(stats.alloc_count == 2);
+ auto* ptr1 = guard1.__get();
+
+ guard2 = std::move(guard1);
+ assert(stats.alloc_count == 1);
+ assert(guard1.__get() == nullptr);
+ assert(guard2.__get() == ptr1);
+ }
+ assert(stats.alloc_count == 0);
+ }
+
+ { // Self-assignment is a no-op.
+ using A2 = AssignableAllocator<int>;
+
+ test_allocator_statistics stats;
+ {
+ std::__allocation_guard<A2> guard(A2(stats), size);
+ assert(stats.alloc_count == 1);
+ auto* ptr = guard.__get();
+
+ guard = std::move(guard);
+ assert(stats.alloc_count == 1);
+ assert(guard.__get() == ptr);
+ }
+ assert(stats.alloc_count == 0);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/allocator_void.trivial.compile.pass.cpp b/libcxx/test/libcxx-03/memory/allocator_void.trivial.compile.pass.cpp
new file mode 100644
index 0000000000000..b7dfc190e8e91
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/allocator_void.trivial.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that std::allocator<void> is trivial. This was the case before C++20
+// with the std::allocator<void> explicit specialization, and this test makes sure
+// that we maintain that property across all standards.
+//
+// This is important since triviality has implications on how the type is passed
+// as a function argument in the ABI.
+
+#include <memory>
+#include <type_traits>
+
+typedef std::allocator<void> A1;
+struct A2 : std::allocator<void> { };
+
+static_assert(std::is_trivially_default_constructible<A1>::value, "");
+static_assert(std::is_trivially_copyable<A1>::value, "");
+
+static_assert(std::is_trivially_default_constructible<A2>::value, "");
+static_assert(std::is_trivially_copyable<A2>::value, "");
diff --git a/libcxx/test/libcxx-03/memory/allocator_volatile.verify.cpp b/libcxx/test/libcxx-03/memory/allocator_volatile.verify.cpp
new file mode 100644
index 0000000000000..53fdc08e7a024
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/allocator_volatile.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
+//
+//===----------------------------------------------------------------------===//
+
+// http://wg21.link/LWG2447 gives implementors freedom to reject const or volatile types in `std::allocator`.
+
+#include <memory>
+
+std::allocator<const int> A1; // expected-error@*:* {{std::allocator does not support const types}}
+std::allocator<volatile int> A2; // expected-error@*:* {{std::allocator does not support volatile types}}
diff --git a/libcxx/test/libcxx-03/memory/is_allocator.pass.cpp b/libcxx/test/libcxx-03/memory/is_allocator.pass.cpp
new file mode 100644
index 0000000000000..cf11d077bf086
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/is_allocator.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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <memory>
+// UNSUPPORTED: c++03, c++11, c++14
+
+// template<typename _Alloc>
+// struct __is_allocator;
+
+// Is either true_type or false_type depending on if A is an allocator.
+
+#include <memory>
+#include <string>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+#include "test_allocator.h"
+
+template <typename T>
+void test_allocators()
+{
+ static_assert(!std::__is_allocator<T>::value, "" );
+ static_assert( std::__is_allocator<std::allocator<T>>::value, "" );
+ static_assert( std::__is_allocator<test_allocator<T>>::value, "" );
+ static_assert( std::__is_allocator<min_allocator<T>>::value, "" );
+}
+
+
+int main(int, char**)
+{
+ // test_allocators<void>();
+ test_allocators<char>();
+ test_allocators<int>();
+ test_allocators<std::string>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/shared_ptr_array.pass.cpp b/libcxx/test/libcxx-03/memory/shared_ptr_array.pass.cpp
new file mode 100644
index 0000000000000..cc8c743830826
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/shared_ptr_array.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// These compiler versions and platforms don't enable sized deallocation by default.
+// ADDITIONAL_COMPILE_FLAGS(clang-17): -fsized-deallocation
+// ADDITIONAL_COMPILE_FLAGS(clang-18): -fsized-deallocation
+// ADDITIONAL_COMPILE_FLAGS(apple-clang-15): -fsized-deallocation
+// ADDITIONAL_COMPILE_FLAGS(apple-clang-16): -fsized-deallocation
+// ADDITIONAL_COMPILE_FLAGS(target=x86_64-w64-windows-gnu): -fsized-deallocation
+// ADDITIONAL_COMPILE_FLAGS(target=i686-w64-windows-gnu): -fsized-deallocation
+
+// This test will fail with ASan if the implementation passes different sizes
+// to corresponding allocation and deallocation functions.
+
+#include <memory>
+
+int main(int, char**) {
+ std::allocate_shared<int[]>(std::allocator<int>{}, 10);
+ std::make_shared<int[]>(10);
+
+ std::allocate_shared<int[10]>(std::allocator<int>{});
+ std::make_shared<int[10]>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp b/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp
new file mode 100644
index 0000000000000..f70f8134d1dda
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/swap_allocator.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <memory>
+
+// template <typename _Alloc>
+// void __swap_allocator(_Alloc& __a1, _Alloc& __a2);
+
+#include <__memory/swap_allocator.h>
+#include <cassert>
+#include <memory>
+#include <utility>
+
+#include "test_macros.h"
+
+template <bool Propagate, bool Noexcept>
+struct Alloc {
+ int i = 0;
+ Alloc() = default;
+ Alloc(int set_i) : i(set_i) {}
+
+ using value_type = int;
+ using propagate_on_container_swap = std::integral_constant<bool, Propagate>;
+
+ friend void swap(Alloc& a1, Alloc& a2) TEST_NOEXCEPT_COND(Noexcept) {
+ std::swap(a1.i, a2.i);
+ }
+
+};
+
+using PropagatingAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/true>;
+static_assert(std::allocator_traits<PropagatingAlloc>::propagate_on_container_swap::value, "");
+
+using NonPropagatingAlloc = Alloc</*Propagate=*/false, /*Noexcept=*/true>;
+static_assert(!std::allocator_traits<NonPropagatingAlloc>::propagate_on_container_swap::value, "");
+
+using NoexceptSwapAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/true>;
+using ThrowingSwapAlloc = Alloc</*Propagate=*/true, /*Noexcept=*/false>;
+
+int main(int, char**) {
+ {
+ PropagatingAlloc a1(1), a2(42);
+ std::__swap_allocator(a1, a2);
+ assert(a1.i == 42);
+ assert(a2.i == 1);
+ }
+
+ {
+ NonPropagatingAlloc a1(1), a2(42);
+ std::__swap_allocator(a1, a2);
+ assert(a1.i == 1);
+ assert(a2.i == 42);
+ }
+
+#if TEST_STD_VER >= 11
+ {
+ NoexceptSwapAlloc noexcept_alloc;
+ static_assert(noexcept(std::__swap_allocator(noexcept_alloc, noexcept_alloc)), "");
+ }
+
+#if TEST_STD_VER > 11
+ { // From C++14, `__swap_allocator` is unconditionally noexcept.
+ ThrowingSwapAlloc throwing_alloc;
+ static_assert(noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), "");
+ }
+#else
+ { // Until C++14, `__swap_allocator` is only noexcept if the underlying `swap` function is `noexcept`.
+ ThrowingSwapAlloc throwing_alloc;
+ static_assert(!noexcept(std::__swap_allocator(throwing_alloc, throwing_alloc)), "");
+ }
+#endif // TEST_STD_VER > 11
+#endif // TEST_STD_VER >= 11
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/trivial_abi/shared_ptr_arg.pass.cpp b/libcxx/test/libcxx-03/memory/trivial_abi/shared_ptr_arg.pass.cpp
new file mode 100644
index 0000000000000..601c6c2d2cdc3
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/trivial_abi/shared_ptr_arg.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Test shared_ptr<T> with trivial_abi as parameter type.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
+
+// XFAIL: gcc
+// UNSUPPORTED: c++03
+
+#include <memory>
+#include <cassert>
+
+__attribute__((noinline)) void call_something() { asm volatile(""); }
+
+struct Node {
+ int* shared_val;
+
+ explicit Node(int* ptr) : shared_val(ptr) {}
+ ~Node() { ++(*shared_val); }
+};
+
+__attribute__((noinline)) bool get_val(std::shared_ptr<Node> /*unused*/) {
+ call_something();
+ return true;
+}
+
+__attribute__((noinline)) void expect_1(int* shared, bool /*unused*/) {
+ assert(*shared == 1);
+}
+
+int main(int, char**) {
+ int shared = 0;
+
+ // Without trivial-abi, the shared_ptr is deleted at the end of this
+ // statement; expect_1 will see shared == 0 because it's not incremented (in
+ // ~Node()) until expect_1 returns.
+ //
+ // With trivial-abi, expect_1 will see shared == 1 because shared_val is
+ // incremented before get_val returns.
+ expect_1(&shared, get_val(std::make_shared<Node>(&shared)));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_arg.pass.cpp b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_arg.pass.cpp
new file mode 100644
index 0000000000000..8a7367bf29749
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_arg.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Test unique_ptr<T> with trivial_abi as parameter type.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
+
+// XFAIL: gcc
+
+#include <memory>
+#include <cassert>
+
+__attribute__((noinline)) void call_something() { asm volatile(""); }
+
+struct Node {
+ int* shared_val;
+
+ explicit Node(int* ptr) : shared_val(ptr) {}
+ ~Node() { ++(*shared_val); }
+};
+
+__attribute__((noinline)) bool get_val(std::unique_ptr<Node> /*unused*/) {
+ call_something();
+ return true;
+}
+
+__attribute__((noinline)) void expect_1(int* shared, bool /*unused*/) {
+ assert(*shared == 1);
+}
+
+int main(int, char**) {
+ int shared = 0;
+
+ // Without trivial-abi, the unique_ptr is deleted at the end of this
+ // statement; expect_1 will see shared == 0 because it's not incremented (in
+ // ~Node()) until expect_1 returns.
+ //
+ // With trivial-abi, expect_1 will see shared == 1 because shared_val is
+ // incremented before get_val returns.
+ expect_1(&shared, get_val(std::unique_ptr<Node>(new Node(&shared))));
+
+ // Check that the shared-value is still 1.
+ expect_1(&shared, true);
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_array.pass.cpp b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_array.pass.cpp
new file mode 100644
index 0000000000000..e11dc071485a7
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_array.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Test unique_ptr<T[]> with trivial_abi as parameter type.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
+
+// XFAIL: gcc
+// UNSUPPORTED: c++03
+
+#include <memory>
+#include <cassert>
+
+__attribute__((noinline)) void call_something() { asm volatile(""); }
+
+struct Node {
+ int* shared_val;
+
+ explicit Node(int* ptr) : shared_val(ptr) {}
+ Node(const Node&) = default;
+ Node& operator=(const Node&) = default;
+ ~Node() { ++(*shared_val); }
+};
+
+__attribute__((noinline)) bool get_val(std::unique_ptr<Node[]> /*unused*/) {
+ call_something();
+ return true;
+}
+
+__attribute__((noinline)) void expect_3(int* shared, bool /*unused*/) {
+ assert(*shared == 3);
+}
+
+int main(int, char**) {
+ int shared = 0;
+
+ // Without trivial-abi, the unique_ptr is deleted at the end of this
+ // statement, expect_3 will see shared == 0 because it's not incremented (in
+ // ~Node()) until the end of this statement.
+ //
+ // With trivial-abi, shared_val is incremented 3 times before get_val returns
+ // because ~Node() was called 3 times.
+ expect_3(&shared, get_val(std::unique_ptr<Node[]>(new Node[3]{
+ Node(&shared), Node(&shared), Node(&shared)})));
+
+ // Check that shared_value is still 3 (ie., ~Node() isn't called again by the end of the full-expression above)
+ expect_3(&shared, true);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_destruction_order.pass.cpp b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_destruction_order.pass.cpp
new file mode 100644
index 0000000000000..8752ba5a01d6e
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_destruction_order.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Test arguments destruction order involving unique_ptr<T> with trivial_abi.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
+
+// XFAIL: gcc
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+__attribute__((noinline)) void call_something() { asm volatile(""); }
+
+struct Base {
+ char* shared_buff;
+ int* cur_idx;
+ const char id;
+
+ explicit Base(char* buf, int* idx, char ch)
+ : shared_buff(buf), cur_idx(idx), id(ch) {}
+ Base(const Base& other) = default;
+ Base& operator=(const Base&) = delete;
+ ~Base() { shared_buff[(*cur_idx)++] = id; }
+};
+
+struct A : Base {
+ explicit A(char* buf, int* idx) : Base(buf, idx, 'A') {}
+};
+
+struct B : Base {
+ explicit B(char* buf, int* idx) : Base(buf, idx, 'B') {}
+};
+
+struct C : Base {
+ explicit C(char* buf, int* idx) : Base(buf, idx, 'C') {}
+};
+
+__attribute__((noinline)) void func(A /*unused*/, std::unique_ptr<B> /*unused*/,
+ C /*unused*/) {
+ call_something();
+}
+
+int main(int, char**) {
+ char shared_buf[3] = {'0', '0', '0'};
+ int cur_idx = 0;
+
+ func(A(shared_buf, &cur_idx), std::unique_ptr<B>(new B(shared_buf, &cur_idx)),
+ C(shared_buf, &cur_idx));
+
+#if defined(TEST_ABI_MICROSOFT)
+ // On Microsoft ABI, the dtor order is always A,B,C (because callee-destroyed)
+ assert(shared_buf[0] == 'A' && shared_buf[1] == 'B' && shared_buf[2] == 'C');
+#else
+ // With trivial_abi, the std::unique_ptr<B> arg is always destructed first.
+ assert(shared_buf[0] == 'B');
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_ret.pass.cpp b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_ret.pass.cpp
new file mode 100644
index 0000000000000..65e9069e07a15
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/trivial_abi/unique_ptr_ret.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Test unique_ptr<T> with trivial_abi as return-type.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI
+
+// XFAIL: gcc
+
+#include <memory>
+#include <cassert>
+
+__attribute__((noinline)) void call_something() { asm volatile(""); }
+
+struct Node {
+ explicit Node() {}
+ Node(const Node&) = default;
+ Node& operator=(const Node&) = default;
+ ~Node() {}
+};
+
+__attribute__((noinline)) std::unique_ptr<Node> make_val(void** local_addr) {
+ call_something();
+
+ auto ret = std::unique_ptr<Node>(new Node);
+
+ // Capture the local address of ret.
+ *local_addr = &ret;
+
+ return ret;
+}
+
+int main(int, char**) {
+ void* local_addr = nullptr;
+ auto ret = make_val(&local_addr);
+ assert(local_addr != nullptr);
+
+ // Without trivial_abi, &ret == local_addr because the return value
+ // is allocated here in main's stackframe.
+ //
+ // With trivial_abi, local_addr is the address of a local variable in
+ // make_val, and hence different from &ret.
+#if !defined(__i386__) && !defined(_WIN32) && !defined(_AIX)
+ // On X86, structs are never returned in registers.
+ // On AIX, structs are never returned in registers.
+ // Thus, unique_ptr will be passed indirectly even if it is trivial.
+ // On Windows, structs with a destructor are always returned indirectly.
+ assert((void*)&ret != local_addr);
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/trivial_abi/weak_ptr_ret.pass.cpp b/libcxx/test/libcxx-03/memory/trivial_abi/weak_ptr_ret.pass.cpp
new file mode 100644
index 0000000000000..0b1a434ee45b5
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/trivial_abi/weak_ptr_ret.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Test weak_ptr<T> with trivial_abi as return-type.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI
+
+// XFAIL: gcc
+
+#include <memory>
+#include <cassert>
+
+__attribute__((noinline)) void call_something() { asm volatile(""); }
+
+struct Node {
+ explicit Node() {}
+ Node(const Node&) = default;
+ Node& operator=(const Node&) = default;
+ ~Node() {}
+};
+
+__attribute__((noinline)) std::weak_ptr<Node>
+make_val(std::shared_ptr<Node>& sptr, void** local_addr) {
+ call_something();
+
+ std::weak_ptr<Node> ret;
+ ret = sptr;
+
+ // Capture the local address of ret.
+ *local_addr = &ret;
+
+ return ret;
+}
+
+int main(int, char**) {
+ void* local_addr = nullptr;
+ auto sptr = std::make_shared<Node>();
+ std::weak_ptr<Node> ret = make_val(sptr, &local_addr);
+ assert(local_addr != nullptr);
+
+ // Without trivial_abi, &ret == local_addr because the return value
+ // is allocated here in main's stackframe.
+ //
+ // With trivial_abi, local_addr is the address of a local variable in
+ // make_val, and hence different from &ret.
+#if !defined(__i386__) && !defined(__arm__) && !defined(_WIN32) && !defined(_AIX)
+ // On X86, structs are never returned in registers.
+ // On AIX, structs are never returned in registers.
+ // On ARM32, structs larger than 4 bytes cannot be returned in registers.
+ // On Windows, structs with a destructor are always returned indirectly.
+ // Thus, weak_ptr will be passed indirectly even if it is trivial.
+ assert((void*)&ret != local_addr);
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/memory/uninitialized_allocator_copy.pass.cpp b/libcxx/test/libcxx-03/memory/uninitialized_allocator_copy.pass.cpp
new file mode 100644
index 0000000000000..679ee86844687
--- /dev/null
+++ b/libcxx/test/libcxx-03/memory/uninitialized_allocator_copy.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-exceptions
+
+// ensure that __uninitialized_allocator_copy calls the proper construct and destruct functions
+
+#include <algorithm>
+#include <iterator>
+#include <memory>
+
+#include "test_allocator.h"
+
+template <class T>
+class construct_counting_allocator {
+public:
+ using value_type = T;
+
+ int* constructed_count_;
+ int* max_constructed_count_;
+
+ construct_counting_allocator(int* constructed_count, int* max_constructed_count)
+ : constructed_count_(constructed_count), max_constructed_count_(max_constructed_count) {}
+
+ template <class... Args>
+ void construct(T* ptr, Args&&... args) {
+ ::new (static_cast<void*>(ptr)) T(args...);
+ ++*constructed_count_;
+ *max_constructed_count_ = std::max(*max_constructed_count_, *constructed_count_);
+ }
+
+ void destroy(T* ptr) {
+ --*constructed_count_;
+ ptr->~T();
+ }
+};
+
+int throw_if_zero = 15;
+
+struct ThrowSometimes {
+ ThrowSometimes() = default;
+ ThrowSometimes(const ThrowSometimes&) {
+ if (--throw_if_zero == 0)
+ throw 1;
+ }
+};
+
+int main(int, char**) {
+ int constructed_count = 0;
+ int max_constructed_count = 0;
+ construct_counting_allocator<ThrowSometimes> alloc(&constructed_count, &max_constructed_count);
+ ThrowSometimes in[20];
+ TEST_ALIGNAS_TYPE(ThrowSometimes) char out[sizeof(ThrowSometimes) * 20];
+ try {
+ std::__uninitialized_allocator_copy(
+ alloc, std::begin(in), std::end(in), reinterpret_cast<ThrowSometimes*>(std::begin(out)));
+ } catch (...) {
+ }
+
+ assert(constructed_count == 0);
+ assert(max_constructed_count == 14);
+}
diff --git a/libcxx/test/libcxx-03/minimal_cxx11_configuration.pass.cpp b/libcxx/test/libcxx-03/minimal_cxx11_configuration.pass.cpp
new file mode 100644
index 0000000000000..e0811e02f5c13
--- /dev/null
+++ b/libcxx/test/libcxx-03/minimal_cxx11_configuration.pass.cpp
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test the set of C++11 features that Clang provides as an extension in C++03 mode.
+// The language features we expect are:
+//
+// 1. rvalue references (and perfect forwarding)
+// 2. variadic templates
+// 3. alias templates
+// 4. defaulted and deleted functions.
+// 5. default values for non-type template parameters.
+//
+// Some features we don't get and can't be used in extended C++03 mode:
+//
+// 1. noexcept and constexpr
+// 2. Two closing '>' without a space.
+
+#include <type_traits>
+#include <cassert>
+
+// Equals delete and default are allowed in minimal C++03 mode.
+namespace test_eq_delete_and_default {
+void t1() = delete;
+struct T2 {
+ T2() = default;
+ T2(T2 const&) = delete;
+};
+}
+
+namespace alias_templates {
+template <class T>
+using X = T;
+static_assert((std::is_same<X<int>, int>::value), "");
+}
+
+namespace variadics_templates {
+template <class ...Args>
+int t1(Args...) {
+ return sizeof...(Args);
+}
+void test() {
+ assert(t1() == 0);
+ assert(t1(42) == 1);
+ assert(t1(1, 2, 3) == 3);
+}
+}
+
+namespace rvalue_references_move_semantics {
+struct T {
+ T() : moved(0) {}
+ T(T const& other) : moved(other.moved) {}
+ T(T&& other) : moved(other.moved) { ++moved; other.moved = -1; }
+ int moved;
+};
+void f(T o, int expect_moved) { assert(o.moved == expect_moved); }
+void test() {
+ {
+ T t;
+ assert(t.moved == 0);
+ T t2(static_cast<T&&>(t));
+ assert(t2.moved == 1);
+ assert(t.moved == -1);
+ }
+ {
+ T t;
+ f(t, 0);
+ f(static_cast<T&&>(t), 1);
+ }
+}
+}
+
+namespace rvalue_references_perfect_forwarding {
+template <class Expect, class T>
+void f(T&&) {
+ static_assert((std::is_same<Expect, T&&>::value), "");
+}
+void test() {
+ int x = 42;
+ f<int&>(x);
+ f<int&&>(42);
+ f<int&&>(static_cast<int&&>(x));
+}
+}
+
+namespace default_values_for_nttp {
+template <int I = 42>
+void f() { assert(I == 42); }
+void test() {
+ f();
+}
+}
+
+namespace reference_qualified_functions {
+struct T {
+ T() : lvalue_called(0), rvalue_called(0) {}
+ void foo() const & { lvalue_called++; }
+ void foo() && { rvalue_called++; }
+ mutable int lvalue_called;
+ int rvalue_called;
+};
+
+void test() {
+ {
+ T t;
+ t.foo();
+ assert(t.lvalue_called == 1);
+ assert(t.rvalue_called == 0);
+ }
+ {
+ T t;
+ static_cast<T&&>(t).foo();
+ assert(t.lvalue_called == 0);
+ assert(t.rvalue_called == 1);
+ }
+}
+}
+
+int main(int, char**) {
+ variadics_templates::test();
+ rvalue_references_move_semantics::test();
+ rvalue_references_perfect_forwarding::test();
+ default_values_for_nttp::test();
+ reference_qualified_functions::test();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/module_std.gen.py b/libcxx/test/libcxx-03/module_std.gen.py
new file mode 100644
index 0000000000000..fc23985caf30d
--- /dev/null
+++ b/libcxx/test/libcxx-03/module_std.gen.py
@@ -0,0 +1,38 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that all named declarations with external linkage match the
+# exported declarations in their associated module partition.
+# Then it tests the sum of the exported declarations in the module
+# partitions matches the export of the std module.
+
+# Note the test of the std module requires all partitions to be tested
+# first. Since lit tests have no dependencies, this means the test needs
+# to be one monolitic test. Since the test doesn't take very long it's
+# not a huge issue.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+import sys
+
+sys.path.append(sys.argv[1])
+from libcxx.test.modules import module_test_generator
+
+generator = module_test_generator(
+ "%t",
+ "%{module-dir}",
+ "%{clang-tidy}",
+ "%{test-tools-dir}/clang_tidy_checks/libcxx-tidy.plugin",
+ "%{cxx}",
+ "%{flags} %{compile_flags}",
+ "std",
+)
+
+
+print("//--- module_std.sh.cpp")
+generator.write_test("std")
diff --git a/libcxx/test/libcxx-03/module_std_compat.gen.py b/libcxx/test/libcxx-03/module_std_compat.gen.py
new file mode 100644
index 0000000000000..000aa29986122
--- /dev/null
+++ b/libcxx/test/libcxx-03/module_std_compat.gen.py
@@ -0,0 +1,42 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that all named declarations with external linkage match the
+# exported declarations in their associated module partition.
+# Then it tests the sum of the exported declarations in the module
+# partitions matches the export of the std.compat module.
+
+# Note the test of the std.compat module requires all partitions to be tested
+# first. Since lit tests have no dependencies, this means the test needs
+# to be one monolitic test. Since the test doesn't take very long it's
+# not a huge issue.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+import sys
+
+sys.path.append(sys.argv[1])
+from libcxx.header_information import module_c_headers
+from libcxx.test.modules import module_test_generator
+
+generator = module_test_generator(
+ "%t",
+ "%{module-dir}",
+ "%{clang-tidy}",
+ "%{test-tools-dir}/clang_tidy_checks/libcxx-tidy.plugin",
+ "%{cxx}",
+ "%{flags} %{compile_flags}",
+ "std.compat",
+)
+
+
+print("//--- module_std_compat.sh.cpp")
+generator.write_test(
+ "std.compat",
+ module_c_headers,
+)
diff --git a/libcxx/test/libcxx-03/no_assert_include.gen.py b/libcxx/test/libcxx-03/no_assert_include.gen.py
new file mode 100644
index 0000000000000..e0dbc3d815f31
--- /dev/null
+++ b/libcxx/test/libcxx-03/no_assert_include.gen.py
@@ -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
+#
+# ===----------------------------------------------------------------------===##
+
+# Ensure that none of the standard C++ headers implicitly include cassert or
+# assert.h (because assert() is implemented as a macro).
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+import sys
+
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+ lit_header_restrictions,
+ lit_header_undeprecations,
+ public_headers,
+)
+
+for header in public_headers:
+ if header == "cassert":
+ continue
+
+ print(
+ f"""\
+//--- {header}.compile.pass.cpp
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+#include <{header}>
+
+#ifdef assert
+# error "Do not include cassert or assert.h in standard header files"
+#endif
+"""
+ )
diff --git a/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp b/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp
new file mode 100644
index 0000000000000..1bf9d3890f45f
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/bit.ops.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test the __XXXX routines in the <bit> header.
+// These are not supposed to be exhaustive tests, just sanity checks.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__bit/bit_log2.h>
+#include <__bit/countl.h>
+#include <__bit/rotate.h>
+#include <cassert>
+
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX14 bool test() {
+ const unsigned v = 0x12345678;
+
+ ASSERT_SAME_TYPE(unsigned, decltype(std::__rotr(v, 3)));
+ ASSERT_SAME_TYPE(int, decltype(std::__countl_zero(v)));
+
+ assert(std::__rotr(v, 3) == 0x02468acfU);
+ assert(std::__countl_zero(v) == 3);
+
+#if TEST_STD_VER > 17
+ ASSERT_SAME_TYPE(unsigned, decltype(std::__bit_log2(v)));
+ assert(std::__bit_log2(v) == 28);
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER > 11
+ static_assert(test(), "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-clang.pass.cpp b/libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-clang.pass.cpp
new file mode 100644
index 0000000000000..3f17f21e8c108
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-clang.pass.cpp
@@ -0,0 +1,266 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 Clang supports constexpr <cmath> and <cstdlib> functions
+// mentioned in the P0533R9 paper that is part of C++23
+// (https://wg21.link/p0533r9)
+//
+// Every function called in this test should become constexpr. Whenever some
+// of the desired function become constexpr, the programmer switches
+// `ASSERT_NOT_CONSTEXPR_CXX23` to `ASSERT_CONSTEXPR_CXX23` and eventually the
+// paper is implemented in Clang.
+// The test also works as a reference list of unimplemented functions.
+//
+// REQUIRES: clang
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// We don't control the implementation of these functions on windows
+// UNSUPPORTED: windows
+
+#include <cmath>
+#include <cstdlib>
+#include <cassert>
+
+int main(int, char**) {
+ bool ImplementedP0533R9 = true;
+
+#define ASSERT_CONSTEXPR_CXX23(Expr) static_assert(__builtin_constant_p(Expr) && (Expr))
+#define ASSERT_NOT_CONSTEXPR_CXX23(Expr) \
+ static_assert(!__builtin_constant_p(Expr)); \
+ assert(Expr); \
+ ImplementedP0533R9 = false
+
+ int DummyInt;
+ float DummyFloat;
+ double DummyDouble;
+ long double DummyLongDouble;
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::labs(-1L) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llabs(-1LL) == 1LL);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::div(13, 5).rem == 3);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::div(13L, 5L).rem == 3L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::div(13LL, 5LL).rem == 3LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldiv(13L, 5L).rem == 3L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lldiv(13LL, 5LL).rem == 3LL);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexp(0.0f, &DummyInt) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexp(0.0, &DummyInt) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexp(0.0L, &DummyInt) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexpf(0.0f, &DummyInt) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexpl(0.0L, &DummyInt) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ilogb(1.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ilogb(1.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ilogb(1.0L) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ilogbf(1.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ilogbl(1.0L) == 0);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldexp(1.0f, 1) == 2.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldexp(1.0, 1) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldexp(1.0L, 1) == 2.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldexpf(1.0f, 1) == 2.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldexpl(1.0L, 1) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::logb(1.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::logb(1.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::logb(1.0L) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::logbf(1.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::logbl(1.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modf(1.0f, &DummyFloat) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modf(1.0, &DummyDouble) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modf(1.0L, &DummyLongDouble) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modff(1.0f, &DummyFloat) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modfl(1.0L, &DummyLongDouble) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbn(1.0f, 1) == 2.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbn(1.0, 1) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbn(1.0L, 1) == 2.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbnf(1.0f, 1) == 2.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbnl(1.0L, 1) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbln(1.0f, 1L) == 2);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbln(1.0, 1L) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbln(1.0L, 1L) == 2.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalblnf(1.0f, 1L) == 2.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalblnl(1.0L, 1L) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fabs(-1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fabs(-1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fabs(-1.0L) == 1.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fabsf(-1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fabsl(-1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ceil(0.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ceil(0.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ceil(0.0L) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ceilf(0.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ceill(0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::floor(1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::floor(1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::floor(1.0L) == 1.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::floorf(1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::floorl(1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::round(1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::round(1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::round(1.0L) == 1.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::roundf(1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::roundl(1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lround(1.0f) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lround(1.0) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lround(1.0L) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lroundf(1.0f) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lroundl(1.0L) == 1L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llround(1.0f) == 1LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llround(1.0) == 1LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llround(1.0L) == 1LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llroundf(1.0f) == 1LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llroundl(1.0L) == 1LL);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::trunc(1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::trunc(1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::trunc(1.0L) == 1.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::truncf(1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::truncl(1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmod(1.5f, 1.0f) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmod(1.5, 1.0) == 0.5);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmod(1.5L, 1.0L) == 0.5L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmodf(1.5f, 1.0f) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmodl(1.5L, 1.0L) == 0.5L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remainder(0.5f, 1.0f) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remainder(0.5, 1.0) == 0.5);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remainder(0.5L, 1.0L) == 0.5L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remainderf(0.5f, 1.0f) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remainderl(0.5L, 1.0L) == 0.5L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquo(0.5f, 1.0f, &DummyInt) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquo(0.5, 1.0, &DummyInt) == 0.5);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquo(0.5L, 1.0L, &DummyInt) == 0.5L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquof(0.5f, 1.0f, &DummyInt) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquol(0.5L, 1.0L, &DummyInt) == 0.5L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::copysign(1.0f, 1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::copysign(1.0, 1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::copysign(1.0L, 1.0L) == 1.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::copysignf(1.0f, 1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::copysignl(1.0L, 1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nextafter(0.0f, 0.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nextafter(0.0, 0.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nextafter(0.0L, 0.0L) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nextafterf(0.0f, 0.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nextafterl(0.0L, 0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nexttoward(0.0f, 0.0L) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nexttoward(0.0, 0.0L) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nexttoward(0.0L, 0.0L) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nexttowardf(0.0f, 0.0L) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nexttowardl(0.0L, 0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fdim(1.0f, 0.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fdim(1.0, 0.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fdim(1.0L, 0.0L) == 1.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fdimf(1.0f, 0.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fdiml(1.0L, 0.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmax(1.0f, 0.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmax(1.0, 0.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmax(1.0L, 0.0L) == 1.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmaxf(1.0f, 0.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmaxl(1.0L, 0.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmin(1.0f, 0.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmin(1.0, 0.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmin(1.0L, 0.0L) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fminf(1.0f, 0.0f) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fminl(1.0L, 0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0f, 1.0f, 1.0f) == 2.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0, 1.0, 1.0) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0L, 1.0L, 1.0L) == 2.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmaf(1.0f, 1.0f, 1.0f) == 2.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmal(1.0L, 1.0L, 1.0L) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0f) == FP_NORMAL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0) == FP_NORMAL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0L) == FP_NORMAL);
+
+ ASSERT_CONSTEXPR_CXX23(std::isfinite(-1.0f) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isfinite(-1.0) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isfinite(-1.0L) == 1);
+
+ ASSERT_CONSTEXPR_CXX23(std::isinf(-1.0f) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isinf(-1.0) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isinf(-1.0L) == 0);
+
+ ASSERT_CONSTEXPR_CXX23(std::isnan(-1.0f) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isnan(-1.0) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isnan(-1.0L) == 0);
+
+ ASSERT_CONSTEXPR_CXX23(std::isnormal(-1.0f) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isnormal(-1.0) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isnormal(-1.0L) == 1);
+
+// TODO(LLVM 22): Remove `__has_constexpr_builtin` conditional once support for Clang 19 is dropped.
+#if !__has_constexpr_builtin(__builtin_signbit)
+ ASSERT_NOT_CONSTEXPR_CXX23(std::signbit(-1.0f) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::signbit(-1.0) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::signbit(-1.0L) == 1);
+#else
+ ASSERT_CONSTEXPR_CXX23(std::signbit(-1.0f) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::signbit(-1.0) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::signbit(-1.0L) == 1);
+#endif
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreater(-1.0f, 0.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreater(-1.0, 0.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreater(-1.0L, 0.0L) == 0);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreaterequal(-1.0f, 0.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreaterequal(-1.0, 0.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreaterequal(-1.0L, 0.0L) == 0);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isless(-1.0f, 0.0f) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isless(-1.0, 0.0) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isless(-1.0L, 0.0L) == 1);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessequal(-1.0f, 0.0f) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessequal(-1.0, 0.0) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessequal(-1.0L, 0.0L) == 1);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessgreater(-1.0f, 0.0f) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessgreater(-1.0, 0.0) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessgreater(-1.0L, 0.0L) == 1);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isunordered(-1.0f, 0.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isunordered(-1.0, 0.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isunordered(-1.0L, 0.0L) == 0);
+
+ assert(!ImplementedP0533R9 && R"(
+Congratulations! You just have implemented P0533R9 (https://wg21.link/p0533r9).
+Please go to `clang/www/cxx_status.html` and change the paper's implementation
+status. Also please delete this assert and refactor `ASSERT_CONSTEXPR_CXX23`
+and `ASSERT_NOT_CONSTEXPR_CXX23`.
+)");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-gcc.pass.cpp b/libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-gcc.pass.cpp
new file mode 100644
index 0000000000000..d8779706bcee2
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/c.math/constexpr-cxx23-gcc.pass.cpp
@@ -0,0 +1,256 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 GCC supports constexpr <cmath> and <cstdlib> functions
+// mentioned in the P0533R9 paper that is part of C++23
+// (https://wg21.link/p0533r9)
+//
+// Every function called in this test should become constexpr. Whenever some
+// of the desired function become constexpr, the programmer switches
+// `ASSERT_NOT_CONSTEXPR_CXX23` to `ASSERT_CONSTEXPR_CXX23` and eventually the
+// paper is implemented in Clang.
+// The test also works as a reference list of unimplemented functions.
+//
+// REQUIRES: gcc
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include <cmath>
+#include <cstdlib>
+#include <cassert>
+
+int main(int, char**) {
+ bool ImplementedP0533R9 = true;
+
+#define ASSERT_CONSTEXPR_CXX23(Expr) static_assert(__builtin_constant_p(Expr) && (Expr))
+#define ASSERT_NOT_CONSTEXPR_CXX23(Expr) \
+ static_assert(!__builtin_constant_p(Expr)); \
+ assert(Expr); \
+ ImplementedP0533R9 = false
+
+ int DummyInt;
+ float DummyFloat;
+ double DummyDouble;
+ long double DummyLongDouble;
+
+ ASSERT_CONSTEXPR_CXX23(std::abs(-1) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1L) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1LL) == 1LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0f) == 1.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::abs(-1.0L) == 1.0L);
+
+ ASSERT_CONSTEXPR_CXX23(std::labs(-1L) == 1L);
+ ASSERT_CONSTEXPR_CXX23(std::llabs(-1LL) == 1LL);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::div(13, 5).rem == 3);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::div(13L, 5L).rem == 3L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::div(13LL, 5LL).rem == 3LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldiv(13L, 5L).rem == 3L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lldiv(13LL, 5LL).rem == 3LL);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexp(0.0f, &DummyInt) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexp(0.0, &DummyInt) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexp(0.0L, &DummyInt) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexpf(0.0f, &DummyInt) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::frexpl(0.0L, &DummyInt) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ilogb(1.0f) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::ilogb(1.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ilogb(1.0L) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::ilogbf(1.0f) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::ilogbl(1.0L) == 0);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldexp(1.0f, 1) == 2.0f);
+ ASSERT_CONSTEXPR_CXX23(std::ldexp(1.0, 1) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ldexp(1.0L, 1) == 2.0L);
+ ASSERT_CONSTEXPR_CXX23(std::ldexpf(1.0f, 1) == 2.0f);
+ ASSERT_CONSTEXPR_CXX23(std::ldexpl(1.0L, 1) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::logb(1.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::logb(1.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::logb(1.0L) == 0.0L);
+ ASSERT_CONSTEXPR_CXX23(std::logbf(1.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::logbl(1.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modf(1.0f, &DummyFloat) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modf(1.0, &DummyDouble) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modf(1.0L, &DummyLongDouble) == 0.0L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modff(1.0f, &DummyFloat) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::modfl(1.0L, &DummyLongDouble) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbn(1.0f, 1) == 2.0f);
+ ASSERT_CONSTEXPR_CXX23(std::scalbn(1.0, 1) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbn(1.0L, 1) == 2.0L);
+ ASSERT_CONSTEXPR_CXX23(std::scalbnf(1.0f, 1) == 2.0f);
+ ASSERT_CONSTEXPR_CXX23(std::scalbnl(1.0L, 1) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbln(1.0f, 1L) == 2);
+ ASSERT_CONSTEXPR_CXX23(std::scalbln(1.0, 1L) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::scalbln(1.0L, 1L) == 2.0L);
+ ASSERT_CONSTEXPR_CXX23(std::scalblnf(1.0f, 1L) == 2.0f);
+ ASSERT_CONSTEXPR_CXX23(std::scalblnl(1.0L, 1L) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fabs(-1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fabs(-1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fabs(-1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::fabsf(-1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fabsl(-1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ceil(0.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::ceil(0.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::ceil(0.0L) == 0.0L);
+ ASSERT_CONSTEXPR_CXX23(std::ceilf(0.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::ceill(0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::floor(1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::floor(1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::floor(1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::floorf(1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::floorl(1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::round(1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::round(1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::round(1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::roundf(1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::roundl(1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lround(1.0f) == 1L);
+ ASSERT_CONSTEXPR_CXX23(std::lround(1.0) == 1L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::lround(1.0L) == 1L);
+ ASSERT_CONSTEXPR_CXX23(std::lroundf(1.0f) == 1L);
+ ASSERT_CONSTEXPR_CXX23(std::lroundl(1.0L) == 1L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llround(1.0f) == 1LL);
+ ASSERT_CONSTEXPR_CXX23(std::llround(1.0) == 1LL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::llround(1.0L) == 1LL);
+ ASSERT_CONSTEXPR_CXX23(std::llroundf(1.0f) == 1LL);
+ ASSERT_CONSTEXPR_CXX23(std::llroundl(1.0L) == 1LL);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::trunc(1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::trunc(1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::trunc(1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::truncf(1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::truncl(1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmod(1.5f, 1.0f) == 0.5f);
+ ASSERT_CONSTEXPR_CXX23(std::fmod(1.5, 1.0) == 0.5);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmod(1.5L, 1.0L) == 0.5L);
+ ASSERT_CONSTEXPR_CXX23(std::fmodf(1.5f, 1.0f) == 0.5f);
+ ASSERT_CONSTEXPR_CXX23(std::fmodl(1.5L, 1.0L) == 0.5L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remainder(0.5f, 1.0f) == 0.5f);
+ ASSERT_CONSTEXPR_CXX23(std::remainder(0.5, 1.0) == 0.5);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remainder(0.5L, 1.0L) == 0.5L);
+ ASSERT_CONSTEXPR_CXX23(std::remainderf(0.5f, 1.0f) == 0.5f);
+ ASSERT_CONSTEXPR_CXX23(std::remainderl(0.5L, 1.0L) == 0.5L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquo(0.5f, 1.0f, &DummyInt) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquo(0.5, 1.0, &DummyInt) == 0.5);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquo(0.5L, 1.0L, &DummyInt) == 0.5L);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquof(0.5f, 1.0f, &DummyInt) == 0.5f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::remquol(0.5L, 1.0L, &DummyInt) == 0.5L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::copysign(1.0f, 1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::copysign(1.0, 1.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::copysign(1.0L, 1.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::copysignf(1.0f, 1.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::copysignl(1.0L, 1.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nextafter(0.0f, 0.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::nextafter(0.0, 0.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nextafter(0.0L, 0.0L) == 0.0L);
+ ASSERT_CONSTEXPR_CXX23(std::nextafterf(0.0f, 0.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::nextafterl(0.0L, 0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nexttoward(0.0f, 0.0L) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::nexttoward(0.0, 0.0L) == 0.0f);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::nexttoward(0.0L, 0.0L) == 0.0L);
+ ASSERT_CONSTEXPR_CXX23(std::nexttowardf(0.0f, 0.0L) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::nexttowardl(0.0L, 0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fdim(1.0f, 0.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fdim(1.0, 0.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fdim(1.0L, 0.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::fdimf(1.0f, 0.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fdiml(1.0L, 0.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmax(1.0f, 0.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fmax(1.0, 0.0) == 1.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmax(1.0L, 0.0L) == 1.0L);
+ ASSERT_CONSTEXPR_CXX23(std::fmaxf(1.0f, 0.0f) == 1.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fmaxl(1.0L, 0.0L) == 1.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmin(1.0f, 0.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fmin(1.0, 0.0) == 0.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fmin(1.0L, 0.0L) == 0.0L);
+ ASSERT_CONSTEXPR_CXX23(std::fminf(1.0f, 0.0f) == 0.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fminl(1.0L, 0.0L) == 0.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0f, 1.0f, 1.0f) == 2.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fma(1.0, 1.0, 1.0) == 2.0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fma(1.0L, 1.0L, 1.0L) == 2.0L);
+ ASSERT_CONSTEXPR_CXX23(std::fmaf(1.0f, 1.0f, 1.0f) == 2.0f);
+ ASSERT_CONSTEXPR_CXX23(std::fmal(1.0L, 1.0L, 1.0L) == 2.0L);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0f) == FP_NORMAL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0) == FP_NORMAL);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::fpclassify(-1.0L) == FP_NORMAL);
+
+ ASSERT_CONSTEXPR_CXX23(std::isfinite(-1.0f) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isfinite(-1.0) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isfinite(-1.0L) == 1);
+
+ ASSERT_CONSTEXPR_CXX23(std::isinf(-1.0f) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isinf(-1.0) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isinf(-1.0L) == 0);
+
+ ASSERT_CONSTEXPR_CXX23(std::isnan(-1.0f) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isnan(-1.0) == 0);
+ ASSERT_CONSTEXPR_CXX23(std::isnan(-1.0L) == 0);
+
+ ASSERT_CONSTEXPR_CXX23(std::isnormal(-1.0f) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isnormal(-1.0) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::isnormal(-1.0L) == 1);
+
+ ASSERT_CONSTEXPR_CXX23(std::signbit(-1.0f) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::signbit(-1.0) == 1);
+ ASSERT_CONSTEXPR_CXX23(std::signbit(-1.0L) == 1);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreater(-1.0f, 0.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreater(-1.0, 0.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreater(-1.0L, 0.0L) == 0);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreaterequal(-1.0f, 0.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreaterequal(-1.0, 0.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isgreaterequal(-1.0L, 0.0L) == 0);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isless(-1.0f, 0.0f) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isless(-1.0, 0.0) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isless(-1.0L, 0.0L) == 1);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessequal(-1.0f, 0.0f) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessequal(-1.0, 0.0) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessequal(-1.0L, 0.0L) == 1);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessgreater(-1.0f, 0.0f) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessgreater(-1.0, 0.0) == 1);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::islessgreater(-1.0L, 0.0L) == 1);
+
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isunordered(-1.0f, 0.0f) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isunordered(-1.0, 0.0) == 0);
+ ASSERT_NOT_CONSTEXPR_CXX23(std::isunordered(-1.0L, 0.0L) == 0);
+
+ assert(!ImplementedP0533R9 && R"(
+Congratulations! You just have implemented P0533R9 (https://wg21.link/p0533r9).
+Please go to `clang/www/cxx_status.html` and change the paper's implementation
+status. Also please delete this assert and refactor `ASSERT_CONSTEXPR_CXX23`
+and `ASSERT_NOT_CONSTEXPR_CXX23`.
+)");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/c.math/constexpr-fns.pass.cpp b/libcxx/test/libcxx-03/numerics/c.math/constexpr-fns.pass.cpp
new file mode 100644
index 0000000000000..ff36293830c5d
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/c.math/constexpr-fns.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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that the overloads of std::__libcpp_{isnan,isinf,isfinite} that take
+// floating-point values are evaluatable from constexpr contexts.
+//
+// These functions need to be constexpr in order to be called from CUDA, see
+// https://reviews.llvm.org/D25403. They don't actually need to be
+// constexpr-evaluatable, but that's what we check here, since we can't check
+// true constexpr-ness.
+//
+// UNSUPPORTED: c++03
+
+#include <cmath>
+
+#include "test_macros.h"
+
+static_assert(std::__constexpr_isinf(0.0) == false, "");
+
+int main(int, char**)
+{
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/c.math/fdelayed-template-parsing.pass.cpp b/libcxx/test/libcxx-03/numerics/c.math/fdelayed-template-parsing.pass.cpp
new file mode 100644
index 0000000000000..a366e8ea40d6b
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/c.math/fdelayed-template-parsing.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that cmath builds with -fdelayed-template-parsing.
+// This is a regression test for an issue introduced in ae22f0b24231,
+// where Clang's limited support for -fdelayed-template-parsing would
+// choke on <cmath>.
+
+// REQUIRES: fdelayed-template-parsing
+// ADDITIONAL_COMPILE_FLAGS: -fdelayed-template-parsing
+
+#include <cmath>
+#include <cassert>
+
+int main(int, char**) {
+ assert(std::isfinite(1.0));
+ assert(!std::isinf(1.0));
+ assert(!std::isnan(1.0));
+
+ return 0;
+}
+
+using namespace std; // on purpose
diff --git a/libcxx/test/libcxx-03/numerics/clamp_to_integral.pass.cpp b/libcxx/test/libcxx-03/numerics/clamp_to_integral.pass.cpp
new file mode 100644
index 0000000000000..68d55afa1f280
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/clamp_to_integral.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// __clamp_to_integral<IntT>(RealT)
+
+// Test the conversion function that truncates floating point types to the
+// closest representable value for the specified integer type, or
+// numeric_limits<IntT>::max()/min() if the value isn't representable.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__random/clamp_to_integral.h>
+#include <cassert>
+#include <cmath>
+#include <limits>
+
+template <class IntT>
+void test() {
+ typedef std::numeric_limits<IntT> Lim;
+ const bool MaxIsRepresentable = sizeof(IntT) < 8;
+ const bool IsSigned = std::is_signed<IntT>::value;
+ struct TestCase {
+ double Input;
+ IntT Expect;
+ bool IsRepresentable;
+ } TestCases[] = {
+ {0, 0, true},
+ {1, 1, true},
+ {IsSigned ? static_cast<IntT>(-1) : 0,
+ IsSigned ? static_cast<IntT>(-1) : 0, true},
+ {Lim::lowest(), Lim::lowest(), true},
+ {static_cast<double>(Lim::max()), Lim::max(), MaxIsRepresentable},
+ {static_cast<double>(Lim::max()) + 1, Lim::max(), false},
+ {static_cast<double>(Lim::max()) + 1024, Lim::max(), false},
+ {nextafter(static_cast<double>(Lim::max()), INFINITY), Lim::max(), false},
+ };
+ for (TestCase TC : TestCases) {
+ auto res = std::__clamp_to_integral<IntT>(TC.Input);
+ assert(res == TC.Expect);
+ if (TC.IsRepresentable) {
+ auto other = static_cast<IntT>(std::trunc(TC.Input));
+ assert(res == other);
+ } else
+ assert(res == Lim::min() || res == Lim::max());
+ }
+}
+
+template <class IntT>
+void test_float() {
+ typedef std::numeric_limits<IntT> Lim;
+ const bool MaxIsRepresentable = sizeof(IntT) < 4;
+ ((void)MaxIsRepresentable);
+ const bool IsSigned = std::is_signed<IntT>::value;
+ struct TestCase {
+ float Input;
+ IntT Expect;
+ bool IsRepresentable;
+ } TestCases[] = {
+ {0, 0, true},
+ {1, 1, true},
+ {IsSigned ? static_cast<IntT>(-1) : 0,
+ IsSigned ? static_cast<IntT>(-1) : 0, true},
+ {Lim::lowest(), Lim::lowest(), true},
+ {static_cast<float>(Lim::max()), Lim::max(), MaxIsRepresentable },
+ {nextafter(static_cast<float>(Lim::max()), INFINITY), Lim::max(), false},
+ };
+ for (TestCase TC : TestCases) {
+ auto res = std::__clamp_to_integral<IntT>(TC.Input);
+ assert(res == TC.Expect);
+ if (TC.IsRepresentable) {
+ auto other = static_cast<IntT>(std::trunc(TC.Input));
+ assert(res == other);
+ } else
+ assert(res == Lim::min() || res == Lim::max());
+ }
+}
+
+int main(int, char**) {
+ test<short>();
+ test<unsigned short>();
+ test<int>();
+ test<unsigned>();
+ test<long long>();
+ test<unsigned long long>();
+ test_float<short>();
+ test_float<int>();
+ test_float<long long>();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/complex.number/__sqr.pass.cpp b/libcxx/test/libcxx-03/numerics/complex.number/__sqr.pass.cpp
new file mode 100644
index 0000000000000..97f4a2419483c
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/complex.number/__sqr.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <complex>
+
+// template<class T>
+// complex<T>
+// __sqr(const complex<T>& x);
+
+#include <complex>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+void
+test()
+{
+ const T tolerance = std::is_same<T, float>::value ? 1.e-6 : 1.e-14;
+
+ typedef std::complex<T> cplx;
+ struct test_case
+ {
+ cplx value;
+ cplx expected;
+ };
+
+ const test_case cases[] = {
+ {cplx( 0, 0), cplx( 0, 0)},
+ {cplx( 1, 0), cplx( 1, 0)},
+ {cplx( 2, 0), cplx( 4, 0)},
+ {cplx(-1, 0), cplx( 1, 0)},
+ {cplx( 0, 1), cplx(-1, 0)},
+ {cplx( 0, 2), cplx(-4, 0)},
+ {cplx( 0, -1), cplx(-1, 0)},
+ {cplx( 1, 1), cplx( 0, 2)},
+ {cplx( 1, -1), cplx( 0, -2)},
+ {cplx(-1, -1), cplx( 0, 2)},
+ {cplx(0.5, 0), cplx(0.25, 0)},
+ };
+
+ const unsigned num_cases = sizeof(cases) / sizeof(test_case);
+ for (unsigned i = 0; i < num_cases; ++i)
+ {
+ const test_case& test = cases[i];
+ const std::complex<T> actual = std::__sqr(test.value);
+ assert(std::abs(actual.real() - test.expected.real()) < tolerance);
+ assert(std::abs(actual.imag() - test.expected.imag()) < tolerance);
+ }
+
+ const cplx nan1 = std::__sqr(cplx(NAN, 0));
+ assert(std::isnan(nan1.real()));
+ assert(std::isnan(nan1.imag()));
+
+ const cplx nan2 = std::__sqr(cplx(0, NAN));
+ assert(std::isnan(nan2.real()));
+ assert(std::isnan(nan2.imag()));
+
+ const cplx nan3 = std::__sqr(cplx(NAN, NAN));
+ assert(std::isnan(nan3.real()));
+ assert(std::isnan(nan3.imag()));
+
+ const cplx inf1 = std::__sqr(cplx(INFINITY, 0));
+ assert(std::isinf(inf1.real()));
+ assert(inf1.real() > 0);
+
+ const cplx inf2 = std::__sqr(cplx(0, INFINITY));
+ assert(std::isinf(inf2.real()));
+ assert(inf2.real() < 0);
+}
+
+int main(int, char**)
+{
+ test<float>();
+ test<double>();
+ test<long double>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/complex.number/cmplx.over.pow.pass.cpp b/libcxx/test/libcxx-03/numerics/complex.number/cmplx.over.pow.pass.cpp
new file mode 100644
index 0000000000000..d87e259cefe39
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/complex.number/cmplx.over.pow.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
+//
+//===----------------------------------------------------------------------===//
+
+// <complex>
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// template<class T, class U> complex<__promote_t<T, U>> pow(const complex<T>&, const U&);
+// template<class T, class U> complex<__promote_t<T, U>> pow(const complex<T>&, const complex<U>&);
+// template<class T, class U> complex<__promote_t<T, U>> pow(const T&, const complex<U>&);
+
+// Test that these additional overloads are free from catching std::complex<non-floating-point>,
+// which is expected by several 3rd party libraries, see https://github.com/llvm/llvm-project/issues/109858.
+//
+// Note that we reserve the right to break this in the future if we have a reason to, but for the time being,
+// make sure we don't break this property unintentionally.
+#include <cassert>
+#include <cmath>
+#include <complex>
+#include <type_traits>
+
+#include "test_macros.h"
+
+namespace usr {
+struct usr_tag {};
+
+template <class T, class U>
+typename std::enable_if<(std::is_same<T, usr_tag>::value && std::is_floating_point<U>::value) ||
+ (std::is_floating_point<T>::value && std::is_same<U, usr_tag>::value),
+ int>::type
+pow(const T&, const std::complex<U>&) {
+ return std::is_same<T, usr_tag>::value ? 0 : 1;
+}
+
+template <class T, class U>
+typename std::enable_if<(std::is_same<T, usr_tag>::value && std::is_floating_point<U>::value) ||
+ (std::is_floating_point<T>::value && std::is_same<U, usr_tag>::value),
+ int>::type
+pow(const std::complex<T>&, const U&) {
+ return std::is_same<U, usr_tag>::value ? 2 : 3;
+}
+
+template <class T, class U>
+typename std::enable_if<(std::is_same<T, usr_tag>::value && std::is_floating_point<U>::value) ||
+ (std::is_floating_point<T>::value && std::is_same<U, usr_tag>::value),
+ int>::type
+pow(const std::complex<T>&, const std::complex<U>&) {
+ return std::is_same<T, usr_tag>::value ? 4 : 5;
+}
+} // namespace usr
+
+int main(int, char**) {
+ using std::pow;
+ using usr::pow;
+
+ usr::usr_tag tag;
+ const std::complex<usr::usr_tag> ctag;
+
+ assert(pow(tag, std::complex<float>(1.0f)) == 0);
+ assert(pow(std::complex<float>(1.0f), tag) == 2);
+ assert(pow(tag, std::complex<double>(1.0)) == 0);
+ assert(pow(std::complex<double>(1.0), tag) == 2);
+ assert(pow(tag, std::complex<long double>(1.0l)) == 0);
+ assert(pow(std::complex<long double>(1.0l), tag) == 2);
+
+ assert(pow(1.0f, ctag) == 1);
+ assert(pow(ctag, 1.0f) == 3);
+ assert(pow(1.0, ctag) == 1);
+ assert(pow(ctag, 1.0) == 3);
+ assert(pow(1.0l, ctag) == 1);
+ assert(pow(ctag, 1.0l) == 3);
+
+ assert(pow(ctag, std::complex<float>(1.0f)) == 4);
+ assert(pow(std::complex<float>(1.0f), ctag) == 5);
+ assert(pow(ctag, std::complex<double>(1.0)) == 4);
+ assert(pow(std::complex<double>(1.0), ctag) == 5);
+ assert(pow(ctag, std::complex<long double>(1.0l)) == 4);
+ assert(pow(std::complex<long double>(1.0l), ctag) == 5);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/assert.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/assert.pass.cpp
new file mode 100644
index 0000000000000..2bdf52340abfc
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/assert.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// Test hardening assertions for std::valarray.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <valarray>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ { // Empty valarray
+ std::valarray<int> c;
+ const auto& const_c = c;
+ TEST_LIBCPP_ASSERT_FAILURE(c[0], "valarray::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c[0], "valarray::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c[42], "valarray::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c[42], "valarray::operator[] index out of bounds");
+ }
+
+ { // Non-empty valarray
+ std::valarray<int> c(4);
+ const auto& const_c = c;
+ (void)c[3]; // Check that there's no assertion on valid access.
+ TEST_LIBCPP_ASSERT_FAILURE(c[4], "valarray::operator[] index out of bounds");
+ (void)const_c[3]; // Check that there's no assertion on valid access.
+ TEST_LIBCPP_ASSERT_FAILURE(const_c[4], "valarray::operator[] index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/assert.get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/assert.get.pass.cpp
new file mode 100644
index 0000000000000..f883f87b05df0
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/assert.get.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <valarray>
+
+// template<class T> class gslice_array;
+
+// T __get(size_t i); // where i is out of bounds
+
+#include <valarray>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::gslice_array<unsigned> result =
+ array[std::gslice(0, std::valarray<std::size_t>(N, 1), std::valarray<std::size_t>(1, 1))];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(N), "gslice_array.__get() index out of bounds");
+ }
+ {
+ std::valarray<std::size_t> sizes(2);
+ sizes[0] = 2;
+ sizes[1] = 3;
+
+ std::valarray<std::size_t> strides(2);
+ strides[0] = 6;
+ strides[1] = 1;
+
+ std::gslice_array<unsigned> result = array[std::gslice(1, sizes, strides)];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(6), "gslice_array.__get() index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/get.pass.cpp
new file mode 100644
index 0000000000000..2a1842f69fd2d
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.gslice.array/get.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
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// template<class T> class gslice_array;
+
+// T __get(size_t i);
+
+#include <valarray>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::gslice_array<unsigned> result =
+ array[std::gslice(0, std::valarray<std::size_t>(N, 1), std::valarray<std::size_t>(1, 1))];
+ for (unsigned i = 0; i < N; ++i)
+ assert(result.__get(i) == i);
+ }
+
+ {
+ std::valarray<std::size_t> sizes(2);
+ sizes[0] = 2;
+ sizes[1] = 3;
+
+ std::valarray<std::size_t> strides(2);
+ strides[0] = 6;
+ strides[1] = 1;
+
+ std::gslice_array<unsigned> result = array[std::gslice(1, sizes, strides)];
+ assert(result.__get(0) == input[1 + 0 * 6 + 0 * 1]);
+ assert(result.__get(1) == input[1 + 0 * 6 + 1 * 1]);
+ assert(result.__get(2) == input[1 + 0 * 6 + 2 * 1]);
+
+ assert(result.__get(3) == input[1 + 1 * 6 + 0 * 1]);
+ assert(result.__get(4) == input[1 + 1 * 6 + 1 * 1]);
+ assert(result.__get(5) == input[1 + 1 * 6 + 2 * 1]);
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/assert.get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/assert.get.pass.cpp
new file mode 100644
index 0000000000000..8bf747e6aa7f6
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/assert.get.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <valarray>
+
+// template<class T> class indirect_array;
+
+// T __get(size_t i); // where i is out of bounds
+
+#include <valarray>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::indirect_array<unsigned> result = array[std::valarray<std::size_t>()];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(0), "indirect_array.__get() index out of bounds");
+ }
+ {
+ std::indirect_array<unsigned> result = array[std::valarray<std::size_t>(std::size_t(0), std::size_t(N))];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(N), "indirect_array.__get() index out of bounds");
+ }
+
+ {
+ std::valarray<std::size_t> indirect(std::size_t(0), std::size_t(3));
+ std::indirect_array<unsigned> result = array[indirect];
+ indirect[0] = 4;
+ indirect[1] = 1;
+ indirect[2] = 3;
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(3), "indirect_array.__get() index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/get.pass.cpp
new file mode 100644
index 0000000000000..3c50c740bcaba
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.indirect.array/get.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// template<class T> class indirect_array;
+
+// T __get(size_t i);
+
+#include <valarray>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::indirect_array<unsigned> result = array[std::valarray<std::size_t>(std::size_t(0), std::size_t(N))];
+ for (unsigned i = 0; i < N; ++i)
+ assert(result.__get(i) == 0);
+ }
+
+ {
+ std::valarray<std::size_t> indirect(std::size_t(0), std::size_t(3));
+ indirect[0] = 4;
+ indirect[1] = 1;
+ indirect[2] = 3;
+ std::indirect_array<unsigned> result = array[indirect];
+ assert(result.__get(0) == 4);
+ assert(result.__get(1) == 1);
+ assert(result.__get(2) == 3);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.mask.array/assert.get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.mask.array/assert.get.pass.cpp
new file mode 100644
index 0000000000000..a2d284830c1a5
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.mask.array/assert.get.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <valarray>
+
+// template<class T> class mask_array;
+
+// T __get(size_t i); // where i is out of bounds
+
+#include <valarray>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::mask_array<unsigned> result = array[std::valarray<bool>(false, N)];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(0), "mask_array.__get() index out of bounds");
+ }
+ {
+ std::mask_array<unsigned> result = array[std::valarray<bool>(true, N)];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(N), "mask_array.__get() index out of bounds");
+ }
+
+ {
+ std::valarray<bool> mask(false, N);
+ mask[1] = true;
+ mask[3] = true;
+ std::mask_array<unsigned> result = array[mask];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(2), "mask_array.__get() index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.mask.array/get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.mask.array/get.pass.cpp
new file mode 100644
index 0000000000000..e34c38289222a
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.mask.array/get.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
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// template<class T> class mask_array;
+
+// T __get(size_t i);
+
+#include <valarray>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::mask_array<unsigned> result = array[std::valarray<bool>(true, N)];
+ for (unsigned i = 0; i < N; ++i)
+ assert(result.__get(i) == i);
+ }
+
+ {
+ std::valarray<bool> mask(false, N);
+ mask[1] = true;
+ mask[3] = true;
+ std::mask_array<unsigned> result = array[mask];
+ assert(result.__get(0) == 1);
+ assert(result.__get(1) == 3);
+ }
+
+ {
+ std::valarray<bool> mask(false, N);
+ mask[0] = true;
+ mask[4] = true;
+ std::mask_array<unsigned> result = array[mask];
+ assert(result.__get(0) == 0);
+ assert(result.__get(1) == 4);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.slice.array/assert.get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.slice.array/assert.get.pass.cpp
new file mode 100644
index 0000000000000..0dbad84486976
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.slice.array/assert.get.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <valarray>
+
+// template<class T> class slice_array;
+
+// T __get(size_t i); // where i is out of bounds
+
+#include <valarray>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::slice_array<unsigned> result = array[std::slice(0, 0, 0)];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(0), "slice_array.__get() index out of bounds");
+ }
+ {
+ std::slice_array<unsigned> result = array[std::slice(0, N, 1)];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(N), "slice_array.__get() index out of bounds");
+ }
+ {
+ std::slice_array<unsigned> result = array[std::slice(3, 2, 2)];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(2), "slice_array.__get() index out of bounds");
+ }
+
+ {
+ std::slice_array<unsigned> result = array[std::slice(1, 3, 4)];
+ TEST_LIBCPP_ASSERT_FAILURE(result.__get(3), "slice_array.__get() index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numarray/class.slice.array/get.pass.cpp b/libcxx/test/libcxx-03/numerics/numarray/class.slice.array/get.pass.cpp
new file mode 100644
index 0000000000000..26871f310bae2
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numarray/class.slice.array/get.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// template<class T> class slice_array;
+
+// T __get(size_t i);
+
+#include <valarray>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ unsigned input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ const unsigned N = sizeof(input) / sizeof(input[0]);
+
+ std::valarray<unsigned> array(input, N);
+
+ {
+ std::slice_array<unsigned> result = array[std::slice(0, N, 1)];
+ for (unsigned i = 0; i < N; ++i)
+ assert(result.__get(i) == i);
+ }
+
+ {
+ std::slice_array<unsigned> result = array[std::slice(3, 2, 2)];
+ assert(result.__get(0) == 3);
+ assert(result.__get(1) == 5);
+ }
+
+ {
+ std::slice_array<unsigned> result = array[std::slice(1, 3, 4)];
+ assert(result.__get(0) == 1);
+ assert(result.__get(1) == 5);
+ assert(result.__get(2) == 9);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/numeric.ops/midpoint.integer.pass.cpp b/libcxx/test/libcxx-03/numerics/numeric.ops/midpoint.integer.pass.cpp
new file mode 100644
index 0000000000000..ef559adda772f
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/numeric.ops/midpoint.integer.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
+// <numeric>
+
+// template <class _Tp>
+// _Tp midpoint(_Tp __a, _Tp __b) noexcept
+//
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <numeric>
+
+#include "test_macros.h"
+
+// Users are not supposed to provide template argument lists for
+// functions in the standard library (there's an exception for min and max)
+// However, libc++ protects against this for pointers. The use of T(0)
+// in the test cases resolves potential ambiguity in template argument deduction
+// for the std::midpoint function.
+
+template <typename T>
+void test()
+{
+ ASSERT_SAME_TYPE(T, decltype(std::midpoint<T>(T(0), T(0))));
+}
+
+int main(int, char**)
+{
+ test<signed char>();
+ test<short>();
+ test<int>();
+ test<long>();
+ test<long long>();
+
+ test<std::int8_t>();
+ test<std::int16_t>();
+ test<std::int32_t>();
+ test<std::int64_t>();
+
+ test<unsigned char>();
+ test<unsigned short>();
+ test<unsigned int>();
+ test<unsigned long>();
+ test<unsigned long long>();
+
+ test<std::uint8_t>();
+ test<std::uint16_t>();
+ test<std::uint32_t>();
+ test<std::uint64_t>();
+
+#ifndef TEST_HAS_NO_INT128
+ test<__int128_t>();
+ test<__uint128_t>();
+#endif
+
+ test<char>();
+ test<std::ptrdiff_t>();
+ test<std::size_t>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.device/has-no-random-device.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.device/has-no-random-device.verify.cpp
new file mode 100644
index 0000000000000..03d592774e572
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.device/has-no-random-device.verify.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that std::random_device is not available in namespace std:: when
+// libc++ is built without support for random device.
+
+// REQUIRES: no-random-device
+
+#include <random>
+
+void f() {
+ std::random_device d; // expected-error {{no type named 'random_device' in namespace 'std'}}
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bernoulli/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bernoulli/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..9855d8ae6f866
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bernoulli/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::bernoulli_distribution dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bin/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bin/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..1b1bb4428f80d
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.bin/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::binomial_distribution<int> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.geo/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.geo/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..d9b692ec94727
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.geo/bad_engine.verify.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: -Wno-sign-compare -Wno-shift-count-negative
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::geometric_distribution<int> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 7 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.negbin/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.negbin/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..e526168d6d4ec
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.bern/rand.dist.bern.negbin/bad_engine.verify.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: -Wno-shift-count-negative
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::negative_binomial_distribution<int> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 7 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.cauchy/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.cauchy/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..59e5b50a862dc
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.cauchy/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::cauchy_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.chisq/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.chisq/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..b0265148debf8
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.chisq/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::chi_squared_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 3 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.f/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.f/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..77c97fb3351ad
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.f/bad_engine.verify.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: -Wno-sign-compare
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::fisher_f_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 4 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.lognormal/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.lognormal/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..80c34580bc40d
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.lognormal/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::lognormal_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.normal/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.normal/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..cc697ab5e7ae2
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.normal/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::normal_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.t/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.t/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..151a2bd954c8b
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.t/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::student_t_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 5 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.exp/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.exp/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..b1241214de76f
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.exp/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::exponential_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.extreme/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.extreme/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..c002716a5316a
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.extreme/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::extreme_value_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.gamma/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.gamma/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..8bf87dd8615c6
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.gamma/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::gamma_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 3 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.poisson/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.poisson/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..ef56d9635fc49
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.poisson/bad_engine.verify.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: -Wno-shift-count-negative
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::poisson_distribution<int> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 4 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.weibull/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.weibull/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..e40c1972abeb4
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.pois/rand.dist.pois.weibull/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::weibull_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.discrete/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.discrete/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..a4def062f83f1
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.discrete/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::discrete_distribution<int> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.pconst/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.pconst/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..002071129d03e
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.pconst/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::piecewise_constant_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.plinear/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.plinear/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..0fb54a403ac9e
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.samp/rand.dist.samp.plinear/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::piecewise_linear_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* 2 {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.int/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.int/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..2432843942e29
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.int/bad_engine.verify.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: -Wno-sign-compare
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::uniform_int_distribution<int> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.real/bad_engine.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.real/bad_engine.verify.cpp
new file mode 100644
index 0000000000000..fa5c3a3ebb484
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.dist/rand.dist.uni/rand.dist.uni.real/bad_engine.verify.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <random>
+
+#include <random>
+
+template<class Int>
+struct G {
+ using result_type = Int;
+ result_type operator()();
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return 255; }
+};
+
+void test(std::uniform_real_distribution<double> dist)
+{
+ G<int> badg;
+ G<unsigned> okg;
+
+ dist(badg); //expected-error@*:* {{static assertion failed}} //expected-note {{in instantiation}}
+ dist(okg);
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_int_type.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_int_type.verify.cpp
new file mode 100644
index 0000000000000..eada7422bea4e
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_int_type.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// <random>
+
+#include <random>
+
+void test()
+{
+ {
+ std::binomial_distribution<bool> baddist; //expected-error@*:* {{IntType must be a supported integer type}}
+ std::binomial_distribution<int> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+ {
+ std::discrete_distribution<bool> baddist; //expected-error@*:* {{IntType must be a supported integer type}}
+ std::discrete_distribution<int> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+ {
+ std::geometric_distribution<bool> baddist; //expected-error@*:* {{IntType must be a supported integer type}}
+ std::geometric_distribution<int> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+ {
+ std::negative_binomial_distribution<bool> baddist; //expected-error@*:* {{IntType must be a supported integer type}}
+ std::negative_binomial_distribution<int> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+ {
+ std::poisson_distribution<bool> baddist; //expected-error@*:* {{IntType must be a supported integer type}}
+ std::poisson_distribution<int> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+ {
+ std::uniform_int_distribution<bool> baddist; //expected-error@*:* {{IntType must be a supported integer type}}
+ std::uniform_int_distribution<int> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+}
diff --git a/libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_real_type.verify.cpp b/libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_real_type.verify.cpp
new file mode 100644
index 0000000000000..6c6a109227df9
--- /dev/null
+++ b/libcxx/test/libcxx-03/numerics/rand/rand.req.urng/valid_real_type.verify.cpp
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <random>
+
+#include <random>
+
+void test() {
+ {
+ std::uniform_real_distribution<int>
+ baddist; //expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::uniform_real_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+ {
+ std::exponential_distribution<int>
+ baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::exponential_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::gamma_distribution<int> baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::gamma_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::weibull_distribution<int> baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::weibull_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::extreme_value_distribution<int>
+ baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::extreme_value_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::normal_distribution<int> baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::normal_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::lognormal_distribution<int> baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::lognormal_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::chi_squared_distribution<int>
+ baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::chi_squared_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::cauchy_distribution<int> baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::cauchy_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::fisher_f_distribution<int> baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::fisher_f_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::student_t_distribution<int> baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::student_t_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::piecewise_constant_distribution<int>
+ baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::piecewise_constant_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+
+ {
+ std::piecewise_linear_distribution<int>
+ baddist; // expected-error@*:* {{RealType must be a supported floating-point type}}
+ std::piecewise_linear_distribution<double> okdist;
+ (void)baddist;
+ (void)okdist;
+ }
+}
diff --git a/libcxx/test/libcxx-03/odr_signature.exceptions.sh.cpp b/libcxx/test/libcxx-03/odr_signature.exceptions.sh.cpp
new file mode 100644
index 0000000000000..6bf60b5e82d3c
--- /dev/null
+++ b/libcxx/test/libcxx-03/odr_signature.exceptions.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// TODO: Investigate
+// XFAIL: msvc
+
+// Test that we encode whether exceptions are supported in an ABI tag to avoid
+// ODR violations when linking TUs that have different values for it.
+
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -fno-exceptions -o %t.tu1.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -fexceptions -o %t.tu2.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o
+// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.main.o %{flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe
+
+// -fno-exceptions
+#ifdef TU1
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI inline int f() { return 1; }
+int tu1() { return f(); }
+#endif // TU1
+
+// -fexceptions
+#ifdef TU2
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI inline int f() { return 2; }
+int tu2() { return f(); }
+#endif // TU2
+
+#ifdef MAIN
+# include <cassert>
+
+int tu1();
+int tu2();
+
+int main(int, char**) {
+ assert(tu1() == 1);
+ assert(tu2() == 2);
+ return 0;
+}
+#endif // MAIN
diff --git a/libcxx/test/libcxx-03/odr_signature.hardening.sh.cpp b/libcxx/test/libcxx-03/odr_signature.hardening.sh.cpp
new file mode 100644
index 0000000000000..0dc280bf28182
--- /dev/null
+++ b/libcxx/test/libcxx-03/odr_signature.hardening.sh.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// TODO: Investigate
+// XFAIL: msvc
+
+// Test that we encode the hardening mode in an ABI tag to avoid ODR violations
+// when linking TUs that have different values for it.
+
+// Note that GCC doesn't support `-Wno-macro-redefined`.
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU1 -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST -o %t.tu1.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU2 -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -o %t.tu2.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU3 -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG -o %t.tu3.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DTU4 -U_LIBCPP_HARDENING_MODE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE -o %t.tu4.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DMAIN -o %t.main.o
+// RUN: %{cxx} %t.tu1.o %t.tu2.o %t.tu3.o %t.tu4.o %t.main.o %{flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe
+
+// fast hardening mode
+#ifdef TU1
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI inline int f() { return 1; }
+int tu1() { return f(); }
+#endif // TU1
+
+// extensive hardening mode
+#ifdef TU2
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI inline int f() { return 2; }
+int tu2() { return f(); }
+#endif // TU2
+
+// debug hardening mode
+#ifdef TU3
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI inline int f() { return 3; }
+int tu3() { return f(); }
+#endif // TU3
+
+// No hardening
+#ifdef TU4
+# include <__config>
+_LIBCPP_HIDE_FROM_ABI inline int f() { return 4; }
+int tu4() { return f(); }
+#endif // TU4
+
+#ifdef MAIN
+# include <cassert>
+
+int tu1();
+int tu2();
+int tu3();
+int tu4();
+
+int main(int, char**) {
+ assert(tu1() == 1);
+ assert(tu2() == 2);
+ assert(tu3() == 3);
+ assert(tu4() == 4);
+ return 0;
+}
+#endif // MAIN
diff --git a/libcxx/test/libcxx-03/ranges/no_specializations.verify.cpp b/libcxx/test/libcxx-03/ranges/no_specializations.verify.cpp
new file mode 100644
index 0000000000000..489e3a6a73744
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/no_specializations.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Check that user-specializations are diagnosed
+// See [range.adaptor.object]/5
+
+#include <ranges>
+
+#include "test_macros.h"
+
+#if !__has_warning("-Winvalid-specialization") || TEST_STD_VER <= 20
+// expected-no-diagnostics
+#else
+struct S {};
+
+template <>
+class std::ranges::range_adaptor_closure<S>; // expected-error {{cannot be specialized}}
+#endif
diff --git a/libcxx/test/libcxx-03/ranges/range.access/end.incomplete_type.pass.cpp b/libcxx/test/libcxx-03/ranges/range.access/end.incomplete_type.pass.cpp
new file mode 100644
index 0000000000000..12efa6ac15d01
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.access/end.incomplete_type.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Test the libc++-specific behavior that we handle the IFNDR case for ranges::end
+// by being SFINAE-friendly.
+
+#include <cassert>
+#include <ranges>
+#include <type_traits>
+#include <utility>
+
+struct Incomplete;
+
+constexpr bool test()
+{
+ {
+ extern Incomplete bounded[10];
+ assert((!std::is_invocable_v<decltype(std::ranges::end), decltype((bounded))>));
+ assert((!std::is_invocable_v<decltype(std::ranges::cend), decltype((bounded))>));
+ assert((!std::is_invocable_v<decltype(std::ranges::end), decltype(std::as_const(bounded))>));
+ assert((!std::is_invocable_v<decltype(std::ranges::cend), decltype(std::as_const(bounded))>));
+ }
+ {
+ extern Incomplete unbounded[];
+ assert((!std::is_invocable_v<decltype(std::ranges::end), decltype((unbounded))>));
+ assert((!std::is_invocable_v<decltype(std::ranges::cend), decltype((unbounded))>));
+ assert((!std::is_invocable_v<decltype(std::ranges::end), decltype(std::as_const(unbounded))>));
+ assert((!std::is_invocable_v<decltype(std::ranges::cend), decltype(std::as_const(unbounded))>));
+ }
+
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+ static_assert(test());
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.lifetimebound.verify.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.lifetimebound.verify.cpp
new file mode 100644
index 0000000000000..b60f172363350
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.lifetimebound.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// template<class T>
+// constexpr T& as-lvalue(T&& t) { // exposition only
+
+#include <__utility/as_lvalue.h>
+
+void test() {
+ // Check prvalue
+ {
+ [[maybe_unused]] auto& check = std::__as_lvalue(
+ 0); // expected-warning {{temporary bound to local reference 'check' will be destroyed at the end of the full-expression}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.pass.cpp
new file mode 100644
index 0000000000000..8e47a507f2f8a
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/as-lvalue.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+// template<class T>
+// constexpr T& as-lvalue(T&& t) { // exposition only
+
+#include <__utility/as_lvalue.h>
+#include <type_traits>
+#include <utility>
+
+constexpr bool test() {
+ // Check glvalue
+ {
+ int lvalue{};
+ [[maybe_unused]] decltype(auto) check = std::__as_lvalue(lvalue);
+ static_assert(std::is_same<decltype(check), int&>::value, "");
+ }
+
+ // Check xvalue
+ {
+ int xvalue{};
+ [[maybe_unused]] decltype(auto) check = std::__as_lvalue(std::move(xvalue));
+ static_assert(std::is_same<decltype(check), int&>::value, "");
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test(), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/tuple-for-each.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/tuple-for-each.pass.cpp
new file mode 100644
index 0000000000000..11176c757efaa
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.adaptor.helpers/tuple-for-each.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <ranges>
+
+// template<class F, class Tuple>
+// constexpr void tuple-for-each(F&& f, Tuple&& t) { // exposition only
+
+// LWG3755 tuple-for-each can call user-defined operator,
+
+#include <ranges>
+#include <tuple>
+#include <cstdlib>
+
+struct Evil {
+ void operator,(Evil) { std::abort(); }
+};
+
+int main(int, char**) {
+ std::tuple<int, int> t;
+ std::ranges::__tuple_for_each([](int) { return Evil{}; }, t);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..43b9ebf60f2a0
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.all/all.nodiscard.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Test the libc++ extension that std::views::all is marked as [[nodiscard]].
+
+#include <ranges>
+
+void test() {
+ int range[] = {1, 2, 3};
+
+ std::views::all(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::views::all; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all | std::views::all; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.begin.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.begin.pass.cpp
new file mode 100644
index 0000000000000..57af366317091
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.begin.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <ranges>
+
+// Call begin() on chunk_by_view with empty predicate
+
+#include <ranges>
+
+#include "check_assertion.h"
+#include "types.h"
+
+int main(int, char**) {
+ int input[] = {1, 2, 3};
+ auto view1 = std::views::chunk_by(input, ThrowOnCopyPred{});
+ auto view2 = std::views::chunk_by(input, ThrowOnCopyPred{});
+ try {
+ view1 = view2;
+ } catch (...) {
+ }
+ TEST_LIBCPP_ASSERT_FAILURE(
+ view1.begin(), "Trying to call begin() on a chunk_by_view that does not have a valid predicate.");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-next.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-next.pass.cpp
new file mode 100644
index 0000000000000..1c91ee7198952
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-next.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <ranges>
+
+// Call find-next() on chunk_by_view with empty predicate
+
+#include <ranges>
+
+#include "check_assertion.h"
+#include "types.h"
+
+int main(int, char**) {
+ int input[] = {1, 2, 3};
+ // This is the easiest way to get '__find_next' to fail. If we used default constructed view here,
+ // then begin() would fail instead of __find_next.
+ auto view1 = std::views::chunk_by(input, ThrowOnCopyPred{});
+ auto view2 = std::views::chunk_by(input, ThrowOnCopyPred{});
+ auto it = view1.begin();
+ try {
+ view1 = view2;
+ } catch (...) {
+ }
+ TEST_LIBCPP_ASSERT_FAILURE(
+ ++it, "Trying to call __find_next() on a chunk_by_view that does not have a valid predicate.");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-prev.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-prev.pass.cpp
new file mode 100644
index 0000000000000..2605bf6dde074
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/assert.find-prev.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-exceptions
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <ranges>
+
+// Call find-prev() on chunk_by_view with begin iterator
+// Call find-prev() on chunk_by_view with empty predicate
+
+#include <functional>
+#include <ranges>
+
+#include "check_assertion.h"
+#include "types.h"
+
+int main(int, char**) {
+ int input[] = {1, 1, 2, 2};
+
+ { // Call find-prev() on chunk_by_view with begin iterator
+ auto view = std::views::chunk_by(input, std::equal_to{});
+ auto it = view.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(--it, "Trying to call __find_prev() on a begin iterator.");
+ }
+
+ { // Call find-prev() on chunk_by_view with empty predicate
+ auto view1 = std::views::chunk_by(input, ThrowOnCopyPred{});
+ auto view2 = std::views::chunk_by(input, ThrowOnCopyPred{});
+ auto it = view1.begin();
+ ++it;
+ try {
+ view1 = view2;
+ } catch (...) {
+ }
+ TEST_LIBCPP_ASSERT_FAILURE(
+ --it, "Trying to call __find_prev() on a chunk_by_view that does not have a valid predicate.");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..e696598f618ba
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/no_unique_address.compile.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// XFAIL: msvc
+
+// This test ensures that we use `[[no_unique_address]]` in `chunk_by_view`.
+
+#include <ranges>
+
+struct View : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+};
+
+struct Pred {
+ template <class... Args>
+ bool operator()(const Args&...) const;
+};
+
+template <class View>
+struct Test {
+ [[no_unique_address]] View view;
+ char c;
+};
+
+// [[no_unique_address]] applied to _View
+struct ViewWithPadding : View {
+ alignas(128) char c;
+};
+
+static_assert(sizeof(Test<std::ranges::chunk_by_view<ViewWithPadding, Pred>>) ==
+ sizeof(std::ranges::chunk_by_view<ViewWithPadding, Pred>));
+
+// [[no_unique_address]] applied to movable-box
+struct PredWithPadding : Pred {
+ alignas(128) char c;
+};
+
+static_assert(sizeof(Test<std::ranges::chunk_by_view<View, PredWithPadding>>) ==
+ sizeof(std::ranges::chunk_by_view<View, PredWithPadding>));
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.deref.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.deref.pass.cpp
new file mode 100644
index 0000000000000..8ed84ca8b56a1
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.deref.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <ranges>
+
+// Dereference past end chunk_by_view iterator
+
+#include <functional>
+#include <ranges>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ int input[] = {1, 2, 3};
+ auto view = std::views::chunk_by(input, std::less{});
+ auto it = view.begin();
+ ++it;
+ TEST_LIBCPP_ASSERT_FAILURE(*it, "Trying to dereference past-the-end chunk_by_view iterator.");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.increment.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.increment.pass.cpp
new file mode 100644
index 0000000000000..1a804b71b5e5e
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/range.chunk.by.iter/assert.increment.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: !libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <ranges>
+
+// Increment past end chunk_by_view iterator
+
+#include <functional>
+#include <ranges>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ int input[] = {1, 2, 3};
+ auto view = std::views::chunk_by(input, std::less{});
+ auto it = view.begin();
+ ++it;
+ TEST_LIBCPP_ASSERT_FAILURE(++it, "Trying to increment past end chunk_by_view iterator.");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/types.h b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/types.h
new file mode 100644
index 0000000000000..88fbcefab4d74
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.chunk.by/types.h
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_BY_TYPES_H
+#define TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_BY_TYPES_H
+
+struct ThrowOnCopyPred {
+ ThrowOnCopyPred() = default;
+ ThrowOnCopyPred(const ThrowOnCopyPred&) { throw 0; }
+ ThrowOnCopyPred& operator=(const ThrowOnCopyPred&) = delete;
+
+ ThrowOnCopyPred(ThrowOnCopyPred&&) = default;
+ ThrowOnCopyPred& operator=(ThrowOnCopyPred&&) = default;
+
+ bool operator()(int x, int y) const { return x != y; }
+};
+
+#endif // TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_CHUNK_BY_TYPES_H
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.common.view/adaptor.nodiscard.verify.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.common.view/adaptor.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..bc9d9c90358e4
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.common.view/adaptor.nodiscard.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Test the libc++ extension that std::views::common is marked as [[nodiscard]].
+
+#include <ranges>
+
+void test() {
+ int range[] = {1, 2, 3};
+
+ std::views::common(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::views::common; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all | std::views::common; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.counted/adaptor.nodiscard.verify.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.counted/adaptor.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..bd9b158c695fc
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.counted/adaptor.nodiscard.verify.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, c++11, c++14, c++17
+
+// Test the libc++ extension that std::views::counted is marked as [[nodiscard]].
+
+#include <ranges>
+
+void test() {
+ int range[] = {1, 2, 3};
+
+ std::views::counted(range, 1); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.drop.while/assert.begin.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.drop.while/assert.begin.pass.cpp
new file mode 100644
index 0000000000000..205cf40746207
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.drop.while/assert.begin.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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+// Call begin() on drop_while_view with empty predicate
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-exceptions
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <ranges>
+
+#include "check_assertion.h"
+
+struct Exception {};
+struct ThrowOnCopyPred {
+ ThrowOnCopyPred() = default;
+ ThrowOnCopyPred(const ThrowOnCopyPred&) { throw Exception{}; }
+ ThrowOnCopyPred& operator=(const ThrowOnCopyPred&) = delete;
+
+ ThrowOnCopyPred(ThrowOnCopyPred&&) = default;
+ ThrowOnCopyPred& operator=(ThrowOnCopyPred&&) = default;
+
+ bool operator()(int) const { return false; }
+};
+
+int main(int, char**) {
+ int input[] = {1, 2, 3};
+ auto v1 = std::views::drop_while(input, ThrowOnCopyPred{});
+ auto v2 = std::views::drop_while(input, ThrowOnCopyPred{});
+ try {
+ v1 = v2;
+ } catch (...) {
+ }
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v1.begin(),
+ "drop_while_view needs to have a non-empty predicate before calling begin() -- did a "
+ "previous assignment to this drop_while_view fail?");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/elements_view.no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/elements_view.no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..6901745b6be29
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/elements_view.no_unique_address.compile.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// clang-cl and cl currently don't support [[no_unique_address]]
+// XFAIL: msvc
+
+// Test the libc++ extension that the base view stored in `std::ranges::elements_view`
+// has been marked as _LIBCPP_NO_UNIQUE_ADDRESS
+
+#include <ranges>
+#include <tuple>
+
+
+struct EmptyView : std::ranges::view_base {
+ std::tuple<int>* begin() const;
+ std::tuple<int>* end() const;
+};
+
+using ElementsView = std::ranges::elements_view<EmptyView, 0>;
+
+struct TestClass {
+ [[no_unique_address]] ElementsView view;
+ int i;
+};
+
+static_assert(sizeof(TestClass) == sizeof(int));
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/sentinel.no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/sentinel.no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..2e69a327a7625
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.elements/sentinel.no_unique_address.compile.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test the libc++ extension that the sentinel stored in `std::ranges::elements_view::__sentinel`
+// has been marked as _LIBCPP_NO_UNIQUE_ADDRESS
+
+#include <ranges>
+#include <tuple>
+
+struct EmptySentinel {
+ friend bool operator==(std::tuple<int>* iter, EmptySentinel) { return iter; }
+};
+
+struct Range : std::ranges::view_base {
+ std::tuple<int>* begin() const;
+ EmptySentinel end() const;
+};
+
+using ElementsView = std::ranges::elements_view<Range, 0>;
+using ElementsSent = std::ranges::sentinel_t<ElementsView>;
+
+struct TestClass {
+ [[no_unique_address]] ElementsSent s;
+ int i;
+};
+
+static_assert(sizeof(TestClass) == sizeof(int));
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.outer.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.outer.pass.cpp
new file mode 100644
index 0000000000000..a54980bec287f
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.outer.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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(Parent& parent, OuterIter outer)
+// requires forward_range<Base>; // exposition only
+
+#include <cassert>
+#include <ranges>
+#include <string>
+#include <utility>
+
+#include "types.h"
+
+constexpr bool test() {
+ std::string strings[4] = {"aaaa", "bbbb", "cccc", "dddd"};
+
+ { // Check if `outer_` is initialized with `std::move(outer)` for `iterator<false>`
+ MoveOnAccessSubrange r{DieOnCopyIterator(strings), sentinel_wrapper(strings + 4)};
+ std::ranges::join_view jv(std::move(r));
+ auto iter = jv.begin(); // Calls `iterator(Parent& parent, OuterIter outer)`
+ assert(*iter == 'a');
+ }
+
+ { // Check if `outer_` is initialized with `std::move(outer)` for `iterator<true>`
+ MoveOnAccessSubrange r{DieOnCopyIterator(strings), sentinel_wrapper(strings + 4)};
+ std::ranges::join_view jv(std::ranges::ref_view{r});
+ auto iter = std::as_const(jv).begin(); // Calls `iterator(Parent& parent, OuterIter outer)`
+ assert(*iter == 'a');
+ }
+
+ {
+ // LWG3569 Inner iterator not default_initializable
+ // With the current spec, the constructor under test invokes Inner iterator's default constructor
+ // even if it is not default constructible.
+ // This test is checking that this constructor can be invoked with an inner range with non default
+ // constructible iterator.
+ using NonDefaultCtrIter = cpp20_input_iterator<int*>;
+ static_assert(!std::default_initializable<NonDefaultCtrIter>);
+ using NonDefaultCtrIterView = BufferView<NonDefaultCtrIter, sentinel_wrapper<NonDefaultCtrIter>>;
+ static_assert(std::ranges::input_range<NonDefaultCtrIterView>);
+
+ int buffer[2][2] = {{1, 2}, {3, 4}};
+ NonDefaultCtrIterView inners[] = {buffer[0], buffer[1]};
+ auto outer = std::views::all(inners);
+ std::ranges::join_view jv(outer);
+ auto iter = jv.begin(); // Calls `iterator(Parent& parent, OuterIter outer)`
+ assert(*iter == 1);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.pass.cpp
new file mode 100644
index 0000000000000..3026a02abf00f
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/ctor.parent.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr explicit iterator(Parent& parent)
+// requires (!forward_range<Base>); // exposition only
+
+#include <string>
+#include <ranges>
+
+#include "types.h"
+
+constexpr bool test() {
+ std::string strings[4] = {"eeee", "ffff", "gggg", "hhhh"};
+
+ MoveOnAccessSubrange r{
+ DieOnCopyIterator(cpp20_input_iterator(strings)), sentinel_wrapper(cpp20_input_iterator(strings + 4))};
+ std::ranges::join_view jv(std::move(r));
+ auto iter = jv.begin(); // Calls `iterator(Parent& parent)`
+ assert(*iter == 'e');
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/types.h b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/types.h
new file mode 100644
index 0000000000000..0652d4bdb4717
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/range.join.iterator/types.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_JOIN_RANGE_JOIN_ITERATOR_TYPES_H
+#define TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_JOIN_RANGE_JOIN_ITERATOR_TYPES_H
+
+#include <cassert>
+#include <cstddef>
+#include <ranges>
+
+#include "test_iterators.h"
+
+template <std::input_iterator Iter>
+struct DieOnCopyIterator {
+ using value_type = std::iter_value_t<Iter>;
+ using difference_type = std::iter_difference_t<Iter>;
+
+ DieOnCopyIterator()
+ requires std::default_initializable<Iter>
+ = default;
+
+ constexpr explicit DieOnCopyIterator(Iter iter) : iter_(std::move(iter)) {}
+ constexpr DieOnCopyIterator(DieOnCopyIterator&& other) = default;
+ DieOnCopyIterator& operator=(DieOnCopyIterator&&) = default;
+
+ constexpr DieOnCopyIterator(const DieOnCopyIterator&) { assert(false); }
+ constexpr DieOnCopyIterator& operator=(const DieOnCopyIterator&) { assert(false); }
+
+ constexpr DieOnCopyIterator& operator++() {
+ ++iter_;
+ return *this;
+ }
+
+ constexpr void operator++(int) { iter_++; }
+
+ constexpr DieOnCopyIterator operator++(int)
+ requires std::forward_iterator<Iter>
+ {
+ auto tmp = *this;
+ ++tmp;
+ return tmp;
+ }
+
+ constexpr decltype(auto) operator*() const { return *iter_; }
+
+ friend constexpr bool operator==(const DieOnCopyIterator& left, const DieOnCopyIterator& right)
+ requires std::equality_comparable<Iter>
+ {
+ return left.iter_ == right.iter_;
+ }
+
+ friend constexpr bool operator==(const DieOnCopyIterator& it, const sentinel_wrapper<Iter>& se) {
+ return it.iter_ == se;
+ }
+
+private:
+ Iter iter_ = Iter();
+};
+
+template <class Iter>
+explicit DieOnCopyIterator(Iter) -> DieOnCopyIterator<Iter>;
+
+static_assert(std::input_iterator<DieOnCopyIterator<cpp20_input_iterator<int*>>>);
+static_assert(!std::forward_iterator<DieOnCopyIterator<cpp20_input_iterator<int*>>>);
+static_assert(std::forward_iterator<DieOnCopyIterator<int*>>);
+static_assert(!std::bidirectional_iterator<DieOnCopyIterator<int*>>);
+static_assert(std::sentinel_for<sentinel_wrapper<int*>, DieOnCopyIterator<int*>>);
+
+template <std::input_iterator Iter, std::sentinel_for<Iter> Sent = Iter>
+struct MoveOnAccessSubrange : std::ranges::view_base {
+ constexpr explicit MoveOnAccessSubrange(Iter iter, Sent sent) : iter_(std::move(iter)), sent_(std::move(sent)) {}
+
+ MoveOnAccessSubrange(MoveOnAccessSubrange&&) = default;
+ MoveOnAccessSubrange& operator=(MoveOnAccessSubrange&&) = default;
+
+ MoveOnAccessSubrange(const MoveOnAccessSubrange&) = delete;
+ MoveOnAccessSubrange& operator=(const MoveOnAccessSubrange&) = delete;
+
+ constexpr Iter begin() { return std::move(iter_); }
+ constexpr Sent end() { return std::move(sent_); }
+
+private:
+ Iter iter_;
+ Sent sent_;
+};
+
+template <class Iter, class Sent>
+MoveOnAccessSubrange(Iter, Sent) -> MoveOnAccessSubrange<Iter, Sent>;
+
+static_assert(std::ranges::input_range<MoveOnAccessSubrange<int*, sentinel_wrapper<int*>>>);
+static_assert(std::ranges::forward_range<MoveOnAccessSubrange<DieOnCopyIterator<int*>>>);
+
+template <class Iter, class Sent>
+ requires(!std::same_as<Iter, Sent>)
+struct BufferView : std::ranges::view_base {
+ using T = std::iter_value_t<Iter>;
+ T* data_;
+ std::size_t size_;
+
+ template <std::size_t N>
+ constexpr BufferView(T (&b)[N]) : data_(b), size_(N) {}
+
+ constexpr Iter begin() const { return Iter(data_); }
+ constexpr Sent end() const { return Sent(Iter(data_ + size_)); }
+};
+
+static_assert(std::ranges::input_range<BufferView<int*, sentinel_wrapper<int*>>>);
+
+#endif // TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_JOIN_RANGE_JOIN_ITERATOR_TYPES_H
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/segmented_iterator.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/segmented_iterator.compile.pass.cpp
new file mode 100644
index 0000000000000..6cd17c2b3f353
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.join/segmented_iterator.compile.pass.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <ranges>
+#include <utility>
+#include <vector>
+
+using JoinView = decltype(std::views::join(std::declval<std::vector<std::vector<int>>&>()));
+using JoinIter = std::ranges::iterator_t<JoinView>;
+static_assert(std::__is_segmented_iterator<JoinIter>::value);
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..4a975f472b828
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/no_unique_address.compile.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// class lazy_split_view {
+// _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+// _LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern();
+// };
+
+#include <ranges>
+
+#include <string_view>
+#include "test_iterators.h"
+
+// Verify the optimization that, if `View` is a forward range, the `lazy_split_view` itself doesn't store the `current`
+// iterator (instead, it's stored in the `outer-iterator`).
+//
+// Note that the Standard marks all data members of `lazy_split_view` as "exposition only", so this test has to be
+// libc++-specific.
+namespace test1 {
+
+ using SplitView = std::ranges::lazy_split_view<std::string_view, std::string_view>;
+ // The `lazy_split_view` only stores the `View` and the `Pattern`, not an iterator.
+ static_assert(sizeof(SplitView) == sizeof(std::string_view) * 2);
+
+} // namespace test1
+
+// Verify the optimization that, if `View` is an input range, the `outer-iterator` doesn't store the `current` iterator
+// (instead, it's stored in the `lazy_split_view` itself).
+//
+// Note that the Standard marks all data members of `outer-iterator` as "exposition only", so this test has to be
+// libc++-specific.
+namespace test2 {
+
+ struct InputView : std::ranges::view_base {
+ int x;
+ cpp20_input_iterator<int*> begin() const;
+ sentinel_wrapper<cpp20_input_iterator<int*>> end() const;
+ };
+ static_assert( std::ranges::input_range<InputView>);
+ static_assert(!std::ranges::forward_range<InputView>);
+ static_assert( std::ranges::view<InputView>);
+
+ struct TinyView : std::ranges::view_base {
+ int x;
+ int* begin() const;
+ int* end() const;
+ constexpr static std::size_t size() { return 1; }
+ };
+ static_assert( std::ranges::forward_range<TinyView>);
+ static_assert( std::ranges::__tiny_range<TinyView>);
+ static_assert( std::ranges::view<TinyView>);
+
+ using SplitView = std::ranges::lazy_split_view<InputView, TinyView>;
+ using OuterIter = std::ranges::iterator_t<SplitView>;
+ // The `outer-iterator` only stores a pointer to the parent and a boolean (aligned to the size of a pointer), not an
+ // iterator.
+ static_assert(sizeof(OuterIter) == sizeof(void*) * 2);
+
+} // namespace test2
+
+// Verify the libc++-specific optimization that empty `View` and `Pattern` use the `[[no_unique_address]]` attribute.
+// Both `View` and `Pattern` are forward views.
+namespace test3 {
+
+ struct EmptyView1 : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+ };
+ static_assert( std::ranges::forward_range<EmptyView1>);
+ static_assert( std::ranges::view<EmptyView1>);
+
+ // Note: it's important to inherit `EmptyView1` and `EmptyView2` from different bases, otherwise they still cannot share
+ // the same address regardless of whether `[[no_unique_address]]` is used.
+ struct EmptyView2 : std::ranges::view_interface<EmptyView2> {
+ int* begin() const;
+ int* end() const;
+ };
+ static_assert( std::ranges::forward_range<EmptyView2>);
+ static_assert( std::ranges::view<EmptyView2>);
+
+ static_assert(sizeof(std::ranges::lazy_split_view<EmptyView1, EmptyView2>) == 1);
+
+} // namespace test3
+
+// Verify the libc++-specific optimization that empty `View` and `Pattern` use the `[[no_unique_address]]` attribute.
+// `View` is an input view and `Pattern` is a tiny view.
+namespace test4 {
+
+ struct EmptyInputView : std::ranges::view_base {
+ cpp20_input_iterator<int*> begin() const;
+ sentinel_wrapper<cpp20_input_iterator<int*>> end() const;
+ };
+ static_assert( std::ranges::input_range<EmptyInputView>);
+ static_assert(!std::ranges::forward_range<EmptyInputView>);
+ static_assert( std::ranges::view<EmptyInputView>);
+
+ struct EmptyTinyView : std::ranges::view_base {
+ int* begin() const;
+ int* end() const;
+ constexpr static std::size_t size() { return 1; }
+ };
+ static_assert( std::ranges::forward_range<EmptyTinyView>);
+ static_assert( std::ranges::__tiny_range<EmptyTinyView>);
+ static_assert( std::ranges::view<EmptyTinyView>);
+
+ static_assert(sizeof(std::ranges::lazy_split_view<EmptyInputView, EmptyTinyView>) ==
+ sizeof(std::ranges::__non_propagating_cache<std::ranges::iterator_t<EmptyInputView>>));
+
+} // namespace test4
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp
new file mode 100644
index 0000000000000..22ede4143ffa4
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/assert.equal.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <ranges>
+
+// friend constexpr bool operator==(const inner-iterator& x, default_sentinel_t);
+//
+// Can't compare a default-constructed `inner-iterator` with the default sentinel.
+
+#include <ranges>
+
+#include "check_assertion.h"
+#include "../types.h"
+
+int main(int, char**) {
+ {
+ InnerIterForward i;
+ TEST_LIBCPP_ASSERT_FAILURE(i == std::default_sentinel, "Cannot call comparison on a default-constructed iterator.");
+ }
+
+ {
+ InnerIterInput i;
+ TEST_LIBCPP_ASSERT_FAILURE(i == std::default_sentinel, "Cannot call comparison on a default-constructed iterator.");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp
new file mode 100644
index 0000000000000..b6cbf5241f744
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/assert.equal.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <ranges>
+
+// friend constexpr bool operator==(const inner-iterator& x, default_sentinel_t);
+//
+// Can't compare a default-constructed `inner-iterator` with the default sentinel.
+
+#include <ranges>
+
+#include "check_assertion.h"
+#include "../types.h"
+
+int main(int, char**) {
+ {
+ OuterIterForward i;
+ TEST_LIBCPP_ASSERT_FAILURE(i == std::default_sentinel, "Cannot call comparison on a default-constructed iterator.");
+ }
+
+ {
+ OuterIterInput i;
+ TEST_LIBCPP_ASSERT_FAILURE(i == std::default_sentinel, "Cannot call comparison on a default-constructed iterator.");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/types.h b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/types.h
new file mode 100644
index 0000000000000..12b0de9aa6330
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.lazy.split/types.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_LAZY_SPLIT_TYPES_H
+#define TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_LAZY_SPLIT_TYPES_H
+
+#include <concepts>
+#include <cstddef>
+#include <ranges>
+#include <string_view>
+#include "test_iterators.h"
+
+// ForwardView
+
+struct ForwardView : std::ranges::view_base {
+ constexpr explicit ForwardView() = default;
+ constexpr ForwardView(ForwardView&&) = default;
+ constexpr ForwardView& operator=(ForwardView&&) = default;
+ constexpr forward_iterator<const char*> begin() const { return forward_iterator<const char*>(nullptr); }
+ constexpr forward_iterator<const char*> end() const { return forward_iterator<const char*>(nullptr); }
+};
+static_assert( std::ranges::forward_range<ForwardView>);
+static_assert( std::ranges::forward_range<const ForwardView>);
+static_assert( std::ranges::view<ForwardView>);
+static_assert(!std::is_copy_constructible_v<ForwardView>);
+
+// InputView
+
+struct InputView : std::ranges::view_base {
+ constexpr InputView() = default;
+
+ constexpr cpp20_input_iterator<char*> begin() { return cpp20_input_iterator<char*>(nullptr); }
+ constexpr sentinel_wrapper<cpp20_input_iterator<char*>> end() {
+ return sentinel_wrapper(cpp20_input_iterator<char*>(nullptr));
+ }
+ constexpr cpp20_input_iterator<const char*> begin() const { return cpp20_input_iterator<const char*>(nullptr); }
+ constexpr sentinel_wrapper<cpp20_input_iterator<const char*>> end() const {
+ return sentinel_wrapper(cpp20_input_iterator<const char*>(nullptr));
+ }
+};
+
+static_assert(std::ranges::input_range<InputView>);
+static_assert(std::ranges::input_range<const InputView>);
+static_assert(std::ranges::view<InputView>);
+
+// ForwardTinyView
+
+struct ForwardTinyView : std::ranges::view_base {
+ constexpr ForwardTinyView() = default;
+ constexpr forward_iterator<const char*> begin() const { return forward_iterator<const char*>(nullptr); }
+ constexpr forward_iterator<const char*> end() const { return forward_iterator<const char*>(nullptr); }
+ constexpr static std::size_t size() { return 1; }
+};
+static_assert(std::ranges::forward_range<ForwardTinyView>);
+static_assert(std::ranges::view<ForwardTinyView>);
+LIBCPP_STATIC_ASSERT(std::ranges::__tiny_range<ForwardTinyView>);
+
+// Aliases
+
+using SplitViewForward = std::ranges::lazy_split_view<ForwardView, ForwardView>;
+using OuterIterForward = std::ranges::iterator_t<SplitViewForward>;
+using InnerIterForward = std::ranges::iterator_t<OuterIterForward::value_type>;
+
+using SplitViewInput = std::ranges::lazy_split_view<InputView, ForwardTinyView>;
+using OuterIterInput = std::ranges::iterator_t<SplitViewInput>;
+using InnerIterInput = std::ranges::iterator_t<OuterIterInput::value_type>;
+
+#endif // TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_LAZY_SPLIT_TYPES_H
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/arrow.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/arrow.pass.cpp
new file mode 100644
index 0000000000000..a6764284e7f7e
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/arrow.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
+
+// T* <copyable-box>::operator->()
+// const T* <copyable-box>::operator->() const
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility> // in_place_t
+
+#include "types.h"
+
+template <class T>
+constexpr void check() {
+ // non-const version
+ {
+ std::ranges::__movable_box<T> x(std::in_place, 10);
+ T* result = x.operator->();
+ static_assert(noexcept(x.operator->()));
+ assert(result->value == 10);
+ assert(x->value == 10);
+ }
+
+ // const version
+ {
+ std::ranges::__movable_box<T> const x(std::in_place, 10);
+ const T* result = x.operator->();
+ static_assert(noexcept(x.operator->()));
+ assert(result->value == 10);
+ assert(x->value == 10);
+ }
+}
+
+constexpr bool test() {
+ check<CopyConstructible>(); // primary template
+ check<Copyable>(); // optimization #1
+ check<NothrowCopyConstructible>(); // optimization #2
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.copy.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.copy.pass.cpp
new file mode 100644
index 0000000000000..94c4dec2687b7
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.copy.pass.cpp
@@ -0,0 +1,168 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <copyable-box>& operator=(<copyable-box> const&)
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-self-assign-overloaded
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility> // in_place_t
+
+#include "test_macros.h"
+#include "types.h"
+
+constexpr bool test() {
+ // Test the primary template
+ {
+ using Box = std::ranges::__movable_box<CopyConstructible>;
+ static_assert(std::is_copy_assignable_v<Box>);
+ static_assert(!std::is_nothrow_copy_assignable_v<Box>);
+
+ {
+ Box x(std::in_place, 5);
+ Box const y(std::in_place, 10);
+ Box& result = (x = y);
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ }
+ // check self-assignment
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = x);
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ }
+ }
+
+ // Test optimization #1 for copy-assignment
+ {
+ using Box = std::ranges::__movable_box<Copyable>;
+ static_assert(std::is_copy_assignable_v<Box>);
+ static_assert(!std::is_nothrow_copy_assignable_v<Box>);
+
+ {
+ Box x(std::in_place, 5);
+ Box const y(std::in_place, 10);
+ Box& result = (x = y);
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ assert((*x).did_copy_assign);
+ }
+ // check self-assignment (should use the underlying type's assignment too)
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = x);
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ assert((*x).did_copy_assign);
+ }
+ }
+
+ // Test optimization #2 for copy-assignment
+ {
+ using Box = std::ranges::__movable_box<NothrowCopyConstructible>;
+ static_assert(std::is_copy_assignable_v<Box>);
+ static_assert(std::is_nothrow_copy_assignable_v<Box>);
+
+ {
+ Box x(std::in_place, 5);
+ Box const y(std::in_place, 10);
+ Box& result = (x = y);
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ }
+ // check self-assignment
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = x);
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ }
+ }
+
+ return true;
+}
+
+// Tests for the empty state. Those can't be constexpr, since they are only reached
+// through throwing an exception.
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+void test_empty_state() {
+ using Box = std::ranges::__movable_box<ThrowsOnCopy>;
+
+ // assign non-empty to empty
+ {
+ Box x = create_empty_box();
+ Box const y(std::in_place, 10);
+ Box& result = (x = y);
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ }
+ // assign empty to non-empty
+ {
+ Box x(std::in_place, 5);
+ Box const y = create_empty_box();
+ Box& result = (x = y);
+
+ assert(&result == &x);
+ assert(!x.__has_value());
+ assert(!y.__has_value());
+ }
+ // assign empty to empty
+ {
+ Box x = create_empty_box();
+ Box const y = create_empty_box();
+ Box& result = (x = y);
+
+ assert(&result == &x);
+ assert(!x.__has_value());
+ assert(!y.__has_value());
+ }
+ // check self-assignment in empty case
+ {
+ Box x = create_empty_box();
+ Box& result = (x = x);
+
+ assert(&result == &x);
+ assert(!x.__has_value());
+ }
+}
+#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ test_empty_state();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.move.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.move.pass.cpp
new file mode 100644
index 0000000000000..d4dc612a8de63
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/assign.move.pass.cpp
@@ -0,0 +1,228 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <copyable-box>& operator=(<copyable-box>&&)
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-self-move
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility> // in_place_t
+
+#include "test_macros.h"
+#include "types.h"
+
+constexpr bool test() {
+ // Test the primary template
+ {
+ using Box = std::ranges::__movable_box<CopyConstructible>;
+ static_assert(std::is_move_assignable_v<Box>);
+ static_assert(!std::is_nothrow_move_assignable_v<Box>);
+
+ {
+ Box x(std::in_place, 5);
+ Box y(std::in_place, 10);
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ }
+ // check self-assignment
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = std::move(x));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ }
+ }
+
+ // Make sure that we use the native move assignment in the primary template if we can.
+ {
+ using Box = std::ranges::__movable_box<CopyConstructibleMovable>;
+ static_assert(std::is_move_assignable_v<Box>);
+ static_assert(
+ std::is_nothrow_move_assignable_v<Box> == std::is_nothrow_move_assignable_v<CopyConstructibleMovable>);
+
+ {
+ Box x(std::in_place, 5);
+ Box y(std::in_place, 10);
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ assert((*x).did_move_assign);
+ }
+ // check self-assignment
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = std::move(x));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ assert((*x).did_move_assign);
+ }
+ }
+
+ // Test optimization #1 for move assignment
+ {
+ using Box = std::ranges::__movable_box<Copyable>;
+ static_assert(std::is_move_assignable_v<Box>);
+ static_assert(!std::is_nothrow_move_assignable_v<Box>);
+
+ {
+ Box x(std::in_place, 5);
+ Box y(std::in_place, 10);
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ assert((*x).did_move_assign);
+ }
+ // check self-assignment (should use the underlying type's assignment too)
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = std::move(x));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ assert((*x).did_move_assign);
+ }
+ }
+
+ // Test optimization #1 for move assignment with a type that uses optimization #2 for copy assignment
+ {
+ using Box = std::ranges::__movable_box<MovableNothrowCopyConstructible>;
+ static_assert(std::is_move_assignable_v<Box>);
+ static_assert(
+ std::is_nothrow_move_assignable_v<Box> == std::is_nothrow_move_assignable_v<MovableNothrowCopyConstructible>);
+
+ {
+ Box x(std::in_place, 5);
+ Box y(std::in_place, 10);
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ assert((*x).did_move_assign);
+ }
+ // check self-assignment (should use the underlying type's assignment too)
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = std::move(x));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ assert((*x).did_move_assign);
+ }
+ }
+
+ // Test optimization #2 for move assignment
+ {
+ using Box = std::ranges::__movable_box<NothrowCopyConstructible>;
+ static_assert(std::is_move_assignable_v<Box>);
+ static_assert(std::is_nothrow_move_assignable_v<Box>);
+
+ {
+ Box x(std::in_place, 5);
+ Box y(std::in_place, 10);
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ }
+ // check self-assignment
+ {
+ Box x(std::in_place, 5);
+ Box& result = (x = std::move(x));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert((*x).value == 5);
+ }
+ }
+
+ return true;
+}
+
+// Tests for the empty state. Those can't be constexpr, since they are only reached
+// through throwing an exception.
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+void test_empty_state() {
+ using Box = std::ranges::__movable_box<ThrowsOnCopy>;
+
+ // assign non-empty to empty
+ {
+ Box x = create_empty_box();
+ Box y(std::in_place, 10);
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(x.__has_value());
+ assert(y.__has_value());
+ assert((*x).value == 10);
+ }
+ // assign empty to non-empty
+ {
+ Box x(std::in_place, 5);
+ Box y = create_empty_box();
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(!x.__has_value());
+ assert(!y.__has_value());
+ }
+ // assign empty to empty
+ {
+ Box x = create_empty_box();
+ Box y = create_empty_box();
+ Box& result = (x = std::move(y));
+
+ assert(&result == &x);
+ assert(!x.__has_value());
+ assert(!y.__has_value());
+ }
+ // check self-assignment in empty case
+ {
+ Box x = create_empty_box();
+ Box& result = (x = std::move(x));
+
+ assert(&result == &x);
+ assert(!x.__has_value());
+ }
+}
+#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ test_empty_state();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.default.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.default.pass.cpp
new file mode 100644
index 0000000000000..3014dc00ca970
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.default.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <copyable-box>::<copyable-box>()
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility> // in_place_t
+
+#include "types.h"
+
+template <class T>
+using Box = std::ranges::__movable_box<T>;
+
+struct NoDefault {
+ NoDefault() = delete;
+};
+static_assert(!std::is_default_constructible_v<Box<NoDefault>>);
+
+template <bool Noexcept>
+struct DefaultNoexcept {
+ DefaultNoexcept() noexcept(Noexcept);
+};
+static_assert(std::is_nothrow_default_constructible_v<Box<DefaultNoexcept<true>>>);
+static_assert(!std::is_nothrow_default_constructible_v<Box<DefaultNoexcept<false>>>);
+
+constexpr bool test() {
+ // check primary template
+ {
+ Box<CopyConstructible> box;
+ assert(box.__has_value());
+ assert((*box).value == CopyConstructible().value);
+ }
+
+ // check optimization #1
+ {
+ Box<Copyable> box;
+ assert(box.__has_value());
+ assert((*box).value == Copyable().value);
+ }
+
+ // check optimization #2
+ {
+ Box<NothrowCopyConstructible> box;
+ assert(box.__has_value());
+ assert((*box).value == NothrowCopyConstructible().value);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.in_place.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.in_place.pass.cpp
new file mode 100644
index 0000000000000..6f97b7eb0b9be
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/ctor.in_place.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
+
+// template<class ...Args>
+// explicit <copyable-box>::<copyable-box>(in_place_t, Args&& ...args);
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility> // in_place_t
+
+#include "types.h"
+
+struct UnknownType {};
+
+template <bool Noexcept>
+struct NothrowConstructible {
+ explicit NothrowConstructible(int) noexcept(Noexcept);
+};
+
+constexpr bool test() {
+ // Test the primary template
+ {
+ using Box = std::ranges::__movable_box<CopyConstructible>;
+ Box x(std::in_place, 5);
+ assert((*x).value == 5);
+
+ static_assert(!std::is_constructible_v<Box, std::in_place_t, UnknownType>);
+ }
+
+ // Test optimization #1
+ {
+ using Box = std::ranges::__movable_box<Copyable>;
+ Box x(std::in_place, 5);
+ assert((*x).value == 5);
+
+ static_assert(!std::is_constructible_v<Box, std::in_place_t, UnknownType>);
+ }
+
+ // Test optimization #2
+ {
+ using Box = std::ranges::__movable_box<NothrowCopyConstructible>;
+ Box x(std::in_place, 5);
+ assert((*x).value == 5);
+
+ static_assert(!std::is_constructible_v<Box, std::in_place_t, UnknownType>);
+ }
+
+ static_assert(
+ std::is_nothrow_constructible_v<std::ranges::__movable_box<NothrowConstructible<true>>, std::in_place_t, int>);
+ static_assert(
+ !std::is_nothrow_constructible_v<std::ranges::__movable_box<NothrowConstructible<false>>, std::in_place_t, int>);
+
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/deref.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/deref.pass.cpp
new file mode 100644
index 0000000000000..37734f05a15b5
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/deref.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
+
+// T& <copyable-box>::operator*()
+// T const& <copyable-box>::operator*() const
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility> // in_place_t
+
+#include "types.h"
+
+template <class T>
+constexpr void check() {
+ // non-const version
+ {
+ std::ranges::__movable_box<T> x(std::in_place, 10);
+ T& result = *x;
+ static_assert(noexcept(*x));
+ assert(result.value == 10);
+ }
+
+ // const version
+ {
+ std::ranges::__movable_box<T> const x(std::in_place, 10);
+ T const& result = *x;
+ static_assert(noexcept(*x));
+ assert(result.value == 10);
+ }
+}
+
+constexpr bool test() {
+ check<CopyConstructible>(); // primary template
+ check<Copyable>(); // optimization #1
+ check<NothrowCopyConstructible>(); // optimization #2
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/empty_object.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/empty_object.pass.cpp
new file mode 100644
index 0000000000000..9712635a0010b
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/empty_object.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// This test ensures that <movable-box> behaves correctly when it holds an empty type.
+
+#include <ranges>
+
+#include <cassert>
+#include <utility>
+
+bool copied = false;
+bool moved = false;
+
+struct Empty {
+ Empty() noexcept {}
+ Empty(Empty const&) noexcept { copied = true; }
+ Empty(Empty&&) noexcept { moved = true; }
+ Empty& operator=(Empty const&) = delete;
+ Empty& operator=(Empty&&) = delete;
+};
+
+using Box = std::ranges::__movable_box<Empty>;
+
+struct Inherit : Box {};
+
+struct Hold : Box {
+ [[no_unique_address]] Inherit member;
+};
+
+int main(int, char**) {
+ Hold box;
+
+ Box& base = static_cast<Box&>(box);
+ Box& member = static_cast<Box&>(box.member);
+
+ // Despite [[no_unique_address]], the two objects have the same type so they
+ // can't share the same address.
+ assert(&base != &member);
+
+ // Make sure that we do perform the copy-construction, which wouldn't be the
+ // case if the two <movable-box>s had the same address.
+ base = member;
+ assert(copied);
+
+ base = std::move(member);
+ assert(moved);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/has_value.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/has_value.pass.cpp
new file mode 100644
index 0000000000000..397e6384b2afc
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/has_value.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
+
+// bool <copyable-box>::__has_value() const
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility> // in_place_t
+
+#include "types.h"
+
+template <class T>
+constexpr void check() {
+ std::ranges::__movable_box<T> const x(std::in_place, 10);
+ assert(x.__has_value());
+}
+
+constexpr bool test() {
+ check<CopyConstructible>(); // primary template
+ check<Copyable>(); // optimization #1
+ check<NothrowCopyConstructible>(); // optimization #2
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+
+ // Tests for the empty state. Those can't be constexpr, since they are only reached
+ // through throwing an exception.
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ {
+ std::ranges::__movable_box<ThrowsOnCopy> x = create_empty_box();
+ assert(!x.__has_value());
+ }
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/no_unique_address.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/no_unique_address.pass.cpp
new file mode 100644
index 0000000000000..4ec6c888f9c1c
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/no_unique_address.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
+
+// clang-cl and cl currently don't support [[no_unique_address]]
+// XFAIL: msvc
+
+#include <ranges>
+
+#include <cassert>
+#include <utility>
+
+#include "test_macros.h"
+
+template <class T, bool ExpectNoUniqueAddress>
+void test_no_unique_address() {
+ struct Test {
+ [[no_unique_address]] std::ranges::__movable_box<T> box_;
+ bool b2;
+ };
+
+ if constexpr (ExpectNoUniqueAddress) {
+ static_assert(sizeof(Test) == sizeof(bool));
+ } else {
+ static_assert(sizeof(Test) > sizeof(bool));
+ }
+}
+
+struct Copyable {};
+
+struct NotCopyAssignable {
+ constexpr NotCopyAssignable() = default;
+ constexpr NotCopyAssignable(const NotCopyAssignable&) = default;
+ NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+struct NotMoveAssignable {
+ constexpr NotMoveAssignable() = default;
+ constexpr NotMoveAssignable(const NotMoveAssignable&) = default;
+ NotMoveAssignable& operator=(const NotMoveAssignable&) = default;
+ constexpr NotMoveAssignable(NotMoveAssignable&&) = default;
+ NotMoveAssignable& operator=(NotMoveAssignable&&) = delete;
+};
+
+struct MoveOnly {
+ constexpr MoveOnly() = default;
+ constexpr MoveOnly(const MoveOnly&) = delete;
+ MoveOnly& operator=(const MoveOnly&) = delete;
+ constexpr MoveOnly(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly&&) = default;
+};
+
+struct MoveOnlyNotAssignable {
+ constexpr MoveOnlyNotAssignable() = default;
+ constexpr MoveOnlyNotAssignable(const MoveOnlyNotAssignable&) = delete;
+ MoveOnlyNotAssignable& operator=(const MoveOnlyNotAssignable&) = delete;
+ constexpr MoveOnlyNotAssignable(MoveOnlyNotAssignable&&) = default;
+ MoveOnlyNotAssignable& operator=(MoveOnlyNotAssignable&&) = delete;
+};
+
+int main(int, char**) {
+ test_no_unique_address<Copyable, true>();
+ test_no_unique_address<NotCopyAssignable, false>();
+ test_no_unique_address<NotMoveAssignable, false>();
+
+#if TEST_STD_VER >= 23
+ test_no_unique_address<MoveOnly, true>();
+ test_no_unique_address<MoveOnlyNotAssignable, false>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/properties.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/properties.compile.pass.cpp
new file mode 100644
index 0000000000000..6596c7074117f
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/properties.compile.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test various properties of <copyable-box>
+
+#include <ranges>
+
+#include <optional>
+
+#include "MoveOnly.h"
+
+#include "types.h"
+
+template <class T>
+constexpr bool valid_movable_box = requires { typename std::ranges::__movable_box<T>; };
+
+struct NotCopyConstructible {
+ NotCopyConstructible() = default;
+ NotCopyConstructible(NotCopyConstructible&&) = default;
+ NotCopyConstructible(NotCopyConstructible const&) = delete;
+ NotCopyConstructible& operator=(NotCopyConstructible&&) = default;
+ NotCopyConstructible& operator=(NotCopyConstructible const&) = default;
+};
+
+static_assert(!valid_movable_box<void>); // not an object type
+static_assert(!valid_movable_box<int&>); // not an object type
+
+#if _LIBCPP_STD_VER >= 23
+struct NotCopyConstructibleNotMoveConstructible {
+ NotCopyConstructibleNotMoveConstructible() = default;
+ NotCopyConstructibleNotMoveConstructible(NotCopyConstructibleNotMoveConstructible&&) = delete;
+ NotCopyConstructibleNotMoveConstructible(NotCopyConstructibleNotMoveConstructible const&) = delete;
+ NotCopyConstructibleNotMoveConstructible& operator=(NotCopyConstructibleNotMoveConstructible&&) = delete;
+ NotCopyConstructibleNotMoveConstructible& operator=(NotCopyConstructibleNotMoveConstructible const&) = delete;
+};
+
+// [P2494R2] Relaxing range adaptors to allow for move only types.
+static_assert(!valid_movable_box<NotCopyConstructibleNotMoveConstructible>);
+static_assert(valid_movable_box<NotCopyConstructible>);
+static_assert(valid_movable_box<MoveOnly>);
+#else
+static_assert(!valid_movable_box<NotCopyConstructible>);
+#endif
+
+// primary template
+static_assert(sizeof(std::ranges::__movable_box<CopyConstructible>) == sizeof(std::optional<CopyConstructible>));
+
+// optimization #1
+static_assert(sizeof(std::ranges::__movable_box<Copyable>) == sizeof(Copyable));
+static_assert(alignof(std::ranges::__movable_box<Copyable>) == alignof(Copyable));
+
+// optimization #2
+static_assert(sizeof(std::ranges::__movable_box<NothrowCopyConstructible>) == sizeof(NothrowCopyConstructible));
+static_assert(alignof(std::ranges::__movable_box<NothrowCopyConstructible>) == alignof(NothrowCopyConstructible));
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/types.h b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/types.h
new file mode 100644
index 0000000000000..9e6bf5d89c18e
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.move.wrap/types.h
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_COPY_WRAP_TYPES_H
+#define TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_COPY_WRAP_TYPES_H
+
+#include <ranges>
+#include <cassert>
+#include <concepts>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// NOTE: These types are strongly tied to the implementation of __movable_box. See the documentation
+// in __movable_box for the meaning of optimizations #1 and #2.
+
+// Copy constructible, but neither copyable nor nothrow_copy/move_constructible. This uses the primary template.
+struct CopyConstructible {
+ constexpr CopyConstructible() = default;
+ constexpr explicit CopyConstructible(int x) : value(x) {}
+ CopyConstructible(CopyConstructible const&) noexcept(false) = default;
+ CopyConstructible& operator=(CopyConstructible const&) = delete;
+
+ int value = -1;
+};
+static_assert(!std::copyable<CopyConstructible>);
+static_assert(!std::is_nothrow_copy_constructible_v<CopyConstructible>);
+static_assert(!std::movable<CopyConstructible>);
+static_assert(!std::is_nothrow_move_constructible_v<CopyConstructible>);
+
+// Copy constructible and movable, but not copyable. This uses the primary template, however we're
+// still able to use the native move-assignment operator in this case.
+struct CopyConstructibleMovable {
+ constexpr CopyConstructibleMovable() = default;
+ constexpr explicit CopyConstructibleMovable(int x) : value(x) {}
+ CopyConstructibleMovable(CopyConstructibleMovable const&) noexcept(false) = default;
+ CopyConstructibleMovable(CopyConstructibleMovable&&) noexcept(false) = default;
+ CopyConstructibleMovable& operator=(CopyConstructibleMovable const&) = delete;
+
+ constexpr CopyConstructibleMovable& operator=(CopyConstructibleMovable&& other) {
+ value = other.value;
+ did_move_assign = true;
+ return *this;
+ }
+
+ int value = -1;
+ bool did_move_assign = false;
+};
+
+// Copyable type that is not nothrow_copy/move_constructible.
+// This triggers optimization #1 for the copy assignment and the move assignment.
+struct Copyable {
+ constexpr Copyable() = default;
+ constexpr explicit Copyable(int x) : value(x) {}
+ Copyable(Copyable const&) noexcept(false) = default;
+
+ constexpr Copyable& operator=(Copyable const& other) noexcept(false) {
+ value = other.value;
+ did_copy_assign = true;
+ return *this;
+ }
+
+ constexpr Copyable& operator=(Copyable&& other) noexcept(false) {
+ value = other.value;
+ did_move_assign = true;
+ return *this;
+ }
+
+ int value = -1;
+ bool did_copy_assign = false;
+ bool did_move_assign = false;
+};
+static_assert(std::copyable<Copyable>);
+static_assert(!std::is_nothrow_copy_constructible_v<Copyable>);
+static_assert(std::movable<Copyable>);
+static_assert(!std::is_nothrow_move_constructible_v<Copyable>);
+
+// Non-copyable type that is nothrow_copy_constructible and nothrow_move_constructible.
+// This triggers optimization #2 for the copy assignment and the move assignment.
+struct NothrowCopyConstructible {
+ constexpr NothrowCopyConstructible() = default;
+ constexpr explicit NothrowCopyConstructible(int x) : value(x) {}
+ NothrowCopyConstructible(NothrowCopyConstructible const&) noexcept = default;
+ NothrowCopyConstructible(NothrowCopyConstructible&&) noexcept = default;
+ NothrowCopyConstructible& operator=(NothrowCopyConstructible const&) = delete;
+
+ int value = -1;
+};
+static_assert(!std::copyable<NothrowCopyConstructible>);
+static_assert(std::is_nothrow_copy_constructible_v<NothrowCopyConstructible>);
+static_assert(!std::movable<NothrowCopyConstructible>);
+static_assert(std::is_nothrow_move_constructible_v<NothrowCopyConstructible>);
+
+// Non-copyable type that is nothrow_copy_constructible, and that is movable but NOT nothrow_move_constructible.
+// This triggers optimization #2 for the copy assignment, and optimization #1 for the move assignment.
+struct MovableNothrowCopyConstructible {
+ constexpr MovableNothrowCopyConstructible() = default;
+ constexpr explicit MovableNothrowCopyConstructible(int x) : value(x) {}
+ MovableNothrowCopyConstructible(MovableNothrowCopyConstructible const&) noexcept = default;
+ MovableNothrowCopyConstructible(MovableNothrowCopyConstructible&&) noexcept(false) = default;
+ constexpr MovableNothrowCopyConstructible& operator=(MovableNothrowCopyConstructible&& other) {
+ value = other.value;
+ did_move_assign = true;
+ return *this;
+ }
+
+ int value = -1;
+ bool did_move_assign = false;
+};
+static_assert(!std::copyable<MovableNothrowCopyConstructible>);
+static_assert(std::is_nothrow_copy_constructible_v<MovableNothrowCopyConstructible>);
+static_assert(std::movable<MovableNothrowCopyConstructible>);
+static_assert(!std::is_nothrow_move_constructible_v<MovableNothrowCopyConstructible>);
+
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+// A type that we can make throw when copied from. This is used to create a
+// copyable-box in the empty state.
+static constexpr int THROW_WHEN_COPIED_FROM = 999;
+struct ThrowsOnCopy {
+ constexpr ThrowsOnCopy() = default;
+ constexpr explicit ThrowsOnCopy(int x) : value(x) {}
+ ThrowsOnCopy(ThrowsOnCopy const& other) {
+ if (other.value == THROW_WHEN_COPIED_FROM)
+ throw 0;
+ else
+ value = other.value;
+ }
+
+ ThrowsOnCopy& operator=(ThrowsOnCopy const&) = delete; // prevent from being copyable
+
+ int value = -1;
+};
+
+// Creates an empty box. The only way to do that is to try assigning one box
+// to another and have that fail due to an exception when calling the copy
+// constructor. The assigned-to box will then be in the empty state.
+inline std::ranges::__movable_box<ThrowsOnCopy> create_empty_box() {
+ std::ranges::__movable_box<ThrowsOnCopy> box1;
+ std::ranges::__movable_box<ThrowsOnCopy> box2(std::in_place, THROW_WHEN_COPIED_FROM);
+ try {
+ box1 = box2; // throws during assignment, which is implemented as a call to the copy ctor
+ } catch (...) {
+ // now, box1 is empty
+ assert(!box1.__has_value());
+ return box1;
+ }
+ assert(false && "should never be reached");
+ return box1; // to silence warning about missing return in non-void function
+}
+#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
+
+#endif // TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_COPY_WRAP_TYPES_H
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.reverse/adaptor.nodiscard.verify.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.reverse/adaptor.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..2f7eb94611928
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.reverse/adaptor.nodiscard.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Test the libc++ extension that std::views::reverse is marked as [[nodiscard]].
+
+#include <ranges>
+
+void test() {
+ int range[] = {1, 2, 3};
+
+ std::views::reverse(range); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::views::reverse; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all | std::views::reverse; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.adaptors/range.split/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.split/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..7950827dcc868
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.split/no_unique_address.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// 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/libcxx/test/libcxx-03/ranges/range.adaptors/range.transform/adaptor.nodiscard.verify.cpp b/libcxx/test/libcxx-03/ranges/range.adaptors/range.transform/adaptor.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..0a5fbf72a83ee
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.adaptors/range.transform/adaptor.nodiscard.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test the libc++ extension that std::views::transform is marked as [[nodiscard]].
+
+#include <ranges>
+
+void test() {
+ int range[] = {1, 2, 3};
+ auto f = [](int i) { return i; };
+
+ std::views::transform(f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::transform(range, f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ range | std::views::transform(f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::views::all | std::views::transform(f); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.factories/range.istream.view/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.factories/range.istream.view/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..56d973d411408
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.factories/range.istream.view/no_unique_address.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: no-localization
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Test the libc++ extension that the value stored in `std::ranges::istream_view` has been marked
+// as _LIBCPP_NO_UNIQUE_ADDRESS
+
+#include <istream>
+#include <ranges>
+
+struct Empty {
+ friend std::istream& operator>>(std::istream& i, Empty const&) { return i; }
+};
+
+static_assert(sizeof(std::ranges::istream_view<Empty>) == sizeof(void*));
diff --git a/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp b/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp
new file mode 100644
index 0000000000000..6d4e541d98906
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.piecewise.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// REQUIRES: has-unix-headers
+// XFAIL: availability-verbose_abort-missing
+
+// template<class... TArgs, class... BoundArgs>
+// requires constructible_from<T, TArgs...> &&
+// constructible_from<Bound, BoundArgs...>
+// constexpr explicit repeat_view(piecewise_construct_t,
+// tuple<TArgs...> value_args, tuple<BoundArgs...> bound_args = tuple<>{});
+
+#include <ranges>
+#include <tuple>
+
+#include "check_assertion.h"
+
+// clang-format off
+int main(int, char**) {
+ using Repeat = std::ranges::repeat_view<int, int>;
+ TEST_LIBCPP_ASSERT_FAILURE(Repeat(std::piecewise_construct, std::tuple{1}, std::tuple{-1}), "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
+
+ return 0;
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.value.bound.pass.cpp b/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.value.bound.pass.cpp
new file mode 100644
index 0000000000000..2e9c74bc35978
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/ctor.value.bound.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, c++20
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// REQUIRES: has-unix-headers
+// XFAIL: availability-verbose_abort-missing
+
+// constexpr explicit repeat_view(W&& value, Bound bound = Bound());
+// constexpr explicit repeat_view(const W& value, Bound bound = Bound());
+
+#include <ranges>
+
+#include "check_assertion.h"
+
+// clang-format off
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::repeat_view(0, -1), "The value of bound must be greater than or equal to 0");
+ const int val = 0;
+ TEST_LIBCPP_ASSERT_FAILURE(std::ranges::repeat_view(val, -1), "The value of bound must be greater than or equal to 0");
+
+ return 0;
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..6ab2ee173ca1b
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.factories/range.repeat.view/no_unique_address.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// XFAIL: msvc
+
+// This test ensures that we use `[[no_unique_address]]` in `repeat_view`.
+
+#include <ranges>
+
+struct Empty {};
+
+struct Test {
+ [[no_unique_address]] std::ranges::repeat_view<Empty> v;
+ bool b;
+};
+
+static_assert(sizeof(Test) == sizeof(bool));
diff --git a/libcxx/test/libcxx-03/ranges/range.factories/range.single.view/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.factories/range.single.view/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..10883b8385780
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.factories/range.single.view/no_unique_address.compile.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// XFAIL: msvc
+
+// This test ensures that we use `[[no_unique_address]]` in `single_view`.
+
+#include <ranges>
+
+struct Empty {};
+
+struct Test {
+ [[no_unique_address]] std::ranges::single_view<Empty> v;
+ bool b;
+};
+
+static_assert(sizeof(Test) == sizeof(bool));
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.copy.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.copy.pass.cpp
new file mode 100644
index 0000000000000..598aeb3a13254
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.copy.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// __non_propagating_cache& operator=(__non_propagating_cache const&);
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-self-assign
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+template<bool NoexceptCopy>
+struct CopyAssignable {
+ int x;
+ constexpr explicit CopyAssignable(int i) : x(i) { }
+ CopyAssignable(CopyAssignable const&) = default;
+ constexpr CopyAssignable& operator=(CopyAssignable const& other) noexcept(NoexceptCopy) {
+ x = other.x;
+ return *this;
+ }
+ constexpr bool operator==(CopyAssignable const& other) const { return x == other.x; }
+};
+
+struct NotCopyAssignable {
+ int x;
+ constexpr explicit NotCopyAssignable(int i) : x(i) { }
+ NotCopyAssignable(NotCopyAssignable const&) = default;
+ NotCopyAssignable& operator=(NotCopyAssignable const&) = delete;
+ constexpr bool operator==(NotCopyAssignable const& other) const { return x == other.x; }
+};
+
+template <class T>
+constexpr void test() {
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ static_assert(std::is_nothrow_copy_assignable_v<Cache>);
+
+ // Assign to an empty cache
+ {
+ Cache a; a.__emplace(3);
+ Cache b;
+
+ Cache& result = (b = a);
+ assert(&result == &b);
+ assert(!b.__has_value()); // make sure we don't propagate
+
+ assert(a.__has_value()); // make sure we don't "steal" from the source
+ assert(*a == T{3}); //
+ }
+
+ // Assign to a non-empty cache
+ {
+ Cache a; a.__emplace(3);
+ Cache b; b.__emplace(5);
+
+ Cache& result = (b = a);
+ assert(&result == &b);
+ assert(!b.__has_value()); // make sure we don't propagate
+
+ assert(a.__has_value()); // make sure we don't "steal" from the source
+ assert(*a == T{3}); //
+ }
+
+ // Self-assignment should not do anything (case with empty cache)
+ {
+ Cache b;
+ Cache& result = (b = b);
+ assert(&result == &b);
+ assert(!b.__has_value());
+ }
+
+ // Self-assignment should not do anything (case with non-empty cache)
+ {
+ Cache b; b.__emplace(5);
+ Cache& result = (b = b);
+ assert(&result == &b);
+ assert(b.__has_value());
+ assert(*b == T{5});
+ }
+}
+
+constexpr bool tests() {
+ test<CopyAssignable<true>>();
+ test<CopyAssignable<false>>();
+ test<NotCopyAssignable>();
+ test<int>();
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.move.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.move.pass.cpp
new file mode 100644
index 0000000000000..84fc092d5479e
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/assign.move.pass.cpp
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// __non_propagating_cache& operator=(__non_propagating_cache&&);
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-self-assign
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+template<bool NoexceptMove>
+struct MoveAssignable {
+ int x;
+ constexpr explicit MoveAssignable(int i) : x(i) { }
+ MoveAssignable(MoveAssignable&&) = default;
+ constexpr MoveAssignable& operator=(MoveAssignable&& other) noexcept(NoexceptMove) {
+ x = other.x;
+ other.x = -1;
+ return *this;
+ }
+};
+
+struct NotMoveAssignable {
+ int x;
+ constexpr explicit NotMoveAssignable(int i) : x(i) { }
+ NotMoveAssignable(NotMoveAssignable&&) = default;
+ NotMoveAssignable& operator=(NotMoveAssignable&&) = delete;
+};
+
+template <class T>
+constexpr void test() {
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ static_assert(std::is_nothrow_move_assignable_v<Cache>);
+
+ // Assign to an empty cache
+ {
+ Cache a; a.__emplace(3);
+ Cache b;
+
+ Cache& result = (b = std::move(a));
+ assert(&result == &b);
+ assert(!b.__has_value()); // make sure we don't propagate
+ assert(!a.__has_value()); // make sure we disengage the source
+ }
+
+ // Assign to a non-empty cache
+ {
+ Cache a; a.__emplace(3);
+ Cache b; b.__emplace(5);
+
+ Cache& result = (b = std::move(a));
+ assert(&result == &b);
+ assert(!b.__has_value()); // make sure we don't propagate
+ assert(!a.__has_value()); // make sure we disengage the source
+ }
+
+ // Self-assignment should clear the cache (case with empty cache)
+ {
+ Cache b;
+
+ Cache& result = (b = std::move(b));
+ assert(&result == &b);
+ assert(!b.__has_value());
+ }
+
+ // Self-assignment should clear the cache (case with non-empty cache)
+ {
+ Cache b; b.__emplace(5);
+
+ Cache& result = (b = std::move(b));
+ assert(&result == &b);
+ assert(!b.__has_value());
+ }
+}
+
+constexpr bool tests() {
+ test<MoveAssignable<true>>();
+ test<MoveAssignable<false>>();
+ test<NotMoveAssignable>();
+ test<int>();
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/constraints.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/constraints.compile.pass.cpp
new file mode 100644
index 0000000000000..407b9df273151
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/constraints.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+// requires is_object_v<T>
+// class non-propagating-cache;
+
+#include <ranges>
+
+template<template<class...> class T, class ...Args>
+concept well_formed = requires {
+ typename T<Args...>;
+};
+
+struct T { };
+static_assert( well_formed<std::ranges::__non_propagating_cache, int>);
+static_assert( well_formed<std::ranges::__non_propagating_cache, T>);
+static_assert( well_formed<std::ranges::__non_propagating_cache, void (*)()>);
+static_assert(!well_formed<std::ranges::__non_propagating_cache, void>);
+static_assert(!well_formed<std::ranges::__non_propagating_cache, T&>);
+static_assert(!well_formed<std::ranges::__non_propagating_cache, void()>);
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.copy.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.copy.pass.cpp
new file mode 100644
index 0000000000000..e20c32dd3dd99
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.copy.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
+
+// __non_propagating_cache(__non_propagating_cache const&);
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+
+template<bool NoexceptCopy>
+struct CopyConstructible {
+ int x;
+ constexpr explicit CopyConstructible(int i) : x(i) { }
+ constexpr CopyConstructible(CopyConstructible const& other) noexcept(NoexceptCopy) : x(other.x) { }
+ CopyConstructible& operator=(CopyConstructible const&) = default;
+ constexpr bool operator==(CopyConstructible const& other) const { return x == other.x; }
+};
+
+struct NotCopyConstructible {
+ int x;
+ constexpr explicit NotCopyConstructible(int i) : x(i) { }
+ NotCopyConstructible(NotCopyConstructible const&) = delete;
+ NotCopyConstructible(NotCopyConstructible&&) = default;
+ constexpr bool operator==(NotCopyConstructible const& other) const { return x == other.x; }
+};
+
+template <class T>
+constexpr void test() {
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ static_assert(std::is_nothrow_copy_constructible_v<Cache>);
+ Cache a;
+ a.__emplace(3);
+
+ // Test with direct initialization
+ {
+ Cache b(a);
+ assert(!b.__has_value()); // make sure we don't propagate
+
+ assert(a.__has_value()); // make sure we don't "steal" from the source
+ assert(*a == T{3}); //
+ }
+
+ // Test with copy initialization
+ {
+ Cache b = a;
+ assert(!b.__has_value()); // make sure we don't propagate
+
+ assert(a.__has_value()); // make sure we don't "steal" from the source
+ assert(*a == T{3}); //
+ }
+}
+
+constexpr bool tests() {
+ test<CopyConstructible<true>>();
+ test<CopyConstructible<false>>();
+ test<NotCopyConstructible>();
+ test<int>();
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.default.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.default.pass.cpp
new file mode 100644
index 0000000000000..109e487f1ee62
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.default.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// __non_propagating_cache();
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+
+struct HasDefault { HasDefault() = default; };
+struct NoDefault { NoDefault() = delete; };
+
+template <class T>
+constexpr void test() {
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ static_assert(std::is_nothrow_default_constructible_v<Cache>);
+ Cache cache;
+ assert(!cache.__has_value());
+}
+
+constexpr bool tests() {
+ test<HasDefault>();
+ test<NoDefault>();
+ test<int>();
+ test<char*>();
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.move.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.move.pass.cpp
new file mode 100644
index 0000000000000..6070130465797
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/ctor.move.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// __non_propagating_cache(__non_propagating_cache&&);
+
+#include <ranges>
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+template<bool NoexceptMove>
+struct MoveConstructible {
+ int x;
+ constexpr explicit MoveConstructible(int i) : x(i) { }
+ constexpr MoveConstructible(MoveConstructible&& other) noexcept(NoexceptMove) : x(other.x) { other.x = -1; }
+ MoveConstructible& operator=(MoveConstructible&&) = default;
+};
+
+template <class T>
+constexpr void test() {
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ static_assert(std::is_nothrow_move_constructible_v<Cache>);
+
+ // Test with direct initialization
+ {
+ Cache a;
+ a.__emplace(3);
+
+ Cache b(std::move(a));
+ assert(!b.__has_value()); // make sure we don't propagate
+ assert(!a.__has_value()); // make sure we disengage the source
+ }
+
+ // Test with copy initialization
+ {
+ Cache a;
+ a.__emplace(3);
+
+ Cache b = std::move(a);
+ assert(!b.__has_value()); // make sure we don't propagate
+ assert(!a.__has_value()); // make sure we disengage the source
+ }
+}
+
+constexpr bool tests() {
+ test<MoveConstructible<true>>();
+ test<MoveConstructible<false>>();
+ test<int>();
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/deref.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/deref.pass.cpp
new file mode 100644
index 0000000000000..3a07516deecaf
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/deref.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 T const& operator*() const;
+// constexpr T& operator*();
+
+#include <ranges>
+
+#include <cassert>
+
+template <class T>
+constexpr void test() {
+ using Cache = std::ranges::__non_propagating_cache<T>;
+
+ // non-const version
+ {
+ Cache cache; cache.__emplace(3);
+ T& result = *cache;
+ assert(result == T{3});
+ }
+
+ // const version
+ {
+ Cache cache; cache.__emplace(3);
+ T const& result = *static_cast<Cache const&>(cache);
+ assert(result == T{3});
+ }
+}
+
+struct T {
+ int x;
+ constexpr explicit T(int i) : x(i) { }
+ constexpr bool operator==(T const& other) const { return x == other.x; }
+};
+
+constexpr bool tests() {
+ test<T>();
+ test<int>();
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace.pass.cpp
new file mode 100644
index 0000000000000..c94fea67c4949
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 ...Args>
+// constexpr T& __emplace(Args&& ...);
+
+#include <ranges>
+
+#include <cassert>
+#include <tuple>
+
+template<int I>
+struct X {
+ int value = -1;
+ template<int J>
+ friend constexpr bool operator==(X const& a, X<J> const& b) { return I == J && a.value == b.value; }
+};
+
+struct NonMovable {
+ int value = -1;
+ NonMovable() = default;
+ constexpr explicit NonMovable(int v) : value(v) { }
+ NonMovable(NonMovable&&) = delete;
+ NonMovable& operator=(NonMovable&&) = delete;
+};
+
+constexpr bool test() {
+ {
+ using T = std::tuple<>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace();
+ assert(&result == &*cache);
+ assert(result == T());
+ }
+
+ {
+ using T = std::tuple<X<0>>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace();
+ assert(&result == &*cache);
+ assert(result == T());
+ }
+ {
+ using T = std::tuple<X<0>>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace(X<0>{0});
+ assert(&result == &*cache);
+ assert(result == T(X<0>{0}));
+ }
+
+ {
+ using T = std::tuple<X<0>, X<1>>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace();
+ assert(&result == &*cache);
+ assert(result == T());
+ }
+ {
+ using T = std::tuple<X<0>, X<1>>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace(X<0>{0}, X<1>{1});
+ assert(&result == &*cache);
+ assert(result == T(X<0>{0}, X<1>{1}));
+ }
+
+ // Make sure that we do not require the type to be movable when we emplace it.
+ // Move elision should be performed instead, see http://eel.is/c++draft/range.nonprop.cache#note-1.
+ {
+ using Cache = std::ranges::__non_propagating_cache<NonMovable>;
+ Cache cache;
+ NonMovable& result = cache.__emplace();
+ assert(&result == &*cache);
+ assert(result.value == -1);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(test());
+ test();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace_from.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace_from.pass.cpp
new file mode 100644
index 0000000000000..d097be338c801
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/emplace_from.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// template<class Fn>
+// constexpr T& __emplace_from(Fn const&);
+
+#include <ranges>
+
+#include <cassert>
+#include <tuple>
+
+template<int I>
+struct X {
+ int value = -1;
+ template<int J>
+ friend constexpr bool operator==(X const& a, X<J> const& b) { return I == J && a.value == b.value; }
+};
+
+struct NonMovable {
+ int value = -1;
+ NonMovable() = default;
+ constexpr explicit NonMovable(int v) : value(v) { }
+ NonMovable(NonMovable&&) = delete;
+ NonMovable& operator=(NonMovable&&) = delete;
+};
+
+constexpr bool test() {
+ {
+ using T = std::tuple<>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace_from([] { return T(); });
+ assert(&result == &*cache);
+ assert(result == T());
+ }
+ {
+ using T = std::tuple<X<0>>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace_from([] { return T(X<0>{0}); });
+ assert(&result == &*cache);
+ assert(result == T(X<0>{0}));
+ }
+ {
+ using T = std::tuple<X<0>, X<1>>;
+ using Cache = std::ranges::__non_propagating_cache<T>;
+ Cache cache;
+ T& result = cache.__emplace_from([] { return T(X<0>{0}, X<1>{1}); });
+ assert(&result == &*cache);
+ assert(result == T(X<0>{0}, X<1>{1}));
+ }
+
+ // Make sure that we do not require the type to be movable when we emplace it.
+ // Move elision should be performed instead, see http://eel.is/c++draft/range.nonprop.cache#note-1.
+ {
+ using Cache = std::ranges::__non_propagating_cache<NonMovable>;
+ Cache cache;
+ NonMovable& result = cache.__emplace_from([] { return NonMovable(3); });
+ assert(&result == &*cache);
+ assert(result.value == 3);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(test());
+ test();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.nonprop.cache/has_value.pass.cpp b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/has_value.pass.cpp
new file mode 100644
index 0000000000000..e27306200a0f9
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.nonprop.cache/has_value.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// constexpr bool __has_value() const;
+
+#include <ranges>
+
+#include <cassert>
+
+template <class T>
+constexpr void test() {
+ using Cache = std::ranges::__non_propagating_cache<T>;
+
+ // __has_value on an empty cache
+ {
+ Cache const cache;
+ assert(!cache.__has_value());
+ }
+
+ // __has_value on a non-empty cache
+ {
+ Cache cache; cache.__emplace();
+ assert(cache.__has_value());
+ }
+}
+
+struct T { };
+
+constexpr bool tests() {
+ test<T>();
+ test<int>();
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(tests());
+ tests();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.utility.helpers/different_from.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.utility.helpers/different_from.compile.pass.cpp
new file mode 100644
index 0000000000000..26f6a77181d25
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.utility.helpers/different_from.compile.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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Check that different_from.h is self-contained
+
+#include <__concepts/different_from.h>
+
+static_assert(std::__different_from<int, char>);
+static_assert(std::__different_from<const int, char>);
+static_assert(!std::__different_from<const int, int>);
+static_assert(!std::__different_from<const volatile int, int>);
+static_assert(!std::__different_from<const int&, int>);
+static_assert(!std::__different_from<int&, int>);
+static_assert(!std::__different_from<int&&, int>);
+static_assert(!std::__different_from<int, int&>);
+static_assert(!std::__different_from<int&, const int&>);
+static_assert(!std::__different_from<int(&)(), int()>);
+static_assert(std::__different_from<int(&)(), int(*)()>);
diff --git a/libcxx/test/libcxx-03/ranges/range.utility.helpers/has_arrow.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.utility.helpers/has_arrow.compile.pass.cpp
new file mode 100644
index 0000000000000..4f246f414b26b
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.utility.helpers/has_arrow.compile.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <cstddef>
+#include <iterator>
+
+#include "test_macros.h"
+
+struct simple_iter {
+ typedef std::input_iterator_tag iterator_category;
+ typedef int value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef int* pointer;
+ typedef int& reference;
+
+ reference operator*() const;
+ pointer operator->() const;
+ friend bool operator==(const simple_iter&, const simple_iter&);
+ friend bool operator< (const simple_iter&, const simple_iter&);
+ friend bool operator<=(const simple_iter&, const simple_iter&);
+ friend bool operator> (const simple_iter&, const simple_iter&);
+ friend bool operator>=(const simple_iter&, const simple_iter&);
+
+ simple_iter& operator++();
+ simple_iter operator++(int);
+};
+
+struct no_star {
+ typedef std::input_iterator_tag iterator_category;
+ typedef int value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef int* pointer;
+ typedef int& reference;
+
+ /* reference operator*() const; */
+ pointer operator->() const;
+ friend bool operator==(const simple_iter&, const simple_iter&);
+ friend bool operator< (const simple_iter&, const simple_iter&);
+ friend bool operator<=(const simple_iter&, const simple_iter&);
+ friend bool operator> (const simple_iter&, const simple_iter&);
+ friend bool operator>=(const simple_iter&, const simple_iter&);
+
+ simple_iter& operator++();
+ simple_iter operator++(int);
+};
+
+struct no_arrow {
+ typedef std::input_iterator_tag iterator_category;
+ typedef int value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef int* pointer;
+ typedef int& reference;
+
+ reference operator*() const;
+ /* pointer operator->() const; */
+ friend bool operator==(const simple_iter&, const simple_iter&);
+ friend bool operator< (const simple_iter&, const simple_iter&);
+ friend bool operator<=(const simple_iter&, const simple_iter&);
+ friend bool operator> (const simple_iter&, const simple_iter&);
+ friend bool operator>=(const simple_iter&, const simple_iter&);
+
+ simple_iter& operator++();
+ simple_iter operator++(int);
+};
+
+struct E {};
+struct Incomplete;
+
+static_assert(std::__has_arrow<int*>);
+static_assert(std::__has_arrow<E*>);
+static_assert(!std::__has_arrow<Incomplete*>); // Because it's not an input_iterator.
+static_assert(std::__has_arrow<simple_iter>);
+static_assert(!std::__has_arrow<no_star>);
+static_assert(!std::__has_arrow<no_arrow>);
diff --git a/libcxx/test/libcxx-03/ranges/range.utility.helpers/simple_view.compile.pass.cpp b/libcxx/test/libcxx-03/ranges/range.utility.helpers/simple_view.compile.pass.cpp
new file mode 100644
index 0000000000000..440b12e2c71c7
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.utility.helpers/simple_view.compile.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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <ranges>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "test_range.h"
+
+struct SimpleView : std::ranges::view_base {
+ int *begin() const;
+ int *end() const;
+};
+
+struct WrongConstView : std::ranges::view_base {
+ int *begin();
+ const int *begin() const;
+ int *end();
+ const int *end() const;
+};
+
+struct NoConstView : std::ranges::view_base {
+ int *begin();
+ int *end();
+};
+
+struct DifferentSentinel : std::ranges::view_base {
+ int *begin() const;
+ sentinel_wrapper<int*> end() const;
+};
+
+struct WrongConstSentinel : std::ranges::view_base {
+ int *begin() const;
+ sentinel_wrapper<int*> end();
+ sentinel_wrapper<const int*> end() const;
+};
+
+static_assert( std::ranges::__simple_view<SimpleView>);
+static_assert(!std::ranges::__simple_view<WrongConstView>);
+static_assert(!std::ranges::__simple_view<NoConstView>);
+static_assert( std::ranges::__simple_view<DifferentSentinel>);
+static_assert(!std::ranges::__simple_view<WrongConstSentinel>);
+
+// To make sure __simple_view and the test version of the concept stay in sync.
+static_assert(simple_view<SimpleView>);
+static_assert(!simple_view<WrongConstView>);
+static_assert(!simple_view<NoConstView>);
+static_assert(simple_view<DifferentSentinel>);
+static_assert(!simple_view<WrongConstSentinel>);
diff --git a/libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.internal_constraints.verify.cpp b/libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.internal_constraints.verify.cpp
new file mode 100644
index 0000000000000..7122ae03860bc
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.internal_constraints.verify.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test that the "mandates" requirements on the given container are checked correctly using `static_assert`.
+
+#include <ranges>
+#include <vector>
+
+template <bool HasDefaultCtr = true, bool HasSingleArgCtr = true,
+ bool HasInsert = true, bool HasInsertWithRightSignature = true,
+ bool HasPushBack = true, bool HasPushBackWithRightSignature = true>
+struct Container {
+ using value_type = int;
+
+ int* begin() const { return nullptr; }
+ int* end() const { return nullptr; }
+
+ Container()
+ requires HasDefaultCtr = default;
+
+ Container(int)
+ requires HasSingleArgCtr {
+ }
+
+ int* insert(int*, int)
+ requires (HasInsert && HasInsertWithRightSignature) {
+ return nullptr;
+ }
+
+ int* insert()
+ requires (HasInsert && !HasInsertWithRightSignature) {
+ return nullptr;
+ }
+
+ void push_back(int)
+ requires (HasPushBack && HasPushBackWithRightSignature) {
+ }
+
+ void push_back()
+ requires (HasPushBack && !HasPushBackWithRightSignature) {
+ }
+
+};
+
+void test() {
+ using R = std::vector<int>;
+ R in = {1, 2, 3};
+
+ // Case 4 -- default-construct (or construct from the extra arguments) and insert.
+ { // All constraints satisfied.
+ using C = Container<>;
+ (void)std::ranges::to<C>(in);
+ (void)std::ranges::to<C>(in, 1);
+ (void)std::ranges::to<C>(in, 1.0);
+ }
+
+ { // No default constructor.
+ using C = Container</*HasDefaultCtr=*/false>;
+ (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
+ }
+
+ { // No single-argument constructor.
+ using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/false>;
+ (void)std::ranges::to<C>(in, 1); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
+ }
+
+ { // No `insert` and no `push_back`.
+ using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/true,
+ /*HasInsert=*/false, /*HasInsertWithRightSignature=*/false,
+ /*HasPushBack=*/false, /*HasPushBackWithRightSignature=*/false>;
+ (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
+ }
+
+ { // No `push_back`, `insert` has a wrong signature.
+ using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/true,
+ /*HasInsert=*/true, /*HasInsertWithRightSignature=*/false,
+ /*HasPushBack=*/false, /*HasPushBackWithRightSignature=*/false>;
+ (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
+ }
+
+ { // No `insert`, `push_back` has a wrong signature.
+ using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/true,
+ /*HasInsert=*/false, /*HasInsertWithRightSignature=*/false,
+ /*HasPushBack=*/true, /*HasPushBackWithRightSignature=*/false>;
+ (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.static_assert.verify.cpp b/libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.static_assert.verify.cpp
new file mode 100644
index 0000000000000..0800ee8cf7bae
--- /dev/null
+++ b/libcxx/test/libcxx-03/ranges/range.utility/range.utility.conv/to.static_assert.verify.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated-volatile
+
+// Test that the "mandates" requirements on the given container are checked using `static_assert`.
+
+#include <ranges>
+#include <vector>
+
+void test_cv_qualifications() {
+ using R = std::vector<int>;
+ R in = {1, 2, 3};
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target container cannot be const-qualified, please remove the const}}
+ (void)std::ranges::to<const R>(in);
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target container cannot be const-qualified, please remove the const}}
+ (void)(in | std::ranges::to<const R>());
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target container cannot be volatile-qualified, please remove the volatile}}
+ (void)std::ranges::to<volatile R>(in);
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target container cannot be volatile-qualified, please remove the volatile}}
+ (void)(in | std::ranges::to<volatile R>());
+}
+//unexpected_types
+void ff();
+void test_unexpected_types() {
+ struct C {
+ int member;
+ int f();
+ };
+
+ enum color { red, green, blue };
+ using member_func_ptr = decltype(&C::f);
+ using member_ptr = decltype(&C::member);
+ using func_ptr = decltype(&ff);
+ using func_t = decltype(ff);
+
+ struct R {
+ int* begin() const { return nullptr; };
+ int* end() const { return nullptr; };
+
+ operator int() const;
+ operator int*() const;
+ operator func_ptr() const;
+ operator member_func_ptr() const;
+ operator member_ptr() const;
+ operator color() const;
+ };
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)std::ranges::to<int>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)(R{} | std::ranges::to<int>());
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)std::ranges::to<int*>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)(R{} | std::ranges::to<int*>());
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)std::ranges::to<func_ptr>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)(R{} | std::ranges::to<func_ptr>());
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)std::ranges::to<member_ptr>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)(R{} | std::ranges::to<member_ptr>());
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)std::ranges::to<func_t>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)(R{} | std::ranges::to<func_t>());
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)std::ranges::to<void>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type.}}
+ (void)(R{} | std::ranges::to<void>());
+
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)std::ranges::to<color>(R{});
+ //expected-error-re@*:* {{static assertion failed{{.*}}The target must be a class type}}
+ (void)(R{} | std::ranges::to<color>());
+}
diff --git a/libcxx/test/libcxx-03/selftest/additional_compile_flags/conditional-compile-flags.sh.cpp b/libcxx/test/libcxx-03/selftest/additional_compile_flags/conditional-compile-flags.sh.cpp
new file mode 100644
index 0000000000000..2c63cb2b12892
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/additional_compile_flags/conditional-compile-flags.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// This test ensures that we can add compile flags that are conditional on Lit features.
+
+// ADDITIONAL_COMPILE_FLAGS(some-defined-feature): -this-flag-should-be-added
+// ADDITIONAL_COMPILE_FLAGS(some-undefined-feature): -this-flag-should-not-be-added
+// RUN: echo "%{compile_flags}" | grep -e '-this-flag-should-be-added'
+// RUN: echo "%{compile_flags}" | grep -v -e '-this-flag-should-not-be-added'
diff --git a/libcxx/test/libcxx-03/selftest/additional_compile_flags/lit.local.cfg b/libcxx/test/libcxx-03/selftest/additional_compile_flags/lit.local.cfg
new file mode 100644
index 0000000000000..fdddd89dbfbd9
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/additional_compile_flags/lit.local.cfg
@@ -0,0 +1,2 @@
+# Add a Lit feature so we can test conditional addition of compile flags.
+config.available_features.add("some-defined-feature")
diff --git a/libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-compile-flags.sh.cpp b/libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-compile-flags.sh.cpp
new file mode 100644
index 0000000000000..561d77c569473
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-compile-flags.sh.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// This test greps for %t, which is expanded to a path with backslashes. When
+// that is passed to grep, those backslashes must be escaped. We escape those
+// within the pattern into a file and use this file with 'grep'.
+
+// Make sure that substitutions are performed inside additional compiler flags.
+
+// ADDITIONAL_COMPILE_FLAGS: -I %t.1
+// ADDITIONAL_COMPILE_FLAGS: -isystem %t.2 -isysroot %t.3
+// RUN: echo "-I %t.1 -isystem %t.2 -isysroot %t.3" | sed "s/\\\/\\\\\\\/g" > %t.escaped.grep
+// RUN: echo "%{compile_flags}" | grep -e -f %t.escaped.grep
diff --git a/libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-run.sh.cpp b/libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-run.sh.cpp
new file mode 100644
index 0000000000000..c8ddddcef0a7f
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/additional_compile_flags/substitutes-in-run.sh.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that additional compiler flags are added to the %{compile_flags}
+// substitution.
+
+// ADDITIONAL_COMPILE_FLAGS: -foo
+// ADDITIONAL_COMPILE_FLAGS: -bar
+// ADDITIONAL_COMPILE_FLAGS: -baz -foom
+// RUN: echo "%{compile_flags}" | grep -e '-foo -bar -baz -foom'
diff --git a/libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-error.compile.fail.cpp b/libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-error.compile.fail.cpp
new file mode 100644
index 0000000000000..9390f7c8eae31
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-error.compile.fail.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if it fails at compile-time
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-success.compile.fail.cpp b/libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-success.compile.fail.cpp
new file mode 100644
index 0000000000000..1bc6bcd49a5c1
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.fail.cpp/compile-success.compile.fail.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it succeeds at compile-time
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-error.compile.pass.cpp b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-error.compile.pass.cpp
new file mode 100644
index 0000000000000..6ff8850537f59
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-error.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at compile-time
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-success.compile.pass.cpp b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-success.compile.pass.cpp
new file mode 100644
index 0000000000000..16ca5f2d71665
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/compile-success.compile.pass.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if it succeeds to compile
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.cpp/link-error.compile.pass.cpp b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/link-error.compile.pass.cpp
new file mode 100644
index 0000000000000..b5f6e5df10903
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/link-error.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes even if there's a link error, i.e. it isn't linked.
+
+extern void this_is_an_undefined_symbol();
+
+int main(int, char**) {
+ this_is_an_undefined_symbol();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.cpp/run-error.compile.pass.cpp b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/run-error.compile.pass.cpp
new file mode 100644
index 0000000000000..dd1f084f6c1bd
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.cpp/run-error.compile.pass.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes even if there's a runtime error, i.e. it isn't run.
+
+int main(int, char**) {
+ return 1;
+}
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-error.compile.pass.mm b/libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-error.compile.pass.mm
new file mode 100644
index 0000000000000..04bb4cc445266
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-error.compile.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at compile-time
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-success.compile.pass.mm b/libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-success.compile.pass.mm
new file mode 100644
index 0000000000000..9effc02650cb4
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.mm/compile-success.compile.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure the test passes if it succeeds to compile
+
+ at interface I;
+ at end
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.mm/link-error.compile.pass.mm b/libcxx/test/libcxx-03/selftest/compile.pass.mm/link-error.compile.pass.mm
new file mode 100644
index 0000000000000..77f6a63c0c9a2
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.mm/link-error.compile.pass.mm
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure the test passes even if there's a link error, i.e. it isn't linked.
+
+ at interface I;
+ at end
+
+extern void this_is_an_undefined_symbol();
+
+int main(int, char**) {
+ this_is_an_undefined_symbol();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/compile.pass.mm/run-error.compile.pass.mm b/libcxx/test/libcxx-03/selftest/compile.pass.mm/run-error.compile.pass.mm
new file mode 100644
index 0000000000000..cdd3ef44d88b5
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/compile.pass.mm/run-error.compile.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure the test passes even if there's a runtime error, i.e. it isn't run.
+
+ at interface I;
+ at end
+
+int main(int, char**) {
+ return 1;
+}
diff --git a/libcxx/test/libcxx-03/selftest/convenience_substitutions/build_run.sh.cpp b/libcxx/test/libcxx-03/selftest/convenience_substitutions/build_run.sh.cpp
new file mode 100644
index 0000000000000..4698167449f18
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/convenience_substitutions/build_run.sh.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that we provide the %{build} and %{run} convenience substitutions.
+
+// RUN: %{build}
+// RUN: %{run} "HELLO"
+
+#include <cassert>
+#include <string>
+
+int main(int argc, char** argv) {
+ assert(argc == 2);
+
+ std::string arg = argv[1];
+ assert(arg == "HELLO");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/convenience_substitutions/verify.sh.cpp b/libcxx/test/libcxx-03/selftest/convenience_substitutions/verify.sh.cpp
new file mode 100644
index 0000000000000..d1713b44a086d
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/convenience_substitutions/verify.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: verify-support
+
+// Make sure that we provide the %{verify} convenience substitution.
+
+// RUN: %{verify}
+
+struct Foo {};
+typedef Foo::x x; // expected-error {{no type named 'x' in 'Foo'}}
diff --git a/libcxx/test/libcxx-03/selftest/dsl/dsl.sh.py b/libcxx/test/libcxx-03/selftest/dsl/dsl.sh.py
new file mode 100644
index 0000000000000..012759436d891
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/dsl/dsl.sh.py
@@ -0,0 +1,629 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# With picolibc, test_program_stderr_is_not_conflated_with_stdout fails
+# because stdout & stderr are treated as the same.
+# XFAIL: LIBCXX-PICOLIBC-FIXME
+
+# Note: We prepend arguments with 'x' to avoid thinking there are too few
+# arguments in case an argument is an empty string.
+# RUN: %{python} %s x%S x%T x%{substitutions}
+
+import base64
+import copy
+import os
+import pickle
+import platform
+import subprocess
+import sys
+import unittest
+from os.path import dirname
+
+# Allow importing 'lit' and the 'libcxx' module. Make sure we put the lit
+# path first so we don't find any system-installed version.
+monorepoRoot = dirname(dirname(dirname(dirname(dirname(dirname(__file__))))))
+sys.path = [
+ os.path.join(monorepoRoot, "libcxx", "utils"),
+ os.path.join(monorepoRoot, "llvm", "utils", "lit"),
+] + sys.path
+import libcxx.test.dsl as dsl
+import lit.LitConfig
+import lit.util
+
+# Steal some parameters from the config running this test so that we can
+# bootstrap our own TestingConfig.
+args = list(map(lambda s: s[1:], sys.argv[1:8])) # Remove the leading 'x'
+SOURCE_ROOT, EXEC_PATH, SUBSTITUTIONS = args
+sys.argv[1:8] = []
+
+# Decode the substitutions.
+SUBSTITUTIONS = pickle.loads(base64.b64decode(SUBSTITUTIONS))
+for s, sub in SUBSTITUTIONS:
+ print("Substitution '{}' is '{}'".format(s, sub))
+
+
+class SetupConfigs(unittest.TestCase):
+ """
+ Base class for the tests below -- it creates a fake TestingConfig.
+ """
+
+ def setUp(self):
+ """
+ Create a fake TestingConfig that can be populated however we wish for
+ the purpose of running unit tests below. We pre-populate it with the
+ minimum required substitutions.
+ """
+ self.litConfig = lit.LitConfig.LitConfig(
+ progname="lit",
+ path=[],
+ quiet=False,
+ useValgrind=False,
+ valgrindLeakCheck=False,
+ valgrindArgs=[],
+ noExecute=False,
+ debug=False,
+ isWindows=platform.system() == "Windows",
+ order="smart",
+ params={},
+ )
+
+ self.config = lit.TestingConfig.TestingConfig.fromdefaults(self.litConfig)
+ self.config.environment = dict(os.environ)
+ self.config.test_source_root = SOURCE_ROOT
+ self.config.test_exec_root = EXEC_PATH
+ self.config.recursiveExpansionLimit = 10
+ self.config.substitutions = copy.deepcopy(SUBSTITUTIONS)
+
+ def getSubstitution(self, substitution):
+ """
+ Return a given substitution from the TestingConfig. It is an error if
+ there is no such substitution.
+ """
+ found = [x for (s, x) in self.config.substitutions if s == substitution]
+ assert len(found) == 1
+ return found[0]
+
+
+def findIndex(list, pred):
+ """Finds the index of the first element satisfying 'pred' in a list, or
+ 'len(list)' if there is no such element."""
+ index = 0
+ for x in list:
+ if pred(x):
+ break
+ else:
+ index += 1
+ return index
+
+
+class TestHasCompileFlag(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.hasCompileFlag
+ """
+
+ def test_no_flag_should_work(self):
+ self.assertTrue(dsl.hasCompileFlag(self.config, ""))
+
+ def test_flag_exists(self):
+ self.assertTrue(dsl.hasCompileFlag(self.config, "-O1"))
+
+ def test_nonexistent_flag(self):
+ self.assertFalse(
+ dsl.hasCompileFlag(self.config, "-this_is_not_a_flag_any_compiler_has")
+ )
+
+ def test_multiple_flags(self):
+ self.assertTrue(dsl.hasCompileFlag(self.config, "-O1 -Dhello"))
+
+
+class TestSourceBuilds(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.sourceBuilds
+ """
+
+ def test_valid_program_builds(self):
+ source = """int main(int, char**) { return 0; }"""
+ self.assertTrue(dsl.sourceBuilds(self.config, source))
+
+ def test_compilation_error_fails(self):
+ source = """int main(int, char**) { this does not compile }"""
+ self.assertFalse(dsl.sourceBuilds(self.config, source))
+
+ def test_link_error_fails(self):
+ source = """extern void this_isnt_defined_anywhere();
+ int main(int, char**) { this_isnt_defined_anywhere(); return 0; }"""
+ self.assertFalse(dsl.sourceBuilds(self.config, source))
+
+
+class TestProgramOutput(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.programOutput
+ """
+
+ def test_valid_program_returns_output(self):
+ source = """
+ #include <cstdio>
+ int main(int, char**) { std::printf("FOOBAR"); return 0; }
+ """
+ self.assertEqual(dsl.programOutput(self.config, source), "FOOBAR")
+
+ def test_valid_program_returns_output_newline_handling(self):
+ source = """
+ #include <cstdio>
+ int main(int, char**) { std::printf("FOOBAR\\n"); return 0; }
+ """
+ self.assertEqual(dsl.programOutput(self.config, source), "FOOBAR\n")
+
+ def test_valid_program_returns_no_output(self):
+ source = """
+ int main(int, char**) { return 0; }
+ """
+ self.assertEqual(dsl.programOutput(self.config, source), "")
+
+ def test_program_that_fails_to_run_raises_runtime_error(self):
+ # The program compiles, but exits with an error
+ source = """
+ int main(int, char**) { return 1; }
+ """
+ self.assertRaises(
+ dsl.ConfigurationRuntimeError,
+ lambda: dsl.programOutput(self.config, source),
+ )
+
+ def test_program_that_fails_to_compile_raises_compilation_error(self):
+ # The program doesn't compile
+ source = """
+ int main(int, char**) { this doesnt compile }
+ """
+ self.assertRaises(
+ dsl.ConfigurationCompilationError,
+ lambda: dsl.programOutput(self.config, source),
+ )
+
+ def test_pass_arguments_to_program(self):
+ source = """
+ #include <cassert>
+ #include <string>
+ int main(int argc, char** argv) {
+ assert(argc == 3);
+ assert(argv[1] == std::string("first-argument"));
+ assert(argv[2] == std::string("second-argument"));
+ return 0;
+ }
+ """
+ args = ["first-argument", "second-argument"]
+ self.assertEqual(dsl.programOutput(self.config, source, args=args), "")
+
+ def test_caching_is_not_too_aggressive(self):
+ # Run a program, then change the substitutions and run it again.
+ # Make sure the program is run the second time and the right result
+ # is given, to ensure we're not incorrectly caching the result of the
+ # first program run.
+ source = """
+ #include <cstdio>
+ int main(int, char**) {
+ std::printf("MACRO=%u\\n", MACRO);
+ return 0;
+ }
+ """
+ compileFlagsIndex = findIndex(
+ self.config.substitutions, lambda x: x[0] == "%{compile_flags}"
+ )
+ compileFlags = self.config.substitutions[compileFlagsIndex][1]
+
+ self.config.substitutions[compileFlagsIndex] = (
+ "%{compile_flags}",
+ compileFlags + " -DMACRO=1",
+ )
+ output1 = dsl.programOutput(self.config, source)
+ self.assertEqual(output1, "MACRO=1\n")
+
+ self.config.substitutions[compileFlagsIndex] = (
+ "%{compile_flags}",
+ compileFlags + " -DMACRO=2",
+ )
+ output2 = dsl.programOutput(self.config, source)
+ self.assertEqual(output2, "MACRO=2\n")
+
+ def test_program_stderr_is_not_conflated_with_stdout(self):
+ # Run a program that produces stdout output and stderr output too, making
+ # sure the stderr output does not pollute the stdout output.
+ source = """
+ #include <cstdio>
+ int main(int, char**) {
+ std::fprintf(stdout, "STDOUT-OUTPUT");
+ std::fprintf(stderr, "STDERR-OUTPUT");
+ return 0;
+ }
+ """
+ self.assertEqual(dsl.programOutput(self.config, source), "STDOUT-OUTPUT")
+
+
+class TestProgramSucceeds(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.programSucceeds
+ """
+
+ def test_success(self):
+ source = """
+ int main(int, char**) { return 0; }
+ """
+ self.assertTrue(dsl.programSucceeds(self.config, source))
+
+ def test_failure(self):
+ source = """
+ int main(int, char**) { return 1; }
+ """
+ self.assertFalse(dsl.programSucceeds(self.config, source))
+
+ def test_compile_failure(self):
+ source = """
+ this does not compile
+ """
+ self.assertRaises(
+ dsl.ConfigurationCompilationError,
+ lambda: dsl.programSucceeds(self.config, source),
+ )
+
+
+class TestHasLocale(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.hasLocale
+ """
+
+ def test_doesnt_explode(self):
+ # It's really hard to test that a system has a given locale, so at least
+ # make sure we don't explode when we try to check it.
+ try:
+ dsl.hasAnyLocale(self.config, ["en_US.UTF-8"])
+ except subprocess.CalledProcessError:
+ self.fail("checking for hasLocale should not explode")
+
+ def test_nonexistent_locale(self):
+ self.assertFalse(
+ dsl.hasAnyLocale(self.config, ["forsurethisisnotanexistinglocale"])
+ )
+
+ def test_localization_program_doesnt_compile(self):
+ compilerIndex = findIndex(self.config.substitutions, lambda x: x[0] == "%{cxx}")
+ self.config.substitutions[compilerIndex] = (
+ "%{cxx}",
+ "this-is-certainly-not-a-valid-compiler!!",
+ )
+ self.assertRaises(
+ dsl.ConfigurationCompilationError,
+ lambda: dsl.hasAnyLocale(self.config, ["en_US.UTF-8"]),
+ )
+
+
+class TestCompilerMacros(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.compilerMacros
+ """
+
+ def test_basic(self):
+ macros = dsl.compilerMacros(self.config)
+ self.assertIsInstance(macros, dict)
+ self.assertGreater(len(macros), 0)
+ for (k, v) in macros.items():
+ self.assertIsInstance(k, str)
+ self.assertIsInstance(v, str)
+
+ def test_no_flag(self):
+ macros = dsl.compilerMacros(self.config)
+ self.assertIn("__cplusplus", macros.keys())
+
+ def test_empty_flag(self):
+ macros = dsl.compilerMacros(self.config, "")
+ self.assertIn("__cplusplus", macros.keys())
+
+ def test_with_flag(self):
+ macros = dsl.compilerMacros(self.config, "-DFOO=3")
+ self.assertIn("__cplusplus", macros.keys())
+ self.assertEqual(macros["FOO"], "3")
+
+ def test_with_flags(self):
+ macros = dsl.compilerMacros(self.config, "-DFOO=3 -DBAR=hello")
+ self.assertIn("__cplusplus", macros.keys())
+ self.assertEqual(macros["FOO"], "3")
+ self.assertEqual(macros["BAR"], "hello")
+
+
+class TestFeatureTestMacros(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.featureTestMacros
+ """
+
+ def test_basic(self):
+ macros = dsl.featureTestMacros(self.config)
+ self.assertIsInstance(macros, dict)
+ self.assertGreater(len(macros), 0)
+ for (k, v) in macros.items():
+ self.assertIsInstance(k, str)
+ self.assertIsInstance(v, int)
+
+
+class TestFeature(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.Feature
+ """
+
+ def test_trivial(self):
+ feature = dsl.Feature(name="name")
+ origSubstitutions = copy.deepcopy(self.config.substitutions)
+ actions = feature.getActions(self.config)
+ self.assertTrue(len(actions) == 1)
+ for a in actions:
+ a.applyTo(self.config)
+ self.assertEqual(origSubstitutions, self.config.substitutions)
+ self.assertIn("name", self.config.available_features)
+
+ def test_name_can_be_a_callable(self):
+ feature = dsl.Feature(name=lambda cfg: "name")
+ for a in feature.getActions(self.config):
+ a.applyTo(self.config)
+ self.assertIn("name", self.config.available_features)
+
+ def test_name_is_not_a_string_1(self):
+ feature = dsl.Feature(name=None)
+ self.assertRaises(ValueError, lambda: feature.getActions(self.config))
+ self.assertRaises(ValueError, lambda: feature.pretty(self.config))
+
+ def test_name_is_not_a_string_2(self):
+ feature = dsl.Feature(name=lambda cfg: None)
+ self.assertRaises(ValueError, lambda: feature.getActions(self.config))
+ self.assertRaises(ValueError, lambda: feature.pretty(self.config))
+
+ def test_adding_action(self):
+ feature = dsl.Feature(name="name", actions=[dsl.AddCompileFlag("-std=c++03")])
+ origLinkFlags = copy.deepcopy(self.getSubstitution("%{link_flags}"))
+ for a in feature.getActions(self.config):
+ a.applyTo(self.config)
+ self.assertIn("name", self.config.available_features)
+ self.assertIn("-std=c++03", self.getSubstitution("%{compile_flags}"))
+ self.assertEqual(origLinkFlags, self.getSubstitution("%{link_flags}"))
+
+ def test_actions_can_be_a_callable(self):
+ feature = dsl.Feature(
+ name="name",
+ actions=lambda cfg: (
+ self.assertIs(self.config, cfg),
+ [dsl.AddCompileFlag("-std=c++03")],
+ )[1],
+ )
+ for a in feature.getActions(self.config):
+ a.applyTo(self.config)
+ self.assertIn("-std=c++03", self.getSubstitution("%{compile_flags}"))
+
+ def test_unsupported_feature(self):
+ feature = dsl.Feature(name="name", when=lambda _: False)
+ self.assertEqual(feature.getActions(self.config), [])
+
+ def test_is_supported_gets_passed_the_config(self):
+ feature = dsl.Feature(
+ name="name", when=lambda cfg: (self.assertIs(self.config, cfg), True)[1]
+ )
+ self.assertEqual(len(feature.getActions(self.config)), 1)
+
+
+def _throw():
+ raise ValueError()
+
+
+class TestParameter(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.Parameter
+ """
+
+ def test_empty_name_should_blow_up(self):
+ self.assertRaises(
+ ValueError,
+ lambda: dsl.Parameter(
+ name="", choices=["c++03"], type=str, help="", actions=lambda _: []
+ ),
+ )
+
+ def test_empty_choices_should_blow_up(self):
+ self.assertRaises(
+ ValueError,
+ lambda: dsl.Parameter(
+ name="std", choices=[], type=str, help="", actions=lambda _: []
+ ),
+ )
+
+ def test_no_choices_is_ok(self):
+ param = dsl.Parameter(name="triple", type=str, help="", actions=lambda _: [])
+ self.assertEqual(param.name, "triple")
+
+ def test_name_is_set_correctly(self):
+ param = dsl.Parameter(
+ name="std", choices=["c++03"], type=str, help="", actions=lambda _: []
+ )
+ self.assertEqual(param.name, "std")
+
+ def test_no_value_provided_and_no_default_value(self):
+ param = dsl.Parameter(
+ name="std", choices=["c++03"], type=str, help="", actions=lambda _: []
+ )
+ self.assertRaises(
+ ValueError, lambda: param.getActions(self.config, self.litConfig.params)
+ )
+
+ def test_no_value_provided_and_default_value(self):
+ param = dsl.Parameter(
+ name="std",
+ choices=["c++03"],
+ type=str,
+ help="",
+ default="c++03",
+ actions=lambda std: [dsl.AddFeature(std)],
+ )
+ for a in param.getActions(self.config, self.litConfig.params):
+ a.applyTo(self.config)
+ self.assertIn("c++03", self.config.available_features)
+
+ def test_value_provided_on_command_line_and_no_default_value(self):
+ self.litConfig.params["std"] = "c++03"
+ param = dsl.Parameter(
+ name="std",
+ choices=["c++03"],
+ type=str,
+ help="",
+ actions=lambda std: [dsl.AddFeature(std)],
+ )
+ for a in param.getActions(self.config, self.litConfig.params):
+ a.applyTo(self.config)
+ self.assertIn("c++03", self.config.available_features)
+
+ def test_value_provided_on_command_line_and_default_value(self):
+ """The value provided on the command line should override the default value"""
+ self.litConfig.params["std"] = "c++11"
+ param = dsl.Parameter(
+ name="std",
+ choices=["c++03", "c++11"],
+ type=str,
+ default="c++03",
+ help="",
+ actions=lambda std: [dsl.AddFeature(std)],
+ )
+ for a in param.getActions(self.config, self.litConfig.params):
+ a.applyTo(self.config)
+ self.assertIn("c++11", self.config.available_features)
+ self.assertNotIn("c++03", self.config.available_features)
+
+ def test_value_provided_in_config_and_default_value(self):
+ """The value provided in the config should override the default value"""
+ self.config.std = "c++11"
+ param = dsl.Parameter(
+ name="std",
+ choices=["c++03", "c++11"],
+ type=str,
+ default="c++03",
+ help="",
+ actions=lambda std: [dsl.AddFeature(std)],
+ )
+ for a in param.getActions(self.config, self.litConfig.params):
+ a.applyTo(self.config)
+ self.assertIn("c++11", self.config.available_features)
+ self.assertNotIn("c++03", self.config.available_features)
+
+ def test_value_provided_in_config_and_on_command_line(self):
+ """The value on the command line should override the one in the config"""
+ self.config.std = "c++11"
+ self.litConfig.params["std"] = "c++03"
+ param = dsl.Parameter(
+ name="std",
+ choices=["c++03", "c++11"],
+ type=str,
+ help="",
+ actions=lambda std: [dsl.AddFeature(std)],
+ )
+ for a in param.getActions(self.config, self.litConfig.params):
+ a.applyTo(self.config)
+ self.assertIn("c++03", self.config.available_features)
+ self.assertNotIn("c++11", self.config.available_features)
+
+ def test_no_actions(self):
+ self.litConfig.params["std"] = "c++03"
+ param = dsl.Parameter(
+ name="std", choices=["c++03"], type=str, help="", actions=lambda _: []
+ )
+ actions = param.getActions(self.config, self.litConfig.params)
+ self.assertEqual(actions, [])
+
+ def test_boolean_value_parsed_from_trueish_string_parameter(self):
+ self.litConfig.params["enable_exceptions"] = "True"
+ param = dsl.Parameter(
+ name="enable_exceptions",
+ choices=[True, False],
+ type=bool,
+ help="",
+ actions=lambda exceptions: [] if exceptions else _throw(),
+ )
+ self.assertEqual(param.getActions(self.config, self.litConfig.params), [])
+
+ def test_boolean_value_from_true_boolean_parameter(self):
+ self.litConfig.params["enable_exceptions"] = True
+ param = dsl.Parameter(
+ name="enable_exceptions",
+ choices=[True, False],
+ type=bool,
+ help="",
+ actions=lambda exceptions: [] if exceptions else _throw(),
+ )
+ self.assertEqual(param.getActions(self.config, self.litConfig.params), [])
+
+ def test_boolean_value_parsed_from_falseish_string_parameter(self):
+ self.litConfig.params["enable_exceptions"] = "False"
+ param = dsl.Parameter(
+ name="enable_exceptions",
+ choices=[True, False],
+ type=bool,
+ help="",
+ actions=lambda exceptions: []
+ if exceptions
+ else [dsl.AddFeature("-fno-exceptions")],
+ )
+ for a in param.getActions(self.config, self.litConfig.params):
+ a.applyTo(self.config)
+ self.assertIn("-fno-exceptions", self.config.available_features)
+
+ def test_boolean_value_from_false_boolean_parameter(self):
+ self.litConfig.params["enable_exceptions"] = False
+ param = dsl.Parameter(
+ name="enable_exceptions",
+ choices=[True, False],
+ type=bool,
+ help="",
+ actions=lambda exceptions: []
+ if exceptions
+ else [dsl.AddFeature("-fno-exceptions")],
+ )
+ for a in param.getActions(self.config, self.litConfig.params):
+ a.applyTo(self.config)
+ self.assertIn("-fno-exceptions", self.config.available_features)
+
+ def test_list_parsed_from_comma_delimited_string_empty(self):
+ self.litConfig.params["additional_features"] = ""
+ param = dsl.Parameter(
+ name="additional_features", type=list, help="", actions=lambda f: f
+ )
+ self.assertEqual(param.getActions(self.config, self.litConfig.params), [])
+
+ def test_list_parsed_from_comma_delimited_string_1(self):
+ self.litConfig.params["additional_features"] = "feature1"
+ param = dsl.Parameter(
+ name="additional_features", type=list, help="", actions=lambda f: f
+ )
+ self.assertEqual(
+ param.getActions(self.config, self.litConfig.params), ["feature1"]
+ )
+
+ def test_list_parsed_from_comma_delimited_string_2(self):
+ self.litConfig.params["additional_features"] = "feature1,feature2"
+ param = dsl.Parameter(
+ name="additional_features", type=list, help="", actions=lambda f: f
+ )
+ self.assertEqual(
+ param.getActions(self.config, self.litConfig.params),
+ ["feature1", "feature2"],
+ )
+
+ def test_list_parsed_from_comma_delimited_string_3(self):
+ self.litConfig.params["additional_features"] = "feature1,feature2, feature3"
+ param = dsl.Parameter(
+ name="additional_features", type=list, help="", actions=lambda f: f
+ )
+ self.assertEqual(
+ param.getActions(self.config, self.litConfig.params),
+ ["feature1", "feature2", "feature3"],
+ )
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/libcxx/test/libcxx-03/selftest/dsl/lit.local.cfg b/libcxx/test/libcxx-03/selftest/dsl/lit.local.cfg
new file mode 100644
index 0000000000000..352719b8f48d8
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/dsl/lit.local.cfg
@@ -0,0 +1,15 @@
+# Since we try to pass substitutions as-is to some tests, we must "escape"
+# them in case they contain other substitutions. Otherwise, the substitutions
+# will be fully expanded when passed to the tests. For example, we want an
+# %{exec} substitution that contains `--execdir %T` to be passed as-is, without
+# substituting the directory. This way, the test itself can populate %T as it
+# sees fit, and %{exec} will respect it.
+#
+# To solve this problem, we pickle the substitutions and base64 encode that
+# to pass it to the test, and we decode and unpickle the substitutions from
+# within the test.
+import base64, lit.util, pickle
+
+base64Encode = lambda s: lit.util.to_string(base64.b64encode(lit.util.to_bytes(s)))
+escapedSubstitutions = base64Encode(pickle.dumps(config.substitutions))
+config.substitutions.append(("%{substitutions}", escapedSubstitutions))
diff --git a/libcxx/test/libcxx-03/selftest/file_dependencies/a.txt b/libcxx/test/libcxx-03/selftest/file_dependencies/a.txt
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libcxx/test/libcxx-03/selftest/file_dependencies/absolute-and-relative-paths.sh.cpp b/libcxx/test/libcxx-03/selftest/file_dependencies/absolute-and-relative-paths.sh.cpp
new file mode 100644
index 0000000000000..ac52f67dfac3a
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/file_dependencies/absolute-and-relative-paths.sh.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that FILE_DEPENDENCIES work with relative AND absolute paths.
+
+// FILE_DEPENDENCIES: %S/a.txt
+// RUN: test -e %T/a.txt
+
+// FILE_DEPENDENCIES: dir/b.txt
+// RUN: test -e %T/b.txt
diff --git a/libcxx/test/libcxx-03/selftest/file_dependencies/dir/b.txt b/libcxx/test/libcxx-03/selftest/file_dependencies/dir/b.txt
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libcxx/test/libcxx-03/selftest/file_dependencies/substitute-in-dependencies.sh.cpp b/libcxx/test/libcxx-03/selftest/file_dependencies/substitute-in-dependencies.sh.cpp
new file mode 100644
index 0000000000000..c63684c7834df
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/file_dependencies/substitute-in-dependencies.sh.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that lit substitutions are expanded inside FILE_DEPENDENCIES lines.
+
+// FILE_DEPENDENCIES: %s
+// RUN: test -e %T/substitute-in-dependencies.sh.cpp
diff --git a/libcxx/test/libcxx-03/selftest/gen.cpp/empty.gen.cpp b/libcxx/test/libcxx-03/selftest/gen.cpp/empty.gen.cpp
new file mode 100644
index 0000000000000..e0a36db25775e
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/gen.cpp/empty.gen.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure we can generate no tests at all
+
+// RUN: :
diff --git a/libcxx/test/libcxx-03/selftest/gen.cpp/one.gen.cpp b/libcxx/test/libcxx-03/selftest/gen.cpp/one.gen.cpp
new file mode 100644
index 0000000000000..077baa11d89b6
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/gen.cpp/one.gen.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure we can generate one test
+
+// RUN: echo "//--- test1.compile.pass.cpp"
diff --git a/libcxx/test/libcxx-03/selftest/gen.cpp/two.gen.cpp b/libcxx/test/libcxx-03/selftest/gen.cpp/two.gen.cpp
new file mode 100644
index 0000000000000..91ddf5208dcfd
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/gen.cpp/two.gen.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure we can generate two tests
+
+// RUN: echo "//--- test1.compile.pass.cpp"
+// RUN: echo "//--- test2.compile.pass.cpp"
diff --git a/libcxx/test/libcxx-03/selftest/link.fail.cpp/compile-error.link.fail.cpp b/libcxx/test/libcxx-03/selftest/link.fail.cpp/compile-error.link.fail.cpp
new file mode 100644
index 0000000000000..607be79b8c08d
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.fail.cpp/compile-error.link.fail.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at compile-time.
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/link.fail.cpp/link-error.link.fail.cpp b/libcxx/test/libcxx-03/selftest/link.fail.cpp/link-error.link.fail.cpp
new file mode 100644
index 0000000000000..7289406723efe
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.fail.cpp/link-error.link.fail.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if it fails at link time.
+
+extern void this_is_an_undefined_symbol();
+
+int main(int, char**) {
+ this_is_an_undefined_symbol();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/link.fail.cpp/link-success.link.fail.cpp b/libcxx/test/libcxx-03/selftest/link.fail.cpp/link-success.link.fail.cpp
new file mode 100644
index 0000000000000..95d812abc09ed
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.fail.cpp/link-success.link.fail.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it succeeds to link.
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.cpp/compile-error.link.pass.cpp b/libcxx/test/libcxx-03/selftest/link.pass.cpp/compile-error.link.pass.cpp
new file mode 100644
index 0000000000000..607be79b8c08d
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.cpp/compile-error.link.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at compile-time.
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.cpp/link-error.link.pass.cpp b/libcxx/test/libcxx-03/selftest/link.pass.cpp/link-error.link.pass.cpp
new file mode 100644
index 0000000000000..422c9a16afc05
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.cpp/link-error.link.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails to link.
+
+extern void this_is_an_undefined_symbol();
+
+int main(int, char**) {
+ this_is_an_undefined_symbol();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.cpp/link-success.link.pass.cpp b/libcxx/test/libcxx-03/selftest/link.pass.cpp/link-success.link.pass.cpp
new file mode 100644
index 0000000000000..f25da55d42a38
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.cpp/link-success.link.pass.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if it succeeds to link.
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.cpp/run-error.link.pass.cpp b/libcxx/test/libcxx-03/selftest/link.pass.cpp/run-error.link.pass.cpp
new file mode 100644
index 0000000000000..ee44d1798d489
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.cpp/run-error.link.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if it succeeds to link, even though it would have
+// failed at runtime.
+
+int main(int, char**) {
+ return 1;
+}
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.mm/compile-error.link.pass.mm b/libcxx/test/libcxx-03/selftest/link.pass.mm/compile-error.link.pass.mm
new file mode 100644
index 0000000000000..6227641c54ed5
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.mm/compile-error.link.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at compile-time.
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.mm/link-error.link.pass.mm b/libcxx/test/libcxx-03/selftest/link.pass.mm/link-error.link.pass.mm
new file mode 100644
index 0000000000000..e95594276e1ea
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.mm/link-error.link.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails to link.
+
+extern void this_is_an_undefined_symbol();
+
+int main(int, char**) {
+ this_is_an_undefined_symbol();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.mm/link-success.link.pass.mm b/libcxx/test/libcxx-03/selftest/link.pass.mm/link-success.link.pass.mm
new file mode 100644
index 0000000000000..a831d7f914f2e
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.mm/link-success.link.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure the test passes if it succeeds to link.
+
+ at interface I;
+ at end
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/link.pass.mm/run-error.link.pass.mm b/libcxx/test/libcxx-03/selftest/link.pass.mm/run-error.link.pass.mm
new file mode 100644
index 0000000000000..778fab3329ae6
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/link.pass.mm/run-error.link.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure the test passes if it succeeds to link, even though it would have
+// failed at runtime.
+
+ at interface I;
+ at end
+
+int main(int, char**) {
+ return 1;
+}
diff --git a/libcxx/test/libcxx-03/selftest/modules/no-modules.sh.cpp b/libcxx/test/libcxx-03/selftest/modules/no-modules.sh.cpp
new file mode 100644
index 0000000000000..74e65a9072f7b
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/modules/no-modules.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that the compile flags contain no module information.
+
+// MODULE_DEPENDENCIES:
+
+// RUN: echo "%{compile_flags}" | grep -v "std.pcm"
+// RUN: echo "%{compile_flags}" | grep -v "std.compat.pcm"
diff --git a/libcxx/test/libcxx-03/selftest/modules/std-and-std.compat-module.sh.cpp b/libcxx/test/libcxx-03/selftest/modules/std-and-std.compat-module.sh.cpp
new file mode 100644
index 0000000000000..d56ebb2961d4a
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/modules/std-and-std.compat-module.sh.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
+// UNSUPPORTED: clang-modules-build
+// UNSUPPORTED: gcc
+
+// XFAIL: has-no-cxx-module-support
+
+// Make sure that the compile flags contain the expected elements.
+// The tests only look for the expected components and not the exact flags.
+// Otherwise changing the location of the module would break this test.
+
+// MODULE_DEPENDENCIES: std std.compat
+
+// RUN: echo "%{compile_flags}" | grep -- "-fmodule-file=std=.*/std.pcm .*/std.pcm"
+// RUN: echo "%{compile_flags}" | grep -- "-fmodule-file=std.compat=.*/std.compat.pcm .*/std.compat.pcm"
diff --git a/libcxx/test/libcxx-03/selftest/modules/std-module.sh.cpp b/libcxx/test/libcxx-03/selftest/modules/std-module.sh.cpp
new file mode 100644
index 0000000000000..ec43994fa1ef9
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/modules/std-module.sh.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, c++11, c++14, c++17, c++20
+// UNSUPPORTED: clang-modules-build
+// UNSUPPORTED: gcc
+
+// XFAIL: has-no-cxx-module-support
+
+// Make sure that the compile flags contain the expected elements.
+// The tests only look for the expected components and not the exact flags.
+// Otherwise changing the location of the module would break this test.
+
+// MODULE_DEPENDENCIES: std
+
+// RUN: echo "%{compile_flags}" | grep -- "-fmodule-file=std=.*/std.pcm .*/std.pcm"
+
+// The std module should not provide the std.compat module
+// RUN: echo "%{compile_flags}" | grep -v "std.compat.pcm"
diff --git a/libcxx/test/libcxx-03/selftest/modules/std.compat-module.sh.cpp b/libcxx/test/libcxx-03/selftest/modules/std.compat-module.sh.cpp
new file mode 100644
index 0000000000000..e84709853fbca
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/modules/std.compat-module.sh.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, c++11, c++14, c++17, c++20
+// UNSUPPORTED: clang-modules-build
+// UNSUPPORTED: gcc
+
+// XFAIL: has-no-cxx-module-support
+
+// Make sure that the compile flags contain the expected elements.
+// The tests only look for the expected components and not the exact flags.
+// Otherwise changing the location of the module would break this test.
+
+// MODULE_DEPENDENCIES: std.compat
+
+// RUN: echo "%{compile_flags}" | grep -- "-fmodule-file=std.compat=.*/std.compat.pcm .*/std.compat.pcm"
+
+// It's unspecified whether std.compat is built on the std module.
+// Therefore don't test its presence
diff --git a/libcxx/test/libcxx-03/selftest/pass.cpp/compile-error.pass.cpp b/libcxx/test/libcxx-03/selftest/pass.cpp/compile-error.pass.cpp
new file mode 100644
index 0000000000000..6ff8850537f59
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.cpp/compile-error.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at compile-time
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/pass.cpp/link-error.pass.cpp b/libcxx/test/libcxx-03/selftest/pass.cpp/link-error.pass.cpp
new file mode 100644
index 0000000000000..70e2ab66e8bee
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.cpp/link-error.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at link-time
+
+extern void this_is_an_undefined_symbol();
+
+int main(int, char**) {
+ this_is_an_undefined_symbol();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.cpp/run-error.pass.cpp b/libcxx/test/libcxx-03/selftest/pass.cpp/run-error.pass.cpp
new file mode 100644
index 0000000000000..eac7d8846e23a
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.cpp/run-error.pass.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at runtime.
+
+int main(int, char**) {
+ return 1;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.cpp/run-success.pass.cpp b/libcxx/test/libcxx-03/selftest/pass.cpp/run-success.pass.cpp
new file mode 100644
index 0000000000000..c37b79a99612b
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.cpp/run-success.pass.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes pass if it succeeds at runtime.
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.cpp/werror.pass.cpp b/libcxx/test/libcxx-03/selftest/pass.cpp/werror.pass.cpp
new file mode 100644
index 0000000000000..590785fc1774d
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.cpp/werror.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure that even a simple unused variable warning is treated as an
+// error in the test suite. This is to make sure the test suite always runs
+// with -Werror.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wunused-variable
+
+// TODO: We don't enable -Werror on GCC right now, because too many tests fail.
+// UNSUPPORTED: gcc
+
+int main(int, char**) {
+ int foo;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.mm/compile-error.pass.mm b/libcxx/test/libcxx-03/selftest/pass.mm/compile-error.pass.mm
new file mode 100644
index 0000000000000..04bb4cc445266
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.mm/compile-error.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at compile-time
+
+struct Foo { };
+typedef Foo::x x;
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/pass.mm/link-error.pass.mm b/libcxx/test/libcxx-03/selftest/pass.mm/link-error.pass.mm
new file mode 100644
index 0000000000000..abc34d6793516
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.mm/link-error.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at link-time
+
+extern void this_is_an_undefined_symbol();
+
+int main(int, char**) {
+ this_is_an_undefined_symbol();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.mm/no-arc.pass.mm b/libcxx/test/libcxx-03/selftest/pass.mm/no-arc.pass.mm
new file mode 100644
index 0000000000000..dd33d1b2f7d51
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.mm/no-arc.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure ARC is not enabled by default in these tests.
+
+#if __has_feature(objc_arc)
+# error "arc should not be enabled by default"
+#endif
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.mm/run-error.pass.mm b/libcxx/test/libcxx-03/selftest/pass.mm/run-error.pass.mm
new file mode 100644
index 0000000000000..22e17666eab07
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.mm/run-error.pass.mm
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails at runtime.
+
+int main(int, char**) {
+ return 1;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.mm/run-success.pass.mm b/libcxx/test/libcxx-03/selftest/pass.mm/run-success.pass.mm
new file mode 100644
index 0000000000000..4021b24b75ec0
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.mm/run-success.pass.mm
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure the test passes pass if it succeeds at runtime.
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/pass.mm/use-objective-cxx.pass.mm b/libcxx/test/libcxx-03/selftest/pass.mm/use-objective-cxx.pass.mm
new file mode 100644
index 0000000000000..ddd2304ef727d
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/pass.mm/use-objective-cxx.pass.mm
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: objective-c++
+
+// Make sure we can use Objective C++ features in these tests.
+
+ at interface Foo
+ at end
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/remote-substitutions.sh.cpp b/libcxx/test/libcxx-03/selftest/remote-substitutions.sh.cpp
new file mode 100644
index 0000000000000..da279790a1f25
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/remote-substitutions.sh.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// 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
+// host and their path is fixed up (directly in the command-line) to their
+// path on the remote host instead of the local host.
+//
+// We also check that the path of test-executables is replaced whether they
+// appear first in the command-line or not.
+
+// UNSUPPORTED: executor-has-no-bash
+// RUN: %{cxx} %s %{flags} %{compile_flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe 0
+// RUN: %{exec} bash -c '! %t.exe 1'
+
+#include <cassert>
+#include <cstdlib>
+
+int main(int argc, char** argv) {
+ assert(argc == 2);
+ int ret = std::atoi(argv[1]);
+ return ret;
+}
diff --git a/libcxx/test/libcxx-03/selftest/sh.cpp/run-error.sh.cpp b/libcxx/test/libcxx-03/selftest/sh.cpp/run-error.sh.cpp
new file mode 100644
index 0000000000000..4be0c05c4f076
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/sh.cpp/run-error.sh.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if it fails to run
+
+// RUN: false
diff --git a/libcxx/test/libcxx-03/selftest/sh.cpp/run-success.sh.cpp b/libcxx/test/libcxx-03/selftest/sh.cpp/run-success.sh.cpp
new file mode 100644
index 0000000000000..724d03ddb848e
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/sh.cpp/run-success.sh.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if it succeeds to run
+
+// RUN: :
diff --git a/libcxx/test/libcxx-03/selftest/sh.cpp/substitutions.sh.cpp b/libcxx/test/libcxx-03/selftest/sh.cpp/substitutions.sh.cpp
new file mode 100644
index 0000000000000..99bfb9a3c97d8
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/sh.cpp/substitutions.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure we have access to the following substitutions at all times:
+// - %{cxx}
+// - %{flags}
+// - %{compile_flags}
+// - %{link_flags}
+// - %{exec}
+
+// RUN: %{cxx} %s %{flags} %{compile_flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe
+
+#include <cassert>
+
+int main(int argc, char**) {
+ assert(argc == 1);
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/sh.cpp/werror.sh.cpp b/libcxx/test/libcxx-03/selftest/sh.cpp/werror.sh.cpp
new file mode 100644
index 0000000000000..3188f57ec8fd1
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/sh.cpp/werror.sh.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure that even a simple unused variable warning is treated as an
+// error in the test suite, including in .sh.cpp tests.
+
+// TODO: We don't enable -Werror on GCC right now, because too many tests fail.
+// UNSUPPORTED: gcc
+
+// RUN: %{build} -Wunused-variable
+// RUN: %{run}
+
+int main(int, char**) {
+ int foo;
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/shell-no-escape-builtins.sh.cpp b/libcxx/test/libcxx-03/selftest/shell-no-escape-builtins.sh.cpp
new file mode 100644
index 0000000000000..9f129d5703bf8
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/shell-no-escape-builtins.sh.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that we don't escape Shell builtins like `!`, because the
+// shell otherwise thinks it's a command and it can't find it.
+
+// RUN: ! false
diff --git a/libcxx/test/libcxx-03/selftest/stdin-is-piped.sh.cpp b/libcxx/test/libcxx-03/selftest/stdin-is-piped.sh.cpp
new file mode 100644
index 0000000000000..ffd10631c6a67
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/stdin-is-piped.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that the executor pipes standard input to the test-executable being run.
+
+// RUN: %{build}
+// RUN: echo "abc" | %{exec} %t.exe
+
+#include <cstdio>
+
+int main(int, char**) {
+ int input[] = {std::getchar(), std::getchar(), std::getchar()};
+
+ if (input[0] == 'a' && input[1] == 'b' && input[2] == 'c')
+ return 0;
+ return 1;
+}
diff --git a/libcxx/test/libcxx-03/selftest/test_macros.pass.cpp b/libcxx/test/libcxx-03/selftest/test_macros.pass.cpp
new file mode 100644
index 0000000000000..9bcf7cf9a31f5
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/test_macros.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Test the "test_macros.h" header.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__config>
+#include "test_macros.h"
+
+#ifndef TEST_STD_VER
+#error TEST_STD_VER must be defined
+#endif
+
+#ifndef TEST_NOEXCEPT
+#error TEST_NOEXCEPT must be defined
+#endif
+
+#ifndef LIBCPP_ASSERT
+#error LIBCPP_ASSERT must be defined
+#endif
+
+#ifndef LIBCPP_STATIC_ASSERT
+#error LIBCPP_STATIC_ASSERT must be defined
+#endif
+
+void test_noexcept() TEST_NOEXCEPT
+{
+}
+
+int main(int, char**)
+{
+ test_noexcept();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/selftest/tmpdir-exists.sh.cpp b/libcxx/test/libcxx-03/selftest/tmpdir-exists.sh.cpp
new file mode 100644
index 0000000000000..7f9e69d269d63
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/tmpdir-exists.sh.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that the directory represented by %T exists when we run the test.
+
+// RUN: test -d %T
diff --git a/libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics-unmarked.verify.cpp b/libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics-unmarked.verify.cpp
new file mode 100644
index 0000000000000..d59d42b98fc0a
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics-unmarked.verify.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if there are no diagnostics, but we didn't
+// use the 'expected-no-diagnostics' markup.
+//
+// Note: For the purpose of this test, make sure the file would otherwise
+// compile to make sure we really fail due to a lack of markup.
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics.verify.cpp b/libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics.verify.cpp
new file mode 100644
index 0000000000000..d622c786ee371
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/verify.cpp/no-diagnostics.verify.cpp
@@ -0,0 +1,11 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if we expected no diagnostics
+
+// expected-no-diagnostics
diff --git a/libcxx/test/libcxx-03/selftest/verify.cpp/no-werror.verify.cpp b/libcxx/test/libcxx-03/selftest/verify.cpp/no-werror.verify.cpp
new file mode 100644
index 0000000000000..e96d6be9087bc
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/verify.cpp/no-werror.verify.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure clang-verify tests distinguish warnings from errors.
+
+// ADDITIONAL_COMPILE_FLAGS: -Wunused-variable
+
+void f() {
+ int foo; // expected-warning {{unused variable}}
+}
diff --git a/libcxx/test/libcxx-03/selftest/verify.cpp/right-diagnostic.verify.cpp b/libcxx/test/libcxx-03/selftest/verify.cpp/right-diagnostic.verify.cpp
new file mode 100644
index 0000000000000..8bca568707dc4
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/verify.cpp/right-diagnostic.verify.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure the test passes if the expected diagnostic is correct.
+
+struct Foo { };
+typedef Foo::x x; // expected-error{{no type named 'x' in 'Foo'}}
diff --git a/libcxx/test/libcxx-03/selftest/verify.cpp/wrong-diagnostic.verify.cpp b/libcxx/test/libcxx-03/selftest/verify.cpp/wrong-diagnostic.verify.cpp
new file mode 100644
index 0000000000000..3bc2ba841ad9a
--- /dev/null
+++ b/libcxx/test/libcxx-03/selftest/verify.cpp/wrong-diagnostic.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: *
+
+// Make sure the test DOES NOT pass if the expected diagnostic is wrong.
+
+struct Foo { };
+typedef Foo::x x; // expected-error{{this is not found in the errors}}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/alignof.compile.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/alignof.compile.pass.cpp
new file mode 100644
index 0000000000000..49cbde14c568b
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/alignof.compile.pass.cpp
@@ -0,0 +1,146 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Ensure that we never change the size or alignment of `basic_string`
+
+// UNSUPPORTED: c++03
+
+#include <cstdint>
+#include <iterator>
+#include <string>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+#include "test_allocator.h"
+
+template <class T>
+class small_pointer {
+public:
+ using value_type = T;
+ using difference_type = std::int16_t;
+ using pointer = small_pointer;
+ using reference = T&;
+ using iterator_category = std::random_access_iterator_tag;
+
+private:
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::int16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+template <class CharT>
+using min_string = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>;
+
+template <class CharT>
+using test_string = std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT>>;
+
+template <class CharT>
+using small_string = std::basic_string<CharT, std::char_traits<CharT>, small_iter_allocator<CharT>>;
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(alignof(std::string) == 8, "");
+static_assert(alignof(min_string<char>) == 8, "");
+static_assert(alignof(test_string<char>) == 8, "");
+static_assert(alignof(small_string<char>) == 2, "");
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+# if __WCHAR_WIDTH__ == 32
+static_assert(alignof(std::wstring) == 8, "");
+static_assert(alignof(min_string<wchar_t>) == 8, "");
+static_assert(alignof(test_string<wchar_t>) == 8, "");
+static_assert(alignof(small_string<wchar_t>) == 4, "");
+# elif __WCHAR_WIDTH__ == 16
+static_assert(alignof(std::wstring) == 8, "");
+static_assert(alignof(min_string<wchar_t>) == 8, "");
+static_assert(alignof(test_string<wchar_t>) == 8, "");
+static_assert(alignof(small_string<wchar_t>) == 2, "");
+# else
+# error "Unexpected wchar_t width"
+# endif
+# endif
+
+# ifndef TEST_HAS_NO_CHAR8_T
+static_assert(alignof(std::u8string) == 8, "");
+static_assert(alignof(min_string<char8_t>) == 8, "");
+static_assert(alignof(test_string<char8_t>) == 8, "");
+static_assert(alignof(small_string<char8_t>) == 2, "");
+# endif
+
+# ifndef TEST_HAS_NO_UNICODE_CHARS
+static_assert(alignof(std::u16string) == 8, "");
+static_assert(alignof(std::u32string) == 8, "");
+static_assert(alignof(min_string<char16_t>) == 8, "");
+static_assert(alignof(min_string<char32_t>) == 8, "");
+static_assert(alignof(test_string<char16_t>) == 8, "");
+static_assert(alignof(test_string<char32_t>) == 8, "");
+static_assert(alignof(small_string<char16_t>) == 2, "");
+static_assert(alignof(small_string<char32_t>) == 4, "");
+# endif
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(alignof(std::string) == 4, "");
+static_assert(alignof(min_string<char>) == 4, "");
+static_assert(alignof(test_string<char>) == 4, "");
+static_assert(alignof(small_string<char>) == 2, "");
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+# if __WCHAR_WIDTH__ == 32
+static_assert(alignof(std::wstring) == 4, "");
+static_assert(alignof(min_string<wchar_t>) == 4, "");
+static_assert(alignof(test_string<wchar_t>) == 4, "");
+static_assert(alignof(small_string<wchar_t>) == 4, "");
+# elif __WCHAR_WIDTH__ == 16
+static_assert(alignof(std::wstring) == 4, "");
+static_assert(alignof(min_string<wchar_t>) == 4, "");
+static_assert(alignof(test_string<wchar_t>) == 4, "");
+static_assert(alignof(small_string<wchar_t>) == 2, "");
+# else
+# error "Unexpected wchar_t width"
+# endif
+# endif
+
+# ifndef TEST_HAS_NO_CHAR8_T
+static_assert(alignof(std::u8string) == 4, "");
+static_assert(alignof(min_string<char8_t>) == 4, "");
+static_assert(alignof(test_string<char8_t>) == 4, "");
+static_assert(alignof(small_string<char8_t>) == 2, "");
+# endif
+
+# ifndef TEST_HAS_NO_UNICODE_CHARS
+static_assert(alignof(std::u16string) == 4, "");
+static_assert(alignof(std::u32string) == 4, "");
+static_assert(alignof(min_string<char16_t>) == 4, "");
+static_assert(alignof(min_string<char32_t>) == 4, "");
+static_assert(alignof(test_string<char16_t>) == 4, "");
+static_assert(alignof(test_string<char32_t>) == 4, "");
+static_assert(alignof(small_string<char32_t>) == 4, "");
+# endif
+
+#else
+# error "std::size_t has an unexpected size"
+#endif
diff --git a/libcxx/test/libcxx-03/strings/basic.string/nonnull.verify.cpp b/libcxx/test/libcxx-03/strings/basic.string/nonnull.verify.cpp
new file mode 100644
index 0000000000000..d61896277afd4
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/nonnull.verify.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// Ensure that APIs which take a CharT* (and no size for it) are diagnosing passing a nullptr to them
+
+#include <string>
+
+#include "test_macros.h"
+
+void func() {
+ const char* const np = nullptr;
+ std::string str1(np); // expected-warning {{null passed}}
+ std::string str2(np, std::allocator<char>{}); // expected-warning {{null passed}}
+ str2 = np; // expected-warning {{null passed}}
+ str2 += np; // expected-warning {{null passed}}
+ str2.append(np); // expected-warning {{null passed}}
+ str2.insert(0, np); // expected-warning {{null passed}}
+ str2.find(np); // expected-warning {{null passed}}
+ str2.rfind(np); // expected-warning {{null passed}}
+ str2.find_first_of(np); // expected-warning {{null passed}}
+ str2.find_last_of(np); // expected-warning {{null passed}}
+ str2.find_first_not_of(np); // expected-warning {{null passed}}
+ str2.find_last_not_of(np); // expected-warning {{null passed}}
+ str2.compare(np); // expected-warning {{null passed}}
+ str2.compare(0, 0, np); // expected-warning {{null passed}}
+
+#if TEST_STD_VER >= 20
+ str2.starts_with(np); // expected-warning {{null passed}}
+ str2.ends_with(np); // expected-warning {{null passed}}
+#endif
+#if TEST_STD_VER >= 23
+ str2.contains(np); // expected-warning {{null passed}}
+#endif
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/sizeof.compile.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/sizeof.compile.pass.cpp
new file mode 100644
index 0000000000000..31f1a94c73216
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/sizeof.compile.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Ensure that we never change the size or alignment of `basic_string`
+
+#include <cstdint>
+#include <iterator>
+#include <string>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+#include "test_allocator.h"
+
+template <class T>
+class small_pointer {
+public:
+ using value_type = T;
+ using difference_type = std::int16_t;
+ using pointer = small_pointer;
+ using reference = T&;
+ using iterator_category = std::random_access_iterator_tag;
+
+private:
+ std::uint16_t offset;
+};
+
+template <class T>
+class small_iter_allocator {
+public:
+ using value_type = T;
+ using pointer = small_pointer<T>;
+ using size_type = std::int16_t;
+ using difference_type = std::int16_t;
+
+ small_iter_allocator() TEST_NOEXCEPT {}
+
+ template <class U>
+ small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
+
+ T* allocate(std::size_t n);
+ void deallocate(T* p, std::size_t);
+
+ friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
+ friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
+};
+
+template <class CharT>
+using min_string = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT> >;
+
+template <class CharT>
+using test_string = std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT> >;
+
+template <class CharT>
+using small_string = std::basic_string<CharT, std::char_traits<CharT>, small_iter_allocator<CharT> >;
+
+#if __SIZE_WIDTH__ == 64
+
+static_assert(sizeof(std::string) == 24, "");
+static_assert(sizeof(min_string<char>) == 24, "");
+static_assert(sizeof(test_string<char>) == 32, "");
+static_assert(sizeof(small_string<char>) == 6, "");
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+# if __WCHAR_WIDTH__ == 32
+static_assert(sizeof(std::wstring) == 24, "");
+static_assert(sizeof(min_string<wchar_t>) == 24, "");
+static_assert(sizeof(test_string<wchar_t>) == 32, "");
+static_assert(sizeof(small_string<wchar_t>) == 12, "");
+# elif __WCHAR_WIDTH__ == 16
+static_assert(sizeof(std::wstring) == 24, "");
+static_assert(sizeof(min_string<wchar_t>) == 24, "");
+static_assert(sizeof(test_string<wchar_t>) == 32, "");
+static_assert(sizeof(small_string<wchar_t>) == 6, "");
+# else
+# error "Unexpected wchar_t width"
+# endif
+# endif
+
+# ifndef TEST_HAS_NO_CHAR8_T
+static_assert(sizeof(std::u8string) == 24, "");
+static_assert(sizeof(min_string<char8_t>) == 24, "");
+static_assert(sizeof(test_string<char8_t>) == 32, "");
+static_assert(sizeof(small_string<char8_t>) == 6, "");
+# endif
+
+# ifndef TEST_HAS_NO_UNICODE_CHARS
+static_assert(sizeof(std::u16string) == 24, "");
+static_assert(sizeof(std::u32string) == 24, "");
+static_assert(sizeof(min_string<char16_t>) == 24, "");
+static_assert(sizeof(min_string<char32_t>) == 24, "");
+static_assert(sizeof(test_string<char16_t>) == 32, "");
+static_assert(sizeof(test_string<char32_t>) == 32, "");
+static_assert(sizeof(small_string<char16_t>) == 6, "");
+static_assert(sizeof(small_string<char32_t>) == 12, "");
+# endif
+
+#elif __SIZE_WIDTH__ == 32
+
+static_assert(sizeof(std::string) == 12, "");
+static_assert(sizeof(min_string<char>) == 12, "");
+static_assert(sizeof(test_string<char>) == 24, "");
+static_assert(sizeof(small_string<char>) == 6, "");
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+# if __WCHAR_WIDTH__ == 32
+static_assert(sizeof(std::wstring) == 12, "");
+static_assert(sizeof(min_string<wchar_t>) == 12, "");
+static_assert(sizeof(test_string<wchar_t>) == 24, "");
+static_assert(sizeof(small_string<wchar_t>) == 12, "");
+# elif __WCHAR_WIDTH__ == 16
+static_assert(sizeof(std::wstring) == 12, "");
+static_assert(sizeof(min_string<wchar_t>) == 12, "");
+static_assert(sizeof(test_string<wchar_t>) == 24, "");
+static_assert(sizeof(small_string<wchar_t>) == 6, "");
+# else
+# error "Unexpected wchar_t width"
+# endif
+# endif
+
+# ifndef TEST_HAS_NO_CHAR8_T
+static_assert(sizeof(std::u8string) == 12, "");
+static_assert(sizeof(min_string<char8_t>) == 12, "");
+static_assert(sizeof(test_string<char8_t>) == 24, "");
+static_assert(sizeof(small_string<char>) == 6, "");
+# endif
+
+# ifndef TEST_HAS_NO_UNICODE_CHARS
+static_assert(sizeof(std::u16string) == 12, "");
+static_assert(sizeof(std::u32string) == 12, "");
+static_assert(sizeof(min_string<char16_t>) == 12, "");
+static_assert(sizeof(min_string<char32_t>) == 12, "");
+static_assert(sizeof(test_string<char16_t>) == 24, "");
+static_assert(sizeof(test_string<char32_t>) == 24, "");
+static_assert(sizeof(small_string<char16_t>) == 6, "");
+static_assert(sizeof(small_string<char32_t>) == 12, "");
+# endif
+
+#else
+# error "std::size_t has an unexpected size"
+#endif
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.back.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.back.pass.cpp
new file mode 100644
index 0000000000000..36a485a1e4d00
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.back.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call back() on empty container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ S s;
+ TEST_LIBCPP_ASSERT_FAILURE(s.back(), "string::back(): string is empty");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cback.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cback.pass.cpp
new file mode 100644
index 0000000000000..d810acd67e7e7
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cback.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call back() on empty const container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ const S s;
+ TEST_LIBCPP_ASSERT_FAILURE(s.back(), "string::back(): string is empty");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cfront.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cfront.pass.cpp
new file mode 100644
index 0000000000000..12e7ef3328b04
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cfront.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call front() on empty const container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ const S s;
+ TEST_LIBCPP_ASSERT_FAILURE(s.front(), "string::front(): string is empty");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cindex.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cindex.pass.cpp
new file mode 100644
index 0000000000000..3983352712963
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.cindex.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Index const string out of bounds.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ const S s;
+ assert(s[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(s[1], "string index out of bounds");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.front.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.front.pass.cpp
new file mode 100644
index 0000000000000..24df3fcad0c5c
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.front.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call front() on empty container.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ S s;
+ TEST_LIBCPP_ASSERT_FAILURE(s.front(), "string::front(): string is empty");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.index.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.index.pass.cpp
new file mode 100644
index 0000000000000..d26997d8d24c2
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.access/assert.index.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Index string out of bounds.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ S s;
+ assert(s[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(s[1], "string index out of bounds");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/PR53170.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/PR53170.pass.cpp
new file mode 100644
index 0000000000000..e7b775068c54b
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/PR53170.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// void reserve(); // Deprecated in C++20.
+// void reserve(size_type);
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE
+
+// This test ensures that libc++ implements https://wg21.link/P0966R1 (reserve never shrinks)
+// even before C++20. This is required in order to avoid ODR violations because basic_string::reserve(size)
+// is compiled into the shared library. Hence, it needs to have the same definition in all Standard modes.
+//
+// However, note that reserve() does shrink, and it does so in all Standard modes.
+//
+// Reported as https://llvm.org/PR53170.
+
+// reserve(n) used to shrink the string until https://llvm.org/D117332 was shipped in LLVM 14.
+// XFAIL: using-built-library-before-llvm-14
+
+#include <string>
+#include <stdexcept>
+#include <cassert>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+template <class S>
+TEST_CONSTEXPR_CXX20 bool test() {
+ // Test that a call to reserve() does shrink the string.
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ S s(1000, 'a');
+ typename S::size_type old_cap = s.capacity();
+ s.resize(20);
+ assert(s.capacity() == old_cap);
+
+ s.reserve();
+ assert(s.capacity() < old_cap);
+ }
+
+ // Test that a call to reserve(smaller-than-capacity) never shrinks the string.
+ {
+ S s(1000, 'a');
+ typename S::size_type old_cap = s.capacity();
+ s.resize(20);
+ assert(s.capacity() == old_cap);
+
+ s.reserve(10);
+ assert(s.capacity() == old_cap);
+ }
+
+ // In particular, test that reserve(0) does NOT shrink the string.
+ {
+ S s(1000, 'a');
+ typename S::size_type old_cap = s.capacity();
+ s.resize(20);
+ assert(s.capacity() == old_cap);
+
+ s.reserve(0);
+ assert(s.capacity() == old_cap);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test<std::string>();
+
+#if TEST_STD_VER >= 11
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+#endif
+
+#if TEST_STD_VER > 17
+ static_assert(test<std::string>());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp
new file mode 100644
index 0000000000000..77da29225957b
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/allocation_size.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+#include "test_macros.h"
+
+// alignment of the string heap buffer is hardcoded to 8
+const std::size_t alignment = 8;
+
+int main(int, char**) {
+ std::string input_string;
+ input_string.resize(64, 'a');
+
+ // Call a constructor which selects its size using __recommend.
+ std::string test_string(input_string.data());
+ const std::size_t expected_align8_size = 71;
+
+ // Demonstrate the lesser capacity/allocation size when the alignment requirement is 8.
+ if (alignment == 8) {
+ assert(test_string.capacity() == expected_align8_size);
+ } else {
+ assert(test_string.capacity() == expected_align8_size + 8);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
new file mode 100644
index 0000000000000..7b3f81e21d8a8
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <string>
+
+// This test ensures that the correct max_size() is returned depending on the platform.
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+#include "test_macros.h"
+
+// alignment of the string heap buffer is hardcoded to 8
+static const std::size_t alignment = 8;
+
+template <class = int>
+TEST_CONSTEXPR_CXX20 void full_size() {
+ std::string str;
+ assert(str.max_size() == std::numeric_limits<std::size_t>::max() - alignment - 1);
+
+#ifndef TEST_HAS_NO_CHAR8_T
+ std::u8string u8str;
+ assert(u8str.max_size() == std::numeric_limits<std::size_t>::max() - alignment - 1);
+#endif
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ std::wstring wstr;
+ assert(wstr.max_size() ==
+ ((std::numeric_limits<std::size_t>::max() / sizeof(wchar_t) - alignment) & ~std::size_t(1)) - 1);
+#endif
+
+ std::u16string u16str;
+ std::u32string u32str;
+ assert(u16str.max_size() == ((std::numeric_limits<std::size_t>::max() / 2 - alignment) & ~std::size_t(1)) - 1);
+ assert(u32str.max_size() == ((std::numeric_limits<std::size_t>::max() / 4 - alignment) & ~std::size_t(1)) - 1);
+}
+
+template <class = int>
+TEST_CONSTEXPR_CXX20 void half_size() {
+ std::string str;
+ assert(str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment - 1);
+
+#ifndef TEST_HAS_NO_CHAR8_T
+ std::u8string u8str;
+ assert(u8str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment - 1);
+#endif
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ std::wstring wstr;
+ assert(wstr.max_size() ==
+ std::numeric_limits<std::size_t>::max() / std::max<size_t>(2ul, sizeof(wchar_t)) - alignment - 1);
+#endif
+
+ std::u16string u16str;
+ std::u32string u32str;
+ assert(u16str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment - 1);
+ assert(u32str.max_size() == std::numeric_limits<std::size_t>::max() / 4 - alignment - 1);
+}
+
+TEST_CONSTEXPR_CXX20 bool test() {
+#if _LIBCPP_ABI_VERSION == 1
+
+# if defined(__x86_64__) || defined(__i386__)
+ full_size();
+# elif defined(__APPLE__) && defined(__aarch64__)
+ half_size();
+# elif defined(__arm__) || defined(__aarch64__)
+# ifdef __BIG_ENDIAN__
+ half_size();
+# else
+ full_size();
+# endif
+# elif defined(__powerpc__) || defined(__powerpc64__)
+# ifdef __BIG_ENDIAN__
+ half_size();
+# else
+ full_size();
+# endif
+# elif defined(__sparc64__)
+ half_size();
+# elif defined(__riscv)
+ full_size();
+# elif defined(_WIN32)
+ full_size();
+# else
+# error "Your target system seems to be unsupported."
+# endif
+
+#else
+
+# if defined(__arm__) || defined(__aarch64__)
+# ifdef __BIG_ENDIAN__
+ full_size();
+# else
+ half_size();
+# endif
+# else
+ half_size();
+# endif
+
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
new file mode 100644
index 0000000000000..101838e8f525e
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <string>
+
+// void shrink_to_fit(); // constexpr since C++20
+
+#include <cassert>
+#include <string>
+
+#include "asan_testing.h"
+#include "increasing_allocator.h"
+
+template <typename T>
+struct oversizing_allocator {
+ using value_type = T;
+ oversizing_allocator() = default;
+ template <typename U>
+ oversizing_allocator(const oversizing_allocator<U>&) noexcept {}
+ std::allocation_result<T*> allocate_at_least(std::size_t n) {
+ ++n;
+ return {static_cast<T*>(::operator new(n * sizeof(T))), n};
+ }
+ T* allocate(std::size_t n) { return allocate_at_least(n).ptr; }
+ void deallocate(T* p, std::size_t) noexcept { ::operator delete(static_cast<void*>(p)); }
+};
+
+template <typename T, typename U>
+bool operator==(oversizing_allocator<T>, oversizing_allocator<U>) {
+ return true;
+}
+
+// Make sure we use an allocation returned by allocate_at_least if it is smaller than the current allocation
+// even if it contains more bytes than we requested.
+// Fix issue: https://github.com/llvm/llvm-project/pull/115659
+void test_oversizing_allocator() {
+ std::basic_string<char, std::char_traits<char>, oversizing_allocator<char>> s{
+ "String does not fit in the internal buffer and is a bit longer"};
+ s = "String does not fit in the internal buffer";
+ std::size_t capacity = s.capacity();
+ std::size_t size = s.size();
+ s.shrink_to_fit();
+ assert(s.capacity() < capacity);
+ assert(s.size() == size);
+}
+
+// Make sure libc++ shrink_to_fit does NOT swap buffer with equal allocation sizes
+void test_no_swap_with_equal_allocation_size() {
+ { // Test with custom allocator with a minimum allocation size
+ std::basic_string<char, std::char_traits<char>, min_size_allocator<128, char> > s(
+ "A long string exceeding SSO limit but within min alloc size");
+ std::size_t capacity = s.capacity();
+ std::size_t size = s.size();
+ auto data = s.data();
+ s.shrink_to_fit();
+ assert(s.capacity() <= capacity);
+ assert(s.size() == size);
+ assert(is_string_asan_correct(s));
+ assert(s.capacity() == capacity && s.data() == data);
+ }
+ { // Test with custom allocator with a minimum power of two allocation size
+ std::basic_string<char, std::char_traits<char>, pow2_allocator<char> > s(
+ "This is a long string that exceeds the SSO limit");
+ std::size_t capacity = s.capacity();
+ std::size_t size = s.size();
+ auto data = s.data();
+ s.shrink_to_fit();
+ assert(s.capacity() <= capacity);
+ assert(s.size() == size);
+ assert(is_string_asan_correct(s));
+ assert(s.capacity() == capacity && s.data() == data);
+ }
+}
+
+int main(int, char**) {
+ test_oversizing_allocator();
+ test_no_swap_with_equal_allocation_size();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.cons/constinit_sso_string.compile.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.cons/constinit_sso_string.compile.pass.cpp
new file mode 100644
index 0000000000000..9fd82f2e2ae7a
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.cons/constinit_sso_string.compile.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Ensure that strings which fit within the SSO size can be constant-initialized
+// as both a global and local.
+
+#include <string>
+
+#if __SIZE_WIDTH__ == 64
+# define LONGEST_STR "0123456789012345678901"
+#elif __SIZE_WIDTH__ == 32
+# define LONGEST_STR "0123456789"
+#else
+# error "std::size_t has an unexpected size"
+#endif
+
+constinit std::string g_str = LONGEST_STR;
+void fn() { constexpr std::string l_str = LONGEST_STR; }
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
new file mode 100644
index 0000000000000..d4a0b318f36d7
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// basic_string(const basic_string<charT,traits,Allocator>& str);
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class S>
+TEST_CONSTEXPR_CXX20 bool test() {
+ // Tests that a long string holding a SSO size string results in
+ // an SSO copy constructed value.
+ S s1("1234567890123456789012345678901234567890123456789012345678901234567890");
+ s1.resize(7);
+ S s2(s1);
+ LIBCPP_ASSERT(s2.__invariants());
+ assert(s2 == s1);
+ assert(s2.capacity() < sizeof(S));
+
+ return true;
+}
+
+int main(int, char**) {
+ test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
+#if TEST_STD_VER >= 11
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+#endif
+#if TEST_STD_VER > 17
+ static_assert(test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>());
+ static_assert(test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.cons/debug.iterator.substr.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.cons/debug.iterator.substr.pass.cpp
new file mode 100644
index 0000000000000..b237a8e91336a
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.cons/debug.iterator.substr.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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Check that basic_string(basic_string&&, size_type, Allocator) and
+// basic_string(basic_string&&, size_type, size_type, Allocator) inserts the container into the debug database
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <cassert>
+#include <string>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ using namespace std::string_literals;
+
+ {
+ std::string s = {"Banane"s, 1};
+ auto i = s.begin();
+ assert(i[0] == 'a');
+ TEST_LIBCPP_ASSERT_FAILURE(i[5], "Attempted to subscript an iterator outside its valid range");
+ }
+ {
+ std::string s = {"Banane"s, 0, 5};
+ auto i = s.begin();
+ assert(i[0] == 'B');
+ TEST_LIBCPP_ASSERT_FAILURE(i[5], "Attempted to subscript an iterator outside its valid range");
+ }
+ {
+ std::string s = {"long long string so no SSO"s, 21};
+ auto i = s.begin();
+ assert(i[0] == 'o');
+ TEST_LIBCPP_ASSERT_FAILURE(i[5], "Attempted to subscript an iterator outside its valid range");
+ }
+ {
+ std::string s = {"long long string so no SSO"s, 0, 5};
+ auto i = s.begin();
+ assert(i[0] == 'l');
+ TEST_LIBCPP_ASSERT_FAILURE(i[5], "Attempted to subscript an iterator outside its valid range");
+ }
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
new file mode 100644
index 0000000000000..56c9d63d0dbaf
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Add to iterator out of bounds.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-string
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class C>
+void test() {
+ C c(1, '\0');
+ typename C::iterator i = c.begin();
+ i += 1;
+ assert(i == c.end());
+ i = c.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(i += 2, "__bounded_iter::operator+=: Attempt to advance an iterator past the end");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
new file mode 100644
index 0000000000000..43a9739bf936f
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Decrement iterator prior to begin.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-string
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class C>
+void test() {
+ C c(1, '\0');
+ typename C::iterator i = c.end();
+ --i;
+ assert(i == c.begin());
+ TEST_LIBCPP_ASSERT_FAILURE(--i, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
new file mode 100644
index 0000000000000..e2326be021033
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Dereference non-dereferenceable iterator.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-string
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class C>
+void test() {
+ C c(1, '\0');
+ typename C::iterator i = c.end();
+ TEST_LIBCPP_ASSERT_FAILURE(*i, "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp
new file mode 100644
index 0000000000000..a7453f3115197
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Increment iterator past end.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-string
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class C>
+void test() {
+ C c(1, '\0');
+ typename C::iterator i = c.begin();
+ ++i;
+ assert(i == c.end());
+ TEST_LIBCPP_ASSERT_FAILURE(++i, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp
new file mode 100644
index 0000000000000..e7d384413b589
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Index iterator out of bounds.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators-in-string
+// UNSUPPORTED: libcpp-hardening-mode=none, c++03
+
+#include <string>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class C>
+void test() {
+ using T = decltype(std::uint8_t() - std::uint8_t());
+ C c(1, '\0');
+ typename C::iterator i = c.begin();
+ assert(i[0] == 0);
+ TEST_LIBCPP_ASSERT_FAILURE(i[1], "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
+ TEST_LIBCPP_ASSERT_FAILURE(i[-1], "__bounded_iter::operator[]: Attempt to index an iterator past the start");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp
new file mode 100644
index 0000000000000..c55410edf4eba
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Compare iterators from different containers with <.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ S s1;
+ S s2;
+ TEST_LIBCPP_ASSERT_FAILURE(s1.begin() < s2.begin(), "Attempted to compare incomparable iterators");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp
new file mode 100644
index 0000000000000..d3274cbd90cc5
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Subtract iterators from different containers.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ S s1;
+ S s2;
+ TEST_LIBCPP_ASSERT_FAILURE(s1.begin() - s2.begin(), "Attempted to subtract incompatible iterators");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp
new file mode 100644
index 0000000000000..036e75965c488
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator position) with end()
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ S l1("123");
+ typename S::const_iterator i = l1.end();
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(i), "string::erase(iterator) called with a non-dereferenceable iterator");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp
new file mode 100644
index 0000000000000..54c011c4d54a0
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// void pop_back();
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <string>
+
+#include "check_assertion.h"
+
+template <class S>
+void test() {
+ S s;
+ TEST_LIBCPP_ASSERT_FAILURE(s.pop_back(), "string::pop_back(): string is already empty");
+}
+
+int main(int, char**) {
+ test<std::string>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp
new file mode 100644
index 0000000000000..93fd6caf0ba23
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator position) with an iterator from another container
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ S l1("123");
+ S l2("123");
+ typename S::const_iterator i = l2.begin();
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(i), "string::erase(iterator) called with an iterator not referring to this string");
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp
new file mode 100644
index 0000000000000..ed97e21d9411e
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator first, const_iterator last); with invalid iterators
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <string>
+
+#include "check_assertion.h"
+#include "min_allocator.h"
+
+template <class S>
+void test() {
+ // With first iterator from another container
+ {
+ S l1("123");
+ S l2("123");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), l1.cbegin() + 1),
+ "string::erase(iterator, iterator) called with an iterator not referring to this string");
+ }
+
+ // With second iterator from another container
+ {
+ S l1("123");
+ S l2("123");
+ TEST_LIBCPP_ASSERT_FAILURE(l1.erase(l1.cbegin(), l2.cbegin() + 1), "Attempted to compare incomparable iterators");
+ }
+
+ // With both iterators from another container
+ {
+ S l1("123");
+ S l2("123");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l2.cbegin(), l2.cbegin() + 1),
+ "string::erase(iterator, iterator) called with an iterator not referring to this string");
+ }
+
+ // With an invalid range
+ {
+ S l1("123");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l1.erase(l1.cbegin() + 1, l1.cbegin()), "string::erase(first, last) called with invalid range");
+ }
+}
+
+int main(int, char**) {
+ test<std::string>();
+ test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp
new file mode 100644
index 0000000000000..561f79e0e18fb
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_char.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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// iterator insert(const_iterator p, charT c);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+// TODO: Since string::insert(iter, char) is intantiated in the dylib, this test doesn't
+// actually work if the dylib hasn't been built with debug assertions enabled.
+// Until we overhaul the debug mode, mark this test as unsupported to avoid
+// spurious CI failures.
+// REQUIRES: never-run
+
+#include <string>
+
+#include "check_assertion.h"
+
+template <class S>
+void test() {
+ S s;
+ S s2;
+ TEST_LIBCPP_ASSERT_FAILURE(
+ s.insert(s2.begin(), '1'),
+ "string::insert(iterator, character) called with an iterator not referring to this string");
+}
+
+int main(int, char**) {
+ test<std::string>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp
new file mode 100644
index 0000000000000..eef525349972b
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class InputIterator>
+// iterator insert(const_iterator p, InputIterator first, InputIterator last);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <string>
+
+#include "check_assertion.h"
+
+template <class S>
+void test() {
+ S v;
+ S v2;
+ char a[] = "123";
+ const int N = sizeof(a) / sizeof(a[0]);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v.insert(v2.cbegin() + 10, a, a + N), "Attempted to add/subtract an iterator outside its valid range");
+}
+
+int main(int, char**) {
+ test<std::string>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp
new file mode 100644
index 0000000000000..4b7532678f2e5
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// iterator insert(const_iterator p, size_type n, charT c);
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: !libcpp-has-legacy-debug-mode, c++03
+
+#include <string>
+
+#include "check_assertion.h"
+
+template <class S>
+void test() {
+ S s;
+ S s2;
+ TEST_LIBCPP_ASSERT_FAILURE(s.insert(s2.begin(), 1, 'a'),
+ "string::insert(iterator, n, value) called with an iterator not referring to this string");
+}
+
+int main(int, char**) {
+ test<std::string>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/resize_default_initialized.pass.cpp
new file mode 100644
index 0000000000000..8e6e07d659c1a
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/basic.string/string.modifiers/resize_default_initialized.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
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// __resize_default_init(size_type)
+
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX20 void write_c_str(char* buf, int size) {
+ for (int i = 0; i < size; ++i) {
+ buf[i] = 'a';
+ }
+ buf[size] = '\0';
+}
+
+template <class S>
+TEST_CONSTEXPR_CXX20 void test_buffer_usage() {
+ {
+ unsigned buff_size = 125;
+ unsigned used_size = buff_size - 16;
+ S s;
+ s.__resize_default_init(buff_size);
+ write_c_str(&s[0], used_size);
+ assert(s.size() == buff_size);
+ assert(std::char_traits<char>().length(s.data()) == used_size);
+ s.__resize_default_init(used_size);
+ assert(s.size() == used_size);
+ assert(s.data()[used_size] == '\0');
+ for (unsigned i = 0; i < used_size; ++i) {
+ assert(s[i] == 'a');
+ }
+ }
+}
+
+template <class S>
+TEST_CONSTEXPR_CXX20 void test_basic() {
+ {
+ S s;
+ s.__resize_default_init(3);
+ assert(s.size() == 3);
+ assert(s.data()[3] == '\0');
+ for (int i = 0; i < 3; ++i)
+ s[i] = 'a' + i;
+ s.__resize_default_init(1);
+ assert(s[0] == 'a');
+ assert(s.data()[1] == '\0');
+ assert(s.size() == 1);
+ }
+}
+
+template <class S>
+TEST_CONSTEXPR_CXX20 bool test() {
+ test_basic<S>();
+ test_buffer_usage<S>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test<std::string>();
+#if TEST_STD_VER > 17
+ static_assert(test<std::string>());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/c.strings/constexpr.cstring.compile.pass.cpp b/libcxx/test/libcxx-03/strings/c.strings/constexpr.cstring.compile.pass.cpp
new file mode 100644
index 0000000000000..cd993d8918e9d
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/c.strings/constexpr.cstring.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Check that __constexpr_* cstring functions are actually constexpr
+
+#include <__string/constexpr_c_functions.h>
+
+constexpr unsigned char Banand[] = "Banand";
+constexpr unsigned char Banane[] = "Banane";
+constexpr unsigned char Bananf[] = "Bananf";
+
+static_assert(std::__constexpr_strlen("Banane") == 6, "");
+static_assert(std::__constexpr_memcmp(Banane, Banand, std::__element_count(6)) == 1, "");
+static_assert(std::__constexpr_memcmp(Banane, Banane, std::__element_count(6)) == 0, "");
+static_assert(std::__constexpr_memcmp(Banane, Bananf, std::__element_count(6)) == -1, "");
+
+static_assert(!std::__constexpr_memcmp_equal(Banane, Banand, std::__element_count(6)), "");
+static_assert(std::__constexpr_memcmp_equal(Banane, Banane, std::__element_count(6)), "");
+
+constexpr bool test_constexpr_wmemchr() {
+ const char str[] = "Banane";
+ return std::__constexpr_memchr(str, 'n', 6) == str + 2;
+}
+static_assert(test_constexpr_wmemchr(), "");
diff --git a/libcxx/test/libcxx-03/strings/c.strings/constexpr.cwchar.compile.pass.cpp b/libcxx/test/libcxx-03/strings/c.strings/constexpr.cwchar.compile.pass.cpp
new file mode 100644
index 0000000000000..02feed064eacc
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/c.strings/constexpr.cwchar.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// UNSUPPORTED: no-wide-characters
+
+// Check that __constexpr_* cwchar functions are actually constexpr
+
+#include <cwchar>
+
+static_assert(std::__constexpr_wcslen(L"Banane") == 6, "");
+static_assert(std::__constexpr_wmemcmp(L"Banane", L"Banand", 6) == 1, "");
+static_assert(std::__constexpr_wmemcmp(L"Banane", L"Banane", 6) == 0, "");
+static_assert(std::__constexpr_wmemcmp(L"Banane", L"Bananf", 6) == -1, "");
+
+constexpr bool test_constexpr_wmemchr() {
+ const wchar_t str[] = L"Banane";
+ return std::__constexpr_wmemchr(str, 'n', 6) == str + 2;
+}
+static_assert(test_constexpr_wmemchr(), "");
diff --git a/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp b/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp
new file mode 100644
index 0000000000000..2009cbe28a91f
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/c.strings/constexpr_memmove.pass.cpp
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// _Tp* __constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n);
+//
+// General tests for __constexpr_memmove.
+//
+// In particular, we try to ensure that __constexpr_memmove behaves like
+// __builtin_memmove as closely as possible. This means that it produces the
+// same effect, but also that it has the same type requirements.
+//
+// __builtin_memmove only requires that the types are TriviallyCopyable
+// (which is interestingly different from both is_trivially_XXX_constructible
+// and is_trivially_XXX_assignable), so we use some funky types to test these
+// corner cases.
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__string/constexpr_c_functions.h>
+#include <cassert>
+#include <cstdint>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// The following types are all TriviallyCopyable, but they are not all
+// trivially_{copy,move}_{constructible,assignable}. TriviallyCopyable
+// guarantees that the type is *at least* one of the four, but no more
+// than that.
+struct CopyConstructible {
+ CopyConstructible() = default;
+ int value = 0;
+
+ CopyConstructible(const CopyConstructible&) = default;
+ CopyConstructible(CopyConstructible&&) = delete;
+ CopyConstructible& operator=(const CopyConstructible&) = delete;
+ CopyConstructible& operator=(CopyConstructible&&) = delete;
+};
+
+struct MoveConstructible {
+ MoveConstructible() = default;
+ int value = 0;
+
+ MoveConstructible(const MoveConstructible&) = delete;
+ MoveConstructible(MoveConstructible&&) = default;
+ MoveConstructible& operator=(const MoveConstructible&) = delete;
+ MoveConstructible& operator=(MoveConstructible&&) = delete;
+};
+
+struct CopyAssignable {
+ CopyAssignable() = default;
+ int value = 0;
+
+ CopyAssignable(const CopyAssignable&) = delete;
+ CopyAssignable(CopyAssignable&&) = delete;
+ CopyAssignable& operator=(const CopyAssignable&) = default;
+ CopyAssignable& operator=(CopyAssignable&&) = delete;
+};
+
+struct MoveAssignable {
+ MoveAssignable() = default;
+ int value = 0;
+
+ MoveAssignable(const MoveAssignable&) = delete;
+ MoveAssignable(MoveAssignable&&) = delete;
+ MoveAssignable& operator=(const MoveAssignable&) = delete;
+ MoveAssignable& operator=(MoveAssignable&&) = default;
+};
+
+template <class Source, class Dest>
+TEST_CONSTEXPR_CXX14 void test_user_defined_types() {
+ static_assert(std::is_trivially_copyable<Source>::value, "test the test");
+ static_assert(std::is_trivially_copyable<Dest>::value, "test the test");
+
+ // Note that we can't just initialize with an initializer list since some of the types we use here
+ // are not copy-constructible, which is required in pre-C++20 Standards for that syntax to work.
+ Source src[3];
+ src[0].value = 1;
+ src[1].value = 2;
+ src[2].value = 3;
+ Dest dst[3];
+ dst[0].value = 111;
+ dst[1].value = 111;
+ dst[2].value = 111;
+
+ Dest* result = std::__constexpr_memmove(dst, src, std::__element_count(3));
+ assert(result == dst);
+ assert(dst[0].value == 1);
+ assert(dst[1].value == 2);
+ assert(dst[2].value == 3);
+}
+
+template <class Source, class Dest>
+TEST_CONSTEXPR_CXX14 void test_builtin_types() {
+ Source src[3] = {1, 2, 3};
+ Dest dst[3] = {111, 111, 111};
+
+ Dest* result = std::__constexpr_memmove(dst, src, std::__element_count(3));
+ assert(result == dst);
+ assert(dst[0] == 1);
+ assert(dst[1] == 2);
+ assert(dst[2] == 3);
+}
+
+template <class SourcePtr, class DestPtr, class ObjectType>
+TEST_CONSTEXPR_CXX14 void test_pointer_types() {
+ ObjectType objs[3] = {1, 2, 3};
+
+ SourcePtr src[3] = {objs + 0, objs + 1, objs + 2};
+ DestPtr dst[3] = {nullptr, nullptr, nullptr};
+
+ DestPtr* result = std::__constexpr_memmove(dst, src, std::__element_count(3));
+ assert(result == dst);
+ assert(dst[0] == objs + 0);
+ assert(dst[1] == objs + 1);
+ assert(dst[2] == objs + 2);
+}
+
+TEST_CONSTEXPR_CXX14 bool test() {
+ test_user_defined_types<CopyConstructible, CopyConstructible>();
+ test_user_defined_types<MoveConstructible, MoveConstructible>();
+ test_user_defined_types<CopyAssignable, CopyAssignable>();
+ test_user_defined_types<MoveAssignable, MoveAssignable>();
+
+ test_builtin_types<char, char>();
+ test_builtin_types<short, short>();
+ test_builtin_types<int, int>();
+ test_builtin_types<long, long>();
+ test_builtin_types<long long, long long>();
+
+ // Cross-type
+ test_builtin_types<std::int16_t, std::uint16_t>();
+ test_builtin_types<std::int16_t, char16_t>();
+ test_builtin_types<std::int32_t, std::uint32_t>();
+ test_builtin_types<std::int32_t, char32_t>();
+
+ test_pointer_types<char*, char*, char>();
+ test_pointer_types<int*, int*, int>();
+ test_pointer_types<long*, long*, long>();
+ test_pointer_types<void*, void*, int>();
+ test_pointer_types<int* const, int*, int>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 14
+ static_assert(test(), "");
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/string.view/assert.ctor.length.pass.cpp b/libcxx/test/libcxx-03/strings/string.view/assert.ctor.length.pass.cpp
new file mode 100644
index 0000000000000..af8b393f9e0a7
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/string.view/assert.ctor.length.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// Construct a string_view from an invalid length
+// constexpr basic_string_view( const _CharT* s, size_type len )
+
+#include <string_view>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ char c = 0;
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::string_view(&c, -1), "string_view::string_view(_CharT *, size_t): length does not fit in difference_type");
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/string.view/assert.ctor.pointer.pass.cpp b/libcxx/test/libcxx-03/strings/string.view/assert.ctor.pointer.pass.cpp
new file mode 100644
index 0000000000000..1810ec1ca8ac9
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/string.view/assert.ctor.pointer.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// Construct a string_view from a null pointer
+// constexpr basic_string_view( const CharT* s );
+
+#include <string_view>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::string_view((char const*)NULL), "null pointer passed to non-null argument of char_traits<...>::length");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::string_view((char const*)nullptr), "null pointer passed to non-null argument of char_traits<...>::length");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::string_view((char const*)0), "null pointer passed to non-null argument of char_traits<...>::length");
+ {
+ std::string_view v;
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v == (char const*)nullptr, "null pointer passed to non-null argument of char_traits<...>::length");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ v == (char const*)NULL, "null pointer passed to non-null argument of char_traits<...>::length");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (char const*)nullptr == v, "null pointer passed to non-null argument of char_traits<...>::length");
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (char const*)NULL == v, "null pointer passed to non-null argument of char_traits<...>::length");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp b/libcxx/test/libcxx-03/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp
new file mode 100644
index 0000000000000..5043a88cbc3da
--- /dev/null
+++ b/libcxx/test/libcxx-03/strings/string.view/string.view.iterators/assert.iterator-indexing.pass.cpp
@@ -0,0 +1,158 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that std::string_view's iterators check for OOB accesses when the debug mode is enabled.
+
+// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators
+// UNSUPPORTED: libcpp-hardening-mode=none
+
+#include <iterator>
+#include <string_view>
+
+#include "check_assertion.h"
+
+template <typename Iter>
+void test_iterator(Iter begin, Iter end, bool reverse) {
+ ptrdiff_t distance = std::distance(begin, end);
+
+ // Dereferencing an iterator at the end.
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ *end,
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
+#if _LIBCPP_STD_VER >= 20
+ // In C++20 mode, std::reverse_iterator implements operator->, but not operator*, with
+ // std::prev instead of operator--. std::prev ultimately calls operator+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ end.operator->(),
+ reverse ? "__bounded_iter::operator+=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
+#else
+ TEST_LIBCPP_ASSERT_FAILURE(
+ end.operator->(),
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
+#endif
+ }
+
+ // Incrementing an iterator past the end.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator++: Attempt to advance an iterator past the end";
+ auto it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it++, msg);
+ it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(++it, msg);
+ }
+
+ // Decrementing an iterator past the start.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator++: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator--: Attempt to rewind an iterator past the start";
+ auto it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it--, msg);
+ it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(--it, msg);
+ }
+
+ // Advancing past the end with operator+= and operator+.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator+=: Attempt to advance an iterator past the end";
+ auto it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it += 1, msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end + 1, msg);
+ it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it += (distance + 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin + (distance + 1), msg);
+ }
+
+ // Advancing past the end with operator-= and operator-.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator+=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator-=: Attempt to advance an iterator past the end";
+ auto it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= (-1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end - (-1), msg);
+ it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= (-distance - 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin - (-distance - 1), msg);
+ }
+
+ // Rewinding past the start with operator+= and operator+.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator+=: Attempt to rewind an iterator past the start";
+ auto it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it += (-1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin + (-1), msg);
+ it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it += (-distance - 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end + (-distance - 1), msg);
+ }
+
+ // Rewinding past the start with operator-= and operator-.
+ {
+ [[maybe_unused]] const char* msg =
+ reverse ? "__bounded_iter::operator+=: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator-=: Attempt to rewind an iterator past the start";
+ auto it = begin;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= 1, msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin - 1, msg);
+ it = end;
+ TEST_LIBCPP_ASSERT_FAILURE(it -= (distance + 1), msg);
+ TEST_LIBCPP_ASSERT_FAILURE(end - (distance + 1), msg);
+ }
+
+ // Out-of-bounds operator[].
+ {
+ [[maybe_unused]] const char* end_msg =
+ reverse ? "__bounded_iter::operator--: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator[]: Attempt to index an iterator at or past the end";
+ [[maybe_unused]] const char* past_end_msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to rewind an iterator past the start"
+ : "__bounded_iter::operator[]: Attempt to index an iterator at or past the end";
+ [[maybe_unused]] const char* past_start_msg =
+ reverse ? "__bounded_iter::operator-=: Attempt to advance an iterator past the end"
+ : "__bounded_iter::operator[]: Attempt to index an iterator past the start";
+ TEST_LIBCPP_ASSERT_FAILURE(begin[distance], end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin[distance + 1], past_end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin[-1], past_start_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(begin[-99], past_start_msg);
+
+ auto it = begin + 1;
+ TEST_LIBCPP_ASSERT_FAILURE(it[distance - 1], end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(it[distance], past_end_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(it[-2], past_start_msg);
+ TEST_LIBCPP_ASSERT_FAILURE(it[-99], past_start_msg);
+ }
+}
+
+int main(int, char**) {
+ std::string_view const str("hello world");
+
+ // string_view::iterator
+ test_iterator(str.begin(), str.end(), /*reverse=*/false);
+
+ // string_view::const_iterator
+ test_iterator(str.cbegin(), str.cend(), /*reverse=*/false);
+
+ // string_view::reverse_iterator
+ test_iterator(str.rbegin(), str.rend(), /*reverse=*/true);
+
+ // string_view::const_reverse_iterator
+ test_iterator(str.crbegin(), str.crend(), /*reverse=*/true);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/system_reserved_names.gen.py b/libcxx/test/libcxx-03/system_reserved_names.gen.py
new file mode 100644
index 0000000000000..a4f2928eda332
--- /dev/null
+++ b/libcxx/test/libcxx-03/system_reserved_names.gen.py
@@ -0,0 +1,206 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that headers are not tripped up by the surrounding code defining various
+# alphabetic macros. Also ensure that we don't swallow the definition of user
+# provided macros (in other words, ensure that we push/pop correctly everywhere).
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+# END.
+
+import sys
+
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+ lit_header_restrictions,
+ lit_header_undeprecations,
+ public_headers,
+)
+
+for header in public_headers:
+ print(
+ f"""\
+//--- {header}.compile.pass.cpp
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
+
+// This is required to detect the platform we're building for below.
+#include <__config>
+
+#define SYSTEM_RESERVED_NAME This name should not be used in libc++
+
+// libc++ does not use single-letter names as a matter of principle.
+// But Windows' own <wchar.h>, <math.h>, and <exception> use many of these
+// (at least C,E,F,I,M,N,P,S,X,Y,Z) as uglified function parameter names,
+// so don't define these on Windows.
+//
+#ifndef _WIN32
+#define _A SYSTEM_RESERVED_NAME
+#define _B SYSTEM_RESERVED_NAME
+#define _C SYSTEM_RESERVED_NAME
+#define _D SYSTEM_RESERVED_NAME
+#define _E SYSTEM_RESERVED_NAME
+#define _F SYSTEM_RESERVED_NAME
+#define _G SYSTEM_RESERVED_NAME
+#define _H SYSTEM_RESERVED_NAME
+#define _I SYSTEM_RESERVED_NAME
+#define _J SYSTEM_RESERVED_NAME
+#define _K SYSTEM_RESERVED_NAME
+#define _L SYSTEM_RESERVED_NAME
+#define _M SYSTEM_RESERVED_NAME
+#define _N SYSTEM_RESERVED_NAME
+#define _O SYSTEM_RESERVED_NAME
+#define _P SYSTEM_RESERVED_NAME
+#define _Q SYSTEM_RESERVED_NAME
+#define _R SYSTEM_RESERVED_NAME
+#define _S SYSTEM_RESERVED_NAME
+#define _T SYSTEM_RESERVED_NAME
+#define _U SYSTEM_RESERVED_NAME
+#define _V SYSTEM_RESERVED_NAME
+#define _W SYSTEM_RESERVED_NAME
+#define _X SYSTEM_RESERVED_NAME
+#define _Y SYSTEM_RESERVED_NAME
+#define _Z SYSTEM_RESERVED_NAME
+#endif
+
+// FreeBSD's <sys/types.h> uses _M
+//
+#ifdef __FreeBSD__
+# undef _M
+#endif
+
+// Test that libc++ doesn't use names that collide with FreeBSD system macros.
+// newlib and picolibc also define these macros
+#if !defined(__FreeBSD__) && !defined(_NEWLIB_VERSION)
+# define __null_sentinel SYSTEM_RESERVED_NAME
+# define __generic SYSTEM_RESERVED_NAME
+#endif
+
+// tchar.h defines these macros on Windows
+#ifndef _WIN32
+# define _UI SYSTEM_RESERVED_NAME
+# define _PUC SYSTEM_RESERVED_NAME
+# define _CPUC SYSTEM_RESERVED_NAME
+# define _PC SYSTEM_RESERVED_NAME
+# define _CRPC SYSTEM_RESERVED_NAME
+# define _CPC SYSTEM_RESERVED_NAME
+#endif
+
+// yvals.h on MINGW defines this macro
+#ifndef _WIN32
+# define _C2 SYSTEM_RESERVED_NAME
+#endif
+
+// Test that libc++ doesn't use names that collide with Win32 API macros.
+// Obviously we can only define these on non-Windows platforms.
+#ifndef _WIN32
+# define __allocator SYSTEM_RESERVED_NAME
+# define __bound SYSTEM_RESERVED_NAME
+# define __deallocate SYSTEM_RESERVED_NAME
+# define __deref SYSTEM_RESERVED_NAME
+# define __format_string SYSTEM_RESERVED_NAME
+# define __full SYSTEM_RESERVED_NAME
+# define __in SYSTEM_RESERVED_NAME
+# define __inout SYSTEM_RESERVED_NAME
+# define __nz SYSTEM_RESERVED_NAME
+# define __out SYSTEM_RESERVED_NAME
+# define __part SYSTEM_RESERVED_NAME
+# define __post SYSTEM_RESERVED_NAME
+# define __pre SYSTEM_RESERVED_NAME
+#endif
+
+// Newlib & picolibc use __input as a parameter name of a64l & l64a
+#ifndef _NEWLIB_VERSION
+# define __input SYSTEM_RESERVED_NAME
+#endif
+#define __output SYSTEM_RESERVED_NAME
+
+#define __acquire SYSTEM_RESERVED_NAME
+#define __release SYSTEM_RESERVED_NAME
+
+// Android and FreeBSD use this for __attribute__((__unused__))
+#if !defined(__FreeBSD__) && !defined(__ANDROID__)
+#define __unused SYSTEM_RESERVED_NAME
+#endif
+
+// These names are not reserved, so the user can macro-define them.
+// These are intended to find improperly _Uglified template parameters.
+#define A SYSTEM_RESERVED_NAME
+#define Arg SYSTEM_RESERVED_NAME
+#define Args SYSTEM_RESERVED_NAME
+#define As SYSTEM_RESERVED_NAME
+#define B SYSTEM_RESERVED_NAME
+#define Bs SYSTEM_RESERVED_NAME
+#define C SYSTEM_RESERVED_NAME
+#define Cp SYSTEM_RESERVED_NAME
+#define Cs SYSTEM_RESERVED_NAME
+// Windows setjmp.h contains a struct member named 'D' on ARM/AArch64.
+#ifndef _WIN32
+# define D SYSTEM_RESERVED_NAME
+#endif
+#define Dp SYSTEM_RESERVED_NAME
+#define Ds SYSTEM_RESERVED_NAME
+#define E SYSTEM_RESERVED_NAME
+#define Ep SYSTEM_RESERVED_NAME
+#define Es SYSTEM_RESERVED_NAME
+#define N SYSTEM_RESERVED_NAME
+#define Np SYSTEM_RESERVED_NAME
+#define Ns SYSTEM_RESERVED_NAME
+#define R SYSTEM_RESERVED_NAME
+#define Rp SYSTEM_RESERVED_NAME
+#define Rs SYSTEM_RESERVED_NAME
+#define T SYSTEM_RESERVED_NAME
+#define Tp SYSTEM_RESERVED_NAME
+#define Ts SYSTEM_RESERVED_NAME
+#define Type SYSTEM_RESERVED_NAME
+#define Types SYSTEM_RESERVED_NAME
+#define U SYSTEM_RESERVED_NAME
+#define Up SYSTEM_RESERVED_NAME
+#define Us SYSTEM_RESERVED_NAME
+#define V SYSTEM_RESERVED_NAME
+#define Vp SYSTEM_RESERVED_NAME
+#define Vs SYSTEM_RESERVED_NAME
+#define X SYSTEM_RESERVED_NAME
+#define Xp SYSTEM_RESERVED_NAME
+#define Xs SYSTEM_RESERVED_NAME
+
+// The classic Windows min/max macros
+#define min SYSTEM_RESERVED_NAME
+#define max SYSTEM_RESERVED_NAME
+
+// Test to make sure curses has no conflicting macros with the standard library
+#define move SYSTEM_RESERVED_NAME
+#define erase SYSTEM_RESERVED_NAME
+#define refresh SYSTEM_RESERVED_NAME
+
+// Dinkumware libc ctype.h uses these definitions
+#define _XA SYSTEM_RESERVED_NAME
+#define _XS SYSTEM_RESERVED_NAME
+#define _BB SYSTEM_RESERVED_NAME
+#define _CN SYSTEM_RESERVED_NAME
+#define _DI SYSTEM_RESERVED_NAME
+#define _LO SYSTEM_RESERVED_NAME
+#define _PU SYSTEM_RESERVED_NAME
+#define _SP SYSTEM_RESERVED_NAME
+#define _UP SYSTEM_RESERVED_NAME
+#define _XD SYSTEM_RESERVED_NAME
+
+#include <{header}>
+
+// Make sure we don't swallow the definition of the macros we push/pop
+#define STRINGIFY_IMPL(x) #x
+#define STRINGIFY(x) STRINGIFY_IMPL(x)
+static_assert(__builtin_strcmp(STRINGIFY(min), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");
+static_assert(__builtin_strcmp(STRINGIFY(max), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");
+static_assert(__builtin_strcmp(STRINGIFY(move), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");
+static_assert(__builtin_strcmp(STRINGIFY(erase), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");
+static_assert(__builtin_strcmp(STRINGIFY(refresh), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");
+"""
+ )
diff --git a/libcxx/test/libcxx-03/thread/atomic.availability.verify.cpp b/libcxx/test/libcxx-03/thread/atomic.availability.verify.cpp
new file mode 100644
index 0000000000000..419be9373b569
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/atomic.availability.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+// REQUIRES: availability-synchronization_library-missing
+
+// Test the availability markup on the C++20 Synchronization Library
+// additions to <atomic>.
+
+#include <atomic>
+
+void f() {
+ {
+ std::atomic<int> i(3);
+ std::memory_order m = std::memory_order_relaxed;
+
+ i.wait(4); // expected-error {{is unavailable}}
+ i.wait(4, m); // expected-error {{is unavailable}}
+ i.notify_one(); // expected-error {{is unavailable}}
+ i.notify_all(); // expected-error {{is unavailable}}
+
+ std::atomic_wait(&i, 4); // expected-error {{is unavailable}}
+ std::atomic_wait_explicit(&i, 4, m); // expected-error {{is unavailable}}
+ std::atomic_notify_one(&i); // expected-error {{is unavailable}}
+ std::atomic_notify_all(&i); // expected-error {{is unavailable}}
+ }
+
+ {
+ std::atomic<int> volatile i(3);
+ std::memory_order m = std::memory_order_relaxed;
+
+ i.wait(4); // expected-error {{is unavailable}}
+ i.wait(4, m); // expected-error {{is unavailable}}
+ i.notify_one(); // expected-error {{is unavailable}}
+ i.notify_all(); // expected-error {{is unavailable}}
+
+ std::atomic_wait(&i, 4); // expected-error {{is unavailable}}
+ std::atomic_wait_explicit(&i, 4, m); // expected-error {{is unavailable}}
+ std::atomic_notify_one(&i); // expected-error {{is unavailable}}
+ std::atomic_notify_all(&i); // expected-error {{is unavailable}}
+ }
+
+ {
+ std::atomic_flag flag;
+ bool b = false;
+ std::memory_order m = std::memory_order_relaxed;
+ flag.wait(b); // expected-error {{is unavailable}}
+ flag.wait(b, m); // expected-error {{is unavailable}}
+ flag.notify_one(); // expected-error {{is unavailable}}
+ flag.notify_all(); // expected-error {{is unavailable}}
+
+ std::atomic_flag_wait(&flag, b); // expected-error {{is unavailable}}
+ std::atomic_flag_wait_explicit(&flag, b, m); // expected-error {{is unavailable}}
+ std::atomic_flag_notify_one(&flag); // expected-error {{is unavailable}}
+ std::atomic_flag_notify_all(&flag); // expected-error {{is unavailable}}
+ }
+
+ {
+ std::atomic_flag volatile flag;
+ bool b = false;
+ std::memory_order m = std::memory_order_relaxed;
+ flag.wait(b); // expected-error {{is unavailable}}
+ flag.wait(b, m); // expected-error {{is unavailable}}
+ flag.notify_one(); // expected-error {{is unavailable}}
+ flag.notify_all(); // expected-error {{is unavailable}}
+
+ std::atomic_flag_wait(&flag, b); // expected-error {{is unavailable}}
+ std::atomic_flag_wait_explicit(&flag, b, m); // expected-error {{is unavailable}}
+ std::atomic_flag_notify_one(&flag); // expected-error {{is unavailable}}
+ std::atomic_flag_notify_all(&flag); // expected-error {{is unavailable}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/thread/barrier.availability.verify.cpp b/libcxx/test/libcxx-03/thread/barrier.availability.verify.cpp
new file mode 100644
index 0000000000000..c9baa8b2ee9fe
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/barrier.availability.verify.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+// REQUIRES: availability-synchronization_library-missing
+
+// Test the availability markup on std::barrier.
+
+#include <barrier>
+#include <utility>
+
+struct CompletionF {
+ void operator()() { }
+};
+
+void f() {
+ // Availability markup on std::barrier<>
+ {
+ std::barrier<> b(10); // expected-error {{is unavailable}}
+ auto token = b.arrive(); // expected-error {{is unavailable}}
+ (void)b.arrive(10); // expected-error {{is unavailable}}
+ b.wait(std::move(token)); // expected-error {{is unavailable}}
+ b.arrive_and_wait(); // expected-error {{is unavailable}}
+ b.arrive_and_drop(); // expected-error {{is unavailable}}
+ }
+
+ // Availability markup on std::barrier<CompletionF> with non-default CompletionF
+ {
+ std::barrier<CompletionF> b(10); // expected-error {{is unavailable}}
+ auto token = b.arrive(); // expected-error {{is unavailable}}
+ (void)b.arrive(10); // expected-error {{is unavailable}}
+ b.wait(std::move(token)); // expected-error {{is unavailable}}
+ b.arrive_and_wait(); // expected-error {{is unavailable}}
+ b.arrive_and_drop(); // expected-error {{is unavailable}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception.pass.cpp b/libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception.pass.cpp
new file mode 100644
index 0000000000000..6d5eb5ef9931f
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-threads
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <future>
+
+// class promise<R>
+
+// void set_exception(exception_ptr p);
+// Test that a null exception_ptr is diagnosed.
+
+#include <future>
+#include <exception>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ std::promise<T> p;
+ TEST_LIBCPP_ASSERT_FAILURE(p.set_exception(std::exception_ptr()), "promise::set_exception: received nullptr");
+ }
+
+ {
+ typedef int& T;
+ std::promise<T> p;
+ TEST_LIBCPP_ASSERT_FAILURE(p.set_exception(std::exception_ptr()), "promise::set_exception: received nullptr");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp b/libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp
new file mode 100644
index 0000000000000..1bffde5e3ebd1
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, no-threads
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <future>
+
+// class promise<R>
+
+// void set_exception_on_thread_exit(exception_ptr p);
+// Test that a null exception_ptr is diagnosed.
+
+#include <future>
+#include <exception>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ typedef int T;
+ std::promise<T> p;
+ TEST_LIBCPP_ASSERT_FAILURE(p.set_exception_at_thread_exit(std::exception_ptr()), "promise::set_exception_at_thread_exit: received nullptr");
+ }
+
+ {
+ typedef int& T;
+ std::promise<T> p;
+ TEST_LIBCPP_ASSERT_FAILURE(p.set_exception_at_thread_exit(std::exception_ptr()), "promise::set_exception_at_thread_exit: received nullptr");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/futures/futures.task/type.depr.verify.cpp b/libcxx/test/libcxx-03/thread/futures/futures.task/type.depr.verify.cpp
new file mode 100644
index 0000000000000..4065637e9eb2a
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/futures/futures.task/type.depr.verify.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03
+
+// <future>
+
+// template<class R, class... ArgTypes>
+// class packaged_task<R(ArgTypes...)>
+// {
+// public:
+// typedef R result_type; // extension
+
+// This libc++ extension is deprecated. See https://github.com/llvm/llvm-project/issues/112856.
+
+#include <future>
+#include <type_traits>
+
+struct A {};
+
+using RA = std::packaged_task<A(int, char)>::result_type; // expected-warning {{'result_type' is deprecated}}
+using RV = std::packaged_task<void(int, char)>::result_type; // expected-warning {{'result_type' is deprecated}}
diff --git a/libcxx/test/libcxx-03/thread/futures/futures.task/types.pass.cpp b/libcxx/test/libcxx-03/thread/futures/futures.task/types.pass.cpp
new file mode 100644
index 0000000000000..659232caa46ec
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/futures/futures.task/types.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03
+
+// <future>
+
+// template<class R, class... ArgTypes>
+// class packaged_task<R(ArgTypes...)>
+// {
+// public:
+// typedef R result_type; // extension
+
+// This is a libc++ extension.
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <future>
+#include <type_traits>
+
+struct A {};
+
+int main(int, char**) {
+ static_assert((std::is_same<std::packaged_task<A(int, char)>::result_type, A>::value), "");
+ static_assert((std::is_same<std::packaged_task<void(int, char)>::result_type, void>::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/latch.availability.verify.cpp b/libcxx/test/libcxx-03/thread/latch.availability.verify.cpp
new file mode 100644
index 0000000000000..3aa50eada252d
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/latch.availability.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// REQUIRES: availability-synchronization_library-missing
+
+// Test the availability markup on std::latch.
+
+#include <latch>
+
+void f() {
+ std::latch latch(10);
+ latch.count_down(); // expected-error {{is unavailable}}
+ latch.count_down(3); // expected-error {{is unavailable}}
+ latch.wait(); // expected-error {{is unavailable}}
+ latch.arrive_and_wait(); // expected-error {{is unavailable}}
+ latch.arrive_and_wait(3); // expected-error {{is unavailable}}
+}
diff --git a/libcxx/test/libcxx-03/thread/semaphore.availability.verify.cpp b/libcxx/test/libcxx-03/thread/semaphore.availability.verify.cpp
new file mode 100644
index 0000000000000..29a6a609124cb
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/semaphore.availability.verify.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
+// REQUIRES: availability-synchronization_library-missing
+
+// Test the availability markup on std::counting_semaphore and std::binary_semaphore.
+
+#include <chrono>
+#include <semaphore>
+
+void f() {
+ {
+ // Tests for std::counting_semaphore with non-default template argument
+ std::counting_semaphore<20> sem(10);
+ sem.release(); // expected-error {{is unavailable}}
+ sem.release(5); // expected-error {{is unavailable}}
+ sem.acquire(); // expected-error {{is unavailable}}
+ sem.try_acquire_for(std::chrono::milliseconds{3}); // expected-error 1-2 {{is unavailable}}
+ sem.try_acquire(); // expected-error {{is unavailable}}
+ sem.try_acquire_until(std::chrono::steady_clock::now()); // expected-error 1-2 {{is unavailable}}
+ }
+ {
+ // Tests for std::counting_semaphore with default template argument
+ std::counting_semaphore<> sem(10);
+ sem.release(); // expected-error {{is unavailable}}
+ sem.release(5); // expected-error {{is unavailable}}
+ sem.acquire(); // expected-error {{is unavailable}}
+ sem.try_acquire_for(std::chrono::milliseconds{3}); // expected-error 1-2 {{is unavailable}}
+ sem.try_acquire(); // expected-error {{is unavailable}}
+ sem.try_acquire_until(std::chrono::steady_clock::now()); // expected-error 1-2 {{is unavailable}}
+ }
+ {
+ // Tests for std::binary_semaphore
+ std::binary_semaphore sem(10);
+ sem.release(); // expected-error {{is unavailable}}
+ sem.release(5); // expected-error {{is unavailable}}
+ sem.acquire(); // expected-error {{is unavailable}}
+ sem.try_acquire_for(std::chrono::milliseconds{3}); // expected-error 1-2 {{is unavailable}}
+ sem.try_acquire(); // expected-error {{is unavailable}}
+ sem.try_acquire_until(std::chrono::steady_clock::now()); // expected-error 1-2 {{is unavailable}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.barrier/assert.arrive.pass.cpp b/libcxx/test/libcxx-03/thread/thread.barrier/assert.arrive.pass.cpp
new file mode 100644
index 0000000000000..419a603a037f8
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.barrier/assert.arrive.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// REQUIRES: has-unix-headers
+
+// <barrier>
+
+// class barrier;
+
+// void arrive(ptrdiff_t __update = 1);
+
+// Make sure that calling arrive with a negative value or with a value greater than 'expected' triggers an assertion
+
+#include <barrier>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::barrier<> b(5);
+ TEST_LIBCPP_ASSERT_FAILURE(b.arrive(0), "barrier:arrive must be called with a value greater than 0");
+ }
+
+ {
+ std::barrier<> b(5);
+ TEST_LIBCPP_ASSERT_FAILURE(b.arrive(10), "update is greater than the expected count for the current barrier phase");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.barrier/assert.ctor.pass.cpp b/libcxx/test/libcxx-03/thread/thread.barrier/assert.ctor.pass.cpp
new file mode 100644
index 0000000000000..0b4fb1d675eaa
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.barrier/assert.ctor.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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// REQUIRES: has-unix-headers
+
+// <barrier>
+
+// class barrier;
+
+// barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF());
+
+// Make sure that constructing barrier with a negative value triggers an assertion
+
+#include <barrier>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ [] { std::barrier<> b(-1); }(),
+ "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with a negative value");
+ }
+
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ [] {
+ auto completion = []() {};
+ std::barrier<decltype(completion)> b(-1, completion);
+ }(),
+ "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with a negative value");
+ }
+
+ // We can't check the precondition for max() because there's no value
+ // that would violate the precondition (in our implementation)
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.condition/PR30202_notify_from_pthread_created_thread.pass.cpp b/libcxx/test/libcxx-03/thread/thread.condition/PR30202_notify_from_pthread_created_thread.pass.cpp
new file mode 100644
index 0000000000000..66251648bd50c
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.condition/PR30202_notify_from_pthread_created_thread.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: no-threads
+// REQUIRES: libcpp-has-thread-api-pthread
+
+// notify_all_at_thread_exit(...) requires move semantics to transfer the
+// unique_lock.
+// UNSUPPORTED: c++03
+
+// <condition_variable>
+
+// void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+// Test that this function works with threads that were not created by
+// std::thread. See https://llvm.org/PR30202
+
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+#include <pthread.h>
+
+#include "test_macros.h"
+
+std::condition_variable cv;
+std::mutex mut;
+bool exited = false;
+
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::high_resolution_clock Clock;
+
+void* func(void*)
+{
+ std::unique_lock<std::mutex> lk(mut);
+ std::notify_all_at_thread_exit(cv, std::move(lk));
+ std::this_thread::sleep_for(ms(300));
+ exited = true;
+ return nullptr;
+}
+
+int main(int, char**)
+{
+ {
+ std::unique_lock<std::mutex> lk(mut);
+ pthread_t id;
+ int res = pthread_create(&id, 0, &func, nullptr);
+ assert(res == 0);
+ Clock::time_point t0 = Clock::now();
+ assert(exited == false);
+ cv.wait(lk);
+ Clock::time_point t1 = Clock::now();
+ assert(exited);
+ assert(t1-t0 > ms(250));
+ pthread_join(id, 0);
+ }
+ exited = false;
+ {
+ std::unique_lock<std::mutex> lk(mut);
+ std::thread t(&func, nullptr);
+ Clock::time_point t0 = Clock::now();
+ assert(exited == false);
+ cv.wait(lk);
+ Clock::time_point t1 = Clock::now();
+ assert(exited);
+ assert(t1-t0 > ms(250));
+ t.join();
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/libcxx/test/libcxx-03/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
new file mode 100644
index 0000000000000..13d1bfcb88126
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: no-threads, libcpp-has-thread-api-external
+
+// XFAIL: windows
+
+// <condition_variable>
+
+// class condition_variable;
+
+// typedef pthread_cond_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <cassert>
+#include <condition_variable>
+#include <pthread.h>
+#include <type_traits>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ static_assert((std::is_same<std::condition_variable::native_handle_type,
+ pthread_cond_t*>::value), "");
+ std::condition_variable cv;
+ std::condition_variable::native_handle_type h = cv.native_handle();
+ assert(h != nullptr);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.latch/assert.arrive_and_wait.pass.cpp b/libcxx/test/libcxx-03/thread/thread.latch/assert.arrive_and_wait.pass.cpp
new file mode 100644
index 0000000000000..e61679554a62e
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.latch/assert.arrive_and_wait.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <latch>
+
+// class latch;
+
+// void arrive_and_wait(ptrdiff_t __update = 1);
+
+// Make sure that calling arrive_and_wait with a negative value triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <latch>
+
+#include "check_assertion.h"
+
+int main(int, char **) {
+ {
+ std::latch l(5);
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l.arrive_and_wait(-10),
+ "latch::arrive_and_wait called with a negative value");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.latch/assert.count_down.pass.cpp b/libcxx/test/libcxx-03/thread/thread.latch/assert.count_down.pass.cpp
new file mode 100644
index 0000000000000..6220cba02af19
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.latch/assert.count_down.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <latch>
+
+// class latch;
+
+// void count_down(ptrdiff_t __update = 1);
+
+// Make sure that calling count_down with a negative value or a value
+// higher than the internal counter triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <latch>
+
+#include "check_assertion.h"
+
+int main(int, char **) {
+ {
+ std::latch l(5);
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ l.count_down(-10), "latch::count_down called with a negative value");
+ }
+
+ {
+ std::latch l(5);
+
+ TEST_LIBCPP_ASSERT_FAILURE(l.count_down(10),
+ "latch::count_down called with a value greater "
+ "than the internal counter");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.latch/assert.ctor.pass.cpp b/libcxx/test/libcxx-03/thread/thread.latch/assert.ctor.pass.cpp
new file mode 100644
index 0000000000000..5f1ea19d82a50
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.latch/assert.ctor.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <latch>
+
+// class latch;
+
+// constexpr explicit latch(ptrdiff_t __expected);
+
+// Make sure that calling latch with a negative value triggers an assertion
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <latch>
+
+#include "check_assertion.h"
+
+int main(int, char **) {
+ {
+ TEST_LIBCPP_ASSERT_FAILURE([]{ std::latch l(-1); }(),
+ "latch::latch(ptrdiff_t): latch cannot be "
+ "initialized with a negative value");
+ }
+
+ // We can't check the precondition for max() because there's no value
+ // that would violate the precondition (in our implementation)
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp b/libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
new file mode 100644
index 0000000000000..3de6635f13be2
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads, libcpp-has-thread-api-external
+
+// XFAIL: windows
+
+// <mutex>
+
+// class mutex;
+
+// typedef pthread_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <mutex>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ std::mutex m;
+ pthread_mutex_t* h = m.native_handle();
+ assert(h);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp b/libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
new file mode 100644
index 0000000000000..d76b3d71d36e3
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads, libcpp-has-thread-api-external
+
+// XFAIL: windows
+
+// <mutex>
+
+// class recursive_mutex;
+
+// typedef pthread_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <mutex>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ std::recursive_mutex m;
+ pthread_mutex_t* h = m.native_handle();
+ assert(h);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp
new file mode 100644
index 0000000000000..5d40fa71a4152
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_annotations_not_enabled.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03
+
+// <mutex>
+
+// This test does not define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS so it
+// should compile without any warnings or errors even though this pattern is not
+// understood by the thread safety annotations.
+
+#include <mutex>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ std::mutex m;
+ m.lock();
+ {
+ std::unique_lock<std::mutex> g(m, std::adopt_lock);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_guard.pass.cpp b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
new file mode 100644
index 0000000000000..1c1f36459c837
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_guard.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// On Windows Clang bugs out when both __declspec and __attribute__ are present,
+// the processing goes awry preventing the definition of the types.
+// XFAIL: msvc
+
+// UNSUPPORTED: no-threads
+// REQUIRES: thread-safety
+
+// <mutex>
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+#include <mutex>
+
+#include "test_macros.h"
+
+std::mutex m;
+int foo __attribute__((guarded_by(m)));
+
+static void scoped() {
+#if TEST_STD_VER >= 17
+ std::scoped_lock<std::mutex> lock(m);
+ foo++;
+#endif
+}
+
+int main(int, char**) {
+ scoped();
+ std::lock_guard<std::mutex> lock(m);
+ foo++;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp
new file mode 100644
index 0000000000000..ddfe3269fdfa7
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_lock_unlock.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// On Windows Clang bugs out when both __declspec and __attribute__ are present,
+// the processing goes awry preventing the definition of the types.
+// XFAIL: msvc
+
+// UNSUPPORTED: no-threads
+// REQUIRES: thread-safety
+
+// <mutex>
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+#include <mutex>
+
+#include "test_macros.h"
+
+std::mutex m;
+int foo __attribute__((guarded_by(m)));
+
+int main(int, char**) {
+ m.lock();
+ foo++;
+ m.unlock();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp
new file mode 100644
index 0000000000000..bab686e7b4ca2
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_missing_unlock.verify.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// On Windows Clang bugs out when both __declspec and __attribute__ are present,
+// the processing goes awry preventing the definition of the types.
+// XFAIL: msvc
+
+// UNSUPPORTED: no-threads
+// REQUIRES: thread-safety
+
+// <mutex>
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+#include <mutex>
+
+std::mutex m;
+
+void f() {
+ m.lock();
+} // expected-error {{mutex 'm' is still held at the end of function}}
diff --git a/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_requires_capability.pass.cpp b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_requires_capability.pass.cpp
new file mode 100644
index 0000000000000..81ce3b25a8394
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.mutex/thread_safety_requires_capability.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// On Windows Clang bugs out when both __declspec and __attribute__ are present,
+// the processing goes awry preventing the definition of the types.
+// XFAIL: msvc
+
+// UNSUPPORTED: no-threads
+// REQUIRES: thread-safety
+
+// <mutex>
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+#include <mutex>
+
+#include "test_macros.h"
+
+std::mutex m;
+int foo __attribute__((guarded_by(m)));
+
+void increment() __attribute__((requires_capability(m))) {
+ foo++;
+}
+
+int main(int, char**) {
+ m.lock();
+ increment();
+ m.unlock();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.semaphore/assert.ctor.pass.cpp b/libcxx/test/libcxx-03/thread/thread.semaphore/assert.ctor.pass.cpp
new file mode 100644
index 0000000000000..1e33add779496
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.semaphore/assert.ctor.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// REQUIRES: has-unix-headers
+
+// <semaphore>
+
+// constexpr explicit counting_semaphore(ptrdiff_t __count);
+
+// Make sure that constructing counting_semaphore with a negative value triggers an assertion
+
+#include <semaphore>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ [] { std::counting_semaphore<> s(-1); }(),
+ "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be "
+ "initialized with a negative value");
+ }
+ // We can't check the precondition for max() because there's no value
+ // that would violate the precondition (in our implementation)
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.semaphore/assert.release.pass.cpp b/libcxx/test/libcxx-03/thread/thread.semaphore/assert.release.pass.cpp
new file mode 100644
index 0000000000000..a5a01a3847878
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.semaphore/assert.release.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// REQUIRES: has-unix-headers
+
+// <semaphore>
+
+// void release(ptrdiff_t __update = 1);
+
+// Make sure that calling release with a negative value triggers or with a value
+// greater than expected triggers an assertion
+
+#include <semaphore>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ std::counting_semaphore<> s(2);
+ TEST_LIBCPP_ASSERT_FAILURE(s.release(-1), "counting_semaphore:release called with a negative value");
+ }
+
+ {
+ // Call release with an arbitrary larger than expected value
+ std::counting_semaphore<> s(2);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ s.release(std::counting_semaphore<>::max()), "update is greater than the expected value");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.shared_mutex/thread_safety.verify.cpp b/libcxx/test/libcxx-03/thread/thread.shared_mutex/thread_safety.verify.cpp
new file mode 100644
index 0000000000000..fee940fff847b
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.shared_mutex/thread_safety.verify.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: no-threads
+// REQUIRES: thread-safety
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+// On Windows Clang bugs out when both __declspec and __attribute__ are present,
+// the processing goes awry preventing the definition of the types.
+// XFAIL: msvc
+
+// <shared_mutex>
+//
+// class shared_mutex;
+//
+// void lock();
+// bool try_lock();
+// void unlock();
+//
+// void lock_shared();
+// bool try_lock_shared();
+// void unlock_shared();
+
+#include <shared_mutex>
+
+std::shared_mutex m;
+int data __attribute__((guarded_by(m))) = 0;
+void read(int);
+
+void f() {
+ // Exclusive locking
+ {
+ m.lock();
+ ++data; // ok
+ m.unlock();
+ }
+ {
+ if (m.try_lock()) {
+ ++data; // ok
+ m.unlock();
+ }
+ }
+
+ // Shared locking
+ {
+ m.lock_shared();
+ read(data); // ok
+ ++data; // expected-error {{writing variable 'data' requires holding shared_mutex 'm' exclusively}}
+ m.unlock_shared();
+ }
+ {
+ if (m.try_lock_shared()) {
+ read(data); // ok
+ ++data; // expected-error {{writing variable 'data' requires holding shared_mutex 'm' exclusively}}
+ m.unlock_shared();
+ }
+ }
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.shared_timed_mutex/thread_safety.verify.cpp b/libcxx/test/libcxx-03/thread/thread.shared_timed_mutex/thread_safety.verify.cpp
new file mode 100644
index 0000000000000..baa8bc614f149
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.shared_timed_mutex/thread_safety.verify.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: no-threads
+// REQUIRES: thread-safety
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
+
+// On Windows Clang bugs out when both __declspec and __attribute__ are present,
+// the processing goes awry preventing the definition of the types.
+// XFAIL: msvc
+
+// <shared_mutex>
+//
+// class shared_timed_mutex;
+//
+// void lock();
+// bool try_lock();
+// bool try_lock_for(const std::chrono::duration<Rep, Period>&);
+// bool try_lock_until(const std::chrono::time_point<Clock, Duration>&);
+// void unlock();
+//
+// void lock_shared();
+// bool try_lock_shared();
+// bool try_lock_shared_for(const std::chrono::duration<Rep, Period>&);
+// bool try_lock_shared_until(const std::chrono::time_point<Clock, Duration>&);
+// void unlock_shared();
+
+#include <chrono>
+#include <shared_mutex>
+
+std::shared_timed_mutex m;
+int data __attribute__((guarded_by(m))) = 0;
+void read(int);
+
+void f(std::chrono::time_point<std::chrono::steady_clock> tp, std::chrono::milliseconds d) {
+ // Exclusive locking
+ {
+ m.lock();
+ ++data; // ok
+ m.unlock();
+ }
+ {
+ if (m.try_lock()) {
+ ++data; // ok
+ m.unlock();
+ }
+ }
+ {
+ if (m.try_lock_for(d)) {
+ ++data; // ok
+ m.unlock();
+ }
+ }
+ {
+ if (m.try_lock_until(tp)) {
+ ++data; // ok
+ m.unlock();
+ }
+ }
+
+ // Shared locking
+ {
+ m.lock_shared();
+ read(data); // ok
+ ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+ m.unlock_shared();
+ }
+ {
+ if (m.try_lock_shared()) {
+ read(data); // ok
+ ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+ m.unlock_shared();
+ }
+ }
+ {
+ if (m.try_lock_shared_for(d)) {
+ read(data); // ok
+ ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+ m.unlock_shared();
+ }
+ }
+ {
+ if (m.try_lock_shared_until(tp)) {
+ read(data); // ok
+ ++data; // expected-error {{writing variable 'data' requires holding shared_timed_mutex 'm' exclusively}}
+ m.unlock_shared();
+ }
+ }
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.stoptoken/atomic_unique_lock.pass.cpp b/libcxx/test/libcxx-03/thread/thread.stoptoken/atomic_unique_lock.pass.cpp
new file mode 100644
index 0000000000000..a8093ae22b38d
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.stoptoken/atomic_unique_lock.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// XFAIL: availability-synchronization_library-missing
+// ADDITIONAL_COMPILE_FLAGS: -Wno-private-header
+
+#include <__stop_token/atomic_unique_lock.h>
+#include <atomic>
+#include <cassert>
+#include <chrono>
+#include <cstdint>
+#include <thread>
+
+#include "make_test_thread.h"
+#include "test_macros.h"
+
+template <uint8_t LockBit>
+void test() {
+ using Lock = std::__atomic_unique_lock<uint8_t, LockBit>;
+
+ // lock on constructor
+ {
+ std::atomic<uint8_t> state{0};
+ Lock l(state);
+ assert(l.__owns_lock());
+ }
+
+ // always give up locking
+ {
+ std::atomic<uint8_t> state{0};
+ Lock l(state, [](auto const&) { return true; });
+ assert(!l.__owns_lock());
+ }
+
+ // test overload that has custom state after lock
+ {
+ std::atomic<uint8_t> state{0};
+ auto neverGiveUpLocking = [](auto const&) { return false; };
+ auto stateAfter = [](auto) { return uint8_t{255}; };
+ Lock l(state, neverGiveUpLocking, stateAfter, std::memory_order_acq_rel);
+ assert(l.__owns_lock());
+ assert(state.load() == 255);
+ }
+
+ // lock and unlock
+ {
+ std::atomic<uint8_t> state{0};
+ Lock l(state);
+ assert(l.__owns_lock());
+
+ l.__unlock();
+ assert(!l.__owns_lock());
+
+ l.__lock();
+ assert(l.__owns_lock());
+ }
+
+ // lock blocking
+ {
+ std::atomic<uint8_t> state{0};
+ int i = 0;
+ Lock l1(state);
+
+ auto thread1 = support::make_test_thread([&] {
+ std::this_thread::sleep_for(std::chrono::milliseconds{10});
+ i = 5;
+ l1.__unlock();
+ });
+
+ Lock l2(state);
+ // l2's lock has to wait for l1's unlocking
+ assert(i == 5);
+
+ thread1.join();
+ }
+}
+
+int main(int, char**) {
+ test<1 << 0>();
+ test<1 << 1>();
+ test<1 << 2>();
+ test<1 << 3>();
+ test<1 << 4>();
+ test<1 << 5>();
+ test<1 << 6>();
+ test<1 << 7>();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_list_view.pass.cpp b/libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_list_view.pass.cpp
new file mode 100644
index 0000000000000..d8cd2fb68e132
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_list_view.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
+// ADDITIONAL_COMPILE_FLAGS: -Wno-private-header
+
+#include <__stop_token/intrusive_list_view.h>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct Node : std::__intrusive_node_base<Node> {
+ int i;
+
+ Node(int ii) : i(ii) {}
+};
+
+using ListView = std::__intrusive_list_view<Node>;
+
+int main(int, char**) {
+ // empty
+ {
+ ListView list;
+ assert(list.__empty());
+ }
+
+ // push_front
+ {
+ ListView list;
+ Node n1(5);
+ list.__push_front(&n1);
+ assert(!list.__empty());
+ }
+
+ // pop_front
+ {
+ ListView list;
+ Node n1(5);
+ Node n2(6);
+ list.__push_front(&n1);
+ list.__push_front(&n2);
+
+ auto f1 = list.__pop_front();
+ assert(f1->i == 6);
+
+ auto f2 = list.__pop_front();
+ assert(f2->i == 5);
+
+ assert(list.__empty());
+ }
+
+ // remove head
+ {
+ ListView list;
+ Node n1(5);
+ Node n2(6);
+ list.__push_front(&n1);
+ list.__push_front(&n2);
+
+ list.__remove(&n2);
+
+ auto f = list.__pop_front();
+ assert(f->i == 5);
+
+ assert(list.__empty());
+ }
+
+ // remove non-head
+ {
+ ListView list;
+ Node n1(5);
+ Node n2(6);
+ Node n3(7);
+ list.__push_front(&n1);
+ list.__push_front(&n2);
+ list.__push_front(&n3);
+
+ list.__remove(&n2);
+
+ auto f1 = list.__pop_front();
+ assert(f1->i == 7);
+
+ auto f2 = list.__pop_front();
+ assert(f2->i == 5);
+
+ assert(list.__empty());
+ }
+
+ // is_head
+ {
+ ListView list;
+ Node n1(5);
+ Node n2(6);
+ list.__push_front(&n1);
+ list.__push_front(&n2);
+
+ assert(!list.__is_head(&n1));
+ assert(list.__is_head(&n2));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_shared_ptr.pass.cpp b/libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_shared_ptr.pass.cpp
new file mode 100644
index 0000000000000..99d4226662a0b
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.stoptoken/intrusive_shared_ptr.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// ADDITIONAL_COMPILE_FLAGS: -Wno-private-header
+
+#include <__stop_token/intrusive_shared_ptr.h>
+#include <atomic>
+#include <cassert>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Object {
+ std::atomic<int> counter = 0;
+};
+
+template <>
+struct std::__intrusive_shared_ptr_traits<Object> {
+ static std::atomic<int>& __get_atomic_ref_count(Object& obj) { return obj.counter; }
+};
+
+using Ptr = std::__intrusive_shared_ptr<Object>;
+
+int main(int, char**) {
+ // default
+ {
+ Ptr ptr;
+ assert(!ptr);
+ }
+
+ // raw ptr
+ {
+ auto object = new Object;
+ Ptr ptr(object);
+ assert(ptr->counter == 1);
+ }
+
+ // copy
+ {
+ auto object = new Object;
+ Ptr ptr(object);
+ auto ptr2 = ptr;
+ assert(ptr->counter == 2);
+ assert(ptr2->counter == 2);
+ }
+
+ // move
+ {
+ auto object = new Object;
+ Ptr ptr(object);
+ auto ptr2 = std::move(ptr);
+ assert(!ptr);
+ assert(ptr2->counter == 1);
+ }
+
+ // copy assign
+ {
+ auto object1 = new Object;
+ auto object2 = new Object;
+ Ptr ptr1(object1);
+ Ptr ptr2(object2);
+
+ ptr1 = ptr2;
+ assert(ptr1->counter == 2);
+ assert(ptr2->counter == 2);
+ }
+
+ // move assign
+ {
+ auto object1 = new Object;
+ auto object2 = new Object;
+ Ptr ptr1(object1);
+ Ptr ptr2(object2);
+
+ ptr1 = std::move(ptr2);
+ assert(ptr1->counter == 1);
+ assert(!ptr2);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.threads/create_late.pass.cpp b/libcxx/test/libcxx-03/thread/thread.threads/create_late.pass.cpp
new file mode 100644
index 0000000000000..847b354702ed8
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.threads/create_late.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: no-threads
+// UNSUPPORTED: c++03
+
+#include "make_test_thread.h"
+
+void func() {}
+
+struct T {
+ ~T() {
+ // __thread_local_data is expected to be destroyed as it was created
+ // from the main(). Now trigger another access.
+ support::make_test_thread(func).join();
+ }
+} t;
+
+int main(int, char**) {
+ // Triggers construction of __thread_local_data.
+ support::make_test_thread(func).join();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
new file mode 100644
index 0000000000000..96ec3332519bc
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.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: no-threads, libcpp-has-thread-api-external
+
+// XFAIL: windows
+
+// <thread>
+
+// class thread
+
+// native_handle_type native_handle();
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main(int, char**)
+{
+ {
+ G g;
+ std::thread t0(g);
+ pthread_t pid = t0.native_handle();
+ assert(pid != 0);
+ t0.join();
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/types.pass.cpp b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/types.pass.cpp
new file mode 100644
index 0000000000000..bb60647ef05d8
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.class/types.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads, libcpp-has-thread-api-external
+// REQUIRES: libcpp-has-thread-api-pthread
+
+// <thread>
+
+// class thread
+// {
+// public:
+// typedef pthread_t native_handle_type;
+// ...
+// };
+
+#include <thread>
+#include <type_traits>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ static_assert((std::is_same<std::thread::native_handle_type, pthread_t>::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
new file mode 100644
index 0000000000000..e64a873fa095f
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-threads
+
+// ALLOW_RETRIES: 3
+
+// <thread>
+
+// template <class Rep, class Period>
+// void sleep_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <thread>
+#include <cassert>
+#include <chrono>
+
+int main(int, char**)
+{
+ typedef std::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ std::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ std::this_thread::sleep_for(ms);
+ time_point t1 = Clock::now();
+ // NOTE: Operating systems are (by default) best effort and therefore we may
+ // have slept longer, perhaps much longer than we requested.
+ assert(t1 - t0 >= ms);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.signals.pass.cpp b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.signals.pass.cpp
new file mode 100644
index 0000000000000..1dba5d8a40976
--- /dev/null
+++ b/libcxx/test/libcxx-03/thread/thread.threads/thread.thread.this/sleep_for.signals.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: no-threads
+
+// This test uses the POSIX header <sys/time.h> which Windows doesn't provide
+// UNSUPPORTED: windows
+
+// ALLOW_RETRIES: 3
+
+// <thread>
+
+// template <class Rep, class Period>
+// void sleep_for(const chrono::duration<Rep, Period>& rel_time);
+
+// This test ensures that we sleep for the right amount of time even when
+// we get interrupted by a signal, as fixed in 58a0a70fb2f1.
+
+#include <thread>
+#include <cassert>
+#include <chrono>
+#include <cstring> // for std::memset
+
+#include <signal.h>
+#include <sys/time.h>
+
+#include "test_macros.h"
+
+void sig_action(int) {}
+
+int main(int, char**)
+{
+ int ec;
+ struct sigaction action;
+ action.sa_handler = &sig_action;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+
+ ec = sigaction(SIGALRM, &action, nullptr);
+ assert(!ec);
+
+ struct itimerval it;
+ std::memset(&it, 0, sizeof(itimerval));
+ it.it_value.tv_sec = 0;
+ it.it_value.tv_usec = 250000;
+ // This will result in a SIGALRM getting fired resulting in the nanosleep
+ // inside sleep_for getting EINTR.
+ ec = setitimer(ITIMER_REAL, &it, nullptr);
+ assert(!ec);
+
+ typedef std::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ std::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ std::this_thread::sleep_for(ms);
+ time_point t1 = Clock::now();
+ // NOTE: Operating systems are (by default) best effort and therefore we may
+ // have slept longer, perhaps much longer than we requested.
+ assert(t1 - t0 >= ms);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/convert_to_tm.pass.cpp b/libcxx/test/libcxx-03/time/convert_to_tm.pass.cpp
new file mode 100644
index 0000000000000..6e3fa62066bcc
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/convert_to_tm.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// template <class _Tm, class _ChronoT>
+// _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value)
+
+// Most of the code is tested indirectly in the chrono formatters. This only
+// tests the hour overflow.
+
+#include <__chrono/convert_to_tm.h>
+#include <chrono>
+#include <cassert>
+#include <format>
+#include <string_view>
+
+#include "test_macros.h"
+
+// libc++ uses a long as representation in std::chrono::hours.
+// std::tm uses an int for its integral members. The overflow in the hour
+// conversion can only occur on platforms where sizeof(long) > sizeof(int).
+// Instead emulate this error by using a "tm" with shorts.
+// (The function is already templated to this is quite easy to do,)
+struct minimal_short_tm {
+ short tm_sec;
+ short tm_min;
+ short tm_hour;
+ const char* tm_zone;
+};
+
+int main(int, char**) {
+ { // Test with the maximum number of hours that fit in a short.
+ std::chrono::hh_mm_ss time{std::chrono::hours{32767}};
+ minimal_short_tm result = std::__convert_to_tm<minimal_short_tm>(time);
+ assert(result.tm_sec == 0);
+ assert(result.tm_min == 0);
+ assert(result.tm_hour == 32767);
+ }
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ { // Test above the maximum number of hours that fit in a short.
+ std::chrono::hh_mm_ss time{std::chrono::hours{32768}};
+ try {
+ TEST_IGNORE_NODISCARD std::__convert_to_tm<minimal_short_tm>(time);
+ assert(false);
+ } catch ([[maybe_unused]] const std::format_error& e) {
+ LIBCPP_ASSERT(e.what() == std::string_view("Formatting hh_mm_ss, encountered an hour overflow"));
+ return 0;
+ }
+ assert(false);
+ }
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.from_utc.pass.cpp b/libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.from_utc.pass.cpp
new file mode 100644
index 0000000000000..d8200439d9737
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.from_utc.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// REQUIRES: has-unix-headers
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <chrono>
+//
+// class gps_clock;
+
+// static gps_time<common_type_t<_Duration, seconds>>
+// from_utc(const utc_time<_Duration>& t) noexcept;
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// The function is specified as
+// gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
+// When t == t.max() there will be a signed integral overflow (other values too).
+int main(int, char**) {
+ using namespace std::literals::chrono_literals;
+ constexpr std::chrono::seconds offset{315964809};
+
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::nanoseconds>::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::nanoseconds>::max() - offset + 1ns),
+ "the UTC to GPS conversion would overflow");
+
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::microseconds>::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::microseconds>::max() - offset + 1us),
+ "the UTC to GPS conversion would overflow");
+
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::milliseconds>::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::milliseconds>::max() - offset + 1ms),
+ "the UTC to GPS conversion would overflow");
+
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_seconds::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(std::chrono::gps_clock::from_utc(std::chrono::utc_seconds::max() - offset + 1s),
+ "the UTC to GPS conversion would overflow");
+
+ // The conversion uses `common_type_t<Duration, seconds>` so types "larger"
+ // than seconds are converted to seconds. Types "larger" than seconds are
+ // stored in "smaller" intergral and the overflow can never occur.
+
+ // Validate the types can never overflow on all current (and future) supported platforms.
+ static_assert(std::chrono::utc_time<std::chrono::days>::max() <= std::chrono::utc_seconds::max() - offset);
+ static_assert(std::chrono::utc_time<std::chrono::weeks>::max() <= std::chrono::utc_seconds::max() - offset);
+ static_assert(std::chrono::utc_time<std::chrono::months>::max() <= std::chrono::utc_seconds::max() - offset);
+ static_assert(std::chrono::utc_time<std::chrono::years>::max() <= std::chrono::utc_seconds::max() - offset);
+
+ // Validate the run-time conversion works.
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::days>::max());
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::weeks>::max());
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::months>::max());
+ (void)std::chrono::gps_clock::from_utc(std::chrono::utc_time<std::chrono::years>::max());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.to_utc.pass.cpp b/libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.to_utc.pass.cpp
new file mode 100644
index 0000000000000..d61b3374f661f
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.clock/time.clock.gps/time.clock.gps.members/assert.to_utc.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// REQUIRES: has-unix-headers
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <chrono>
+//
+// class gps_clock;
+
+// static utc_time<common_type_t<_Duration, seconds>>
+// to_utc(const gps_time<_Duration>& t) noexcept;
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// The function is specified as
+// utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
+// When t == t.min() there will be a signed integral underlow (other values too).
+int main(int, char**) {
+ using namespace std::literals::chrono_literals;
+ constexpr std::chrono::seconds offset{315964809};
+
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::nanoseconds>::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::nanoseconds>::min() + offset - 1ns),
+ "the GPS to UTC conversion would underflow");
+
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::microseconds>::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::microseconds>::min() + offset - 1us),
+ "the GPS to UTC conversion would underflow");
+
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::milliseconds>::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::milliseconds>::min() + offset - 1ms),
+ "the GPS to UTC conversion would underflow");
+
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_seconds::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(std::chrono::gps_clock::to_utc(std::chrono::gps_seconds::min() + offset - 1s),
+ "the GPS to UTC conversion would underflow");
+
+ // The conversion uses `common_type_t<Duration, seconds>` so types "larger"
+ // than seconds are converted to seconds. Types "larger" than seconds are
+ // stored in "smaller" intergral and the underflow can never occur.
+
+ // Validate the types can never underflow on all current (and future) supported platforms.
+ static_assert(std::chrono::gps_time<std::chrono::days>::min() >= std::chrono::gps_seconds::min() + offset);
+ static_assert(std::chrono::gps_time<std::chrono::weeks>::min() >= std::chrono::gps_seconds::min() + offset);
+ static_assert(std::chrono::gps_time<std::chrono::months>::min() >= std::chrono::gps_seconds::min() + offset);
+ static_assert(std::chrono::gps_time<std::chrono::years>::min() >= std::chrono::gps_seconds::min() + offset);
+
+ // Validate the run-time conversion works.
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::days>::min());
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::weeks>::min());
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::months>::min());
+ (void)std::chrono::gps_clock::to_utc(std::chrono::gps_time<std::chrono::years>::min());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.from_utc.pass.cpp b/libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.from_utc.pass.cpp
new file mode 100644
index 0000000000000..f04595ce34ceb
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.from_utc.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// REQUIRES: has-unix-headers
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <chrono>
+//
+// class tai_clock;
+
+// static tai_time<common_type_t<_Duration, seconds>>
+// from_utc(const utc_time<_Duration>& t) noexcept;
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// The function is specified as
+// tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
+// When t == t.max() there will be a signed integral overflow (other values too).
+int main(int, char**) {
+ using namespace std::literals::chrono_literals;
+ constexpr std::chrono::seconds offset{378691210};
+
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::nanoseconds>::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::nanoseconds>::max() - offset + 1ns),
+ "the UTC to TAI conversion would overflow");
+
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::microseconds>::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::microseconds>::max() - offset + 1us),
+ "the UTC to TAI conversion would overflow");
+
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::milliseconds>::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::milliseconds>::max() - offset + 1ms),
+ "the UTC to TAI conversion would overflow");
+
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_seconds::max() - offset);
+ TEST_LIBCPP_ASSERT_FAILURE(std::chrono::tai_clock::from_utc(std::chrono::utc_seconds::max() - offset + 1s),
+ "the UTC to TAI conversion would overflow");
+
+ // The conversion uses `common_type_t<Duration, seconds>` so types "larger"
+ // than seconds are converted to seconds. Types "larger" than seconds are
+ // stored in "smaller" intergral and the overflow can never occur.
+
+ // Validate the types can never overflow on all current (and future) supported platforms.
+ static_assert(std::chrono::utc_time<std::chrono::days>::max() <= std::chrono::utc_seconds::max() - offset);
+ static_assert(std::chrono::utc_time<std::chrono::weeks>::max() <= std::chrono::utc_seconds::max() - offset);
+ static_assert(std::chrono::utc_time<std::chrono::months>::max() <= std::chrono::utc_seconds::max() - offset);
+ static_assert(std::chrono::utc_time<std::chrono::years>::max() <= std::chrono::utc_seconds::max() - offset);
+
+ // Validate the run-time conversion works.
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::days>::max());
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::weeks>::max());
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::months>::max());
+ (void)std::chrono::tai_clock::from_utc(std::chrono::utc_time<std::chrono::years>::max());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.to_utc.pass.cpp b/libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.to_utc.pass.cpp
new file mode 100644
index 0000000000000..624c6c4bce4ca
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.clock/time.clock.tai/time.clock.tai.members/assert.to_utc.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// REQUIRES: has-unix-headers
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// <chrono>
+//
+// class tai_clock;
+
+// static utc_time<common_type_t<_Duration, seconds>>
+// to_utc(const tai_time<_Duration>& t) noexcept;
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// The function is specified as
+// utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
+// When t == t.min() there will be a signed integral underlow (other values too).
+int main(int, char**) {
+ using namespace std::literals::chrono_literals;
+ constexpr std::chrono::seconds offset{378691210};
+
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::nanoseconds>::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::nanoseconds>::min() + offset - 1ns),
+ "the TAI to UTC conversion would underflow");
+
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::microseconds>::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::microseconds>::min() + offset - 1us),
+ "the TAI to UTC conversion would underflow");
+
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::milliseconds>::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::milliseconds>::min() + offset - 1ms),
+ "the TAI to UTC conversion would underflow");
+
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_seconds::min() + offset);
+ TEST_LIBCPP_ASSERT_FAILURE(std::chrono::tai_clock::to_utc(std::chrono::tai_seconds::min() + offset - 1s),
+ "the TAI to UTC conversion would underflow");
+
+ // The conversion uses `common_type_t<Duration, seconds>` so types "larger"
+ // than seconds are converted to seconds. Types "larger" than seconds are
+ // stored in "smaller" intergral and the underflow can never occur.
+
+ // Validate the types can never underflow on all current (and future) supported platforms.
+ static_assert(std::chrono::tai_time<std::chrono::days>::min() >= std::chrono::tai_seconds::min() + offset);
+ static_assert(std::chrono::tai_time<std::chrono::weeks>::min() >= std::chrono::tai_seconds::min() + offset);
+ static_assert(std::chrono::tai_time<std::chrono::months>::min() >= std::chrono::tai_seconds::min() + offset);
+ static_assert(std::chrono::tai_time<std::chrono::years>::min() >= std::chrono::tai_seconds::min() + offset);
+
+ // Validate the run-time conversion works.
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::days>::min());
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::weeks>::min());
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::months>::min());
+ (void)std::chrono::tai_clock::to_utc(std::chrono::tai_time<std::chrono::years>::min());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/get_leap_second_info.pass.cpp b/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/get_leap_second_info.pass.cpp
new file mode 100644
index 0000000000000..e87c5438179ef
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/get_leap_second_info.pass.cpp
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+//
+// class utc_clock;
+
+// template<class Duration>
+// std::chrono::leap_second_info get_leap_second_info(const utc_time<Duration>& ut);
+
+#include <chrono>
+#include <cassert>
+#include <fstream>
+#include <string>
+#include <string_view>
+
+#include "test_macros.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path tzdata = env.create_file("zoneinfo/tzdata.zi");
+const std::filesystem::path leap_seconds = env.create_file("zoneinfo/leap-seconds.list");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) {
+ static int version = 0;
+
+ {
+ std::ofstream f{tzdata};
+ f << "# version " << version++ << '\n';
+ std::ofstream{leap_seconds}.write(input.data(), input.size());
+ }
+ std::chrono::reload_tzdb();
+}
+
+template <class Duration>
+static void test_leap_second_info(
+ std::chrono::time_point<std::chrono::utc_clock, Duration> time, bool is_leap_second, std::chrono::seconds elapsed) {
+ std::chrono::leap_second_info result = std::chrono::get_leap_second_info(time);
+ TEST_REQUIRE(
+ result.is_leap_second == is_leap_second && result.elapsed == elapsed,
+ TEST_WRITE_CONCATENATED(
+ "\nExpected output [",
+ is_leap_second,
+ ", ",
+ elapsed,
+ "]\nActual output [",
+ result.is_leap_second,
+ ", ",
+ result.elapsed,
+ "]\n"));
+}
+
+static void test_no_leap_seconds_entries() {
+ using namespace std::literals::chrono_literals;
+
+ write("");
+
+ test_leap_second_info(
+ std::chrono::utc_seconds{std::chrono::sys_days{std::chrono::January / 1 / 1900}.time_since_epoch()}, false, 0s);
+ test_leap_second_info(
+ std::chrono::utc_seconds{std::chrono::sys_days{std::chrono::January / 1 / 2000}.time_since_epoch()}, false, 0s);
+ test_leap_second_info(
+ std::chrono::utc_seconds{std::chrono::sys_days{std::chrono::January / 1 / 3000}.time_since_epoch()}, false, 0s);
+}
+
+// Note at the time of writing all leap seconds are positive. This test uses
+// fake data to test the behaviour of negative leap seconds.
+static void test_negative_leap_seconds() {
+ using namespace std::literals::chrono_literals;
+
+ // Use small values for simplicity. The dates are seconds since 1.1.1900.
+ write(
+ R"(
+1 10
+60 11
+120 12
+180 11
+240 12
+300 13
+360 12
+)");
+
+ // Transitions from the start of UTC.
+ auto test_transition = [](std::chrono::utc_seconds time, std::chrono::seconds elapsed, bool positive) {
+ if (positive) {
+ // Every transition has the following tests
+ // - 1ns before the start of the transition is_leap_second -> false, elapsed -> elapsed
+ // - at the start of the transition is_leap_second -> true, elapsed -> elapsed + 1
+ // - 1ns after the start of the transition is_leap_second -> true, elapsed -> elapsed + 1
+ // - 1ns before the end of the transition is_leap_second -> true, elapsed -> elapsed + 1
+ // - at the end of the transition is_leap_second -> false, elapsed -> elapsed + 1
+
+ test_leap_second_info(time - 1ns, false, elapsed);
+ test_leap_second_info(time, true, elapsed + 1s);
+ test_leap_second_info(time + 1ns, true, elapsed + 1s);
+ test_leap_second_info(time + 1s - 1ns, true, elapsed + 1s);
+ test_leap_second_info(time + 1s, false, elapsed + 1s);
+ } else {
+ // Every transition has the following tests
+ // - 1ns before the transition is_leap_second -> false, elapsed -> elapsed
+ // - at the transition is_leap_second -> false elapsed -> elapsed - 1
+ // - 1ns after the transition is_leap_second -> false, elapsed -> elapsed - 1
+ test_leap_second_info(time - 1ns, false, elapsed);
+ test_leap_second_info(time, false, elapsed - 1s);
+ test_leap_second_info(time + 1ns, false, elapsed - 1s);
+ }
+ };
+
+ std::chrono::utc_seconds epoch{std::chrono::sys_days{std::chrono::January / 1 / 1900}.time_since_epoch()};
+ test_leap_second_info(epoch, false, 0s);
+
+ // The UTC times are:
+ // epoch + transition time in the database + leap seconds before the transition.
+ test_transition(epoch + 60s + 0s, 0s, true);
+ test_transition(epoch + 120s + 1s, 1s, true);
+ test_transition(epoch + 180s + 2s, 2s, false);
+ test_transition(epoch + 240s + 1s, 1s, true);
+ test_transition(epoch + 300s + 2s, 2s, true);
+ test_transition(epoch + 360s + 3s, 3s, false);
+}
+
+int main(int, const char**) {
+ test_no_leap_seconds_entries();
+ test_negative_leap_seconds();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/from_sys.pass.cpp b/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/from_sys.pass.cpp
new file mode 100644
index 0000000000000..2468daa95c29d
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/from_sys.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
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+//
+// class utc_clock;
+
+// template<class Duration>
+// static utc_time<common_type_t<Duration, seconds>>
+// from_sys(const sys_time<Duration>& time);
+
+#include <chrono>
+#include <cassert>
+#include <fstream>
+#include <string>
+#include <string_view>
+
+#include "test_macros.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path tzdata = env.create_file("zoneinfo/tzdata.zi");
+const std::filesystem::path leap_seconds = env.create_file("zoneinfo/leap-seconds.list");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{tzdata};
+ f << "# version " << version++ << '\n';
+ std::ofstream{leap_seconds}.write(input.data(), input.size());
+}
+
+template <class Duration>
+static void
+test_leap_seconds(std::chrono::time_point<std::chrono::system_clock, Duration> time, std::chrono::seconds expected) {
+ auto utc = std::chrono::utc_clock::from_sys(time);
+ auto diff = utc.time_since_epoch() - time.time_since_epoch();
+ TEST_REQUIRE(
+ diff == expected,
+ TEST_WRITE_CONCATENATED("\tTime: ", time, "\nExpected output ", expected, "\nActual output ", diff, '\n'));
+}
+
+// Note at the time of writing all leap seconds are positive. This test uses
+// fake data to test the behaviour of negative leap seconds.
+int main(int, const char**) {
+ using namespace std::literals::chrono_literals;
+
+ // Use small values for simplicity. The dates are seconds since 1.1.1970.
+ write(
+ R"(
+1 10
+60 11
+120 12
+180 11
+240 12
+300 13
+360 12
+)");
+
+ std::chrono::sys_days epoch = {std::chrono::January / 1 / 1900};
+ test_leap_seconds(epoch, 0s);
+
+ test_leap_seconds(epoch + 60s - 1ns, 0s);
+ test_leap_seconds(epoch + 60s, 1s);
+ test_leap_seconds(epoch + 60s + 1ns, 1s);
+
+ test_leap_seconds(epoch + 120s - 1ns, 1s);
+ test_leap_seconds(epoch + 120s, 2s);
+ test_leap_seconds(epoch + 120s + 1ns, 2s);
+
+ test_leap_seconds(epoch + 180s - 1ns, 2s);
+ test_leap_seconds(epoch + 180s, 1s);
+ test_leap_seconds(epoch + 180s + 1ns, 1s);
+
+ test_leap_seconds(epoch + 240s - 1ns, 1s);
+ test_leap_seconds(epoch + 240s, 2s);
+ test_leap_seconds(epoch + 240s + 1ns, 2s);
+
+ test_leap_seconds(epoch + 300s - 1ns, 2s);
+ test_leap_seconds(epoch + 300s, 3s);
+ test_leap_seconds(epoch + 300s + 1ns, 3s);
+
+ test_leap_seconds(epoch + 360s - 1ns, 3s);
+ test_leap_seconds(epoch + 360s, 2s);
+ test_leap_seconds(epoch + 360s + 1ns, 2s);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/to_sys.pass.cpp b/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/to_sys.pass.cpp
new file mode 100644
index 0000000000000..ab4dff46d9184
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.clock/time.clock.utc/time.clock.utc.members/to_sys.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+//
+// class utc_clock;
+
+// static sys_time<common_type_t<_Duration, seconds>>
+// to_sys(const utc_time<_Duration>& __time);
+
+#include <chrono>
+#include <cassert>
+#include <fstream>
+#include <string>
+#include <string_view>
+
+#include "test_macros.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path tzdata = env.create_file("zoneinfo/tzdata.zi");
+const std::filesystem::path leap_seconds = env.create_file("zoneinfo/leap-seconds.list");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{tzdata};
+ f << "# version " << version++ << '\n';
+ std::ofstream{leap_seconds}.write(input.data(), input.size());
+}
+
+template <class Duration>
+static void test_leap_seconds(std::chrono::utc_time<Duration> time, std::chrono::sys_time<Duration> expected) {
+ auto result = std::chrono::utc_clock::to_sys(time);
+ TEST_REQUIRE(result == expected,
+ TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", result, '\n'));
+}
+
+// Note at the time of writing all leap seconds are positive. This test uses
+// fake data to test the behaviour of negative leap seconds.
+int main(int, const char**) {
+ using namespace std::literals::chrono_literals;
+
+ // Use small values for simplicity. The dates are seconds since 1.1.1970.
+ write(
+ R"(
+1 10
+60 11
+120 12
+180 11
+240 12
+300 13
+360 12
+)");
+
+ std::chrono::sys_seconds sys_epoch{std::chrono::sys_days{std::chrono::January / 1 / 1900}};
+ std::chrono::utc_seconds utc_epoch{sys_epoch.time_since_epoch()};
+
+ test_leap_seconds(utc_epoch, sys_epoch);
+ auto test_transition = [](std::chrono::sys_seconds sys, std::chrono::seconds elapsed, bool positive) {
+ std::chrono::utc_seconds utc = std::chrono::utc_seconds{sys.time_since_epoch()} + elapsed;
+ if (positive) {
+ // Every transition has the following tests
+ // - 1ns before the start of the transition no adjustment needed
+ // - at the start of the transition sys is clamped at the time just prior to the moment
+ // of the leap second insertion. The exact value depends
+ // on the resolution of the result type.
+ // - 1ns before the end of the transition sys is still clamped like before
+ // - at the end of the transition sys is 1s behind the utc time
+ // - 1ns after the end of the transition sys is still 1s behind the utc time
+ test_leap_seconds(utc - 1ns, sys - 1ns);
+ test_leap_seconds(utc, sys - 1s);
+ test_leap_seconds(utc + 0ns, sys - 1ns);
+ test_leap_seconds(utc + 1s - 1ns, sys - 1ns);
+ test_leap_seconds(utc + 1s, sys);
+ test_leap_seconds(utc + 1s + 0ns, sys + 0ns);
+ test_leap_seconds(utc + 1s + 1ns, sys + 1ns);
+ } else {
+ // Every transition has the following tests
+ // - 1ns before the transition no adjustment needed
+ // - at the transition sys is 1s ahead of the utc time
+ // - 1ns after the transition sys is still 1s ahead of the utc time
+ test_leap_seconds(utc - 1ns, sys - 1ns);
+ test_leap_seconds(utc, sys + 1s);
+ test_leap_seconds(utc + 1ns, sys + 1s + 1ns);
+ }
+ };
+
+ test_transition(sys_epoch + 60s, 0s, true);
+ test_transition(sys_epoch + 120s, 1s, true);
+ test_transition(sys_epoch + 180s, 2s, false);
+ test_transition(sys_epoch + 240s, 1s, true);
+ test_transition(sys_epoch + 300s, 2s, true);
+ test_transition(sys_epoch + 360s, 3s, false);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/leap_seconds.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/leap_seconds.pass.cpp
new file mode 100644
index 0000000000000..d7ae21926b4b2
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/leap_seconds.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
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// Tests the IANA database leap seconds parsing and operations.
+// This is not part of the public tzdb interface.
+
+#include <cassert>
+#include <chrono>
+#include <fstream>
+#include <string>
+#include <string_view>
+
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path tzdata = env.create_file("zoneinfo/tzdata.zi");
+const std::filesystem::path leap_seconds = env.create_file("zoneinfo/leap-seconds.list");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{tzdata};
+ f << "# version " << version++ << '\n';
+ std::ofstream{leap_seconds}.write(input.data(), input.size());
+}
+
+static const std::chrono::tzdb& parse(std::string_view input) {
+ write(input);
+ return std::chrono::reload_tzdb();
+}
+
+static void test_exception(std::string_view input, [[maybe_unused]] std::string_view what) {
+ write(input);
+
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD std::chrono::reload_tzdb());
+}
+
+static void test_invalid() {
+ test_exception("0", "corrupt tzdb: expected a non-zero digit");
+
+ test_exception("1", "corrupt tzdb: expected whitespace");
+
+ test_exception("1 ", "corrupt tzdb: expected a non-zero digit");
+
+ test_exception("5764607523034234880 2", "corrupt tzdb: integral too large");
+}
+
+static void test_leap_seconds() {
+ using namespace std::chrono;
+
+ // Test whether loading also sorts the entries in the proper order.
+ const tzdb& result = parse(
+ R"(
+2303683200 12 # 1 Jan 1973
+2287785600 11 # 1 Jul 1972
+2272060800 10 # 1 Jan 1972
+86400 9 # 2 Jan 1900 Dummy entry to test before 1970
+1 8 # 2 Jan 1900 Dummy entry to test before 1970
+
+# Fictional negative leap second
+2303769600 11 # 2 Jan 1973
+
+# largest accepted value by the parser
+5764607523034234879 12
+)");
+
+ assert(result.leap_seconds.size() == 6);
+
+ assert(result.leap_seconds[0].date() == sys_seconds{sys_days{1900y / January / 2}});
+ assert(result.leap_seconds[0].value() == 1s);
+
+ assert(result.leap_seconds[1].date() == sys_seconds{sys_days{1972y / January / 1}});
+ assert(result.leap_seconds[1].value() == 1s);
+
+ assert(result.leap_seconds[2].date() == sys_seconds{sys_days{1972y / July / 1}});
+ assert(result.leap_seconds[2].value() == 1s);
+
+ assert(result.leap_seconds[3].date() == sys_seconds{sys_days{1973y / January / 1}});
+ assert(result.leap_seconds[3].value() == 1s);
+
+ assert(result.leap_seconds[4].date() == sys_seconds{sys_days{1973y / January / 2}});
+ assert(result.leap_seconds[4].value() == -1s);
+
+ assert(result.leap_seconds[5].date() ==
+ sys_seconds{5764607523034234879s
+ // The database uses 1900-01-01 as epoch.
+ - std::chrono::duration_cast<std::chrono::seconds>(
+ sys_days{1970y / January / 1} - sys_days{1900y / January / 1})});
+ assert(result.leap_seconds[5].value() == 1s);
+}
+
+int main(int, const char**) {
+ test_invalid();
+ test_leap_seconds();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/links.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/links.pass.cpp
new file mode 100644
index 0000000000000..9bace25629f72
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/links.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// Tests the IANA database rules links and operations.
+// This is not part of the public tzdb interface.
+
+#include <chrono>
+
+#include <cassert>
+#include <chrono>
+#include <fstream>
+#include <string>
+#include <string_view>
+
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{file};
+ f << "# version " << version++ << '\n';
+ f.write(input.data(), input.size());
+}
+
+static const std::chrono::tzdb& parse(std::string_view input) {
+ write(input);
+ return std::chrono::reload_tzdb();
+}
+
+static void test_exception(std::string_view input, [[maybe_unused]] std::string_view what) {
+ write(input);
+
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD std::chrono::reload_tzdb());
+}
+
+static void test_invalid() {
+ test_exception("L", "corrupt tzdb: expected whitespace");
+
+ test_exception("L ", "corrupt tzdb: expected a string");
+
+ test_exception("L n", "corrupt tzdb: expected whitespace");
+
+ test_exception("L n ", "corrupt tzdb: expected a string");
+}
+
+static void test_link() {
+ const std::chrono::tzdb& result = parse(
+ R"(
+L z d
+l b a
+lInK b b
+)");
+ assert(result.links.size() == 3);
+
+ assert(result.links[0].name() == "a");
+ assert(result.links[0].target() == "b");
+
+ assert(result.links[1].name() == "b");
+ assert(result.links[1].target() == "b");
+
+ assert(result.links[2].name() == "d");
+ assert(result.links[2].target() == "z");
+}
+
+int main(int, const char**) {
+ test_invalid();
+ test_link();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/rules.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/rules.pass.cpp
new file mode 100644
index 0000000000000..237a206b3a95b
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/rules.pass.cpp
@@ -0,0 +1,594 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// Tests the IANA database rules parsing and operations.
+// This is not part of the public tzdb interface.
+// The test uses private implementation headers.
+// ADDITIONAL_COMPILE_FLAGS: -I %{libcxx-dir}/src/experimental/include
+
+#include <chrono>
+#include <cstdio>
+#include <fstream>
+#include <string_view>
+#include <string>
+#include <variant>
+
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+// headers in the dylib
+#include "tzdb/types_private.h"
+#include "tzdb/tzdb_private.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{file};
+ f << "# version " << version++ << '\n';
+ f.write(input.data(), input.size());
+}
+
+struct parse_result {
+ explicit parse_result(std::string_view input) {
+ write(input);
+ std::chrono::tzdb tzdb; // result not needed for the tests.
+ std::chrono::__init_tzdb(tzdb, rules);
+ }
+ std::chrono::__tz::__rules_storage_type rules;
+};
+
+static void test_exception(std::string_view input, [[maybe_unused]] std::string_view what) {
+ write(input);
+
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD std::chrono::reload_tzdb());
+}
+
+static void test_invalid() {
+ test_exception("R", "corrupt tzdb: expected whitespace");
+
+ test_exception("R ", "corrupt tzdb: expected a string");
+
+ test_exception("R r", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r x", "corrupt tzdb: expected a digit");
+ test_exception("R r +", "corrupt tzdb: expected a digit");
+ test_exception("R r mx", "corrupt tzdb year: expected 'min' or 'max'");
+ test_exception("R r -32768", "corrupt tzdb year: year is less than the minimum");
+ test_exception("R r 32768", "corrupt tzdb year: year is greater than the maximum");
+
+ test_exception("R r mix", "corrupt tzdb: expected whitespace");
+ test_exception("R r 0", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r 0 x", "corrupt tzdb: expected a digit");
+ test_exception("R r 0 +", "corrupt tzdb: expected a digit");
+ test_exception("R r 0 mx", "corrupt tzdb year: expected 'min' or 'max'");
+
+ test_exception("R r 0 mix", "corrupt tzdb: expected whitespace");
+ test_exception("R r 0 1", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r 0 1 X", "corrupt tzdb: expected character '-', got 'X' instead");
+
+ test_exception("R r 0 1 -", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r 0 1 - j", "corrupt tzdb month: invalid name");
+
+ test_exception("R r 0 1 - Ja", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r 0 1 - Ja +", "corrupt tzdb weekday: invalid name");
+ test_exception("R r 0 1 - Ja 32", "corrupt tzdb day: value too large");
+ test_exception(
+ "R r 0 1 - Ja l",
+ std::string{"corrupt tzdb: expected character 'a' from string 'last', got '"} + (char)EOF + "' instead");
+ test_exception("R r 0 1 - Ja last", "corrupt tzdb weekday: invalid name");
+ test_exception("R r 0 1 - Ja lastS", "corrupt tzdb weekday: invalid name");
+ test_exception("R r 0 1 - Ja S", "corrupt tzdb weekday: invalid name");
+ test_exception("R r 0 1 - Ja Su", "corrupt tzdb on: expected '>=' or '<='");
+ test_exception(
+ "R r 0 1 - Ja Su>", std::string{"corrupt tzdb: expected character '=', got '"} + (char)EOF + "' instead");
+ test_exception(
+ "R r 0 1 - Ja Su<", std::string{"corrupt tzdb: expected character '=', got '"} + (char)EOF + "' instead");
+ test_exception("R r 0 1 - Ja Su>=+", "corrupt tzdb: expected a non-zero digit");
+ test_exception("R r 0 1 - Ja Su>=0", "corrupt tzdb: expected a non-zero digit");
+ test_exception("R r 0 1 - Ja Su>=32", "corrupt tzdb day: value too large");
+
+ test_exception("R r 0 1 - Ja Su>=31", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r 0 1 - Ja Su>=31 ", "corrupt tzdb: expected a digit");
+ test_exception("R r 0 1 - Ja Su>=31 +", "corrupt tzdb: expected a digit");
+
+ test_exception("R r 0 1 - Ja Su>=31 1", "corrupt tzdb: expected whitespace");
+ test_exception("R r 0 1 - Ja Su>=31 1a", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r 0 1 - Ja Su>=31 1w 2", "corrupt tzdb: expected whitespace");
+ test_exception("R r 0 1 - Ja Su>=31 1w 2a", "corrupt tzdb: expected whitespace");
+
+ test_exception("R r 0 1 - Ja Su>=31 1w 2s", "corrupt tzdb: expected whitespace");
+ test_exception("R r 0 1 - Ja Su>=31 1w 2s ", "corrupt tzdb: expected a string");
+}
+
+static void test_name() {
+ parse_result result{
+ R"(
+R z 0 1 - Ja Su>=31 1w 2s -
+rULE z 0 1 - Ja Su>=31 1w 2s -
+RuLe z 0 1 - Ja Su>=31 1w 2s -
+R a 0 1 - Ja Su>=31 1w 2s -
+R a 0 1 - Ja Su>=31 1w 2s -
+)"};
+
+ assert(result.rules.size() == 2);
+ assert(result.rules[0].first == "a");
+ assert(result.rules[0].second.size() == 2);
+ assert(result.rules[1].first == "z");
+ assert(result.rules[1].second.size() == 3);
+}
+
+static void test_from() {
+ parse_result result{
+ R"(
+# min abbreviations
+R a M 1 - Ja Su>=31 1w 2s -
+R a mI 1 - Ja Su>=31 1w 2s -
+R a mIN 1 - Ja Su>=31 1w 2s -
+
+# max abbrviations
+R a MA 1 - Ja Su>=31 1w 2s -
+R a mAx 1 - Ja Su>=31 1w 2s -
+
+R a -1000 1 - Ja Su>=31 1w 2s -
+R a -100 1 - Ja Su>=31 1w 2s -
+R a 0000 1 - Ja Su>=31 1w 2s -
+R a 100 1 - Ja Su>=31 1w 2s -
+R a 1000 1 - Ja Su>=31 1w 2s -
+)"};
+
+ assert(result.rules.size() == 1);
+ assert(result.rules[0].second.size() == 10);
+
+ assert(result.rules[0].second[0].__from == std::chrono::year::min());
+ assert(result.rules[0].second[1].__from == std::chrono::year::min());
+ assert(result.rules[0].second[2].__from == std::chrono::year::min());
+
+ assert(result.rules[0].second[3].__from == std::chrono::year::max());
+ assert(result.rules[0].second[4].__from == std::chrono::year::max());
+
+ assert(result.rules[0].second[5].__from == std::chrono::year(-1000));
+ assert(result.rules[0].second[6].__from == std::chrono::year(-100));
+ assert(result.rules[0].second[7].__from == std::chrono::year(0));
+ assert(result.rules[0].second[8].__from == std::chrono::year(100));
+ assert(result.rules[0].second[9].__from == std::chrono::year(1000));
+}
+
+static void test_to() {
+ parse_result result{
+ R"(
+# min abbreviations
+R a 0 m - Ja Su>=31 1w 2s -
+R a 0 mi - Ja Su>=31 1w 2s -
+R a 0 min - Ja Su>=31 1w 2s -
+
+# max abbrviations
+R a 0 ma - Ja Su>=31 1w 2s -
+R a 0 max - Ja Su>=31 1w 2s -
+
+R a 0 -1000 - Ja Su>=31 1w 2s -
+R a 0 -100 - Ja Su>=31 1w 2s -
+R a 0 0000 - Ja Su>=31 1w 2s -
+R a 0 100 - Ja Su>=31 1w 2s -
+R a 0 1000 - Ja Su>=31 1w 2s -
+
+# only abbreviations
+R a m O - Ja Su>=31 1w 2s -
+R a ma oN - Ja Su>=31 1w 2s -
+R a -100 onL - Ja Su>=31 1w 2s -
+R a 100 oNlY - Ja Su>=31 1w 2s -
+)"};
+
+ assert(result.rules.size() == 1);
+ assert(result.rules[0].second.size() == 14);
+
+ assert(result.rules[0].second[0].__to == std::chrono::year::min());
+ assert(result.rules[0].second[1].__to == std::chrono::year::min());
+ assert(result.rules[0].second[2].__to == std::chrono::year::min());
+
+ assert(result.rules[0].second[3].__to == std::chrono::year::max());
+ assert(result.rules[0].second[4].__to == std::chrono::year::max());
+
+ assert(result.rules[0].second[5].__to == std::chrono::year(-1000));
+ assert(result.rules[0].second[6].__to == std::chrono::year(-100));
+ assert(result.rules[0].second[7].__to == std::chrono::year(0));
+ assert(result.rules[0].second[8].__to == std::chrono::year(100));
+ assert(result.rules[0].second[9].__to == std::chrono::year(1000));
+
+ assert(result.rules[0].second[10].__to == std::chrono::year::min());
+ assert(result.rules[0].second[11].__to == std::chrono::year::max());
+ assert(result.rules[0].second[12].__to == std::chrono::year(-100));
+ assert(result.rules[0].second[13].__to == std::chrono::year(100));
+}
+
+static void test_in() {
+ parse_result result{
+ R"(
+# All tests in alphabetic order to validate shortest unique abbreviation
+
+# Shortest abbreviation valid
+R s 0 1 - ap Su>=31 1w 2s -
+R s 0 1 - au Su>=31 1w 2s -
+R s 0 1 - d Su>=31 1w 2s -
+R s 0 1 - f Su>=31 1w 2s -
+R s 0 1 - ja Su>=31 1w 2s -
+R s 0 1 - jul Su>=31 1w 2s -
+R s 0 1 - jun Su>=31 1w 2s -
+R s 0 1 - May Su>=31 1w 2s -
+R s 0 1 - mar Su>=31 1w 2s -
+R s 0 1 - n Su>=31 1w 2s -
+R s 0 1 - o Su>=31 1w 2s -
+R s 0 1 - s Su>=31 1w 2s -
+
+# 3 letter abbreviation
+R a 0 1 - APR Su>=31 1w 2s -
+R a 0 1 - AUG Su>=31 1w 2s -
+R a 0 1 - DEC Su>=31 1w 2s -
+R a 0 1 - FEB Su>=31 1w 2s -
+R a 0 1 - JAN Su>=31 1w 2s -
+R a 0 1 - JUL Su>=31 1w 2s -
+R a 0 1 - JUN Su>=31 1w 2s -
+R a 0 1 - MAY Su>=31 1w 2s -
+R a 0 1 - MAR Su>=31 1w 2s -
+R a 0 1 - NOV Su>=31 1w 2s -
+R a 0 1 - OCT Su>=31 1w 2s -
+R a 0 1 - SEP Su>=31 1w 2s -
+
+# Full names
+R f 0 1 - ApRiL Su>=31 1w 2s -
+R f 0 1 - AuGuSt Su>=31 1w 2s -
+R f 0 1 - DeCeMber Su>=31 1w 2s -
+R f 0 1 - FeBrUary Su>=31 1w 2s -
+R f 0 1 - JaNuAry Su>=31 1w 2s -
+R f 0 1 - JuLy Su>=31 1w 2s -
+R f 0 1 - JuNe Su>=31 1w 2s -
+R f 0 1 - MaY Su>=31 1w 2s -
+R f 0 1 - MaRch Su>=31 1w 2s -
+R f 0 1 - NoVemBeR Su>=31 1w 2s -
+R f 0 1 - OcTobEr Su>=31 1w 2s -
+R f 0 1 - SePteMbEr Su>=31 1w 2s -
+)"};
+
+ assert(result.rules.size() == 3);
+ for (std::size_t i = 0; i < result.rules.size(); ++i) {
+ assert(result.rules[i].second.size() == 12);
+
+ assert(result.rules[i].second[0].__in == std::chrono::April);
+ assert(result.rules[i].second[1].__in == std::chrono::August);
+ assert(result.rules[i].second[2].__in == std::chrono::December);
+ assert(result.rules[i].second[3].__in == std::chrono::February);
+ assert(result.rules[i].second[4].__in == std::chrono::January);
+ assert(result.rules[i].second[5].__in == std::chrono::July);
+ assert(result.rules[i].second[6].__in == std::chrono::June);
+ assert(result.rules[i].second[7].__in == std::chrono::May);
+ assert(result.rules[i].second[8].__in == std::chrono::March);
+ assert(result.rules[i].second[9].__in == std::chrono::November);
+ assert(result.rules[i].second[10].__in == std::chrono::October);
+ assert(result.rules[i].second[11].__in == std::chrono::September);
+ }
+};
+
+static void test_on_day() {
+ parse_result result{
+ R"(
+# The parser does not validate the day as valid day of month
+R a 0 1 - Fe 1 1w 2s -
+R a 0 1 - Fe 10 1w 2s -
+R a 0 1 - Fe 20 1w 2s -
+R a 0 1 - Fe 30 1w 2s -
+R a 0 1 - Fe 31 1w 2s -
+)"};
+
+ assert(result.rules.size() == 1);
+ assert(result.rules[0].second.size() == 5);
+ assert(std::get<std::chrono::day>(result.rules[0].second[0].__on) == std::chrono::day(1));
+ assert(std::get<std::chrono::day>(result.rules[0].second[1].__on) == std::chrono::day(10));
+ assert(std::get<std::chrono::day>(result.rules[0].second[2].__on) == std::chrono::day(20));
+ assert(std::get<std::chrono::day>(result.rules[0].second[3].__on) == std::chrono::day(30));
+ assert(std::get<std::chrono::day>(result.rules[0].second[4].__on) == std::chrono::day(31));
+}
+
+static void test_on_last() {
+ parse_result result{
+ R"(
+# All tests in alphabetic order to validate shortest unique abbreviation
+
+# Shortest abbreviation valid
+R s 0 1 - Ja lastF 1w 2s -
+R s 0 1 - Ja lastM 1w 2s -
+R s 0 1 - Ja lastSa 1w 2s -
+R s 0 1 - Ja lastSu 1w 2s -
+R s 0 1 - Ja lastTh 1w 2s -
+R s 0 1 - Ja lastTu 1w 2s -
+R s 0 1 - Ja lastW 1w 2s -
+
+# 3 letter abbreviation
+R a 0 1 - Ja lastFri 1w 2s -
+R a 0 1 - Ja lastMon 1w 2s -
+R a 0 1 - Ja lastSat 1w 2s -
+R a 0 1 - Ja lastSun 1w 2s -
+R a 0 1 - Ja lastThu 1w 2s -
+R a 0 1 - Ja lastTue 1w 2s -
+R a 0 1 - Ja lastWed 1w 2s -
+
+# Full names
+R f 0 1 - Ja lastFriday 1w 2s -
+R f 0 1 - Ja lastMonday 1w 2s -
+R f 0 1 - Ja lastSaturday 1w 2s -
+R f 0 1 - Ja lastSunday 1w 2s -
+R f 0 1 - Ja lastThursday 1w 2s -
+R f 0 1 - Ja lastTuesday 1w 2s -
+R f 0 1 - Ja lastWednesday 1w 2s -
+)"};
+
+ assert(result.rules.size() == 3);
+ for (std::size_t i = 0; i < result.rules.size(); ++i) {
+ assert(result.rules[i].second.size() == 7);
+
+ assert(std::get<std::chrono::weekday_last>(result.rules[i].second[0].__on) ==
+ std::chrono::weekday_last(std::chrono::Friday));
+ assert(std::get<std::chrono::weekday_last>(result.rules[i].second[1].__on) ==
+ std::chrono::weekday_last(std::chrono::Monday));
+ assert(std::get<std::chrono::weekday_last>(result.rules[i].second[2].__on) ==
+ std::chrono::weekday_last(std::chrono::Saturday));
+ assert(std::get<std::chrono::weekday_last>(result.rules[i].second[3].__on) ==
+ std::chrono::weekday_last(std::chrono::Sunday));
+ assert(std::get<std::chrono::weekday_last>(result.rules[i].second[4].__on) ==
+ std::chrono::weekday_last(std::chrono::Thursday));
+ assert(std::get<std::chrono::weekday_last>(result.rules[i].second[5].__on) ==
+ std::chrono::weekday_last(std::chrono::Tuesday));
+ assert(std::get<std::chrono::weekday_last>(result.rules[i].second[6].__on) ==
+ std::chrono::weekday_last(std::chrono::Wednesday));
+ }
+}
+
+static void test_on_constrain() {
+ parse_result result{
+ R"(
+# Shortest abbreviation valid
+R s 0 1 - Ja F>=1 1w 2s -
+R s 0 1 - Ja M<=1 1w 2s -
+R s 0 1 - Ja Sa>=31 1w 2s -
+R s 0 1 - Ja Su<=31 1w 2s -
+R s 0 1 - Ja Th>=10 1w 2s -
+R s 0 1 - Ja Tu<=20 1w 2s -
+R s 0 1 - Ja W>=30 1w 2s -
+
+# 3 letter abbreviation
+R a 0 1 - Ja Fri>=1 1w 2s -
+R a 0 1 - Ja Mon<=1 1w 2s -
+R a 0 1 - Ja Sat>=31 1w 2s -
+R a 0 1 - Ja Sun<=31 1w 2s -
+R a 0 1 - Ja Thu>=10 1w 2s -
+R a 0 1 - Ja Tue<=20 1w 2s -
+R a 0 1 - Ja Wed>=30 1w 2s -
+
+# Full names
+R f 0 1 - Ja Friday>=1 1w 2s -
+R f 0 1 - Ja Monday<=1 1w 2s -
+R f 0 1 - Ja Saturday>=31 1w 2s -
+R f 0 1 - Ja Sunday<=31 1w 2s -
+R f 0 1 - Ja Thursday>=10 1w 2s -
+R f 0 1 - Ja Tuesday<=20 1w 2s -
+R f 0 1 - Ja Wednesday>=30 1w 2s -
+
+)"};
+
+ std::chrono::__tz::__constrained_weekday r;
+ assert(result.rules.size() == 3);
+ for (std::size_t i = 0; i < result.rules.size(); ++i) {
+ assert(result.rules[i].second.size() == 7);
+
+ r = std::get<std::chrono::__tz::__constrained_weekday>(result.rules[i].second[0].__on);
+ assert(r.__weekday == std::chrono::Friday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__ge);
+ assert(r.__day == std::chrono::day(1));
+
+ r = std::get<std::chrono::__tz::__constrained_weekday>(result.rules[i].second[1].__on);
+ assert(r.__weekday == std::chrono::Monday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__le);
+ assert(r.__day == std::chrono::day(1));
+
+ r = std::get<std::chrono::__tz::__constrained_weekday>(result.rules[i].second[2].__on);
+ assert(r.__weekday == std::chrono::Saturday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__ge);
+ assert(r.__day == std::chrono::day(31));
+
+ r = std::get<std::chrono::__tz::__constrained_weekday>(result.rules[i].second[3].__on);
+ assert(r.__weekday == std::chrono::Sunday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__le);
+ assert(r.__day == std::chrono::day(31));
+
+ r = std::get<std::chrono::__tz::__constrained_weekday>(result.rules[i].second[4].__on);
+ assert(r.__weekday == std::chrono::Thursday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__ge);
+ assert(r.__day == std::chrono::day(10));
+
+ r = std::get<std::chrono::__tz::__constrained_weekday>(result.rules[i].second[5].__on);
+ assert(r.__weekday == std::chrono::Tuesday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__le);
+ assert(r.__day == std::chrono::day(20));
+
+ r = std::get<std::chrono::__tz::__constrained_weekday>(result.rules[i].second[6].__on);
+ assert(r.__weekday == std::chrono::Wednesday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__ge);
+ assert(r.__day == std::chrono::day(30));
+ }
+}
+
+static void test_on() {
+ test_on_day();
+ test_on_last();
+ test_on_constrain();
+}
+
+static void test_at() {
+ parse_result result{
+ R"(
+# Based on the examples in the man page.
+# Note the input is not expected to have fractional seconds, they are truncated.
+R a 0 1 - Ja Su>=31 2w 2s -
+R a 0 1 - Ja Su>=31 2:00s 2s -
+R a 0 1 - Ja Su>=31 01:28:14u 2s -
+R a 0 1 - Ja Su>=31 00:19:32.10g 2s -
+R a 0 1 - Ja Su>=31 12:00z 2s -
+R a 0 1 - Ja Su>=31 15:00 2s -
+R a 0 1 - Ja Su>=31 24:00 2s -
+R a 0 1 - Ja Su>=31 260:00 2s -
+R a 0 1 - Ja Su>=31 -2:30 2s -
+R a 0 1 - Ja Su>=31 - 2s -
+)"};
+
+ assert(result.rules.size() == 1);
+ assert(result.rules[0].second.size() == 10);
+
+ assert(result.rules[0].second[0].__at.__time == std::chrono::hours(2));
+ assert(result.rules[0].second[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(result.rules[0].second[1].__at.__time == std::chrono::hours(2));
+ assert(result.rules[0].second[1].__at.__clock == std::chrono::__tz::__clock::__standard);
+
+ assert(result.rules[0].second[2].__at.__time ==
+ std::chrono::hours(1) + std::chrono::minutes(28) + std::chrono::seconds(14));
+ assert(result.rules[0].second[2].__at.__clock == std::chrono::__tz::__clock::__universal);
+
+ assert(result.rules[0].second[3].__at.__time == std::chrono::minutes(19) + std::chrono::seconds(32));
+ assert(result.rules[0].second[3].__at.__clock == std::chrono::__tz::__clock::__universal);
+
+ assert(result.rules[0].second[4].__at.__time == std::chrono::hours(12));
+ assert(result.rules[0].second[4].__at.__clock == std::chrono::__tz::__clock::__universal);
+
+ assert(result.rules[0].second[5].__at.__time == std::chrono::hours(15));
+ assert(result.rules[0].second[5].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(result.rules[0].second[6].__at.__time == std::chrono::hours(24));
+ assert(result.rules[0].second[6].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(result.rules[0].second[7].__at.__time == std::chrono::hours(260));
+ assert(result.rules[0].second[7].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(result.rules[0].second[8].__at.__time == -(std::chrono::hours(2) + std::chrono::minutes(30)));
+ assert(result.rules[0].second[8].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(result.rules[0].second[9].__at.__time == std::chrono::hours(0)); // The man page expresses it in hours
+ assert(result.rules[0].second[9].__at.__clock == std::chrono::__tz::__clock::__local);
+}
+
+static void test_save() {
+ parse_result result{
+ R"(
+R a 0 1 - Ja Su>=31 1w 2d -
+R a 0 1 - Ja Su>=31 1w 2:00s -
+R a 0 1 - Ja Su>=31 1w 0 -
+R a 0 1 - Ja Su>=31 1w 0:00:01 -
+R a 0 1 - Ja Su>=31 1w -0:00:01 -
+)"};
+
+ assert(result.rules.size() == 1);
+ assert(result.rules[0].second.size() == 5);
+
+ assert(result.rules[0].second[0].__save.__time == std::chrono::hours(2));
+ assert(result.rules[0].second[0].__save.__is_dst == true);
+
+ assert(result.rules[0].second[1].__save.__time == std::chrono::hours(2));
+ assert(result.rules[0].second[1].__save.__is_dst == false);
+
+ assert(result.rules[0].second[2].__save.__time == std::chrono::hours(0));
+ assert(result.rules[0].second[2].__save.__is_dst == false);
+
+ assert(result.rules[0].second[3].__save.__time == std::chrono::seconds(1));
+ assert(result.rules[0].second[3].__save.__is_dst == true);
+
+ assert(result.rules[0].second[4].__save.__time == -std::chrono::seconds(1));
+ assert(result.rules[0].second[4].__save.__is_dst == true);
+}
+
+static void test_letter() {
+ parse_result result{
+ R"(
+R a 0 1 - Ja Su>=31 1w 2s -
+R a 0 1 - Ja Su>=31 1w 2s a
+R a 0 1 - Ja Su>=31 1w 2s abc
+)"};
+
+ assert(result.rules.size() == 1);
+ assert(result.rules[0].second.size() == 3);
+
+ assert(result.rules[0].second[0].__letters == "");
+ assert(result.rules[0].second[1].__letters == "a");
+ assert(result.rules[0].second[2].__letters == "abc");
+}
+
+static void test_mixed_order() {
+ // This is a part of the real database. The interesting part is that the
+ // rules NZ and Chatham are interleaved. Make sure the parse algorithm
+ // handles this correctly.
+ parse_result result{
+ R"(
+# Since 1957 Chatham has been 45 minutes ahead of NZ, but until 2018a
+# there was no documented single notation for the date and time of this
+# transition. Duplicate the Rule lines for now, to give the 2018a change
+# time to percolate out.
+Rule NZ 1974 only - Nov Sun>=1 2:00s 1:00 D
+Rule Chatham 1974 only - Nov Sun>=1 2:45s 1:00 -
+Rule NZ 1975 only - Feb lastSun 2:00s 0 S
+Rule Chatham 1975 only - Feb lastSun 2:45s 0 -
+Rule NZ 1975 1988 - Oct lastSun 2:00s 1:00 D
+Rule Chatham 1975 1988 - Oct lastSun 2:45s 1:00 -
+)"};
+
+ assert(result.rules.size() == 2);
+ assert(result.rules[0].second.size() == 3);
+ assert(result.rules[1].second.size() == 3);
+}
+
+int main(int, const char**) {
+ test_invalid();
+ test_name();
+ test_from();
+ test_to();
+ test_in();
+ test_on();
+ test_at();
+ test_save();
+ test_letter();
+ test_mixed_order();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.list/erase_after.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.list/erase_after.pass.cpp
new file mode 100644
index 0000000000000..92842800f6bbd
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.list/erase_after.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
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+//
+// class tzdb_list;
+//
+// const_iterator erase_after(const_iterator p);
+
+#include <cassert>
+#include <chrono>
+#include <fstream>
+#include <iterator>
+
+#include "filesystem_test_helper.h"
+#include "test_macros.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path data = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) { std::ofstream{data}.write(input.data(), input.size()); }
+
+int main(int, const char**) {
+ write("# version 1");
+ std::chrono::tzdb_list& list = std::chrono::get_tzdb_list(); // [1]
+
+ write("# version 2");
+ std::chrono::reload_tzdb(); // [2, 1]
+
+ assert(std::distance(list.begin(), list.end()) == 2);
+ assert(list.front().version == "2");
+
+ list.erase_after(list.begin()); // [2]
+ assert(std::distance(list.begin(), list.end()) == 1);
+ assert(list.front().version == "2");
+
+ write("# version 3");
+ std::chrono::reload_tzdb(); // [3, 2]
+ assert(std::distance(list.begin(), list.end()) == 2);
+
+ write("# version 4");
+ std::chrono::reload_tzdb(); // [4, 3, 2]
+ assert(std::distance(list.begin(), list.end()) == 3);
+ assert(list.front().version == "4");
+
+ std::chrono::tzdb_list::const_iterator it = ++list.begin();
+ assert(it->version == "3");
+
+ list.erase_after(it); // [4, 3]
+ assert(std::distance(list.begin(), list.end()) == 2);
+ assert(list.front().version == "4");
+ assert(it->version == "3");
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.pass.cpp
new file mode 100644
index 0000000000000..5da4c7eea11b4
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.remote/reload_tzdb.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
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// const tzdb& reload_tzdb();
+
+#include <cassert>
+#include <chrono>
+#include <fstream>
+#include <iterator>
+
+#include "filesystem_test_helper.h"
+#include "test_macros.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path data = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) { std::ofstream{data}.write(input.data(), input.size()); }
+
+int main(int, const char**) {
+ write("# version old_version");
+ const std::chrono::tzdb_list& list = std::chrono::get_tzdb_list();
+ std::string version = "new_version";
+
+ assert(list.front().version == "old_version");
+ assert(std::distance(list.begin(), list.end()) == 1);
+ assert(std::distance(list.cbegin(), list.cend()) == 1);
+
+ write("# version new_version");
+ assert(std::chrono::remote_version() == version);
+
+ std::chrono::reload_tzdb();
+
+ assert(std::distance(list.begin(), list.end()) == 2);
+ assert(std::distance(list.cbegin(), list.cend()) == 2);
+ assert(list.front().version == version);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
new file mode 100644
index 0000000000000..08c682964c374
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/time.zone.db.tzdb/locate_zone.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// struct tzdb
+
+// const time_zone* locate_zone(string_view tz_name) const;
+
+#include <cassert>
+#include <chrono>
+#include <fstream>
+#include <string_view>
+
+#include "test_macros.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{file};
+ f << "# version " << version++ << '\n';
+ f.write(input.data(), input.size());
+}
+
+static const std::chrono::tzdb& parse(std::string_view input) {
+ write(input);
+ return std::chrono::reload_tzdb();
+}
+
+int main(int, const char**) {
+ const std::chrono::tzdb& tzdb = parse(
+ R"(
+Z zone 0 r f
+L zone link
+L link link_to_link
+)");
+
+ {
+ const std::chrono::time_zone* tz = tzdb.locate_zone("zone");
+ assert(tz);
+ assert(tz->name() == "zone");
+ }
+ {
+ const std::chrono::time_zone* tz = tzdb.locate_zone("link");
+ assert(tz);
+ assert(tz->name() == "zone");
+ }
+
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ [[maybe_unused]] std::string_view what{"tzdb: requested time zone not found"};
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD tzdb.locate_zone("link_to_link"));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/version.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/version.pass.cpp
new file mode 100644
index 0000000000000..ca3a890f1fa54
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/version.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
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// Tests the IANA database version parsing.
+// This is not part of the public tzdb interface.
+
+#include <chrono>
+#include <cstdio>
+#include <fstream>
+#include <string_view>
+#include <string>
+
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path data = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void test(std::string_view input, std::string_view expected) {
+ std::ofstream{data}.write(input.data(), input.size());
+ std::string version = std::chrono::remote_version();
+
+ TEST_REQUIRE(
+ version == expected,
+ TEST_WRITE_CONCATENATED(
+ "\nInput ", input, "\nExpected version ", expected, "\nActual version ", version, '\n'));
+}
+
+static void test_exception(std::string_view input, [[maybe_unused]] std::string_view what) {
+ std::ofstream{data}.write(input.data(), input.size());
+
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD std::chrono::remote_version());
+}
+
+int main(int, const char**) {
+ test_exception("", std::string{"corrupt tzdb: expected character '#', got '"} + (char)EOF + "' instead");
+ test_exception("#version", "corrupt tzdb: expected whitespace");
+ test("#version \t ABCD", "ABCD");
+ test("#Version \t ABCD", "ABCD");
+ test("#vErsion \t ABCD", "ABCD");
+ test("#verSion \t ABCD", "ABCD");
+ test("#VERSION \t ABCD", "ABCD");
+ test("# \t version \t 2023a", "2023a");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.db/zones.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/zones.pass.cpp
new file mode 100644
index 0000000000000..ded89ed808e17
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.db/zones.pass.cpp
@@ -0,0 +1,380 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// Tests the IANA database zones parsing and operations.
+// This is not part of the public tzdb interface.
+// The test uses private implementation headers.
+// ADDITIONAL_COMPILE_FLAGS: -I %{libcxx-dir}/src/experimental/include
+
+#include <cassert>
+#include <chrono>
+#include <fstream>
+#include <string>
+#include <string_view>
+#include <variant>
+
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+// headers in the dylib
+#include "tzdb/types_private.h"
+#include "tzdb/tzdb_private.h"
+#include "tzdb/time_zone_private.h"
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{file};
+ f << "# version " << version++ << '\n';
+ f.write(input.data(), input.size());
+}
+
+static const std::chrono::tzdb& parse(std::string_view input) {
+ write(input);
+ return std::chrono::reload_tzdb();
+}
+
+static const std::vector<std::chrono::__tz::__continuation>& continuations(const std::chrono::time_zone& time_zone) {
+ return time_zone.__implementation().__continuations();
+}
+
+static void test_exception(std::string_view input, [[maybe_unused]] std::string_view what) {
+ write(input);
+
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD std::chrono::reload_tzdb());
+}
+
+static void test_invalid() {
+ test_exception("Z", "corrupt tzdb: expected whitespace");
+
+ test_exception("Z ", "corrupt tzdb: expected a string");
+
+ test_exception("Z n", "corrupt tzdb: expected whitespace");
+
+ test_exception("Z n ", "corrupt tzdb: expected a digit");
+ test_exception("Z n x", "corrupt tzdb: expected a digit");
+ test_exception("Z n +", "corrupt tzdb: expected a digit");
+
+ test_exception("Z n 0", "corrupt tzdb: expected whitespace");
+
+ test_exception("Z n 0 ", "corrupt tzdb: expected a string");
+
+ test_exception("Z n 0 r", "corrupt tzdb: expected whitespace");
+
+ test_exception("Z n 0 r ", "corrupt tzdb: expected a string");
+}
+
+static void test_name() {
+ const std::chrono::tzdb& result = parse(
+ R"(
+Z n 0 r f
+)");
+ assert(result.zones.size() == 1);
+ assert(result.zones[0].name() == "n");
+}
+
+static void test_stdoff() {
+ const std::chrono::tzdb& result = parse(
+ R"(
+# Based on the examples in the man page.
+# Note the input is not expected to have fractional seconds, they are truncated.
+Zo na 2 r f
+Zon nb 2:00 r f
+Zone nc 01:28:14 r f
+zONE nd 00:19:32.10 r f
+zoNe ne 12:00 r f
+Z nf 15:00 r f
+Z ng 24:00 r f
+Z nh 260:00 r f
+Z ni -2:30 r f
+Z nj - r f
+)");
+
+ assert(result.zones.size() == 10);
+ for (std::size_t i = 0; i < result.zones.size(); ++i)
+ assert(continuations(result.zones[0]).size() == 1);
+
+ assert(continuations(result.zones[0])[0].__stdoff == std::chrono::hours(2));
+ assert(continuations(result.zones[1])[0].__stdoff == std::chrono::hours(2));
+ assert(continuations(result.zones[2])[0].__stdoff ==
+ std::chrono::hours(1) + std::chrono::minutes(28) + std::chrono::seconds(14));
+ assert(continuations(result.zones[3])[0].__stdoff == std::chrono::minutes(19) + std::chrono::seconds(32));
+ assert(continuations(result.zones[4])[0].__stdoff == std::chrono::hours(12));
+ assert(continuations(result.zones[5])[0].__stdoff == std::chrono::hours(15));
+ assert(continuations(result.zones[6])[0].__stdoff == std::chrono::hours(24));
+ assert(continuations(result.zones[7])[0].__stdoff == std::chrono::hours(260));
+ assert(continuations(result.zones[8])[0].__stdoff == -(std::chrono::hours(2) + std::chrono::minutes(30)));
+ assert(continuations(result.zones[9])[0].__stdoff == std::chrono::hours(0)); // The man page expresses it in hours
+}
+
+static void test_rules() {
+ const std::chrono::tzdb& result = parse(
+ R"(
+Z na 0 - f
+Z nb 0 r f
+Z nc 0 2d f
+Z nd 0 2:00s f
+Z ne 0 0 f
+Z nf 0 0:00:01 f
+Z ng 0 -0:00:01 f
+)");
+
+ assert(result.zones.size() == 7);
+ for (std::size_t i = 0; i < result.zones.size(); ++i)
+ assert(continuations(result.zones[0]).size() == 1);
+
+ assert(std::holds_alternative<std::monostate>(continuations(result.zones[0])[0].__rules));
+ assert(std::get<std::string>(continuations(result.zones[1])[0].__rules) == "r");
+
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[2])[0].__rules).__time ==
+ std::chrono::hours(2));
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[2])[0].__rules).__is_dst == true);
+
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[3])[0].__rules).__time ==
+ std::chrono::hours(2));
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[3])[0].__rules).__is_dst == false);
+
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[4])[0].__rules).__time ==
+ std::chrono::hours(0));
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[4])[0].__rules).__is_dst == false);
+
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[5])[0].__rules).__time ==
+ std::chrono::seconds(1));
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[5])[0].__rules).__is_dst == true);
+
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[6])[0].__rules).__time ==
+ -std::chrono::seconds(1));
+ assert(std::get<std::chrono::__tz::__save>(continuations(result.zones[6])[0].__rules).__is_dst == true);
+}
+
+static void test_format() {
+ const std::chrono::tzdb& result = parse(
+ R"(
+Z n 0 r f
+)");
+ assert(result.zones.size() == 1);
+ assert(continuations(result.zones[0]).size() == 1);
+ assert(continuations(result.zones[0])[0].__format == "f");
+}
+
+static void test_until() {
+ const std::chrono::tzdb& result = parse(
+ R"(
+Z na 0 r f
+Z nb 0 r f 1000
+Z nc 0 r f -1000 N
+Z nd 0 r f ma S 31
+Z ne 0 r f 0 jA LASTw
+Z nf 0 r f -42 jUN m<=1
+Z ng 0 r f 42 jul Su>=12
+Z nh 0 r f 42 JUl 1 2w
+Z ni 0 r f 42 July 1 01:28:14u
+Z nj 0 r f 42 Jul 1 -
+)");
+ assert(result.zones.size() == 10);
+ for (std::size_t i = 0; i < result.zones.size(); ++i)
+ assert(continuations(result.zones[0]).size() == 1);
+
+ std::chrono::__tz::__constrained_weekday r;
+
+ assert(continuations(result.zones[0])[0].__year == std::chrono::year::min());
+ assert(continuations(result.zones[0])[0].__in == std::chrono::January);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[0].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[0])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[1])[0].__year == std::chrono::year(1000));
+ assert(continuations(result.zones[1])[0].__in == std::chrono::January);
+ assert(std::get<std::chrono::day>(continuations(result.zones[1])[0].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[1])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[1])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[2])[0].__year == std::chrono::year(-1000));
+ assert(continuations(result.zones[2])[0].__in == std::chrono::November);
+ assert(std::get<std::chrono::day>(continuations(result.zones[2])[0].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[2])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[2])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[3])[0].__year == std::chrono::year::max());
+ assert(continuations(result.zones[3])[0].__in == std::chrono::September);
+ assert(std::get<std::chrono::day>(continuations(result.zones[3])[0].__on) == std::chrono::day(31));
+ assert(continuations(result.zones[3])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[3])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[4])[0].__year == std::chrono::year(0));
+ assert(continuations(result.zones[4])[0].__in == std::chrono::January);
+ assert(std::get<std::chrono::weekday_last>(continuations(result.zones[4])[0].__on) ==
+ std::chrono::weekday_last{std::chrono::Wednesday});
+ assert(continuations(result.zones[4])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[4])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[5])[0].__year == std::chrono::year(-42));
+ assert(continuations(result.zones[5])[0].__in == std::chrono::June);
+ r = std::get<std::chrono::__tz::__constrained_weekday>(continuations(result.zones[5])[0].__on);
+ assert(r.__weekday == std::chrono::Monday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__le);
+ assert(r.__day == std::chrono::day(1));
+ assert(continuations(result.zones[5])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[5])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[6])[0].__year == std::chrono::year(42));
+ assert(continuations(result.zones[6])[0].__in == std::chrono::July);
+ r = std::get<std::chrono::__tz::__constrained_weekday>(continuations(result.zones[6])[0].__on);
+ assert(r.__weekday == std::chrono::Sunday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__ge);
+ assert(r.__day == std::chrono::day(12));
+ assert(continuations(result.zones[6])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[6])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[7])[0].__year == std::chrono::year(42));
+ assert(continuations(result.zones[7])[0].__in == std::chrono::July);
+ assert(std::get<std::chrono::day>(continuations(result.zones[7])[0].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[7])[0].__at.__time == std::chrono::hours(2));
+ assert(continuations(result.zones[7])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[8])[0].__year == std::chrono::year(42));
+ assert(continuations(result.zones[8])[0].__in == std::chrono::July);
+ assert(std::get<std::chrono::day>(continuations(result.zones[8])[0].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[8])[0].__at.__time ==
+ std::chrono::hours(1) + std::chrono::minutes(28) + std::chrono::seconds(14));
+ assert(continuations(result.zones[8])[0].__at.__clock == std::chrono::__tz::__clock::__universal);
+
+ assert(continuations(result.zones[9])[0].__year == std::chrono::year(42));
+ assert(continuations(result.zones[9])[0].__in == std::chrono::July);
+ assert(std::get<std::chrono::day>(continuations(result.zones[9])[0].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[9])[0].__at.__time == std::chrono::hours(0)); // The man page expresses it in hours
+ assert(continuations(result.zones[9])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+}
+
+static void test_continuation() {
+ const std::chrono::tzdb& result = parse(
+ R"(
+Z na 0 r f
+0 r f 1000
+0 r f -1000 N
+0 r f ma S 31
+0 r f 0 Ja lastW
+0 r f -42 Jun M<=1
+0 r f 42 Jul Su>=12
+0 r f 42 Jul 1 2w
+0 r f 42 Jul 1 01:28:14u
+0 r f 42 Jul 1 -
+)");
+
+ assert(result.zones.size() == 1);
+ assert(continuations(result.zones[0]).size() == 10);
+
+ std::chrono::__tz::__constrained_weekday r;
+
+ assert(continuations(result.zones[0])[0].__year == std::chrono::year::min());
+ assert(continuations(result.zones[0])[0].__in == std::chrono::January);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[0].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[0])[0].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[0].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[1].__year == std::chrono::year(1000));
+ assert(continuations(result.zones[0])[1].__in == std::chrono::January);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[1].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[0])[1].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[1].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[2].__year == std::chrono::year(-1000));
+ assert(continuations(result.zones[0])[2].__in == std::chrono::November);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[2].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[0])[2].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[2].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[3].__year == std::chrono::year::max());
+ assert(continuations(result.zones[0])[3].__in == std::chrono::September);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[3].__on) == std::chrono::day(31));
+ assert(continuations(result.zones[0])[3].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[3].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[4].__year == std::chrono::year(0));
+ assert(continuations(result.zones[0])[4].__in == std::chrono::January);
+ assert(std::get<std::chrono::weekday_last>(continuations(result.zones[0])[4].__on) ==
+ std::chrono::weekday_last{std::chrono::Wednesday});
+ assert(continuations(result.zones[0])[4].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[4].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[5].__year == std::chrono::year(-42));
+ assert(continuations(result.zones[0])[5].__in == std::chrono::June);
+ r = std::get<std::chrono::__tz::__constrained_weekday>(continuations(result.zones[0])[5].__on);
+ assert(r.__weekday == std::chrono::Monday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__le);
+ assert(r.__day == std::chrono::day(1));
+ assert(continuations(result.zones[0])[5].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[5].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[6].__year == std::chrono::year(42));
+ assert(continuations(result.zones[0])[6].__in == std::chrono::July);
+ r = std::get<std::chrono::__tz::__constrained_weekday>(continuations(result.zones[0])[6].__on);
+ assert(r.__weekday == std::chrono::Sunday);
+ assert(r.__comparison == std::chrono::__tz::__constrained_weekday::__ge);
+ assert(r.__day == std::chrono::day(12));
+ assert(continuations(result.zones[0])[6].__at.__time == std::chrono::seconds(0));
+ assert(continuations(result.zones[0])[6].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[7].__year == std::chrono::year(42));
+ assert(continuations(result.zones[0])[7].__in == std::chrono::July);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[7].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[0])[7].__at.__time == std::chrono::hours(2));
+ assert(continuations(result.zones[0])[7].__at.__clock == std::chrono::__tz::__clock::__local);
+
+ assert(continuations(result.zones[0])[8].__year == std::chrono::year(42));
+ assert(continuations(result.zones[0])[8].__in == std::chrono::July);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[8].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[0])[8].__at.__time ==
+ std::chrono::hours(1) + std::chrono::minutes(28) + std::chrono::seconds(14));
+ assert(continuations(result.zones[0])[8].__at.__clock == std::chrono::__tz::__clock::__universal);
+
+ assert(continuations(result.zones[0])[9].__year == std::chrono::year(42));
+ assert(continuations(result.zones[0])[9].__in == std::chrono::July);
+ assert(std::get<std::chrono::day>(continuations(result.zones[0])[9].__on) == std::chrono::day(1));
+ assert(continuations(result.zones[0])[9].__at.__time == std::chrono::hours(0)); // The man page expresses it in hours
+ assert(continuations(result.zones[0])[9].__at.__clock == std::chrono::__tz::__clock::__local);
+}
+
+int main(int, const char**) {
+ test_invalid();
+ test_name();
+ test_stdoff();
+ test_rules();
+ test_format();
+ test_until();
+
+ test_continuation();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
new file mode 100644
index 0000000000000..73e6bf2846f0e
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.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
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+
+// <chrono>
+
+// class ambiguous_local_time
+//
+// template<class Duration>
+// ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// [time.zone.exception.ambig]/2
+// Preconditions: i.result == local_info::ambiguous is true.
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (std::chrono::ambiguous_local_time{
+ std::chrono::local_seconds{},
+ std::chrono::local_info{-1, // this is not one of the "named" result values
+ std::chrono::sys_info{},
+ std::chrono::sys_info{}}}),
+ "creating an ambiguous_local_time from a local_info that is not ambiguous");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (std::chrono::ambiguous_local_time{
+ std::chrono::local_seconds{},
+ std::chrono::local_info{std::chrono::local_info::unique, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
+ "creating an ambiguous_local_time from a local_info that is not ambiguous");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (std::chrono::ambiguous_local_time{
+ std::chrono::local_seconds{},
+ std::chrono::local_info{
+ std::chrono::local_info::nonexistent, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
+ "creating an ambiguous_local_time from a local_info that is not ambiguous");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
new file mode 100644
index 0000000000000..fdd9f79958f98
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.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
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+
+// <chrono>
+
+// class nonexistent_local_time
+//
+// template<class Duration>
+// nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// [time.zone.exception.nonexist]/2
+// Preconditions: i.result == local_info::nonexistent is true.
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (std::chrono::nonexistent_local_time{
+ std::chrono::local_seconds{},
+ std::chrono::local_info{-1, // this is not one of the "named" result values
+ std::chrono::sys_info{},
+ std::chrono::sys_info{}}}),
+ "creating an nonexistent_local_time from a local_info that is not non-existent");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (std::chrono::nonexistent_local_time{
+ std::chrono::local_seconds{},
+ std::chrono::local_info{std::chrono::local_info::unique, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
+ "creating an nonexistent_local_time from a local_info that is not non-existent");
+
+ TEST_LIBCPP_ASSERT_FAILURE(
+ (std::chrono::nonexistent_local_time{
+ std::chrono::local_seconds{},
+ std::chrono::local_info{
+ std::chrono::local_info::ambiguous, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
+ "creating an nonexistent_local_time from a local_info that is not non-existent");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.local/ostream.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.local/ostream.pass.cpp
new file mode 100644
index 0000000000000..b3fbaaf30aaec
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.local/ostream.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
+// UNSUPPORTED: no-localization
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+
+// <chrono>
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const local_info& r);
+
+// [time.zone.info.local]
+// 7 Effects: Streams out the local_info object r in an unspecified format.
+// 8 Returns: os.
+//
+// Tests the output produced by this function.
+
+#include <cassert>
+#include <chrono>
+#include <memory>
+#include <sstream>
+
+#include "assert_macros.h"
+#include "test_macros.h"
+#include "make_string.h"
+#include "concat_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test(std::basic_string_view<CharT> expected, std::chrono::local_info&& info) {
+ std::basic_stringstream<CharT> sstr;
+ sstr << info;
+ std::basic_string<CharT> output = sstr.str();
+
+ TEST_REQUIRE(expected == output,
+ TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", output, '\n'));
+}
+
+template <class CharT>
+static void test() {
+ using namespace std::literals::chrono_literals;
+ namespace tz = std::chrono;
+ // result values matching the "known" results
+ test(SV("unique: "
+ "{[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\", "
+ "[1970-01-01 00:00:00, 1970-01-01 00:00:00) 00:00:00 0min \"\"}"),
+ tz::local_info{tz::local_info::unique,
+ tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"},
+ tz::sys_info{}});
+
+ test(SV("non-existent: "
+ "{[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min \"NEG\", "
+ "[1970-01-01 00:00:00, 2038-12-31 00:00:00) -12:23:45 67min \"POS\"}"),
+ tz::local_info{
+ tz::local_info::nonexistent,
+ tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
+ static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
+ 12h + 23min + 45s,
+ -67min,
+ "NEG"},
+ tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
+ static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
+ -(12h + 23min + 45s),
+ 67min,
+ "POS"}});
+
+ test(SV("ambiguous: "
+ "{[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min \"NEG\", "
+ "[1970-01-01 00:00:00, 2038-12-31 00:00:00) -12:23:45 67min \"POS\"}"),
+ tz::local_info{
+ tz::local_info::ambiguous,
+ tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
+ static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
+ 12h + 23min + 45s,
+ -67min,
+ "NEG"},
+ tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
+ static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
+ -(12h + 23min + 45s),
+ 67min,
+ "POS"}});
+
+ // result values not matching the "known" results
+ test(
+ SV("unspecified result (-1): "
+ "{[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\", "
+ "[1970-01-01 00:00:00, 1970-01-01 00:00:00) 00:00:00 0min \"\"}"),
+ tz::local_info{-1, tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"}, tz::sys_info{}});
+ test(SV("unspecified result (3): "
+ "{[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\", "
+ "[1970-01-01 00:00:00, 1970-01-01 00:00:00) 00:00:00 0min \"\"}"),
+ tz::local_info{3, tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"}, tz::sys_info{}});
+}
+
+int main(int, const char**) {
+ test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp
new file mode 100644
index 0000000000000..6b41c7bdf2344
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.info/time.zone.info.sys/ostream.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
+// UNSUPPORTED: no-localization
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+
+// <chrono>
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const sys_info& r);
+
+// [time.zone.info.sys]
+// 7 Effects: Streams out the sys_info object r in an unspecified format.
+// 8 Returns: os.
+//
+// Tests the output produced by this function.
+
+#include <cassert>
+#include <chrono>
+#include <memory>
+#include <sstream>
+
+#include "assert_macros.h"
+#include "test_macros.h"
+#include "make_string.h"
+#include "concat_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test(std::basic_string_view<CharT> expected, std::chrono::sys_info&& info) {
+ std::basic_stringstream<CharT> sstr;
+ sstr << info;
+ std::basic_string<CharT> output = sstr.str();
+
+ TEST_REQUIRE(expected == output,
+ TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", output, '\n'));
+}
+
+template <class CharT>
+static void test() {
+ using namespace std::literals::chrono_literals;
+ namespace tz = std::chrono;
+
+ test(SV("[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\""),
+ tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"});
+
+ test(SV("[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min \"DMY\""),
+ tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
+ static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
+ 12h + 23min + 45s,
+ -67min,
+ "DMY"});
+}
+
+int main(int, const char**) {
+ test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/choose.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/choose.pass.cpp
new file mode 100644
index 0000000000000..23ef9c8480960
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/choose.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// enum class choose;
+
+#include <chrono>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ using E = std::chrono::choose;
+ static_assert(std::is_enum_v<E>);
+
+ // Check that E is a scoped enum by checking for conversions.
+ using UT = std::underlying_type_t<E>;
+ static_assert(!std::is_convertible_v<E, UT>);
+
+ [[maybe_unused]] const E& early = E::earliest;
+ [[maybe_unused]] const E& late = E::latest;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
new file mode 100644
index 0000000000000..d9ca1c80751cc
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// template <class _Duration>
+// local_time<common_type_t<Duration, seconds>>
+// to_local(const sys_time<Duration>& tp) const;
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// Tests values that cannot be converted. To make sure the test is does not depend on changes
+// in the database it uses a time zone with a fixed offset.
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(std::chrono::locate_zone("Etc/GMT+1")->to_local(std::chrono::sys_seconds::min()),
+ "cannot convert the system time; it would be before the minimum local clock value");
+
+ // TODO TZDB look why std::chrono::sys_seconds::max() fails
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::locate_zone("Etc/GMT-1")->to_local(std::chrono::sys_seconds::max() - std::chrono::seconds(1)),
+ "cannot convert the system time; it would be after the maximum local clock value");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
new file mode 100644
index 0000000000000..3a2ff00088676
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.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
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+
+// <chrono>
+
+// template <class _Duration>
+// sys_time<common_type_t<Duration, seconds>>
+// to_sys(const local_time<Duration>& tp) const;
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// Tests values that cannot be converted. To make sure the test is does not depend on changes
+// in the database it uses a time zone with a fixed offset.
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(std::chrono::locate_zone("Etc/GMT-1")->to_sys(std::chrono::local_seconds::min()),
+ "cannot convert the local time; it would be before the minimum system clock value");
+
+ // TODO TZDB look why std::chrono::local_seconds::max() fails
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::locate_zone("Etc/GMT+1")->to_sys(std::chrono::local_seconds::max() - std::chrono::seconds(1)),
+ "cannot convert the local time; it would be after the maximum system clock value");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
new file mode 100644
index 0000000000000..65429345ae794
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+
+// <chrono>
+
+// template <class _Duration>
+// sys_time<common_type_t<Duration, seconds>>
+// to_sys(const local_time<Duration>& tp, choose z) const;
+
+#include <chrono>
+
+#include "check_assertion.h"
+
+// Tests values that cannot be converted. To make sure the test is does not depend on changes
+// in the database it uses a time zone with a fixed offset.
+int main(int, char**) {
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::locate_zone("Etc/GMT-1")->to_sys(std::chrono::local_seconds::min(), std::chrono::choose::earliest),
+ "cannot convert the local time; it would be before the minimum system clock value");
+
+ // TODO TZDB look why std::chrono::local_seconds::max() fails
+ TEST_LIBCPP_ASSERT_FAILURE(
+ std::chrono::locate_zone("Etc/GMT+1")
+ ->to_sys(std::chrono::local_seconds::max() - std::chrono::seconds(1), std::chrono::choose::latest),
+ "cannot convert the local time; it would be after the maximum system clock value");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.pass.cpp
new file mode 100644
index 0000000000000..afd1273421f39
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.pass.cpp
@@ -0,0 +1,204 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// class time_zone;
+
+// template <class _Duration>
+// sys_info get_info(const sys_time<_Duration>& time) const;
+
+// tests the parts not validated in the public test
+// - Validates a zone with an UNTIL in its last continuation is corrupt
+// - The formatting of the FORMAT field's constrains
+// - Formatting of "%z", this is valid but not present in the actual database
+
+#include <algorithm>
+#include <cassert>
+#include <fstream>
+#include <chrono>
+#include <format>
+
+#include "test_macros.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+/***** ***** HELPERS ***** *****/
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{file};
+ f << "# version " << version++ << '\n';
+ f.write(input.data(), input.size());
+}
+
+static const std::chrono::tzdb& parse(std::string_view input) {
+ write(input);
+ return std::chrono::reload_tzdb();
+}
+
+[[nodiscard]] static std::chrono::sys_seconds to_sys_seconds(int year) {
+ std::chrono::year_month_day result{std::chrono::year{year}, std::chrono::January, std::chrono::day{1}};
+
+ return std::chrono::time_point_cast<std::chrono::seconds>(static_cast<std::chrono::sys_days>(result));
+}
+
+static void test_exception([[maybe_unused]] std::string_view input, [[maybe_unused]] std::string_view what) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ const std::chrono::tzdb& tzdb = parse(input);
+ const std::chrono::time_zone* tz = tzdb.locate_zone("Format");
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD tz->get_info(to_sys_seconds(2000)));
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+static void zone_without_until_entry() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ const std::chrono::tzdb& tzdb = parse(
+ R"(
+Z America/Paramaribo -3:40:40 - LMT 1911
+-3:40:52 - PMT 1935
+-3:40:36 - PMT 1945 O
+-3:30 - -0330 1984 O
+# -3 - -03 Commented out so the last entry has an UNTIL field.
+)");
+ const std::chrono::time_zone* tz = tzdb.locate_zone("America/Paramaribo");
+
+ TEST_IGNORE_NODISCARD tz->get_info(to_sys_seconds(1984));
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ std::string what = "tzdb: corrupt db";
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD tz->get_info(to_sys_seconds(1985)));
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+static void invalid_format() {
+ test_exception(
+ R"(
+R F 2000 max - Jan 5 0 0 foo
+Z Format 0 F %zandfoo)",
+ "corrupt tzdb FORMAT field: %z should be the entire contents, instead contains '%zandfoo'");
+
+ test_exception(
+ R"(
+R F 2000 max - Jan 5 0 0 foo
+Z Format 0 F %q)",
+ "corrupt tzdb FORMAT field: invalid sequence '%q' found, expected %s or %z");
+
+ test_exception(
+ R"(
+R F 2000 max - Jan 5 0 0 foo
+Z Format 0 F !)",
+ "corrupt tzdb FORMAT field: invalid character '!' found, expected +, -, or an alphanumeric value");
+
+ test_exception(
+ R"(
+R F 2000 max - Jan 5 0 0 foo
+Z Format 0 F @)",
+ "corrupt tzdb FORMAT field: invalid character '@' found, expected +, -, or an alphanumeric value");
+
+ test_exception(
+ R"(
+R F 2000 max - Jan 5 0 0 foo
+Z Format 0 F $)",
+ "corrupt tzdb FORMAT field: invalid character '$' found, expected +, -, or an alphanumeric value");
+
+ test_exception(
+ R"(
+R F 1970 max - Jan 5 0 0 foo
+Z Format 0 F %)",
+ "corrupt tzdb FORMAT field: input ended with the start of the escape sequence '%'");
+
+ test_exception(
+ R"(
+R F 2000 max - Jan 5 0 0 -
+Z Format 0 F %s)",
+ "corrupt tzdb FORMAT field: result is empty");
+}
+
+static void test_abbrev(std::string_view input, std::string_view expected) {
+ const std::chrono::tzdb& tzdb = parse(input);
+ const std::chrono::time_zone* tz = tzdb.locate_zone("Format");
+ std::string result = tz->get_info(to_sys_seconds(2000)).abbrev;
+ TEST_LIBCPP_REQUIRE(result == expected, TEST_WRITE_CONCATENATED("\nExpected ", expected, "\nActual ", result, '\n'));
+}
+
+static void percentage_z_format() {
+ test_abbrev(
+ R"(
+R F 1999 max - Jan 5 0 0 foo
+Z Format 0 F %z)",
+ "+00");
+
+ test_abbrev(
+ R"(
+R F 1999 max - Jan 5 0 1 foo
+Z Format 0 F %z)",
+ "+01");
+
+ test_abbrev(
+ R"(
+R F 1999 max - Jan 5 0 -1 foo
+Z Format 0 F %z)",
+ "-01");
+
+ test_abbrev(
+ R"(
+R F 1999 max - Jan 5 0 0 foo
+Z Format 0:45 F %z)",
+ "+0045");
+
+ test_abbrev(
+ R"(
+R F 1999 max - Jan 5 0 -1 foo
+Z Format 0:45 F %z)",
+ "-0015");
+
+ test_abbrev(
+ R"(
+Z Format -1:2:20 - LMT 1912 Ja 1 1u
+-1 - %z)",
+ "-01");
+}
+
+int main(int, const char**) {
+ zone_without_until_entry();
+ invalid_format();
+ percentage_z_format();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.rule_selection.pass.cpp b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.rule_selection.pass.cpp
new file mode 100644
index 0000000000000..33c5d0499bca8
--- /dev/null
+++ b/libcxx/test/libcxx-03/time/time.zone/time.zone.timezone/time.zone.members/get_info.sys_time.rule_selection.pass.cpp
@@ -0,0 +1,185 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: no-filesystem, no-localization, no-tzdb
+
+// XFAIL: libcpp-has-no-experimental-tzdb
+// XFAIL: availability-tzdb-missing
+
+// <chrono>
+
+// class time_zone;
+
+// template <class _Duration>
+// sys_info get_info(const sys_time<_Duration>& time) const;
+
+// The time zone database contains of the following entries
+// - Zones,
+// - Rules,
+// - Links, and
+// - Leapseconds.
+//
+// The public tzdb struct stores all entries except the Rules. How
+// implementations keep track of the Rules is not specified. When the sys_info
+// for a time_zone is requested it needs to use the correct Rules. This lookup
+// cannot rely on 'get_tzdb()` since that returns the most recently loaded
+// database.
+//
+// A reload could change the rules of a time zone or the time zone could no
+// longer be present in the current database. These two conditions are tested.
+//
+// It is possible the tzdb entry has been removed by the user from the tzdb_list
+// after a reload. This is UB and not tested.
+
+#include <cassert>
+#include <fstream>
+#include <chrono>
+
+#include "test_macros.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
+#include "filesystem_test_helper.h"
+#include "test_tzdb.h"
+
+/***** ***** HELPERS ***** *****/
+
+scoped_test_env env;
+[[maybe_unused]] const std::filesystem::path dir = env.create_dir("zoneinfo");
+const std::filesystem::path file = env.create_file("zoneinfo/tzdata.zi");
+
+std::string_view std::chrono::__libcpp_tzdb_directory() {
+ static std::string result = dir.string();
+ return result;
+}
+
+static void write(std::string_view input) {
+ static int version = 0;
+
+ std::ofstream f{file};
+ f << "# version " << version++ << '\n';
+ f.write(input.data(), input.size());
+}
+
+static const std::chrono::tzdb& parse(std::string_view input) {
+ write(input);
+ return std::chrono::reload_tzdb();
+}
+
+[[nodiscard]] static std::chrono::sys_seconds to_sys_seconds(
+ std::chrono::year year,
+ std::chrono::month month,
+ std::chrono::day day,
+ std::chrono::hours h = std::chrono::hours(0),
+ std::chrono::minutes m = std::chrono::minutes{0},
+ std::chrono::seconds s = std::chrono::seconds{0}) {
+ std::chrono::year_month_day result{year, month, day};
+
+ return std::chrono::time_point_cast<std::chrono::seconds>(static_cast<std::chrono::sys_days>(result)) + h + m + s;
+}
+
+static void assert_equal(const std::chrono::sys_info& lhs, const std::chrono::sys_info& rhs) {
+ TEST_REQUIRE(lhs.begin == rhs.begin,
+ TEST_WRITE_CONCATENATED("\nBegin:\nExpected output ", lhs.begin, "\nActual output ", rhs.begin, '\n'));
+ TEST_REQUIRE(lhs.end == rhs.end,
+ TEST_WRITE_CONCATENATED("\nEnd:\nExpected output ", lhs.end, "\nActual output ", rhs.end, '\n'));
+ TEST_REQUIRE(
+ lhs.offset == rhs.offset,
+ TEST_WRITE_CONCATENATED("\nOffset:\nExpected output ", lhs.offset, "\nActual output ", rhs.offset, '\n'));
+ TEST_REQUIRE(lhs.save == rhs.save,
+ TEST_WRITE_CONCATENATED("\nSave:\nExpected output ", lhs.save, "\nActual output ", rhs.save, '\n'));
+ TEST_REQUIRE(
+ lhs.abbrev == rhs.abbrev,
+ TEST_WRITE_CONCATENATED("\nAbbrev:\nExpected output ", lhs.abbrev, "\nActual output ", rhs.abbrev, '\n'));
+}
+
+/***** ***** TESTS ***** *****/
+
+int main(int, const char**) {
+ using namespace std::literals::chrono_literals;
+
+ // DST starts on the first of March.
+ const std::chrono::tzdb& tzdb_1 = parse(
+ R"(
+Z Test 0 - LMT 1900
+0 Rule %s
+
+R Rule 1900 max - Mar 1 2u 1 Summer
+R Rule 1900 max - Oct 1 2u 0 Winter
+)");
+
+ const std::chrono::time_zone* tz_1 = tzdb_1.locate_zone("Test");
+ assert_equal(
+ std::chrono::sys_info(
+ to_sys_seconds(1901y, std::chrono::March, 1d, 2h),
+ to_sys_seconds(1901y, std::chrono::October, 1d, 2h),
+ 1h,
+ 60min,
+ "Summer"),
+ tz_1->get_info(to_sys_seconds(1901y, std::chrono::March, 1d, 2h)));
+
+ // The DST start changes from the first of March to the first of April.
+ const std::chrono::tzdb& tzdb_2 = parse(
+ R"(
+Z Test 0 - LMT 1900
+0 Rule %s
+
+R Rule 1900 max - Apr 1 2u 1 Summer
+R Rule 1900 max - Oct 1 2u 0 Winter
+)");
+
+ const std::chrono::time_zone* tz_2 = tzdb_2.locate_zone("Test");
+ assert_equal(
+ std::chrono::sys_info(
+ to_sys_seconds(1900y, std::chrono::October, 1d, 2h),
+ to_sys_seconds(1901y, std::chrono::April, 1d, 2h),
+ 0s,
+ 0min,
+ "Winter"),
+ tz_2->get_info(to_sys_seconds(1901y, std::chrono::March, 1d, 2h)));
+
+ // Validate when using tz_1 the DST still starts on the first of March.
+ assert_equal(
+ std::chrono::sys_info(
+ to_sys_seconds(1901y, std::chrono::March, 1d, 2h),
+ to_sys_seconds(1901y, std::chrono::October, 1d, 2h),
+ 1h,
+ 60min,
+ "Summer"),
+ tz_1->get_info(to_sys_seconds(1901y, std::chrono::March, 1d, 2h)));
+
+ // The zone Test is no longer present
+ [[maybe_unused]] const std::chrono::tzdb& tzdb_3 = parse("Z Etc/UTC 0 - UTC");
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ TEST_VALIDATE_EXCEPTION(
+ std::runtime_error,
+ [&]([[maybe_unused]] const std::runtime_error& e) {
+ std::string what = "tzdb: requested time zone not found";
+ TEST_LIBCPP_REQUIRE(
+ e.what() == what,
+ TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n'));
+ },
+ TEST_IGNORE_NODISCARD tzdb_3.locate_zone("Test"));
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+ // Search the zone Test in the original version 1 of the TZDB.
+ // This database should be unaffected by the removal in version 3.
+ tz_1 = tzdb_1.locate_zone("Test");
+
+ // Validate the rules still uses version 1's DST switch in March.
+ assert_equal(
+ std::chrono::sys_info(
+ to_sys_seconds(1901y, std::chrono::March, 1d, 2h),
+ to_sys_seconds(1901y, std::chrono::October, 1d, 2h),
+ 1h,
+ 60min,
+ "Summer"),
+ tz_1->get_info(to_sys_seconds(1901y, std::chrono::March, 1d, 2h)));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/transitive_includes.gen.py b/libcxx/test/libcxx-03/transitive_includes.gen.py
new file mode 100644
index 0000000000000..6f99240436632
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes.gen.py
@@ -0,0 +1,102 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that we don't remove transitive includes of public C++ headers in the library accidentally.
+# When we remove a transitive public include, clients tend to break because they don't always
+# properly include what they use. Note that we don't check which system (C) headers are
+# included transitively, because that is too unstable across platforms, and hence difficult
+# to test for.
+#
+# This is not meant to block libc++ from removing unused transitive includes
+# forever, however we do try to group removals for a couple of releases
+# to avoid breaking users at every release.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+# block Lit from interpreting a RUN/XFAIL/etc inside the generation script
+# END.
+
+import sys
+sys.path.append(sys.argv[1])
+from libcxx.header_information import lit_header_restrictions, public_headers
+
+import re
+
+# To re-generate the list of expected headers, temporarily set this to True, and run this test.
+# Note that this needs to be done for all supported language versions of libc++:
+# for std in c++03 c++11 c++14 c++17 c++20 c++23 c++26; do <build>/bin/llvm-lit --param std=$std libcxx/test/libcxx/transitive_includes.gen.py; done
+regenerate_expected_results = False
+
+if regenerate_expected_results:
+ print(
+ f"""\
+//--- generate-transitive-includes.sh.cpp
+// RUN: mkdir %t
+"""
+ )
+
+ all_traces = []
+ for header in sorted(public_headers):
+ if header.is_C_compatibility() or header.is_internal():
+ continue
+
+ normalized_header = re.sub("/", "_", str(header))
+ print(
+ f"""\
+// RUN: echo "#include <{header}>" | %{{cxx}} -xc++ - %{{flags}} %{{compile_flags}} --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.{normalized_header}.txt
+"""
+ )
+ all_traces.append(f"%t/trace-includes.{normalized_header}.txt")
+
+ print(
+ f"""\
+// RUN: %{{python}} %{{libcxx-dir}}/test/libcxx/transitive_includes/to_csv.py {' '.join(all_traces)} > %{{libcxx-dir}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv
+"""
+ )
+
+else:
+ for header in public_headers:
+ if header.is_C_compatibility() or header.is_internal():
+ continue
+
+ # Escape slashes for the awk command below
+ escaped_header = str(header).replace("/", "\\/")
+
+ print(
+ f"""\
+//--- {header}.sh.cpp
+{lit_header_restrictions.get(header, '')}
+
+// TODO: Fix this test to make it work with localization or wide characters disabled
+// UNSUPPORTED: no-localization, no-wide-characters, no-threads, no-filesystem, libcpp-has-no-experimental-tzdb
+
+// When built with modules, this test doesn't work because --trace-includes doesn't
+// report the stack of includes correctly.
+// UNSUPPORTED: clang-modules-build
+
+// This test uses --trace-includes, which is not supported by GCC.
+// UNSUPPORTED: gcc
+
+// This test is not supported when we remove the transitive includes provided for backwards
+// compatibility. When we bulk-remove them, we'll adjust the includes that are expected by
+// this test instead.
+// UNSUPPORTED: transitive-includes-disabled
+
+// TODO: Figure out why <stdatomic.h> doesn't work on FreeBSD
+// UNSUPPORTED: LIBCXX-FREEBSD-FIXME
+
+// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
+
+// RUN: mkdir %t
+// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.txt
+// RUN: %{{python}} %{{libcxx-dir}}/test/libcxx/transitive_includes/to_csv.py %t/trace-includes.txt > %t/actual_transitive_includes.csv
+// RUN: cat %{{libcxx-dir}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv | awk '/^{escaped_header} / {{ print }}' > %t/expected_transitive_includes.csv
+// RUN: diff -w %t/expected_transitive_includes.csv %t/actual_transitive_includes.csv
+#include <{header}>
+"""
+ )
diff --git a/libcxx/test/libcxx-03/transitive_includes/cxx03.csv b/libcxx/test/libcxx-03/transitive_includes/cxx03.csv
new file mode 100644
index 0000000000000..c0031543e47bc
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/cxx03.csv
@@ -0,0 +1,2568 @@
+algorithm atomic
+algorithm bit
+algorithm cctype
+algorithm climits
+algorithm cmath
+algorithm compare
+algorithm concepts
+algorithm cstddef
+algorithm cstdint
+algorithm cstdio
+algorithm cstdlib
+algorithm cstring
+algorithm ctime
+algorithm cwchar
+algorithm cwctype
+algorithm exception
+algorithm initializer_list
+algorithm iosfwd
+algorithm iterator
+algorithm limits
+algorithm memory
+algorithm new
+algorithm optional
+algorithm ratio
+algorithm stdexcept
+algorithm tuple
+algorithm type_traits
+algorithm typeinfo
+algorithm utility
+algorithm variant
+algorithm version
+any algorithm
+any array
+any atomic
+any bit
+any cctype
+any cerrno
+any chrono
+any climits
+any clocale
+any cmath
+any compare
+any concepts
+any cstdarg
+any cstddef
+any cstdint
+any cstdio
+any cstdlib
+any cstring
+any ctime
+any cwchar
+any cwctype
+any exception
+any forward_list
+any functional
+any initializer_list
+any ios
+any iosfwd
+any iterator
+any limits
+any locale
+any memory
+any mutex
+any new
+any optional
+any ratio
+any stdexcept
+any streambuf
+any string
+any string_view
+any system_error
+any tuple
+any type_traits
+any typeinfo
+any unordered_map
+any utility
+any variant
+any vector
+any version
+array algorithm
+array atomic
+array bit
+array cctype
+array climits
+array cmath
+array compare
+array concepts
+array cstddef
+array cstdint
+array cstdio
+array cstdlib
+array cstring
+array ctime
+array cwchar
+array cwctype
+array exception
+array initializer_list
+array iosfwd
+array iterator
+array limits
+array memory
+array new
+array optional
+array ratio
+array stdexcept
+array tuple
+array type_traits
+array typeinfo
+array utility
+array variant
+array version
+atomic climits
+atomic cmath
+atomic compare
+atomic cstddef
+atomic cstdint
+atomic cstdlib
+atomic cstring
+atomic ctime
+atomic limits
+atomic ratio
+atomic type_traits
+atomic version
+barrier atomic
+barrier climits
+barrier cmath
+barrier compare
+barrier concepts
+barrier cstddef
+barrier cstdint
+barrier cstdlib
+barrier cstring
+barrier ctime
+barrier exception
+barrier initializer_list
+barrier iosfwd
+barrier iterator
+barrier limits
+barrier memory
+barrier new
+barrier ratio
+barrier stdexcept
+barrier tuple
+barrier type_traits
+barrier typeinfo
+barrier utility
+barrier variant
+barrier version
+bit cstdint
+bit cstdlib
+bit iosfwd
+bit limits
+bit type_traits
+bit version
+bitset algorithm
+bitset atomic
+bitset bit
+bitset cctype
+bitset climits
+bitset cmath
+bitset compare
+bitset concepts
+bitset cstddef
+bitset cstdint
+bitset cstdio
+bitset cstdlib
+bitset cstring
+bitset ctime
+bitset cwchar
+bitset cwctype
+bitset exception
+bitset initializer_list
+bitset iosfwd
+bitset iterator
+bitset limits
+bitset memory
+bitset new
+bitset optional
+bitset ratio
+bitset stdexcept
+bitset string
+bitset string_view
+bitset tuple
+bitset type_traits
+bitset typeinfo
+bitset utility
+bitset variant
+bitset version
+ccomplex algorithm
+ccomplex array
+ccomplex atomic
+ccomplex bit
+ccomplex bitset
+ccomplex cctype
+ccomplex cerrno
+ccomplex climits
+ccomplex clocale
+ccomplex cmath
+ccomplex compare
+ccomplex complex
+ccomplex concepts
+ccomplex cstdarg
+ccomplex cstddef
+ccomplex cstdint
+ccomplex cstdio
+ccomplex cstdlib
+ccomplex cstring
+ccomplex ctime
+ccomplex cwchar
+ccomplex cwctype
+ccomplex deque
+ccomplex exception
+ccomplex format
+ccomplex functional
+ccomplex initializer_list
+ccomplex ios
+ccomplex iosfwd
+ccomplex istream
+ccomplex iterator
+ccomplex limits
+ccomplex locale
+ccomplex memory
+ccomplex mutex
+ccomplex new
+ccomplex optional
+ccomplex ostream
+ccomplex print
+ccomplex queue
+ccomplex ratio
+ccomplex sstream
+ccomplex stack
+ccomplex stdexcept
+ccomplex streambuf
+ccomplex string
+ccomplex string_view
+ccomplex system_error
+ccomplex tuple
+ccomplex type_traits
+ccomplex typeinfo
+ccomplex unordered_map
+ccomplex utility
+ccomplex variant
+ccomplex vector
+ccomplex version
+charconv cmath
+charconv concepts
+charconv cstddef
+charconv cstdint
+charconv cstdlib
+charconv cstring
+charconv iosfwd
+charconv limits
+charconv new
+charconv type_traits
+charconv version
+chrono algorithm
+chrono array
+chrono atomic
+chrono bit
+chrono cctype
+chrono cerrno
+chrono climits
+chrono clocale
+chrono cmath
+chrono compare
+chrono concepts
+chrono cstdarg
+chrono cstddef
+chrono cstdint
+chrono cstdio
+chrono cstdlib
+chrono cstring
+chrono ctime
+chrono cwchar
+chrono cwctype
+chrono exception
+chrono forward_list
+chrono functional
+chrono initializer_list
+chrono ios
+chrono iosfwd
+chrono iterator
+chrono limits
+chrono locale
+chrono memory
+chrono mutex
+chrono new
+chrono optional
+chrono ratio
+chrono stdexcept
+chrono streambuf
+chrono string
+chrono string_view
+chrono system_error
+chrono tuple
+chrono type_traits
+chrono typeinfo
+chrono unordered_map
+chrono utility
+chrono variant
+chrono vector
+chrono version
+cinttypes cstdint
+cmath cstdint
+cmath limits
+cmath type_traits
+cmath version
+codecvt algorithm
+codecvt atomic
+codecvt bit
+codecvt cctype
+codecvt cerrno
+codecvt climits
+codecvt clocale
+codecvt cmath
+codecvt compare
+codecvt concepts
+codecvt cstddef
+codecvt cstdint
+codecvt cstdio
+codecvt cstdlib
+codecvt cstring
+codecvt ctime
+codecvt cwchar
+codecvt cwctype
+codecvt exception
+codecvt initializer_list
+codecvt iosfwd
+codecvt iterator
+codecvt limits
+codecvt memory
+codecvt mutex
+codecvt new
+codecvt optional
+codecvt ratio
+codecvt stdexcept
+codecvt string
+codecvt string_view
+codecvt system_error
+codecvt tuple
+codecvt type_traits
+codecvt typeinfo
+codecvt utility
+codecvt variant
+codecvt version
+compare cmath
+compare cstddef
+compare cstdint
+compare limits
+compare type_traits
+compare version
+complex algorithm
+complex array
+complex atomic
+complex bit
+complex bitset
+complex cctype
+complex cerrno
+complex climits
+complex clocale
+complex cmath
+complex compare
+complex concepts
+complex cstdarg
+complex cstddef
+complex cstdint
+complex cstdio
+complex cstdlib
+complex cstring
+complex ctime
+complex cwchar
+complex cwctype
+complex deque
+complex exception
+complex format
+complex functional
+complex initializer_list
+complex ios
+complex iosfwd
+complex istream
+complex iterator
+complex limits
+complex locale
+complex memory
+complex mutex
+complex new
+complex optional
+complex ostream
+complex print
+complex queue
+complex ratio
+complex sstream
+complex stack
+complex stdexcept
+complex streambuf
+complex string
+complex string_view
+complex system_error
+complex tuple
+complex type_traits
+complex typeinfo
+complex unordered_map
+complex utility
+complex variant
+complex vector
+complex version
+concepts cstddef
+concepts cstdint
+concepts type_traits
+concepts version
+condition_variable algorithm
+condition_variable atomic
+condition_variable bit
+condition_variable cctype
+condition_variable cerrno
+condition_variable climits
+condition_variable cmath
+condition_variable compare
+condition_variable concepts
+condition_variable cstddef
+condition_variable cstdint
+condition_variable cstdio
+condition_variable cstdlib
+condition_variable cstring
+condition_variable ctime
+condition_variable cwchar
+condition_variable cwctype
+condition_variable exception
+condition_variable initializer_list
+condition_variable iosfwd
+condition_variable iterator
+condition_variable limits
+condition_variable memory
+condition_variable new
+condition_variable optional
+condition_variable ratio
+condition_variable stdexcept
+condition_variable string
+condition_variable string_view
+condition_variable system_error
+condition_variable tuple
+condition_variable type_traits
+condition_variable typeinfo
+condition_variable utility
+condition_variable variant
+condition_variable version
+coroutine cmath
+coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine iosfwd
+coroutine limits
+coroutine type_traits
+coroutine version
+cstddef version
+ctgmath algorithm
+ctgmath array
+ctgmath atomic
+ctgmath bit
+ctgmath bitset
+ctgmath cctype
+ctgmath cerrno
+ctgmath climits
+ctgmath clocale
+ctgmath cmath
+ctgmath compare
+ctgmath complex
+ctgmath concepts
+ctgmath cstdarg
+ctgmath cstddef
+ctgmath cstdint
+ctgmath cstdio
+ctgmath cstdlib
+ctgmath cstring
+ctgmath ctime
+ctgmath cwchar
+ctgmath cwctype
+ctgmath deque
+ctgmath exception
+ctgmath format
+ctgmath functional
+ctgmath initializer_list
+ctgmath ios
+ctgmath iosfwd
+ctgmath istream
+ctgmath iterator
+ctgmath limits
+ctgmath locale
+ctgmath memory
+ctgmath mutex
+ctgmath new
+ctgmath optional
+ctgmath ostream
+ctgmath print
+ctgmath queue
+ctgmath ratio
+ctgmath sstream
+ctgmath stack
+ctgmath stdexcept
+ctgmath streambuf
+ctgmath string
+ctgmath string_view
+ctgmath system_error
+ctgmath tuple
+ctgmath type_traits
+ctgmath typeinfo
+ctgmath unordered_map
+ctgmath utility
+ctgmath variant
+ctgmath vector
+ctgmath version
+cwchar cctype
+cwchar cstddef
+cwchar cwctype
+cwchar version
+cwctype cctype
+deque algorithm
+deque array
+deque atomic
+deque bit
+deque cctype
+deque cerrno
+deque climits
+deque clocale
+deque cmath
+deque compare
+deque concepts
+deque cstdarg
+deque cstddef
+deque cstdint
+deque cstdio
+deque cstdlib
+deque cstring
+deque ctime
+deque cwchar
+deque cwctype
+deque exception
+deque functional
+deque initializer_list
+deque ios
+deque iosfwd
+deque iterator
+deque limits
+deque locale
+deque memory
+deque mutex
+deque new
+deque optional
+deque ratio
+deque stdexcept
+deque streambuf
+deque string
+deque string_view
+deque system_error
+deque tuple
+deque type_traits
+deque typeinfo
+deque unordered_map
+deque utility
+deque variant
+deque vector
+deque version
+exception cstddef
+exception cstdint
+exception cstdlib
+exception new
+exception type_traits
+exception typeinfo
+exception version
+execution cstddef
+execution version
+expected version
+experimental/iterator algorithm
+experimental/iterator atomic
+experimental/iterator bit
+experimental/iterator bitset
+experimental/iterator cctype
+experimental/iterator cerrno
+experimental/iterator climits
+experimental/iterator clocale
+experimental/iterator cmath
+experimental/iterator compare
+experimental/iterator concepts
+experimental/iterator cstdarg
+experimental/iterator cstddef
+experimental/iterator cstdint
+experimental/iterator cstdio
+experimental/iterator cstdlib
+experimental/iterator cstring
+experimental/iterator ctime
+experimental/iterator cwchar
+experimental/iterator cwctype
+experimental/iterator exception
+experimental/iterator initializer_list
+experimental/iterator ios
+experimental/iterator iosfwd
+experimental/iterator iterator
+experimental/iterator limits
+experimental/iterator locale
+experimental/iterator memory
+experimental/iterator mutex
+experimental/iterator new
+experimental/iterator optional
+experimental/iterator ratio
+experimental/iterator stdexcept
+experimental/iterator streambuf
+experimental/iterator string
+experimental/iterator string_view
+experimental/iterator system_error
+experimental/iterator tuple
+experimental/iterator type_traits
+experimental/iterator typeinfo
+experimental/iterator utility
+experimental/iterator variant
+experimental/iterator version
+experimental/memory cstddef
+experimental/memory cstdint
+experimental/memory cstring
+experimental/memory limits
+experimental/memory type_traits
+experimental/memory version
+experimental/propagate_const cstddef
+experimental/propagate_const cstdint
+experimental/propagate_const type_traits
+experimental/propagate_const version
+experimental/simd cstddef
+experimental/simd cstdint
+experimental/simd limits
+experimental/simd type_traits
+experimental/simd version
+experimental/utility cmath
+experimental/utility compare
+experimental/utility cstddef
+experimental/utility cstdint
+experimental/utility cstdlib
+experimental/utility initializer_list
+experimental/utility iosfwd
+experimental/utility limits
+experimental/utility type_traits
+experimental/utility utility
+experimental/utility version
+filesystem algorithm
+filesystem atomic
+filesystem bit
+filesystem cctype
+filesystem cerrno
+filesystem climits
+filesystem cmath
+filesystem compare
+filesystem concepts
+filesystem cstddef
+filesystem cstdint
+filesystem cstdio
+filesystem cstdlib
+filesystem cstring
+filesystem ctime
+filesystem cwchar
+filesystem cwctype
+filesystem exception
+filesystem initializer_list
+filesystem iosfwd
+filesystem iterator
+filesystem limits
+filesystem memory
+filesystem new
+filesystem optional
+filesystem ratio
+filesystem stdexcept
+filesystem string
+filesystem string_view
+filesystem system_error
+filesystem tuple
+filesystem type_traits
+filesystem typeinfo
+filesystem utility
+filesystem variant
+filesystem version
+flat_map cmath
+flat_map compare
+flat_map cstddef
+flat_map cstdint
+flat_map initializer_list
+flat_map limits
+flat_map type_traits
+flat_map version
+flat_set cmath
+flat_set compare
+flat_set cstddef
+flat_set cstdint
+flat_set initializer_list
+flat_set limits
+flat_set type_traits
+flat_set version
+format algorithm
+format array
+format atomic
+format bit
+format cctype
+format cerrno
+format climits
+format clocale
+format cmath
+format compare
+format concepts
+format cstdarg
+format cstddef
+format cstdint
+format cstdio
+format cstdlib
+format cstring
+format ctime
+format cwchar
+format cwctype
+format deque
+format exception
+format functional
+format initializer_list
+format ios
+format iosfwd
+format iterator
+format limits
+format locale
+format memory
+format mutex
+format new
+format optional
+format queue
+format ratio
+format stack
+format stdexcept
+format streambuf
+format string
+format string_view
+format system_error
+format tuple
+format type_traits
+format typeinfo
+format unordered_map
+format utility
+format variant
+format vector
+format version
+forward_list algorithm
+forward_list array
+forward_list atomic
+forward_list bit
+forward_list cctype
+forward_list cerrno
+forward_list climits
+forward_list clocale
+forward_list cmath
+forward_list compare
+forward_list concepts
+forward_list cstdarg
+forward_list cstddef
+forward_list cstdint
+forward_list cstdio
+forward_list cstdlib
+forward_list cstring
+forward_list ctime
+forward_list cwchar
+forward_list cwctype
+forward_list exception
+forward_list functional
+forward_list initializer_list
+forward_list ios
+forward_list iosfwd
+forward_list iterator
+forward_list limits
+forward_list locale
+forward_list memory
+forward_list mutex
+forward_list new
+forward_list optional
+forward_list ratio
+forward_list stdexcept
+forward_list streambuf
+forward_list string
+forward_list string_view
+forward_list system_error
+forward_list tuple
+forward_list type_traits
+forward_list typeinfo
+forward_list unordered_map
+forward_list utility
+forward_list variant
+forward_list vector
+forward_list version
+fstream algorithm
+fstream array
+fstream atomic
+fstream bit
+fstream bitset
+fstream cctype
+fstream cerrno
+fstream climits
+fstream clocale
+fstream cmath
+fstream compare
+fstream concepts
+fstream cstdarg
+fstream cstddef
+fstream cstdint
+fstream cstdio
+fstream cstdlib
+fstream cstring
+fstream ctime
+fstream cwchar
+fstream cwctype
+fstream deque
+fstream exception
+fstream filesystem
+fstream format
+fstream functional
+fstream initializer_list
+fstream iomanip
+fstream ios
+fstream iosfwd
+fstream istream
+fstream iterator
+fstream limits
+fstream locale
+fstream memory
+fstream mutex
+fstream new
+fstream optional
+fstream ostream
+fstream print
+fstream queue
+fstream ratio
+fstream stack
+fstream stdexcept
+fstream streambuf
+fstream string
+fstream string_view
+fstream system_error
+fstream tuple
+fstream type_traits
+fstream typeinfo
+fstream unordered_map
+fstream utility
+fstream variant
+fstream vector
+fstream version
+functional algorithm
+functional array
+functional atomic
+functional bit
+functional cctype
+functional cerrno
+functional climits
+functional clocale
+functional cmath
+functional compare
+functional concepts
+functional cstdarg
+functional cstddef
+functional cstdint
+functional cstdio
+functional cstdlib
+functional cstring
+functional ctime
+functional cwchar
+functional cwctype
+functional exception
+functional initializer_list
+functional ios
+functional iosfwd
+functional iterator
+functional limits
+functional locale
+functional memory
+functional mutex
+functional new
+functional optional
+functional ratio
+functional stdexcept
+functional streambuf
+functional string
+functional string_view
+functional system_error
+functional tuple
+functional type_traits
+functional typeinfo
+functional unordered_map
+functional utility
+functional variant
+functional vector
+functional version
+future algorithm
+future array
+future atomic
+future bit
+future bitset
+future cctype
+future cerrno
+future chrono
+future climits
+future clocale
+future cmath
+future compare
+future concepts
+future cstdarg
+future cstddef
+future cstdint
+future cstdio
+future cstdlib
+future cstring
+future ctime
+future cwchar
+future cwctype
+future deque
+future exception
+future format
+future forward_list
+future functional
+future initializer_list
+future ios
+future iosfwd
+future istream
+future iterator
+future limits
+future locale
+future memory
+future mutex
+future new
+future optional
+future ostream
+future print
+future queue
+future ratio
+future sstream
+future stack
+future stdexcept
+future streambuf
+future string
+future string_view
+future system_error
+future thread
+future tuple
+future type_traits
+future typeinfo
+future unordered_map
+future utility
+future variant
+future vector
+future version
+initializer_list cstddef
+initializer_list version
+iomanip algorithm
+iomanip array
+iomanip atomic
+iomanip bit
+iomanip bitset
+iomanip cctype
+iomanip cerrno
+iomanip climits
+iomanip clocale
+iomanip cmath
+iomanip compare
+iomanip concepts
+iomanip cstdarg
+iomanip cstddef
+iomanip cstdint
+iomanip cstdio
+iomanip cstdlib
+iomanip cstring
+iomanip ctime
+iomanip cwchar
+iomanip cwctype
+iomanip deque
+iomanip exception
+iomanip format
+iomanip functional
+iomanip initializer_list
+iomanip ios
+iomanip iosfwd
+iomanip istream
+iomanip iterator
+iomanip limits
+iomanip locale
+iomanip memory
+iomanip mutex
+iomanip new
+iomanip optional
+iomanip ostream
+iomanip print
+iomanip queue
+iomanip ratio
+iomanip stack
+iomanip stdexcept
+iomanip streambuf
+iomanip string
+iomanip string_view
+iomanip system_error
+iomanip tuple
+iomanip type_traits
+iomanip typeinfo
+iomanip unordered_map
+iomanip utility
+iomanip variant
+iomanip vector
+iomanip version
+ios algorithm
+ios atomic
+ios bit
+ios cctype
+ios cerrno
+ios climits
+ios clocale
+ios cmath
+ios compare
+ios concepts
+ios cstddef
+ios cstdint
+ios cstdio
+ios cstdlib
+ios cstring
+ios ctime
+ios cwchar
+ios cwctype
+ios exception
+ios initializer_list
+ios iosfwd
+ios iterator
+ios limits
+ios memory
+ios mutex
+ios new
+ios optional
+ios ratio
+ios stdexcept
+ios string
+ios string_view
+ios system_error
+ios tuple
+ios type_traits
+ios typeinfo
+ios utility
+ios variant
+ios version
+iosfwd version
+iostream algorithm
+iostream array
+iostream atomic
+iostream bit
+iostream bitset
+iostream cctype
+iostream cerrno
+iostream climits
+iostream clocale
+iostream cmath
+iostream compare
+iostream concepts
+iostream cstdarg
+iostream cstddef
+iostream cstdint
+iostream cstdio
+iostream cstdlib
+iostream cstring
+iostream ctime
+iostream cwchar
+iostream cwctype
+iostream deque
+iostream exception
+iostream format
+iostream functional
+iostream initializer_list
+iostream ios
+iostream iosfwd
+iostream istream
+iostream iterator
+iostream limits
+iostream locale
+iostream memory
+iostream mutex
+iostream new
+iostream optional
+iostream ostream
+iostream print
+iostream queue
+iostream ratio
+iostream stack
+iostream stdexcept
+iostream streambuf
+iostream string
+iostream string_view
+iostream system_error
+iostream tuple
+iostream type_traits
+iostream typeinfo
+iostream unordered_map
+iostream utility
+iostream variant
+iostream vector
+iostream version
+istream algorithm
+istream array
+istream atomic
+istream bit
+istream bitset
+istream cctype
+istream cerrno
+istream climits
+istream clocale
+istream cmath
+istream compare
+istream concepts
+istream cstdarg
+istream cstddef
+istream cstdint
+istream cstdio
+istream cstdlib
+istream cstring
+istream ctime
+istream cwchar
+istream cwctype
+istream deque
+istream exception
+istream format
+istream functional
+istream initializer_list
+istream ios
+istream iosfwd
+istream iterator
+istream limits
+istream locale
+istream memory
+istream mutex
+istream new
+istream optional
+istream ostream
+istream print
+istream queue
+istream ratio
+istream stack
+istream stdexcept
+istream streambuf
+istream string
+istream string_view
+istream system_error
+istream tuple
+istream type_traits
+istream typeinfo
+istream unordered_map
+istream utility
+istream variant
+istream vector
+istream version
+iterator cctype
+iterator cmath
+iterator compare
+iterator concepts
+iterator cstddef
+iterator cstdint
+iterator cstdio
+iterator cstdlib
+iterator cstring
+iterator cwchar
+iterator cwctype
+iterator exception
+iterator initializer_list
+iterator iosfwd
+iterator limits
+iterator new
+iterator tuple
+iterator type_traits
+iterator typeinfo
+iterator utility
+iterator variant
+iterator version
+latch atomic
+latch climits
+latch cmath
+latch compare
+latch cstddef
+latch cstdint
+latch cstdlib
+latch cstring
+latch ctime
+latch limits
+latch ratio
+latch type_traits
+latch version
+limits cstdint
+limits type_traits
+limits version
+list algorithm
+list array
+list atomic
+list bit
+list cctype
+list cerrno
+list climits
+list clocale
+list cmath
+list compare
+list concepts
+list cstdarg
+list cstddef
+list cstdint
+list cstdio
+list cstdlib
+list cstring
+list ctime
+list cwchar
+list cwctype
+list exception
+list functional
+list initializer_list
+list ios
+list iosfwd
+list iterator
+list limits
+list locale
+list memory
+list mutex
+list new
+list optional
+list ratio
+list stdexcept
+list streambuf
+list string
+list string_view
+list system_error
+list tuple
+list type_traits
+list typeinfo
+list unordered_map
+list utility
+list variant
+list vector
+list version
+locale algorithm
+locale atomic
+locale bit
+locale cctype
+locale cerrno
+locale climits
+locale clocale
+locale cmath
+locale compare
+locale concepts
+locale cstdarg
+locale cstddef
+locale cstdint
+locale cstdio
+locale cstdlib
+locale cstring
+locale ctime
+locale cwchar
+locale cwctype
+locale exception
+locale initializer_list
+locale ios
+locale iosfwd
+locale iterator
+locale limits
+locale memory
+locale mutex
+locale new
+locale optional
+locale ratio
+locale stdexcept
+locale streambuf
+locale string
+locale string_view
+locale system_error
+locale tuple
+locale type_traits
+locale typeinfo
+locale utility
+locale variant
+locale version
+map algorithm
+map array
+map atomic
+map bit
+map cctype
+map cerrno
+map climits
+map clocale
+map cmath
+map compare
+map concepts
+map cstdarg
+map cstddef
+map cstdint
+map cstdio
+map cstdlib
+map cstring
+map ctime
+map cwchar
+map cwctype
+map exception
+map functional
+map initializer_list
+map ios
+map iosfwd
+map iterator
+map limits
+map locale
+map memory
+map mutex
+map new
+map optional
+map ratio
+map stdexcept
+map streambuf
+map string
+map string_view
+map system_error
+map tuple
+map type_traits
+map typeinfo
+map unordered_map
+map utility
+map variant
+map vector
+map version
+mdspan version
+memory atomic
+memory cctype
+memory climits
+memory cmath
+memory compare
+memory concepts
+memory cstddef
+memory cstdint
+memory cstdio
+memory cstdlib
+memory cstring
+memory ctime
+memory cwchar
+memory cwctype
+memory exception
+memory initializer_list
+memory iosfwd
+memory iterator
+memory limits
+memory new
+memory ratio
+memory stdexcept
+memory tuple
+memory type_traits
+memory typeinfo
+memory utility
+memory variant
+memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource cstdlib
+memory_resource exception
+memory_resource iosfwd
+memory_resource new
+memory_resource stdexcept
+memory_resource type_traits
+memory_resource typeinfo
+memory_resource version
+mutex algorithm
+mutex atomic
+mutex bit
+mutex cctype
+mutex cerrno
+mutex climits
+mutex cmath
+mutex compare
+mutex concepts
+mutex cstddef
+mutex cstdint
+mutex cstdio
+mutex cstdlib
+mutex cstring
+mutex ctime
+mutex cwchar
+mutex cwctype
+mutex exception
+mutex initializer_list
+mutex iosfwd
+mutex iterator
+mutex limits
+mutex memory
+mutex new
+mutex optional
+mutex ratio
+mutex stdexcept
+mutex string
+mutex string_view
+mutex system_error
+mutex tuple
+mutex type_traits
+mutex typeinfo
+mutex utility
+mutex variant
+mutex version
+new cstddef
+new cstdint
+new cstdlib
+new type_traits
+new version
+numbers concepts
+numbers cstddef
+numbers cstdint
+numbers type_traits
+numbers version
+numeric algorithm
+numeric array
+numeric atomic
+numeric bit
+numeric cctype
+numeric cerrno
+numeric climits
+numeric clocale
+numeric cmath
+numeric compare
+numeric concepts
+numeric cstdarg
+numeric cstddef
+numeric cstdint
+numeric cstdio
+numeric cstdlib
+numeric cstring
+numeric ctime
+numeric cwchar
+numeric cwctype
+numeric exception
+numeric execution
+numeric functional
+numeric initializer_list
+numeric ios
+numeric iosfwd
+numeric iterator
+numeric limits
+numeric locale
+numeric memory
+numeric mutex
+numeric new
+numeric optional
+numeric ratio
+numeric stdexcept
+numeric streambuf
+numeric string
+numeric string_view
+numeric system_error
+numeric tuple
+numeric type_traits
+numeric typeinfo
+numeric unordered_map
+numeric utility
+numeric variant
+numeric vector
+numeric version
+optional atomic
+optional cctype
+optional climits
+optional cmath
+optional compare
+optional concepts
+optional cstddef
+optional cstdint
+optional cstdio
+optional cstdlib
+optional cstring
+optional ctime
+optional cwchar
+optional cwctype
+optional exception
+optional initializer_list
+optional iosfwd
+optional iterator
+optional limits
+optional memory
+optional new
+optional ratio
+optional stdexcept
+optional tuple
+optional type_traits
+optional typeinfo
+optional utility
+optional variant
+optional version
+ostream algorithm
+ostream array
+ostream atomic
+ostream bit
+ostream bitset
+ostream cctype
+ostream cerrno
+ostream climits
+ostream clocale
+ostream cmath
+ostream compare
+ostream concepts
+ostream cstdarg
+ostream cstddef
+ostream cstdint
+ostream cstdio
+ostream cstdlib
+ostream cstring
+ostream ctime
+ostream cwchar
+ostream cwctype
+ostream deque
+ostream exception
+ostream format
+ostream functional
+ostream initializer_list
+ostream ios
+ostream iosfwd
+ostream iterator
+ostream limits
+ostream locale
+ostream memory
+ostream mutex
+ostream new
+ostream optional
+ostream print
+ostream queue
+ostream ratio
+ostream stack
+ostream stdexcept
+ostream streambuf
+ostream string
+ostream string_view
+ostream system_error
+ostream tuple
+ostream type_traits
+ostream typeinfo
+ostream unordered_map
+ostream utility
+ostream variant
+ostream vector
+ostream version
+print algorithm
+print array
+print atomic
+print bit
+print cctype
+print cerrno
+print climits
+print clocale
+print cmath
+print compare
+print concepts
+print cstdarg
+print cstddef
+print cstdint
+print cstdio
+print cstdlib
+print cstring
+print ctime
+print cwchar
+print cwctype
+print deque
+print exception
+print format
+print functional
+print initializer_list
+print ios
+print iosfwd
+print iterator
+print limits
+print locale
+print memory
+print mutex
+print new
+print optional
+print queue
+print ratio
+print stack
+print stdexcept
+print streambuf
+print string
+print string_view
+print system_error
+print tuple
+print type_traits
+print typeinfo
+print unordered_map
+print utility
+print variant
+print vector
+print version
+queue algorithm
+queue array
+queue atomic
+queue bit
+queue cctype
+queue cerrno
+queue climits
+queue clocale
+queue cmath
+queue compare
+queue concepts
+queue cstdarg
+queue cstddef
+queue cstdint
+queue cstdio
+queue cstdlib
+queue cstring
+queue ctime
+queue cwchar
+queue cwctype
+queue deque
+queue exception
+queue functional
+queue initializer_list
+queue ios
+queue iosfwd
+queue iterator
+queue limits
+queue locale
+queue memory
+queue mutex
+queue new
+queue optional
+queue ratio
+queue stdexcept
+queue streambuf
+queue string
+queue string_view
+queue system_error
+queue tuple
+queue type_traits
+queue typeinfo
+queue unordered_map
+queue utility
+queue variant
+queue vector
+queue version
+random algorithm
+random array
+random atomic
+random bit
+random cctype
+random cerrno
+random climits
+random clocale
+random cmath
+random compare
+random concepts
+random cstdarg
+random cstddef
+random cstdint
+random cstdio
+random cstdlib
+random cstring
+random ctime
+random cwchar
+random cwctype
+random exception
+random execution
+random functional
+random initializer_list
+random ios
+random iosfwd
+random iterator
+random limits
+random locale
+random memory
+random mutex
+random new
+random numeric
+random optional
+random ratio
+random stdexcept
+random streambuf
+random string
+random string_view
+random system_error
+random tuple
+random type_traits
+random typeinfo
+random unordered_map
+random utility
+random variant
+random vector
+random version
+ranges cctype
+ranges cmath
+ranges compare
+ranges concepts
+ranges cstddef
+ranges cstdint
+ranges cstdio
+ranges cstdlib
+ranges cstring
+ranges cwchar
+ranges cwctype
+ranges exception
+ranges initializer_list
+ranges iosfwd
+ranges iterator
+ranges limits
+ranges new
+ranges tuple
+ranges type_traits
+ranges typeinfo
+ranges utility
+ranges variant
+ranges version
+ratio climits
+ratio cstdint
+ratio type_traits
+ratio version
+regex algorithm
+regex array
+regex atomic
+regex bit
+regex cctype
+regex cerrno
+regex climits
+regex clocale
+regex cmath
+regex compare
+regex concepts
+regex cstdarg
+regex cstddef
+regex cstdint
+regex cstdio
+regex cstdlib
+regex cstring
+regex ctime
+regex cwchar
+regex cwctype
+regex deque
+regex exception
+regex functional
+regex initializer_list
+regex ios
+regex iosfwd
+regex iterator
+regex limits
+regex locale
+regex memory
+regex mutex
+regex new
+regex optional
+regex ratio
+regex stdexcept
+regex streambuf
+regex string
+regex string_view
+regex system_error
+regex tuple
+regex type_traits
+regex typeinfo
+regex unordered_map
+regex utility
+regex variant
+regex vector
+regex version
+scoped_allocator atomic
+scoped_allocator cctype
+scoped_allocator climits
+scoped_allocator cmath
+scoped_allocator compare
+scoped_allocator concepts
+scoped_allocator cstddef
+scoped_allocator cstdint
+scoped_allocator cstdio
+scoped_allocator cstdlib
+scoped_allocator cstring
+scoped_allocator ctime
+scoped_allocator cwchar
+scoped_allocator cwctype
+scoped_allocator exception
+scoped_allocator initializer_list
+scoped_allocator iosfwd
+scoped_allocator iterator
+scoped_allocator limits
+scoped_allocator memory
+scoped_allocator new
+scoped_allocator ratio
+scoped_allocator stdexcept
+scoped_allocator tuple
+scoped_allocator type_traits
+scoped_allocator typeinfo
+scoped_allocator utility
+scoped_allocator variant
+scoped_allocator version
+semaphore atomic
+semaphore climits
+semaphore cmath
+semaphore compare
+semaphore cstddef
+semaphore cstdint
+semaphore cstdlib
+semaphore cstring
+semaphore ctime
+semaphore limits
+semaphore ratio
+semaphore type_traits
+semaphore version
+set algorithm
+set array
+set atomic
+set bit
+set cctype
+set cerrno
+set climits
+set clocale
+set cmath
+set compare
+set concepts
+set cstdarg
+set cstddef
+set cstdint
+set cstdio
+set cstdlib
+set cstring
+set ctime
+set cwchar
+set cwctype
+set exception
+set functional
+set initializer_list
+set ios
+set iosfwd
+set iterator
+set limits
+set locale
+set memory
+set mutex
+set new
+set optional
+set ratio
+set stdexcept
+set streambuf
+set string
+set string_view
+set system_error
+set tuple
+set type_traits
+set typeinfo
+set unordered_map
+set utility
+set variant
+set vector
+set version
+shared_mutex algorithm
+shared_mutex atomic
+shared_mutex bit
+shared_mutex cctype
+shared_mutex cerrno
+shared_mutex climits
+shared_mutex cmath
+shared_mutex compare
+shared_mutex concepts
+shared_mutex cstddef
+shared_mutex cstdint
+shared_mutex cstdio
+shared_mutex cstdlib
+shared_mutex cstring
+shared_mutex ctime
+shared_mutex cwchar
+shared_mutex cwctype
+shared_mutex exception
+shared_mutex initializer_list
+shared_mutex iosfwd
+shared_mutex iterator
+shared_mutex limits
+shared_mutex memory
+shared_mutex new
+shared_mutex optional
+shared_mutex ratio
+shared_mutex stdexcept
+shared_mutex string
+shared_mutex string_view
+shared_mutex system_error
+shared_mutex tuple
+shared_mutex type_traits
+shared_mutex typeinfo
+shared_mutex utility
+shared_mutex variant
+shared_mutex version
+source_location cstdint
+source_location version
+span algorithm
+span array
+span atomic
+span bit
+span cctype
+span cerrno
+span climits
+span clocale
+span cmath
+span compare
+span concepts
+span cstdarg
+span cstddef
+span cstdint
+span cstdio
+span cstdlib
+span cstring
+span ctime
+span cwchar
+span cwctype
+span exception
+span functional
+span initializer_list
+span ios
+span iosfwd
+span iterator
+span limits
+span locale
+span memory
+span mutex
+span new
+span optional
+span ratio
+span stdexcept
+span streambuf
+span string
+span string_view
+span system_error
+span tuple
+span type_traits
+span typeinfo
+span unordered_map
+span utility
+span variant
+span vector
+span version
+sstream algorithm
+sstream array
+sstream atomic
+sstream bit
+sstream bitset
+sstream cctype
+sstream cerrno
+sstream climits
+sstream clocale
+sstream cmath
+sstream compare
+sstream concepts
+sstream cstdarg
+sstream cstddef
+sstream cstdint
+sstream cstdio
+sstream cstdlib
+sstream cstring
+sstream ctime
+sstream cwchar
+sstream cwctype
+sstream deque
+sstream exception
+sstream format
+sstream functional
+sstream initializer_list
+sstream ios
+sstream iosfwd
+sstream istream
+sstream iterator
+sstream limits
+sstream locale
+sstream memory
+sstream mutex
+sstream new
+sstream optional
+sstream ostream
+sstream print
+sstream queue
+sstream ratio
+sstream stack
+sstream stdexcept
+sstream streambuf
+sstream string
+sstream string_view
+sstream system_error
+sstream tuple
+sstream type_traits
+sstream typeinfo
+sstream unordered_map
+sstream utility
+sstream variant
+sstream vector
+sstream version
+stack algorithm
+stack array
+stack atomic
+stack bit
+stack cctype
+stack cerrno
+stack climits
+stack clocale
+stack cmath
+stack compare
+stack concepts
+stack cstdarg
+stack cstddef
+stack cstdint
+stack cstdio
+stack cstdlib
+stack cstring
+stack ctime
+stack cwchar
+stack cwctype
+stack deque
+stack exception
+stack functional
+stack initializer_list
+stack ios
+stack iosfwd
+stack iterator
+stack limits
+stack locale
+stack memory
+stack mutex
+stack new
+stack optional
+stack ratio
+stack stdexcept
+stack streambuf
+stack string
+stack string_view
+stack system_error
+stack tuple
+stack type_traits
+stack typeinfo
+stack unordered_map
+stack utility
+stack variant
+stack vector
+stack version
+stdexcept cstddef
+stdexcept cstdint
+stdexcept cstdlib
+stdexcept exception
+stdexcept iosfwd
+stdexcept new
+stdexcept type_traits
+stdexcept typeinfo
+stdexcept version
+stop_token iosfwd
+stop_token version
+streambuf algorithm
+streambuf atomic
+streambuf bit
+streambuf cctype
+streambuf cerrno
+streambuf climits
+streambuf clocale
+streambuf cmath
+streambuf compare
+streambuf concepts
+streambuf cstddef
+streambuf cstdint
+streambuf cstdio
+streambuf cstdlib
+streambuf cstring
+streambuf ctime
+streambuf cwchar
+streambuf cwctype
+streambuf exception
+streambuf initializer_list
+streambuf ios
+streambuf iosfwd
+streambuf iterator
+streambuf limits
+streambuf memory
+streambuf mutex
+streambuf new
+streambuf optional
+streambuf ratio
+streambuf stdexcept
+streambuf string
+streambuf string_view
+streambuf system_error
+streambuf tuple
+streambuf type_traits
+streambuf typeinfo
+streambuf utility
+streambuf variant
+streambuf version
+string algorithm
+string atomic
+string bit
+string cctype
+string climits
+string cmath
+string compare
+string concepts
+string cstddef
+string cstdint
+string cstdio
+string cstdlib
+string cstring
+string ctime
+string cwchar
+string cwctype
+string exception
+string initializer_list
+string iosfwd
+string iterator
+string limits
+string memory
+string new
+string optional
+string ratio
+string stdexcept
+string string_view
+string tuple
+string type_traits
+string typeinfo
+string utility
+string variant
+string version
+string_view algorithm
+string_view atomic
+string_view bit
+string_view cctype
+string_view climits
+string_view cmath
+string_view compare
+string_view concepts
+string_view cstddef
+string_view cstdint
+string_view cstdio
+string_view cstdlib
+string_view cstring
+string_view ctime
+string_view cwchar
+string_view cwctype
+string_view exception
+string_view initializer_list
+string_view iosfwd
+string_view iterator
+string_view limits
+string_view memory
+string_view new
+string_view optional
+string_view ratio
+string_view stdexcept
+string_view tuple
+string_view type_traits
+string_view typeinfo
+string_view utility
+string_view variant
+string_view version
+strstream algorithm
+strstream array
+strstream atomic
+strstream bit
+strstream bitset
+strstream cctype
+strstream cerrno
+strstream climits
+strstream clocale
+strstream cmath
+strstream compare
+strstream concepts
+strstream cstdarg
+strstream cstddef
+strstream cstdint
+strstream cstdio
+strstream cstdlib
+strstream cstring
+strstream ctime
+strstream cwchar
+strstream cwctype
+strstream deque
+strstream exception
+strstream format
+strstream functional
+strstream initializer_list
+strstream ios
+strstream iosfwd
+strstream istream
+strstream iterator
+strstream limits
+strstream locale
+strstream memory
+strstream mutex
+strstream new
+strstream optional
+strstream ostream
+strstream print
+strstream queue
+strstream ratio
+strstream stack
+strstream stdexcept
+strstream streambuf
+strstream string
+strstream string_view
+strstream system_error
+strstream tuple
+strstream type_traits
+strstream typeinfo
+strstream unordered_map
+strstream utility
+strstream variant
+strstream vector
+strstream version
+syncstream algorithm
+syncstream array
+syncstream atomic
+syncstream bit
+syncstream bitset
+syncstream cctype
+syncstream cerrno
+syncstream climits
+syncstream clocale
+syncstream cmath
+syncstream compare
+syncstream concepts
+syncstream cstdarg
+syncstream cstddef
+syncstream cstdint
+syncstream cstdio
+syncstream cstdlib
+syncstream cstring
+syncstream ctime
+syncstream cwchar
+syncstream cwctype
+syncstream deque
+syncstream exception
+syncstream format
+syncstream functional
+syncstream initializer_list
+syncstream ios
+syncstream iosfwd
+syncstream iterator
+syncstream limits
+syncstream locale
+syncstream map
+syncstream memory
+syncstream mutex
+syncstream new
+syncstream optional
+syncstream ostream
+syncstream print
+syncstream queue
+syncstream ratio
+syncstream shared_mutex
+syncstream stack
+syncstream stdexcept
+syncstream streambuf
+syncstream string
+syncstream string_view
+syncstream system_error
+syncstream tuple
+syncstream type_traits
+syncstream typeinfo
+syncstream unordered_map
+syncstream utility
+syncstream variant
+syncstream vector
+syncstream version
+system_error algorithm
+system_error atomic
+system_error bit
+system_error cctype
+system_error cerrno
+system_error climits
+system_error cmath
+system_error compare
+system_error concepts
+system_error cstddef
+system_error cstdint
+system_error cstdio
+system_error cstdlib
+system_error cstring
+system_error ctime
+system_error cwchar
+system_error cwctype
+system_error exception
+system_error initializer_list
+system_error iosfwd
+system_error iterator
+system_error limits
+system_error memory
+system_error new
+system_error optional
+system_error ratio
+system_error stdexcept
+system_error string
+system_error string_view
+system_error tuple
+system_error type_traits
+system_error typeinfo
+system_error utility
+system_error variant
+system_error version
+thread algorithm
+thread array
+thread atomic
+thread bit
+thread bitset
+thread cctype
+thread cerrno
+thread chrono
+thread climits
+thread clocale
+thread cmath
+thread compare
+thread concepts
+thread cstdarg
+thread cstddef
+thread cstdint
+thread cstdio
+thread cstdlib
+thread cstring
+thread ctime
+thread cwchar
+thread cwctype
+thread deque
+thread exception
+thread format
+thread forward_list
+thread functional
+thread initializer_list
+thread ios
+thread iosfwd
+thread istream
+thread iterator
+thread limits
+thread locale
+thread memory
+thread mutex
+thread new
+thread optional
+thread ostream
+thread print
+thread queue
+thread ratio
+thread sstream
+thread stack
+thread stdexcept
+thread streambuf
+thread string
+thread string_view
+thread system_error
+thread tuple
+thread type_traits
+thread typeinfo
+thread unordered_map
+thread utility
+thread variant
+thread vector
+thread version
+tuple cmath
+tuple compare
+tuple cstddef
+tuple cstdint
+tuple cstdlib
+tuple exception
+tuple initializer_list
+tuple iosfwd
+tuple limits
+tuple new
+tuple type_traits
+tuple typeinfo
+tuple utility
+tuple version
+type_traits cstdint
+type_traits version
+typeindex cmath
+typeindex compare
+typeindex cstddef
+typeindex cstdint
+typeindex cstdlib
+typeindex initializer_list
+typeindex iosfwd
+typeindex limits
+typeindex new
+typeindex type_traits
+typeindex typeinfo
+typeindex utility
+typeindex version
+typeinfo cstddef
+typeinfo cstdint
+typeinfo cstdlib
+typeinfo type_traits
+typeinfo version
+unordered_map algorithm
+unordered_map atomic
+unordered_map bit
+unordered_map cctype
+unordered_map climits
+unordered_map cmath
+unordered_map compare
+unordered_map concepts
+unordered_map cstddef
+unordered_map cstdint
+unordered_map cstdio
+unordered_map cstdlib
+unordered_map cstring
+unordered_map ctime
+unordered_map cwchar
+unordered_map cwctype
+unordered_map exception
+unordered_map initializer_list
+unordered_map iosfwd
+unordered_map iterator
+unordered_map limits
+unordered_map memory
+unordered_map new
+unordered_map optional
+unordered_map ratio
+unordered_map stdexcept
+unordered_map tuple
+unordered_map type_traits
+unordered_map typeinfo
+unordered_map utility
+unordered_map variant
+unordered_map version
+unordered_set algorithm
+unordered_set array
+unordered_set atomic
+unordered_set bit
+unordered_set cctype
+unordered_set cerrno
+unordered_set climits
+unordered_set clocale
+unordered_set cmath
+unordered_set compare
+unordered_set concepts
+unordered_set cstdarg
+unordered_set cstddef
+unordered_set cstdint
+unordered_set cstdio
+unordered_set cstdlib
+unordered_set cstring
+unordered_set ctime
+unordered_set cwchar
+unordered_set cwctype
+unordered_set exception
+unordered_set functional
+unordered_set initializer_list
+unordered_set ios
+unordered_set iosfwd
+unordered_set iterator
+unordered_set limits
+unordered_set locale
+unordered_set memory
+unordered_set mutex
+unordered_set new
+unordered_set optional
+unordered_set ratio
+unordered_set stdexcept
+unordered_set streambuf
+unordered_set string
+unordered_set string_view
+unordered_set system_error
+unordered_set tuple
+unordered_set type_traits
+unordered_set typeinfo
+unordered_set unordered_map
+unordered_set utility
+unordered_set variant
+unordered_set vector
+unordered_set version
+utility cmath
+utility compare
+utility cstddef
+utility cstdint
+utility cstdlib
+utility initializer_list
+utility iosfwd
+utility limits
+utility type_traits
+utility version
+valarray algorithm
+valarray array
+valarray atomic
+valarray bit
+valarray cctype
+valarray cerrno
+valarray climits
+valarray clocale
+valarray cmath
+valarray compare
+valarray concepts
+valarray cstdarg
+valarray cstddef
+valarray cstdint
+valarray cstdio
+valarray cstdlib
+valarray cstring
+valarray ctime
+valarray cwchar
+valarray cwctype
+valarray exception
+valarray functional
+valarray initializer_list
+valarray ios
+valarray iosfwd
+valarray iterator
+valarray limits
+valarray locale
+valarray memory
+valarray mutex
+valarray new
+valarray optional
+valarray ratio
+valarray stdexcept
+valarray streambuf
+valarray string
+valarray string_view
+valarray system_error
+valarray tuple
+valarray type_traits
+valarray typeinfo
+valarray unordered_map
+valarray utility
+valarray variant
+valarray vector
+valarray version
+variant cmath
+variant compare
+variant cstddef
+variant cstdint
+variant cstdlib
+variant cstring
+variant exception
+variant initializer_list
+variant iosfwd
+variant limits
+variant new
+variant tuple
+variant type_traits
+variant typeinfo
+variant utility
+variant version
+vector algorithm
+vector array
+vector atomic
+vector bit
+vector cctype
+vector cerrno
+vector climits
+vector clocale
+vector cmath
+vector compare
+vector concepts
+vector cstdarg
+vector cstddef
+vector cstdint
+vector cstdio
+vector cstdlib
+vector cstring
+vector ctime
+vector cwchar
+vector cwctype
+vector exception
+vector initializer_list
+vector ios
+vector iosfwd
+vector iterator
+vector limits
+vector locale
+vector memory
+vector mutex
+vector new
+vector optional
+vector ratio
+vector stdexcept
+vector streambuf
+vector string
+vector string_view
+vector system_error
+vector tuple
+vector type_traits
+vector typeinfo
+vector utility
+vector variant
+vector version
diff --git a/libcxx/test/libcxx-03/transitive_includes/cxx11.csv b/libcxx/test/libcxx-03/transitive_includes/cxx11.csv
new file mode 100644
index 0000000000000..c0031543e47bc
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/cxx11.csv
@@ -0,0 +1,2568 @@
+algorithm atomic
+algorithm bit
+algorithm cctype
+algorithm climits
+algorithm cmath
+algorithm compare
+algorithm concepts
+algorithm cstddef
+algorithm cstdint
+algorithm cstdio
+algorithm cstdlib
+algorithm cstring
+algorithm ctime
+algorithm cwchar
+algorithm cwctype
+algorithm exception
+algorithm initializer_list
+algorithm iosfwd
+algorithm iterator
+algorithm limits
+algorithm memory
+algorithm new
+algorithm optional
+algorithm ratio
+algorithm stdexcept
+algorithm tuple
+algorithm type_traits
+algorithm typeinfo
+algorithm utility
+algorithm variant
+algorithm version
+any algorithm
+any array
+any atomic
+any bit
+any cctype
+any cerrno
+any chrono
+any climits
+any clocale
+any cmath
+any compare
+any concepts
+any cstdarg
+any cstddef
+any cstdint
+any cstdio
+any cstdlib
+any cstring
+any ctime
+any cwchar
+any cwctype
+any exception
+any forward_list
+any functional
+any initializer_list
+any ios
+any iosfwd
+any iterator
+any limits
+any locale
+any memory
+any mutex
+any new
+any optional
+any ratio
+any stdexcept
+any streambuf
+any string
+any string_view
+any system_error
+any tuple
+any type_traits
+any typeinfo
+any unordered_map
+any utility
+any variant
+any vector
+any version
+array algorithm
+array atomic
+array bit
+array cctype
+array climits
+array cmath
+array compare
+array concepts
+array cstddef
+array cstdint
+array cstdio
+array cstdlib
+array cstring
+array ctime
+array cwchar
+array cwctype
+array exception
+array initializer_list
+array iosfwd
+array iterator
+array limits
+array memory
+array new
+array optional
+array ratio
+array stdexcept
+array tuple
+array type_traits
+array typeinfo
+array utility
+array variant
+array version
+atomic climits
+atomic cmath
+atomic compare
+atomic cstddef
+atomic cstdint
+atomic cstdlib
+atomic cstring
+atomic ctime
+atomic limits
+atomic ratio
+atomic type_traits
+atomic version
+barrier atomic
+barrier climits
+barrier cmath
+barrier compare
+barrier concepts
+barrier cstddef
+barrier cstdint
+barrier cstdlib
+barrier cstring
+barrier ctime
+barrier exception
+barrier initializer_list
+barrier iosfwd
+barrier iterator
+barrier limits
+barrier memory
+barrier new
+barrier ratio
+barrier stdexcept
+barrier tuple
+barrier type_traits
+barrier typeinfo
+barrier utility
+barrier variant
+barrier version
+bit cstdint
+bit cstdlib
+bit iosfwd
+bit limits
+bit type_traits
+bit version
+bitset algorithm
+bitset atomic
+bitset bit
+bitset cctype
+bitset climits
+bitset cmath
+bitset compare
+bitset concepts
+bitset cstddef
+bitset cstdint
+bitset cstdio
+bitset cstdlib
+bitset cstring
+bitset ctime
+bitset cwchar
+bitset cwctype
+bitset exception
+bitset initializer_list
+bitset iosfwd
+bitset iterator
+bitset limits
+bitset memory
+bitset new
+bitset optional
+bitset ratio
+bitset stdexcept
+bitset string
+bitset string_view
+bitset tuple
+bitset type_traits
+bitset typeinfo
+bitset utility
+bitset variant
+bitset version
+ccomplex algorithm
+ccomplex array
+ccomplex atomic
+ccomplex bit
+ccomplex bitset
+ccomplex cctype
+ccomplex cerrno
+ccomplex climits
+ccomplex clocale
+ccomplex cmath
+ccomplex compare
+ccomplex complex
+ccomplex concepts
+ccomplex cstdarg
+ccomplex cstddef
+ccomplex cstdint
+ccomplex cstdio
+ccomplex cstdlib
+ccomplex cstring
+ccomplex ctime
+ccomplex cwchar
+ccomplex cwctype
+ccomplex deque
+ccomplex exception
+ccomplex format
+ccomplex functional
+ccomplex initializer_list
+ccomplex ios
+ccomplex iosfwd
+ccomplex istream
+ccomplex iterator
+ccomplex limits
+ccomplex locale
+ccomplex memory
+ccomplex mutex
+ccomplex new
+ccomplex optional
+ccomplex ostream
+ccomplex print
+ccomplex queue
+ccomplex ratio
+ccomplex sstream
+ccomplex stack
+ccomplex stdexcept
+ccomplex streambuf
+ccomplex string
+ccomplex string_view
+ccomplex system_error
+ccomplex tuple
+ccomplex type_traits
+ccomplex typeinfo
+ccomplex unordered_map
+ccomplex utility
+ccomplex variant
+ccomplex vector
+ccomplex version
+charconv cmath
+charconv concepts
+charconv cstddef
+charconv cstdint
+charconv cstdlib
+charconv cstring
+charconv iosfwd
+charconv limits
+charconv new
+charconv type_traits
+charconv version
+chrono algorithm
+chrono array
+chrono atomic
+chrono bit
+chrono cctype
+chrono cerrno
+chrono climits
+chrono clocale
+chrono cmath
+chrono compare
+chrono concepts
+chrono cstdarg
+chrono cstddef
+chrono cstdint
+chrono cstdio
+chrono cstdlib
+chrono cstring
+chrono ctime
+chrono cwchar
+chrono cwctype
+chrono exception
+chrono forward_list
+chrono functional
+chrono initializer_list
+chrono ios
+chrono iosfwd
+chrono iterator
+chrono limits
+chrono locale
+chrono memory
+chrono mutex
+chrono new
+chrono optional
+chrono ratio
+chrono stdexcept
+chrono streambuf
+chrono string
+chrono string_view
+chrono system_error
+chrono tuple
+chrono type_traits
+chrono typeinfo
+chrono unordered_map
+chrono utility
+chrono variant
+chrono vector
+chrono version
+cinttypes cstdint
+cmath cstdint
+cmath limits
+cmath type_traits
+cmath version
+codecvt algorithm
+codecvt atomic
+codecvt bit
+codecvt cctype
+codecvt cerrno
+codecvt climits
+codecvt clocale
+codecvt cmath
+codecvt compare
+codecvt concepts
+codecvt cstddef
+codecvt cstdint
+codecvt cstdio
+codecvt cstdlib
+codecvt cstring
+codecvt ctime
+codecvt cwchar
+codecvt cwctype
+codecvt exception
+codecvt initializer_list
+codecvt iosfwd
+codecvt iterator
+codecvt limits
+codecvt memory
+codecvt mutex
+codecvt new
+codecvt optional
+codecvt ratio
+codecvt stdexcept
+codecvt string
+codecvt string_view
+codecvt system_error
+codecvt tuple
+codecvt type_traits
+codecvt typeinfo
+codecvt utility
+codecvt variant
+codecvt version
+compare cmath
+compare cstddef
+compare cstdint
+compare limits
+compare type_traits
+compare version
+complex algorithm
+complex array
+complex atomic
+complex bit
+complex bitset
+complex cctype
+complex cerrno
+complex climits
+complex clocale
+complex cmath
+complex compare
+complex concepts
+complex cstdarg
+complex cstddef
+complex cstdint
+complex cstdio
+complex cstdlib
+complex cstring
+complex ctime
+complex cwchar
+complex cwctype
+complex deque
+complex exception
+complex format
+complex functional
+complex initializer_list
+complex ios
+complex iosfwd
+complex istream
+complex iterator
+complex limits
+complex locale
+complex memory
+complex mutex
+complex new
+complex optional
+complex ostream
+complex print
+complex queue
+complex ratio
+complex sstream
+complex stack
+complex stdexcept
+complex streambuf
+complex string
+complex string_view
+complex system_error
+complex tuple
+complex type_traits
+complex typeinfo
+complex unordered_map
+complex utility
+complex variant
+complex vector
+complex version
+concepts cstddef
+concepts cstdint
+concepts type_traits
+concepts version
+condition_variable algorithm
+condition_variable atomic
+condition_variable bit
+condition_variable cctype
+condition_variable cerrno
+condition_variable climits
+condition_variable cmath
+condition_variable compare
+condition_variable concepts
+condition_variable cstddef
+condition_variable cstdint
+condition_variable cstdio
+condition_variable cstdlib
+condition_variable cstring
+condition_variable ctime
+condition_variable cwchar
+condition_variable cwctype
+condition_variable exception
+condition_variable initializer_list
+condition_variable iosfwd
+condition_variable iterator
+condition_variable limits
+condition_variable memory
+condition_variable new
+condition_variable optional
+condition_variable ratio
+condition_variable stdexcept
+condition_variable string
+condition_variable string_view
+condition_variable system_error
+condition_variable tuple
+condition_variable type_traits
+condition_variable typeinfo
+condition_variable utility
+condition_variable variant
+condition_variable version
+coroutine cmath
+coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine iosfwd
+coroutine limits
+coroutine type_traits
+coroutine version
+cstddef version
+ctgmath algorithm
+ctgmath array
+ctgmath atomic
+ctgmath bit
+ctgmath bitset
+ctgmath cctype
+ctgmath cerrno
+ctgmath climits
+ctgmath clocale
+ctgmath cmath
+ctgmath compare
+ctgmath complex
+ctgmath concepts
+ctgmath cstdarg
+ctgmath cstddef
+ctgmath cstdint
+ctgmath cstdio
+ctgmath cstdlib
+ctgmath cstring
+ctgmath ctime
+ctgmath cwchar
+ctgmath cwctype
+ctgmath deque
+ctgmath exception
+ctgmath format
+ctgmath functional
+ctgmath initializer_list
+ctgmath ios
+ctgmath iosfwd
+ctgmath istream
+ctgmath iterator
+ctgmath limits
+ctgmath locale
+ctgmath memory
+ctgmath mutex
+ctgmath new
+ctgmath optional
+ctgmath ostream
+ctgmath print
+ctgmath queue
+ctgmath ratio
+ctgmath sstream
+ctgmath stack
+ctgmath stdexcept
+ctgmath streambuf
+ctgmath string
+ctgmath string_view
+ctgmath system_error
+ctgmath tuple
+ctgmath type_traits
+ctgmath typeinfo
+ctgmath unordered_map
+ctgmath utility
+ctgmath variant
+ctgmath vector
+ctgmath version
+cwchar cctype
+cwchar cstddef
+cwchar cwctype
+cwchar version
+cwctype cctype
+deque algorithm
+deque array
+deque atomic
+deque bit
+deque cctype
+deque cerrno
+deque climits
+deque clocale
+deque cmath
+deque compare
+deque concepts
+deque cstdarg
+deque cstddef
+deque cstdint
+deque cstdio
+deque cstdlib
+deque cstring
+deque ctime
+deque cwchar
+deque cwctype
+deque exception
+deque functional
+deque initializer_list
+deque ios
+deque iosfwd
+deque iterator
+deque limits
+deque locale
+deque memory
+deque mutex
+deque new
+deque optional
+deque ratio
+deque stdexcept
+deque streambuf
+deque string
+deque string_view
+deque system_error
+deque tuple
+deque type_traits
+deque typeinfo
+deque unordered_map
+deque utility
+deque variant
+deque vector
+deque version
+exception cstddef
+exception cstdint
+exception cstdlib
+exception new
+exception type_traits
+exception typeinfo
+exception version
+execution cstddef
+execution version
+expected version
+experimental/iterator algorithm
+experimental/iterator atomic
+experimental/iterator bit
+experimental/iterator bitset
+experimental/iterator cctype
+experimental/iterator cerrno
+experimental/iterator climits
+experimental/iterator clocale
+experimental/iterator cmath
+experimental/iterator compare
+experimental/iterator concepts
+experimental/iterator cstdarg
+experimental/iterator cstddef
+experimental/iterator cstdint
+experimental/iterator cstdio
+experimental/iterator cstdlib
+experimental/iterator cstring
+experimental/iterator ctime
+experimental/iterator cwchar
+experimental/iterator cwctype
+experimental/iterator exception
+experimental/iterator initializer_list
+experimental/iterator ios
+experimental/iterator iosfwd
+experimental/iterator iterator
+experimental/iterator limits
+experimental/iterator locale
+experimental/iterator memory
+experimental/iterator mutex
+experimental/iterator new
+experimental/iterator optional
+experimental/iterator ratio
+experimental/iterator stdexcept
+experimental/iterator streambuf
+experimental/iterator string
+experimental/iterator string_view
+experimental/iterator system_error
+experimental/iterator tuple
+experimental/iterator type_traits
+experimental/iterator typeinfo
+experimental/iterator utility
+experimental/iterator variant
+experimental/iterator version
+experimental/memory cstddef
+experimental/memory cstdint
+experimental/memory cstring
+experimental/memory limits
+experimental/memory type_traits
+experimental/memory version
+experimental/propagate_const cstddef
+experimental/propagate_const cstdint
+experimental/propagate_const type_traits
+experimental/propagate_const version
+experimental/simd cstddef
+experimental/simd cstdint
+experimental/simd limits
+experimental/simd type_traits
+experimental/simd version
+experimental/utility cmath
+experimental/utility compare
+experimental/utility cstddef
+experimental/utility cstdint
+experimental/utility cstdlib
+experimental/utility initializer_list
+experimental/utility iosfwd
+experimental/utility limits
+experimental/utility type_traits
+experimental/utility utility
+experimental/utility version
+filesystem algorithm
+filesystem atomic
+filesystem bit
+filesystem cctype
+filesystem cerrno
+filesystem climits
+filesystem cmath
+filesystem compare
+filesystem concepts
+filesystem cstddef
+filesystem cstdint
+filesystem cstdio
+filesystem cstdlib
+filesystem cstring
+filesystem ctime
+filesystem cwchar
+filesystem cwctype
+filesystem exception
+filesystem initializer_list
+filesystem iosfwd
+filesystem iterator
+filesystem limits
+filesystem memory
+filesystem new
+filesystem optional
+filesystem ratio
+filesystem stdexcept
+filesystem string
+filesystem string_view
+filesystem system_error
+filesystem tuple
+filesystem type_traits
+filesystem typeinfo
+filesystem utility
+filesystem variant
+filesystem version
+flat_map cmath
+flat_map compare
+flat_map cstddef
+flat_map cstdint
+flat_map initializer_list
+flat_map limits
+flat_map type_traits
+flat_map version
+flat_set cmath
+flat_set compare
+flat_set cstddef
+flat_set cstdint
+flat_set initializer_list
+flat_set limits
+flat_set type_traits
+flat_set version
+format algorithm
+format array
+format atomic
+format bit
+format cctype
+format cerrno
+format climits
+format clocale
+format cmath
+format compare
+format concepts
+format cstdarg
+format cstddef
+format cstdint
+format cstdio
+format cstdlib
+format cstring
+format ctime
+format cwchar
+format cwctype
+format deque
+format exception
+format functional
+format initializer_list
+format ios
+format iosfwd
+format iterator
+format limits
+format locale
+format memory
+format mutex
+format new
+format optional
+format queue
+format ratio
+format stack
+format stdexcept
+format streambuf
+format string
+format string_view
+format system_error
+format tuple
+format type_traits
+format typeinfo
+format unordered_map
+format utility
+format variant
+format vector
+format version
+forward_list algorithm
+forward_list array
+forward_list atomic
+forward_list bit
+forward_list cctype
+forward_list cerrno
+forward_list climits
+forward_list clocale
+forward_list cmath
+forward_list compare
+forward_list concepts
+forward_list cstdarg
+forward_list cstddef
+forward_list cstdint
+forward_list cstdio
+forward_list cstdlib
+forward_list cstring
+forward_list ctime
+forward_list cwchar
+forward_list cwctype
+forward_list exception
+forward_list functional
+forward_list initializer_list
+forward_list ios
+forward_list iosfwd
+forward_list iterator
+forward_list limits
+forward_list locale
+forward_list memory
+forward_list mutex
+forward_list new
+forward_list optional
+forward_list ratio
+forward_list stdexcept
+forward_list streambuf
+forward_list string
+forward_list string_view
+forward_list system_error
+forward_list tuple
+forward_list type_traits
+forward_list typeinfo
+forward_list unordered_map
+forward_list utility
+forward_list variant
+forward_list vector
+forward_list version
+fstream algorithm
+fstream array
+fstream atomic
+fstream bit
+fstream bitset
+fstream cctype
+fstream cerrno
+fstream climits
+fstream clocale
+fstream cmath
+fstream compare
+fstream concepts
+fstream cstdarg
+fstream cstddef
+fstream cstdint
+fstream cstdio
+fstream cstdlib
+fstream cstring
+fstream ctime
+fstream cwchar
+fstream cwctype
+fstream deque
+fstream exception
+fstream filesystem
+fstream format
+fstream functional
+fstream initializer_list
+fstream iomanip
+fstream ios
+fstream iosfwd
+fstream istream
+fstream iterator
+fstream limits
+fstream locale
+fstream memory
+fstream mutex
+fstream new
+fstream optional
+fstream ostream
+fstream print
+fstream queue
+fstream ratio
+fstream stack
+fstream stdexcept
+fstream streambuf
+fstream string
+fstream string_view
+fstream system_error
+fstream tuple
+fstream type_traits
+fstream typeinfo
+fstream unordered_map
+fstream utility
+fstream variant
+fstream vector
+fstream version
+functional algorithm
+functional array
+functional atomic
+functional bit
+functional cctype
+functional cerrno
+functional climits
+functional clocale
+functional cmath
+functional compare
+functional concepts
+functional cstdarg
+functional cstddef
+functional cstdint
+functional cstdio
+functional cstdlib
+functional cstring
+functional ctime
+functional cwchar
+functional cwctype
+functional exception
+functional initializer_list
+functional ios
+functional iosfwd
+functional iterator
+functional limits
+functional locale
+functional memory
+functional mutex
+functional new
+functional optional
+functional ratio
+functional stdexcept
+functional streambuf
+functional string
+functional string_view
+functional system_error
+functional tuple
+functional type_traits
+functional typeinfo
+functional unordered_map
+functional utility
+functional variant
+functional vector
+functional version
+future algorithm
+future array
+future atomic
+future bit
+future bitset
+future cctype
+future cerrno
+future chrono
+future climits
+future clocale
+future cmath
+future compare
+future concepts
+future cstdarg
+future cstddef
+future cstdint
+future cstdio
+future cstdlib
+future cstring
+future ctime
+future cwchar
+future cwctype
+future deque
+future exception
+future format
+future forward_list
+future functional
+future initializer_list
+future ios
+future iosfwd
+future istream
+future iterator
+future limits
+future locale
+future memory
+future mutex
+future new
+future optional
+future ostream
+future print
+future queue
+future ratio
+future sstream
+future stack
+future stdexcept
+future streambuf
+future string
+future string_view
+future system_error
+future thread
+future tuple
+future type_traits
+future typeinfo
+future unordered_map
+future utility
+future variant
+future vector
+future version
+initializer_list cstddef
+initializer_list version
+iomanip algorithm
+iomanip array
+iomanip atomic
+iomanip bit
+iomanip bitset
+iomanip cctype
+iomanip cerrno
+iomanip climits
+iomanip clocale
+iomanip cmath
+iomanip compare
+iomanip concepts
+iomanip cstdarg
+iomanip cstddef
+iomanip cstdint
+iomanip cstdio
+iomanip cstdlib
+iomanip cstring
+iomanip ctime
+iomanip cwchar
+iomanip cwctype
+iomanip deque
+iomanip exception
+iomanip format
+iomanip functional
+iomanip initializer_list
+iomanip ios
+iomanip iosfwd
+iomanip istream
+iomanip iterator
+iomanip limits
+iomanip locale
+iomanip memory
+iomanip mutex
+iomanip new
+iomanip optional
+iomanip ostream
+iomanip print
+iomanip queue
+iomanip ratio
+iomanip stack
+iomanip stdexcept
+iomanip streambuf
+iomanip string
+iomanip string_view
+iomanip system_error
+iomanip tuple
+iomanip type_traits
+iomanip typeinfo
+iomanip unordered_map
+iomanip utility
+iomanip variant
+iomanip vector
+iomanip version
+ios algorithm
+ios atomic
+ios bit
+ios cctype
+ios cerrno
+ios climits
+ios clocale
+ios cmath
+ios compare
+ios concepts
+ios cstddef
+ios cstdint
+ios cstdio
+ios cstdlib
+ios cstring
+ios ctime
+ios cwchar
+ios cwctype
+ios exception
+ios initializer_list
+ios iosfwd
+ios iterator
+ios limits
+ios memory
+ios mutex
+ios new
+ios optional
+ios ratio
+ios stdexcept
+ios string
+ios string_view
+ios system_error
+ios tuple
+ios type_traits
+ios typeinfo
+ios utility
+ios variant
+ios version
+iosfwd version
+iostream algorithm
+iostream array
+iostream atomic
+iostream bit
+iostream bitset
+iostream cctype
+iostream cerrno
+iostream climits
+iostream clocale
+iostream cmath
+iostream compare
+iostream concepts
+iostream cstdarg
+iostream cstddef
+iostream cstdint
+iostream cstdio
+iostream cstdlib
+iostream cstring
+iostream ctime
+iostream cwchar
+iostream cwctype
+iostream deque
+iostream exception
+iostream format
+iostream functional
+iostream initializer_list
+iostream ios
+iostream iosfwd
+iostream istream
+iostream iterator
+iostream limits
+iostream locale
+iostream memory
+iostream mutex
+iostream new
+iostream optional
+iostream ostream
+iostream print
+iostream queue
+iostream ratio
+iostream stack
+iostream stdexcept
+iostream streambuf
+iostream string
+iostream string_view
+iostream system_error
+iostream tuple
+iostream type_traits
+iostream typeinfo
+iostream unordered_map
+iostream utility
+iostream variant
+iostream vector
+iostream version
+istream algorithm
+istream array
+istream atomic
+istream bit
+istream bitset
+istream cctype
+istream cerrno
+istream climits
+istream clocale
+istream cmath
+istream compare
+istream concepts
+istream cstdarg
+istream cstddef
+istream cstdint
+istream cstdio
+istream cstdlib
+istream cstring
+istream ctime
+istream cwchar
+istream cwctype
+istream deque
+istream exception
+istream format
+istream functional
+istream initializer_list
+istream ios
+istream iosfwd
+istream iterator
+istream limits
+istream locale
+istream memory
+istream mutex
+istream new
+istream optional
+istream ostream
+istream print
+istream queue
+istream ratio
+istream stack
+istream stdexcept
+istream streambuf
+istream string
+istream string_view
+istream system_error
+istream tuple
+istream type_traits
+istream typeinfo
+istream unordered_map
+istream utility
+istream variant
+istream vector
+istream version
+iterator cctype
+iterator cmath
+iterator compare
+iterator concepts
+iterator cstddef
+iterator cstdint
+iterator cstdio
+iterator cstdlib
+iterator cstring
+iterator cwchar
+iterator cwctype
+iterator exception
+iterator initializer_list
+iterator iosfwd
+iterator limits
+iterator new
+iterator tuple
+iterator type_traits
+iterator typeinfo
+iterator utility
+iterator variant
+iterator version
+latch atomic
+latch climits
+latch cmath
+latch compare
+latch cstddef
+latch cstdint
+latch cstdlib
+latch cstring
+latch ctime
+latch limits
+latch ratio
+latch type_traits
+latch version
+limits cstdint
+limits type_traits
+limits version
+list algorithm
+list array
+list atomic
+list bit
+list cctype
+list cerrno
+list climits
+list clocale
+list cmath
+list compare
+list concepts
+list cstdarg
+list cstddef
+list cstdint
+list cstdio
+list cstdlib
+list cstring
+list ctime
+list cwchar
+list cwctype
+list exception
+list functional
+list initializer_list
+list ios
+list iosfwd
+list iterator
+list limits
+list locale
+list memory
+list mutex
+list new
+list optional
+list ratio
+list stdexcept
+list streambuf
+list string
+list string_view
+list system_error
+list tuple
+list type_traits
+list typeinfo
+list unordered_map
+list utility
+list variant
+list vector
+list version
+locale algorithm
+locale atomic
+locale bit
+locale cctype
+locale cerrno
+locale climits
+locale clocale
+locale cmath
+locale compare
+locale concepts
+locale cstdarg
+locale cstddef
+locale cstdint
+locale cstdio
+locale cstdlib
+locale cstring
+locale ctime
+locale cwchar
+locale cwctype
+locale exception
+locale initializer_list
+locale ios
+locale iosfwd
+locale iterator
+locale limits
+locale memory
+locale mutex
+locale new
+locale optional
+locale ratio
+locale stdexcept
+locale streambuf
+locale string
+locale string_view
+locale system_error
+locale tuple
+locale type_traits
+locale typeinfo
+locale utility
+locale variant
+locale version
+map algorithm
+map array
+map atomic
+map bit
+map cctype
+map cerrno
+map climits
+map clocale
+map cmath
+map compare
+map concepts
+map cstdarg
+map cstddef
+map cstdint
+map cstdio
+map cstdlib
+map cstring
+map ctime
+map cwchar
+map cwctype
+map exception
+map functional
+map initializer_list
+map ios
+map iosfwd
+map iterator
+map limits
+map locale
+map memory
+map mutex
+map new
+map optional
+map ratio
+map stdexcept
+map streambuf
+map string
+map string_view
+map system_error
+map tuple
+map type_traits
+map typeinfo
+map unordered_map
+map utility
+map variant
+map vector
+map version
+mdspan version
+memory atomic
+memory cctype
+memory climits
+memory cmath
+memory compare
+memory concepts
+memory cstddef
+memory cstdint
+memory cstdio
+memory cstdlib
+memory cstring
+memory ctime
+memory cwchar
+memory cwctype
+memory exception
+memory initializer_list
+memory iosfwd
+memory iterator
+memory limits
+memory new
+memory ratio
+memory stdexcept
+memory tuple
+memory type_traits
+memory typeinfo
+memory utility
+memory variant
+memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource cstdlib
+memory_resource exception
+memory_resource iosfwd
+memory_resource new
+memory_resource stdexcept
+memory_resource type_traits
+memory_resource typeinfo
+memory_resource version
+mutex algorithm
+mutex atomic
+mutex bit
+mutex cctype
+mutex cerrno
+mutex climits
+mutex cmath
+mutex compare
+mutex concepts
+mutex cstddef
+mutex cstdint
+mutex cstdio
+mutex cstdlib
+mutex cstring
+mutex ctime
+mutex cwchar
+mutex cwctype
+mutex exception
+mutex initializer_list
+mutex iosfwd
+mutex iterator
+mutex limits
+mutex memory
+mutex new
+mutex optional
+mutex ratio
+mutex stdexcept
+mutex string
+mutex string_view
+mutex system_error
+mutex tuple
+mutex type_traits
+mutex typeinfo
+mutex utility
+mutex variant
+mutex version
+new cstddef
+new cstdint
+new cstdlib
+new type_traits
+new version
+numbers concepts
+numbers cstddef
+numbers cstdint
+numbers type_traits
+numbers version
+numeric algorithm
+numeric array
+numeric atomic
+numeric bit
+numeric cctype
+numeric cerrno
+numeric climits
+numeric clocale
+numeric cmath
+numeric compare
+numeric concepts
+numeric cstdarg
+numeric cstddef
+numeric cstdint
+numeric cstdio
+numeric cstdlib
+numeric cstring
+numeric ctime
+numeric cwchar
+numeric cwctype
+numeric exception
+numeric execution
+numeric functional
+numeric initializer_list
+numeric ios
+numeric iosfwd
+numeric iterator
+numeric limits
+numeric locale
+numeric memory
+numeric mutex
+numeric new
+numeric optional
+numeric ratio
+numeric stdexcept
+numeric streambuf
+numeric string
+numeric string_view
+numeric system_error
+numeric tuple
+numeric type_traits
+numeric typeinfo
+numeric unordered_map
+numeric utility
+numeric variant
+numeric vector
+numeric version
+optional atomic
+optional cctype
+optional climits
+optional cmath
+optional compare
+optional concepts
+optional cstddef
+optional cstdint
+optional cstdio
+optional cstdlib
+optional cstring
+optional ctime
+optional cwchar
+optional cwctype
+optional exception
+optional initializer_list
+optional iosfwd
+optional iterator
+optional limits
+optional memory
+optional new
+optional ratio
+optional stdexcept
+optional tuple
+optional type_traits
+optional typeinfo
+optional utility
+optional variant
+optional version
+ostream algorithm
+ostream array
+ostream atomic
+ostream bit
+ostream bitset
+ostream cctype
+ostream cerrno
+ostream climits
+ostream clocale
+ostream cmath
+ostream compare
+ostream concepts
+ostream cstdarg
+ostream cstddef
+ostream cstdint
+ostream cstdio
+ostream cstdlib
+ostream cstring
+ostream ctime
+ostream cwchar
+ostream cwctype
+ostream deque
+ostream exception
+ostream format
+ostream functional
+ostream initializer_list
+ostream ios
+ostream iosfwd
+ostream iterator
+ostream limits
+ostream locale
+ostream memory
+ostream mutex
+ostream new
+ostream optional
+ostream print
+ostream queue
+ostream ratio
+ostream stack
+ostream stdexcept
+ostream streambuf
+ostream string
+ostream string_view
+ostream system_error
+ostream tuple
+ostream type_traits
+ostream typeinfo
+ostream unordered_map
+ostream utility
+ostream variant
+ostream vector
+ostream version
+print algorithm
+print array
+print atomic
+print bit
+print cctype
+print cerrno
+print climits
+print clocale
+print cmath
+print compare
+print concepts
+print cstdarg
+print cstddef
+print cstdint
+print cstdio
+print cstdlib
+print cstring
+print ctime
+print cwchar
+print cwctype
+print deque
+print exception
+print format
+print functional
+print initializer_list
+print ios
+print iosfwd
+print iterator
+print limits
+print locale
+print memory
+print mutex
+print new
+print optional
+print queue
+print ratio
+print stack
+print stdexcept
+print streambuf
+print string
+print string_view
+print system_error
+print tuple
+print type_traits
+print typeinfo
+print unordered_map
+print utility
+print variant
+print vector
+print version
+queue algorithm
+queue array
+queue atomic
+queue bit
+queue cctype
+queue cerrno
+queue climits
+queue clocale
+queue cmath
+queue compare
+queue concepts
+queue cstdarg
+queue cstddef
+queue cstdint
+queue cstdio
+queue cstdlib
+queue cstring
+queue ctime
+queue cwchar
+queue cwctype
+queue deque
+queue exception
+queue functional
+queue initializer_list
+queue ios
+queue iosfwd
+queue iterator
+queue limits
+queue locale
+queue memory
+queue mutex
+queue new
+queue optional
+queue ratio
+queue stdexcept
+queue streambuf
+queue string
+queue string_view
+queue system_error
+queue tuple
+queue type_traits
+queue typeinfo
+queue unordered_map
+queue utility
+queue variant
+queue vector
+queue version
+random algorithm
+random array
+random atomic
+random bit
+random cctype
+random cerrno
+random climits
+random clocale
+random cmath
+random compare
+random concepts
+random cstdarg
+random cstddef
+random cstdint
+random cstdio
+random cstdlib
+random cstring
+random ctime
+random cwchar
+random cwctype
+random exception
+random execution
+random functional
+random initializer_list
+random ios
+random iosfwd
+random iterator
+random limits
+random locale
+random memory
+random mutex
+random new
+random numeric
+random optional
+random ratio
+random stdexcept
+random streambuf
+random string
+random string_view
+random system_error
+random tuple
+random type_traits
+random typeinfo
+random unordered_map
+random utility
+random variant
+random vector
+random version
+ranges cctype
+ranges cmath
+ranges compare
+ranges concepts
+ranges cstddef
+ranges cstdint
+ranges cstdio
+ranges cstdlib
+ranges cstring
+ranges cwchar
+ranges cwctype
+ranges exception
+ranges initializer_list
+ranges iosfwd
+ranges iterator
+ranges limits
+ranges new
+ranges tuple
+ranges type_traits
+ranges typeinfo
+ranges utility
+ranges variant
+ranges version
+ratio climits
+ratio cstdint
+ratio type_traits
+ratio version
+regex algorithm
+regex array
+regex atomic
+regex bit
+regex cctype
+regex cerrno
+regex climits
+regex clocale
+regex cmath
+regex compare
+regex concepts
+regex cstdarg
+regex cstddef
+regex cstdint
+regex cstdio
+regex cstdlib
+regex cstring
+regex ctime
+regex cwchar
+regex cwctype
+regex deque
+regex exception
+regex functional
+regex initializer_list
+regex ios
+regex iosfwd
+regex iterator
+regex limits
+regex locale
+regex memory
+regex mutex
+regex new
+regex optional
+regex ratio
+regex stdexcept
+regex streambuf
+regex string
+regex string_view
+regex system_error
+regex tuple
+regex type_traits
+regex typeinfo
+regex unordered_map
+regex utility
+regex variant
+regex vector
+regex version
+scoped_allocator atomic
+scoped_allocator cctype
+scoped_allocator climits
+scoped_allocator cmath
+scoped_allocator compare
+scoped_allocator concepts
+scoped_allocator cstddef
+scoped_allocator cstdint
+scoped_allocator cstdio
+scoped_allocator cstdlib
+scoped_allocator cstring
+scoped_allocator ctime
+scoped_allocator cwchar
+scoped_allocator cwctype
+scoped_allocator exception
+scoped_allocator initializer_list
+scoped_allocator iosfwd
+scoped_allocator iterator
+scoped_allocator limits
+scoped_allocator memory
+scoped_allocator new
+scoped_allocator ratio
+scoped_allocator stdexcept
+scoped_allocator tuple
+scoped_allocator type_traits
+scoped_allocator typeinfo
+scoped_allocator utility
+scoped_allocator variant
+scoped_allocator version
+semaphore atomic
+semaphore climits
+semaphore cmath
+semaphore compare
+semaphore cstddef
+semaphore cstdint
+semaphore cstdlib
+semaphore cstring
+semaphore ctime
+semaphore limits
+semaphore ratio
+semaphore type_traits
+semaphore version
+set algorithm
+set array
+set atomic
+set bit
+set cctype
+set cerrno
+set climits
+set clocale
+set cmath
+set compare
+set concepts
+set cstdarg
+set cstddef
+set cstdint
+set cstdio
+set cstdlib
+set cstring
+set ctime
+set cwchar
+set cwctype
+set exception
+set functional
+set initializer_list
+set ios
+set iosfwd
+set iterator
+set limits
+set locale
+set memory
+set mutex
+set new
+set optional
+set ratio
+set stdexcept
+set streambuf
+set string
+set string_view
+set system_error
+set tuple
+set type_traits
+set typeinfo
+set unordered_map
+set utility
+set variant
+set vector
+set version
+shared_mutex algorithm
+shared_mutex atomic
+shared_mutex bit
+shared_mutex cctype
+shared_mutex cerrno
+shared_mutex climits
+shared_mutex cmath
+shared_mutex compare
+shared_mutex concepts
+shared_mutex cstddef
+shared_mutex cstdint
+shared_mutex cstdio
+shared_mutex cstdlib
+shared_mutex cstring
+shared_mutex ctime
+shared_mutex cwchar
+shared_mutex cwctype
+shared_mutex exception
+shared_mutex initializer_list
+shared_mutex iosfwd
+shared_mutex iterator
+shared_mutex limits
+shared_mutex memory
+shared_mutex new
+shared_mutex optional
+shared_mutex ratio
+shared_mutex stdexcept
+shared_mutex string
+shared_mutex string_view
+shared_mutex system_error
+shared_mutex tuple
+shared_mutex type_traits
+shared_mutex typeinfo
+shared_mutex utility
+shared_mutex variant
+shared_mutex version
+source_location cstdint
+source_location version
+span algorithm
+span array
+span atomic
+span bit
+span cctype
+span cerrno
+span climits
+span clocale
+span cmath
+span compare
+span concepts
+span cstdarg
+span cstddef
+span cstdint
+span cstdio
+span cstdlib
+span cstring
+span ctime
+span cwchar
+span cwctype
+span exception
+span functional
+span initializer_list
+span ios
+span iosfwd
+span iterator
+span limits
+span locale
+span memory
+span mutex
+span new
+span optional
+span ratio
+span stdexcept
+span streambuf
+span string
+span string_view
+span system_error
+span tuple
+span type_traits
+span typeinfo
+span unordered_map
+span utility
+span variant
+span vector
+span version
+sstream algorithm
+sstream array
+sstream atomic
+sstream bit
+sstream bitset
+sstream cctype
+sstream cerrno
+sstream climits
+sstream clocale
+sstream cmath
+sstream compare
+sstream concepts
+sstream cstdarg
+sstream cstddef
+sstream cstdint
+sstream cstdio
+sstream cstdlib
+sstream cstring
+sstream ctime
+sstream cwchar
+sstream cwctype
+sstream deque
+sstream exception
+sstream format
+sstream functional
+sstream initializer_list
+sstream ios
+sstream iosfwd
+sstream istream
+sstream iterator
+sstream limits
+sstream locale
+sstream memory
+sstream mutex
+sstream new
+sstream optional
+sstream ostream
+sstream print
+sstream queue
+sstream ratio
+sstream stack
+sstream stdexcept
+sstream streambuf
+sstream string
+sstream string_view
+sstream system_error
+sstream tuple
+sstream type_traits
+sstream typeinfo
+sstream unordered_map
+sstream utility
+sstream variant
+sstream vector
+sstream version
+stack algorithm
+stack array
+stack atomic
+stack bit
+stack cctype
+stack cerrno
+stack climits
+stack clocale
+stack cmath
+stack compare
+stack concepts
+stack cstdarg
+stack cstddef
+stack cstdint
+stack cstdio
+stack cstdlib
+stack cstring
+stack ctime
+stack cwchar
+stack cwctype
+stack deque
+stack exception
+stack functional
+stack initializer_list
+stack ios
+stack iosfwd
+stack iterator
+stack limits
+stack locale
+stack memory
+stack mutex
+stack new
+stack optional
+stack ratio
+stack stdexcept
+stack streambuf
+stack string
+stack string_view
+stack system_error
+stack tuple
+stack type_traits
+stack typeinfo
+stack unordered_map
+stack utility
+stack variant
+stack vector
+stack version
+stdexcept cstddef
+stdexcept cstdint
+stdexcept cstdlib
+stdexcept exception
+stdexcept iosfwd
+stdexcept new
+stdexcept type_traits
+stdexcept typeinfo
+stdexcept version
+stop_token iosfwd
+stop_token version
+streambuf algorithm
+streambuf atomic
+streambuf bit
+streambuf cctype
+streambuf cerrno
+streambuf climits
+streambuf clocale
+streambuf cmath
+streambuf compare
+streambuf concepts
+streambuf cstddef
+streambuf cstdint
+streambuf cstdio
+streambuf cstdlib
+streambuf cstring
+streambuf ctime
+streambuf cwchar
+streambuf cwctype
+streambuf exception
+streambuf initializer_list
+streambuf ios
+streambuf iosfwd
+streambuf iterator
+streambuf limits
+streambuf memory
+streambuf mutex
+streambuf new
+streambuf optional
+streambuf ratio
+streambuf stdexcept
+streambuf string
+streambuf string_view
+streambuf system_error
+streambuf tuple
+streambuf type_traits
+streambuf typeinfo
+streambuf utility
+streambuf variant
+streambuf version
+string algorithm
+string atomic
+string bit
+string cctype
+string climits
+string cmath
+string compare
+string concepts
+string cstddef
+string cstdint
+string cstdio
+string cstdlib
+string cstring
+string ctime
+string cwchar
+string cwctype
+string exception
+string initializer_list
+string iosfwd
+string iterator
+string limits
+string memory
+string new
+string optional
+string ratio
+string stdexcept
+string string_view
+string tuple
+string type_traits
+string typeinfo
+string utility
+string variant
+string version
+string_view algorithm
+string_view atomic
+string_view bit
+string_view cctype
+string_view climits
+string_view cmath
+string_view compare
+string_view concepts
+string_view cstddef
+string_view cstdint
+string_view cstdio
+string_view cstdlib
+string_view cstring
+string_view ctime
+string_view cwchar
+string_view cwctype
+string_view exception
+string_view initializer_list
+string_view iosfwd
+string_view iterator
+string_view limits
+string_view memory
+string_view new
+string_view optional
+string_view ratio
+string_view stdexcept
+string_view tuple
+string_view type_traits
+string_view typeinfo
+string_view utility
+string_view variant
+string_view version
+strstream algorithm
+strstream array
+strstream atomic
+strstream bit
+strstream bitset
+strstream cctype
+strstream cerrno
+strstream climits
+strstream clocale
+strstream cmath
+strstream compare
+strstream concepts
+strstream cstdarg
+strstream cstddef
+strstream cstdint
+strstream cstdio
+strstream cstdlib
+strstream cstring
+strstream ctime
+strstream cwchar
+strstream cwctype
+strstream deque
+strstream exception
+strstream format
+strstream functional
+strstream initializer_list
+strstream ios
+strstream iosfwd
+strstream istream
+strstream iterator
+strstream limits
+strstream locale
+strstream memory
+strstream mutex
+strstream new
+strstream optional
+strstream ostream
+strstream print
+strstream queue
+strstream ratio
+strstream stack
+strstream stdexcept
+strstream streambuf
+strstream string
+strstream string_view
+strstream system_error
+strstream tuple
+strstream type_traits
+strstream typeinfo
+strstream unordered_map
+strstream utility
+strstream variant
+strstream vector
+strstream version
+syncstream algorithm
+syncstream array
+syncstream atomic
+syncstream bit
+syncstream bitset
+syncstream cctype
+syncstream cerrno
+syncstream climits
+syncstream clocale
+syncstream cmath
+syncstream compare
+syncstream concepts
+syncstream cstdarg
+syncstream cstddef
+syncstream cstdint
+syncstream cstdio
+syncstream cstdlib
+syncstream cstring
+syncstream ctime
+syncstream cwchar
+syncstream cwctype
+syncstream deque
+syncstream exception
+syncstream format
+syncstream functional
+syncstream initializer_list
+syncstream ios
+syncstream iosfwd
+syncstream iterator
+syncstream limits
+syncstream locale
+syncstream map
+syncstream memory
+syncstream mutex
+syncstream new
+syncstream optional
+syncstream ostream
+syncstream print
+syncstream queue
+syncstream ratio
+syncstream shared_mutex
+syncstream stack
+syncstream stdexcept
+syncstream streambuf
+syncstream string
+syncstream string_view
+syncstream system_error
+syncstream tuple
+syncstream type_traits
+syncstream typeinfo
+syncstream unordered_map
+syncstream utility
+syncstream variant
+syncstream vector
+syncstream version
+system_error algorithm
+system_error atomic
+system_error bit
+system_error cctype
+system_error cerrno
+system_error climits
+system_error cmath
+system_error compare
+system_error concepts
+system_error cstddef
+system_error cstdint
+system_error cstdio
+system_error cstdlib
+system_error cstring
+system_error ctime
+system_error cwchar
+system_error cwctype
+system_error exception
+system_error initializer_list
+system_error iosfwd
+system_error iterator
+system_error limits
+system_error memory
+system_error new
+system_error optional
+system_error ratio
+system_error stdexcept
+system_error string
+system_error string_view
+system_error tuple
+system_error type_traits
+system_error typeinfo
+system_error utility
+system_error variant
+system_error version
+thread algorithm
+thread array
+thread atomic
+thread bit
+thread bitset
+thread cctype
+thread cerrno
+thread chrono
+thread climits
+thread clocale
+thread cmath
+thread compare
+thread concepts
+thread cstdarg
+thread cstddef
+thread cstdint
+thread cstdio
+thread cstdlib
+thread cstring
+thread ctime
+thread cwchar
+thread cwctype
+thread deque
+thread exception
+thread format
+thread forward_list
+thread functional
+thread initializer_list
+thread ios
+thread iosfwd
+thread istream
+thread iterator
+thread limits
+thread locale
+thread memory
+thread mutex
+thread new
+thread optional
+thread ostream
+thread print
+thread queue
+thread ratio
+thread sstream
+thread stack
+thread stdexcept
+thread streambuf
+thread string
+thread string_view
+thread system_error
+thread tuple
+thread type_traits
+thread typeinfo
+thread unordered_map
+thread utility
+thread variant
+thread vector
+thread version
+tuple cmath
+tuple compare
+tuple cstddef
+tuple cstdint
+tuple cstdlib
+tuple exception
+tuple initializer_list
+tuple iosfwd
+tuple limits
+tuple new
+tuple type_traits
+tuple typeinfo
+tuple utility
+tuple version
+type_traits cstdint
+type_traits version
+typeindex cmath
+typeindex compare
+typeindex cstddef
+typeindex cstdint
+typeindex cstdlib
+typeindex initializer_list
+typeindex iosfwd
+typeindex limits
+typeindex new
+typeindex type_traits
+typeindex typeinfo
+typeindex utility
+typeindex version
+typeinfo cstddef
+typeinfo cstdint
+typeinfo cstdlib
+typeinfo type_traits
+typeinfo version
+unordered_map algorithm
+unordered_map atomic
+unordered_map bit
+unordered_map cctype
+unordered_map climits
+unordered_map cmath
+unordered_map compare
+unordered_map concepts
+unordered_map cstddef
+unordered_map cstdint
+unordered_map cstdio
+unordered_map cstdlib
+unordered_map cstring
+unordered_map ctime
+unordered_map cwchar
+unordered_map cwctype
+unordered_map exception
+unordered_map initializer_list
+unordered_map iosfwd
+unordered_map iterator
+unordered_map limits
+unordered_map memory
+unordered_map new
+unordered_map optional
+unordered_map ratio
+unordered_map stdexcept
+unordered_map tuple
+unordered_map type_traits
+unordered_map typeinfo
+unordered_map utility
+unordered_map variant
+unordered_map version
+unordered_set algorithm
+unordered_set array
+unordered_set atomic
+unordered_set bit
+unordered_set cctype
+unordered_set cerrno
+unordered_set climits
+unordered_set clocale
+unordered_set cmath
+unordered_set compare
+unordered_set concepts
+unordered_set cstdarg
+unordered_set cstddef
+unordered_set cstdint
+unordered_set cstdio
+unordered_set cstdlib
+unordered_set cstring
+unordered_set ctime
+unordered_set cwchar
+unordered_set cwctype
+unordered_set exception
+unordered_set functional
+unordered_set initializer_list
+unordered_set ios
+unordered_set iosfwd
+unordered_set iterator
+unordered_set limits
+unordered_set locale
+unordered_set memory
+unordered_set mutex
+unordered_set new
+unordered_set optional
+unordered_set ratio
+unordered_set stdexcept
+unordered_set streambuf
+unordered_set string
+unordered_set string_view
+unordered_set system_error
+unordered_set tuple
+unordered_set type_traits
+unordered_set typeinfo
+unordered_set unordered_map
+unordered_set utility
+unordered_set variant
+unordered_set vector
+unordered_set version
+utility cmath
+utility compare
+utility cstddef
+utility cstdint
+utility cstdlib
+utility initializer_list
+utility iosfwd
+utility limits
+utility type_traits
+utility version
+valarray algorithm
+valarray array
+valarray atomic
+valarray bit
+valarray cctype
+valarray cerrno
+valarray climits
+valarray clocale
+valarray cmath
+valarray compare
+valarray concepts
+valarray cstdarg
+valarray cstddef
+valarray cstdint
+valarray cstdio
+valarray cstdlib
+valarray cstring
+valarray ctime
+valarray cwchar
+valarray cwctype
+valarray exception
+valarray functional
+valarray initializer_list
+valarray ios
+valarray iosfwd
+valarray iterator
+valarray limits
+valarray locale
+valarray memory
+valarray mutex
+valarray new
+valarray optional
+valarray ratio
+valarray stdexcept
+valarray streambuf
+valarray string
+valarray string_view
+valarray system_error
+valarray tuple
+valarray type_traits
+valarray typeinfo
+valarray unordered_map
+valarray utility
+valarray variant
+valarray vector
+valarray version
+variant cmath
+variant compare
+variant cstddef
+variant cstdint
+variant cstdlib
+variant cstring
+variant exception
+variant initializer_list
+variant iosfwd
+variant limits
+variant new
+variant tuple
+variant type_traits
+variant typeinfo
+variant utility
+variant version
+vector algorithm
+vector array
+vector atomic
+vector bit
+vector cctype
+vector cerrno
+vector climits
+vector clocale
+vector cmath
+vector compare
+vector concepts
+vector cstdarg
+vector cstddef
+vector cstdint
+vector cstdio
+vector cstdlib
+vector cstring
+vector ctime
+vector cwchar
+vector cwctype
+vector exception
+vector initializer_list
+vector ios
+vector iosfwd
+vector iterator
+vector limits
+vector locale
+vector memory
+vector mutex
+vector new
+vector optional
+vector ratio
+vector stdexcept
+vector streambuf
+vector string
+vector string_view
+vector system_error
+vector tuple
+vector type_traits
+vector typeinfo
+vector utility
+vector variant
+vector version
diff --git a/libcxx/test/libcxx-03/transitive_includes/cxx14.csv b/libcxx/test/libcxx-03/transitive_includes/cxx14.csv
new file mode 100644
index 0000000000000..c2eb5b44e8d7a
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/cxx14.csv
@@ -0,0 +1,2619 @@
+algorithm atomic
+algorithm bit
+algorithm cctype
+algorithm climits
+algorithm cmath
+algorithm compare
+algorithm concepts
+algorithm cstddef
+algorithm cstdint
+algorithm cstdio
+algorithm cstdlib
+algorithm cstring
+algorithm ctime
+algorithm cwchar
+algorithm cwctype
+algorithm exception
+algorithm execution
+algorithm initializer_list
+algorithm iosfwd
+algorithm iterator
+algorithm limits
+algorithm memory
+algorithm new
+algorithm optional
+algorithm ratio
+algorithm stdexcept
+algorithm tuple
+algorithm type_traits
+algorithm typeinfo
+algorithm utility
+algorithm variant
+algorithm version
+any algorithm
+any array
+any atomic
+any bit
+any cctype
+any cerrno
+any chrono
+any climits
+any clocale
+any cmath
+any compare
+any concepts
+any cstdarg
+any cstddef
+any cstdint
+any cstdio
+any cstdlib
+any cstring
+any ctime
+any cwchar
+any cwctype
+any exception
+any execution
+any forward_list
+any functional
+any initializer_list
+any ios
+any iosfwd
+any iterator
+any limits
+any locale
+any memory
+any mutex
+any new
+any optional
+any ratio
+any stdexcept
+any streambuf
+any string
+any string_view
+any system_error
+any tuple
+any type_traits
+any typeinfo
+any unordered_map
+any utility
+any variant
+any vector
+any version
+array algorithm
+array atomic
+array bit
+array cctype
+array climits
+array cmath
+array compare
+array concepts
+array cstddef
+array cstdint
+array cstdio
+array cstdlib
+array cstring
+array ctime
+array cwchar
+array cwctype
+array exception
+array execution
+array initializer_list
+array iosfwd
+array iterator
+array limits
+array memory
+array new
+array optional
+array ratio
+array stdexcept
+array tuple
+array type_traits
+array typeinfo
+array utility
+array variant
+array version
+atomic climits
+atomic cmath
+atomic compare
+atomic cstddef
+atomic cstdint
+atomic cstdlib
+atomic cstring
+atomic ctime
+atomic limits
+atomic ratio
+atomic type_traits
+atomic version
+barrier atomic
+barrier climits
+barrier cmath
+barrier compare
+barrier concepts
+barrier cstddef
+barrier cstdint
+barrier cstdlib
+barrier cstring
+barrier ctime
+barrier exception
+barrier initializer_list
+barrier iosfwd
+barrier iterator
+barrier limits
+barrier memory
+barrier new
+barrier ratio
+barrier stdexcept
+barrier tuple
+barrier type_traits
+barrier typeinfo
+barrier utility
+barrier variant
+barrier version
+bit cstdint
+bit cstdlib
+bit iosfwd
+bit limits
+bit type_traits
+bit version
+bitset algorithm
+bitset atomic
+bitset bit
+bitset cctype
+bitset climits
+bitset cmath
+bitset compare
+bitset concepts
+bitset cstddef
+bitset cstdint
+bitset cstdio
+bitset cstdlib
+bitset cstring
+bitset ctime
+bitset cwchar
+bitset cwctype
+bitset exception
+bitset execution
+bitset initializer_list
+bitset iosfwd
+bitset iterator
+bitset limits
+bitset memory
+bitset new
+bitset optional
+bitset ratio
+bitset stdexcept
+bitset string
+bitset string_view
+bitset tuple
+bitset type_traits
+bitset typeinfo
+bitset utility
+bitset variant
+bitset version
+ccomplex algorithm
+ccomplex array
+ccomplex atomic
+ccomplex bit
+ccomplex bitset
+ccomplex cctype
+ccomplex cerrno
+ccomplex climits
+ccomplex clocale
+ccomplex cmath
+ccomplex compare
+ccomplex complex
+ccomplex concepts
+ccomplex cstdarg
+ccomplex cstddef
+ccomplex cstdint
+ccomplex cstdio
+ccomplex cstdlib
+ccomplex cstring
+ccomplex ctime
+ccomplex cwchar
+ccomplex cwctype
+ccomplex deque
+ccomplex exception
+ccomplex execution
+ccomplex format
+ccomplex functional
+ccomplex initializer_list
+ccomplex ios
+ccomplex iosfwd
+ccomplex istream
+ccomplex iterator
+ccomplex limits
+ccomplex locale
+ccomplex memory
+ccomplex mutex
+ccomplex new
+ccomplex optional
+ccomplex ostream
+ccomplex print
+ccomplex queue
+ccomplex ratio
+ccomplex sstream
+ccomplex stack
+ccomplex stdexcept
+ccomplex streambuf
+ccomplex string
+ccomplex string_view
+ccomplex system_error
+ccomplex tuple
+ccomplex type_traits
+ccomplex typeinfo
+ccomplex unordered_map
+ccomplex utility
+ccomplex variant
+ccomplex vector
+ccomplex version
+charconv cmath
+charconv concepts
+charconv cstddef
+charconv cstdint
+charconv cstdlib
+charconv cstring
+charconv iosfwd
+charconv limits
+charconv new
+charconv type_traits
+charconv version
+chrono algorithm
+chrono array
+chrono atomic
+chrono bit
+chrono cctype
+chrono cerrno
+chrono climits
+chrono clocale
+chrono cmath
+chrono compare
+chrono concepts
+chrono cstdarg
+chrono cstddef
+chrono cstdint
+chrono cstdio
+chrono cstdlib
+chrono cstring
+chrono ctime
+chrono cwchar
+chrono cwctype
+chrono exception
+chrono execution
+chrono forward_list
+chrono functional
+chrono initializer_list
+chrono ios
+chrono iosfwd
+chrono iterator
+chrono limits
+chrono locale
+chrono memory
+chrono mutex
+chrono new
+chrono optional
+chrono ratio
+chrono stdexcept
+chrono streambuf
+chrono string
+chrono string_view
+chrono system_error
+chrono tuple
+chrono type_traits
+chrono typeinfo
+chrono unordered_map
+chrono utility
+chrono variant
+chrono vector
+chrono version
+cinttypes cstdint
+cmath cstdint
+cmath limits
+cmath type_traits
+cmath version
+codecvt algorithm
+codecvt atomic
+codecvt bit
+codecvt cctype
+codecvt cerrno
+codecvt climits
+codecvt clocale
+codecvt cmath
+codecvt compare
+codecvt concepts
+codecvt cstddef
+codecvt cstdint
+codecvt cstdio
+codecvt cstdlib
+codecvt cstring
+codecvt ctime
+codecvt cwchar
+codecvt cwctype
+codecvt exception
+codecvt execution
+codecvt initializer_list
+codecvt iosfwd
+codecvt iterator
+codecvt limits
+codecvt memory
+codecvt mutex
+codecvt new
+codecvt optional
+codecvt ratio
+codecvt stdexcept
+codecvt string
+codecvt string_view
+codecvt system_error
+codecvt tuple
+codecvt type_traits
+codecvt typeinfo
+codecvt utility
+codecvt variant
+codecvt version
+compare cmath
+compare cstddef
+compare cstdint
+compare limits
+compare type_traits
+compare version
+complex algorithm
+complex array
+complex atomic
+complex bit
+complex bitset
+complex cctype
+complex cerrno
+complex climits
+complex clocale
+complex cmath
+complex compare
+complex concepts
+complex cstdarg
+complex cstddef
+complex cstdint
+complex cstdio
+complex cstdlib
+complex cstring
+complex ctime
+complex cwchar
+complex cwctype
+complex deque
+complex exception
+complex execution
+complex format
+complex functional
+complex initializer_list
+complex ios
+complex iosfwd
+complex istream
+complex iterator
+complex limits
+complex locale
+complex memory
+complex mutex
+complex new
+complex optional
+complex ostream
+complex print
+complex queue
+complex ratio
+complex sstream
+complex stack
+complex stdexcept
+complex streambuf
+complex string
+complex string_view
+complex system_error
+complex tuple
+complex type_traits
+complex typeinfo
+complex unordered_map
+complex utility
+complex variant
+complex vector
+complex version
+concepts cstddef
+concepts cstdint
+concepts type_traits
+concepts version
+condition_variable algorithm
+condition_variable atomic
+condition_variable bit
+condition_variable cctype
+condition_variable cerrno
+condition_variable climits
+condition_variable cmath
+condition_variable compare
+condition_variable concepts
+condition_variable cstddef
+condition_variable cstdint
+condition_variable cstdio
+condition_variable cstdlib
+condition_variable cstring
+condition_variable ctime
+condition_variable cwchar
+condition_variable cwctype
+condition_variable exception
+condition_variable execution
+condition_variable initializer_list
+condition_variable iosfwd
+condition_variable iterator
+condition_variable limits
+condition_variable memory
+condition_variable new
+condition_variable optional
+condition_variable ratio
+condition_variable stdexcept
+condition_variable string
+condition_variable string_view
+condition_variable system_error
+condition_variable tuple
+condition_variable type_traits
+condition_variable typeinfo
+condition_variable utility
+condition_variable variant
+condition_variable version
+coroutine cmath
+coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine iosfwd
+coroutine limits
+coroutine type_traits
+coroutine version
+cstddef version
+ctgmath algorithm
+ctgmath array
+ctgmath atomic
+ctgmath bit
+ctgmath bitset
+ctgmath cctype
+ctgmath cerrno
+ctgmath climits
+ctgmath clocale
+ctgmath cmath
+ctgmath compare
+ctgmath complex
+ctgmath concepts
+ctgmath cstdarg
+ctgmath cstddef
+ctgmath cstdint
+ctgmath cstdio
+ctgmath cstdlib
+ctgmath cstring
+ctgmath ctime
+ctgmath cwchar
+ctgmath cwctype
+ctgmath deque
+ctgmath exception
+ctgmath execution
+ctgmath format
+ctgmath functional
+ctgmath initializer_list
+ctgmath ios
+ctgmath iosfwd
+ctgmath istream
+ctgmath iterator
+ctgmath limits
+ctgmath locale
+ctgmath memory
+ctgmath mutex
+ctgmath new
+ctgmath optional
+ctgmath ostream
+ctgmath print
+ctgmath queue
+ctgmath ratio
+ctgmath sstream
+ctgmath stack
+ctgmath stdexcept
+ctgmath streambuf
+ctgmath string
+ctgmath string_view
+ctgmath system_error
+ctgmath tuple
+ctgmath type_traits
+ctgmath typeinfo
+ctgmath unordered_map
+ctgmath utility
+ctgmath variant
+ctgmath vector
+ctgmath version
+cwchar cctype
+cwchar cstddef
+cwchar cwctype
+cwchar version
+cwctype cctype
+deque algorithm
+deque array
+deque atomic
+deque bit
+deque cctype
+deque cerrno
+deque climits
+deque clocale
+deque cmath
+deque compare
+deque concepts
+deque cstdarg
+deque cstddef
+deque cstdint
+deque cstdio
+deque cstdlib
+deque cstring
+deque ctime
+deque cwchar
+deque cwctype
+deque exception
+deque execution
+deque functional
+deque initializer_list
+deque ios
+deque iosfwd
+deque iterator
+deque limits
+deque locale
+deque memory
+deque mutex
+deque new
+deque optional
+deque ratio
+deque stdexcept
+deque streambuf
+deque string
+deque string_view
+deque system_error
+deque tuple
+deque type_traits
+deque typeinfo
+deque unordered_map
+deque utility
+deque variant
+deque vector
+deque version
+exception cstddef
+exception cstdint
+exception cstdlib
+exception new
+exception type_traits
+exception typeinfo
+exception version
+execution cstddef
+execution version
+expected version
+experimental/iterator algorithm
+experimental/iterator atomic
+experimental/iterator bit
+experimental/iterator bitset
+experimental/iterator cctype
+experimental/iterator cerrno
+experimental/iterator climits
+experimental/iterator clocale
+experimental/iterator cmath
+experimental/iterator compare
+experimental/iterator concepts
+experimental/iterator cstdarg
+experimental/iterator cstddef
+experimental/iterator cstdint
+experimental/iterator cstdio
+experimental/iterator cstdlib
+experimental/iterator cstring
+experimental/iterator ctime
+experimental/iterator cwchar
+experimental/iterator cwctype
+experimental/iterator exception
+experimental/iterator execution
+experimental/iterator initializer_list
+experimental/iterator ios
+experimental/iterator iosfwd
+experimental/iterator iterator
+experimental/iterator limits
+experimental/iterator locale
+experimental/iterator memory
+experimental/iterator mutex
+experimental/iterator new
+experimental/iterator optional
+experimental/iterator ratio
+experimental/iterator stdexcept
+experimental/iterator streambuf
+experimental/iterator string
+experimental/iterator string_view
+experimental/iterator system_error
+experimental/iterator tuple
+experimental/iterator type_traits
+experimental/iterator typeinfo
+experimental/iterator utility
+experimental/iterator variant
+experimental/iterator version
+experimental/memory cstddef
+experimental/memory cstdint
+experimental/memory cstring
+experimental/memory limits
+experimental/memory type_traits
+experimental/memory version
+experimental/propagate_const cstddef
+experimental/propagate_const cstdint
+experimental/propagate_const type_traits
+experimental/propagate_const version
+experimental/simd cstddef
+experimental/simd cstdint
+experimental/simd limits
+experimental/simd type_traits
+experimental/simd version
+experimental/type_traits cstddef
+experimental/type_traits cstdint
+experimental/type_traits initializer_list
+experimental/type_traits type_traits
+experimental/type_traits version
+experimental/utility cmath
+experimental/utility compare
+experimental/utility cstddef
+experimental/utility cstdint
+experimental/utility cstdlib
+experimental/utility initializer_list
+experimental/utility iosfwd
+experimental/utility limits
+experimental/utility type_traits
+experimental/utility utility
+experimental/utility version
+filesystem algorithm
+filesystem atomic
+filesystem bit
+filesystem cctype
+filesystem cerrno
+filesystem climits
+filesystem cmath
+filesystem compare
+filesystem concepts
+filesystem cstddef
+filesystem cstdint
+filesystem cstdio
+filesystem cstdlib
+filesystem cstring
+filesystem ctime
+filesystem cwchar
+filesystem cwctype
+filesystem exception
+filesystem execution
+filesystem initializer_list
+filesystem iosfwd
+filesystem iterator
+filesystem limits
+filesystem memory
+filesystem new
+filesystem optional
+filesystem ratio
+filesystem stdexcept
+filesystem string
+filesystem string_view
+filesystem system_error
+filesystem tuple
+filesystem type_traits
+filesystem typeinfo
+filesystem utility
+filesystem variant
+filesystem version
+flat_map cmath
+flat_map compare
+flat_map cstddef
+flat_map cstdint
+flat_map initializer_list
+flat_map limits
+flat_map type_traits
+flat_map version
+flat_set cmath
+flat_set compare
+flat_set cstddef
+flat_set cstdint
+flat_set initializer_list
+flat_set limits
+flat_set type_traits
+flat_set version
+format algorithm
+format array
+format atomic
+format bit
+format cctype
+format cerrno
+format climits
+format clocale
+format cmath
+format compare
+format concepts
+format cstdarg
+format cstddef
+format cstdint
+format cstdio
+format cstdlib
+format cstring
+format ctime
+format cwchar
+format cwctype
+format deque
+format exception
+format execution
+format functional
+format initializer_list
+format ios
+format iosfwd
+format iterator
+format limits
+format locale
+format memory
+format mutex
+format new
+format optional
+format queue
+format ratio
+format stack
+format stdexcept
+format streambuf
+format string
+format string_view
+format system_error
+format tuple
+format type_traits
+format typeinfo
+format unordered_map
+format utility
+format variant
+format vector
+format version
+forward_list algorithm
+forward_list array
+forward_list atomic
+forward_list bit
+forward_list cctype
+forward_list cerrno
+forward_list climits
+forward_list clocale
+forward_list cmath
+forward_list compare
+forward_list concepts
+forward_list cstdarg
+forward_list cstddef
+forward_list cstdint
+forward_list cstdio
+forward_list cstdlib
+forward_list cstring
+forward_list ctime
+forward_list cwchar
+forward_list cwctype
+forward_list exception
+forward_list execution
+forward_list functional
+forward_list initializer_list
+forward_list ios
+forward_list iosfwd
+forward_list iterator
+forward_list limits
+forward_list locale
+forward_list memory
+forward_list mutex
+forward_list new
+forward_list optional
+forward_list ratio
+forward_list stdexcept
+forward_list streambuf
+forward_list string
+forward_list string_view
+forward_list system_error
+forward_list tuple
+forward_list type_traits
+forward_list typeinfo
+forward_list unordered_map
+forward_list utility
+forward_list variant
+forward_list vector
+forward_list version
+fstream algorithm
+fstream array
+fstream atomic
+fstream bit
+fstream bitset
+fstream cctype
+fstream cerrno
+fstream climits
+fstream clocale
+fstream cmath
+fstream compare
+fstream concepts
+fstream cstdarg
+fstream cstddef
+fstream cstdint
+fstream cstdio
+fstream cstdlib
+fstream cstring
+fstream ctime
+fstream cwchar
+fstream cwctype
+fstream deque
+fstream exception
+fstream execution
+fstream filesystem
+fstream format
+fstream functional
+fstream initializer_list
+fstream iomanip
+fstream ios
+fstream iosfwd
+fstream istream
+fstream iterator
+fstream limits
+fstream locale
+fstream memory
+fstream mutex
+fstream new
+fstream optional
+fstream ostream
+fstream print
+fstream queue
+fstream ratio
+fstream stack
+fstream stdexcept
+fstream streambuf
+fstream string
+fstream string_view
+fstream system_error
+fstream tuple
+fstream type_traits
+fstream typeinfo
+fstream unordered_map
+fstream utility
+fstream variant
+fstream vector
+fstream version
+functional algorithm
+functional array
+functional atomic
+functional bit
+functional cctype
+functional cerrno
+functional climits
+functional clocale
+functional cmath
+functional compare
+functional concepts
+functional cstdarg
+functional cstddef
+functional cstdint
+functional cstdio
+functional cstdlib
+functional cstring
+functional ctime
+functional cwchar
+functional cwctype
+functional exception
+functional execution
+functional initializer_list
+functional ios
+functional iosfwd
+functional iterator
+functional limits
+functional locale
+functional memory
+functional mutex
+functional new
+functional optional
+functional ratio
+functional stdexcept
+functional streambuf
+functional string
+functional string_view
+functional system_error
+functional tuple
+functional type_traits
+functional typeinfo
+functional unordered_map
+functional utility
+functional variant
+functional vector
+functional version
+future algorithm
+future array
+future atomic
+future bit
+future bitset
+future cctype
+future cerrno
+future chrono
+future climits
+future clocale
+future cmath
+future compare
+future concepts
+future cstdarg
+future cstddef
+future cstdint
+future cstdio
+future cstdlib
+future cstring
+future ctime
+future cwchar
+future cwctype
+future deque
+future exception
+future execution
+future format
+future forward_list
+future functional
+future initializer_list
+future ios
+future iosfwd
+future istream
+future iterator
+future limits
+future locale
+future memory
+future mutex
+future new
+future optional
+future ostream
+future print
+future queue
+future ratio
+future sstream
+future stack
+future stdexcept
+future streambuf
+future string
+future string_view
+future system_error
+future thread
+future tuple
+future type_traits
+future typeinfo
+future unordered_map
+future utility
+future variant
+future vector
+future version
+initializer_list cstddef
+initializer_list version
+iomanip algorithm
+iomanip array
+iomanip atomic
+iomanip bit
+iomanip bitset
+iomanip cctype
+iomanip cerrno
+iomanip climits
+iomanip clocale
+iomanip cmath
+iomanip compare
+iomanip concepts
+iomanip cstdarg
+iomanip cstddef
+iomanip cstdint
+iomanip cstdio
+iomanip cstdlib
+iomanip cstring
+iomanip ctime
+iomanip cwchar
+iomanip cwctype
+iomanip deque
+iomanip exception
+iomanip execution
+iomanip format
+iomanip functional
+iomanip initializer_list
+iomanip ios
+iomanip iosfwd
+iomanip istream
+iomanip iterator
+iomanip limits
+iomanip locale
+iomanip memory
+iomanip mutex
+iomanip new
+iomanip optional
+iomanip ostream
+iomanip print
+iomanip queue
+iomanip ratio
+iomanip stack
+iomanip stdexcept
+iomanip streambuf
+iomanip string
+iomanip string_view
+iomanip system_error
+iomanip tuple
+iomanip type_traits
+iomanip typeinfo
+iomanip unordered_map
+iomanip utility
+iomanip variant
+iomanip vector
+iomanip version
+ios algorithm
+ios atomic
+ios bit
+ios cctype
+ios cerrno
+ios climits
+ios clocale
+ios cmath
+ios compare
+ios concepts
+ios cstddef
+ios cstdint
+ios cstdio
+ios cstdlib
+ios cstring
+ios ctime
+ios cwchar
+ios cwctype
+ios exception
+ios execution
+ios initializer_list
+ios iosfwd
+ios iterator
+ios limits
+ios memory
+ios mutex
+ios new
+ios optional
+ios ratio
+ios stdexcept
+ios string
+ios string_view
+ios system_error
+ios tuple
+ios type_traits
+ios typeinfo
+ios utility
+ios variant
+ios version
+iosfwd version
+iostream algorithm
+iostream array
+iostream atomic
+iostream bit
+iostream bitset
+iostream cctype
+iostream cerrno
+iostream climits
+iostream clocale
+iostream cmath
+iostream compare
+iostream concepts
+iostream cstdarg
+iostream cstddef
+iostream cstdint
+iostream cstdio
+iostream cstdlib
+iostream cstring
+iostream ctime
+iostream cwchar
+iostream cwctype
+iostream deque
+iostream exception
+iostream execution
+iostream format
+iostream functional
+iostream initializer_list
+iostream ios
+iostream iosfwd
+iostream istream
+iostream iterator
+iostream limits
+iostream locale
+iostream memory
+iostream mutex
+iostream new
+iostream optional
+iostream ostream
+iostream print
+iostream queue
+iostream ratio
+iostream stack
+iostream stdexcept
+iostream streambuf
+iostream string
+iostream string_view
+iostream system_error
+iostream tuple
+iostream type_traits
+iostream typeinfo
+iostream unordered_map
+iostream utility
+iostream variant
+iostream vector
+iostream version
+istream algorithm
+istream array
+istream atomic
+istream bit
+istream bitset
+istream cctype
+istream cerrno
+istream climits
+istream clocale
+istream cmath
+istream compare
+istream concepts
+istream cstdarg
+istream cstddef
+istream cstdint
+istream cstdio
+istream cstdlib
+istream cstring
+istream ctime
+istream cwchar
+istream cwctype
+istream deque
+istream exception
+istream execution
+istream format
+istream functional
+istream initializer_list
+istream ios
+istream iosfwd
+istream iterator
+istream limits
+istream locale
+istream memory
+istream mutex
+istream new
+istream optional
+istream ostream
+istream print
+istream queue
+istream ratio
+istream stack
+istream stdexcept
+istream streambuf
+istream string
+istream string_view
+istream system_error
+istream tuple
+istream type_traits
+istream typeinfo
+istream unordered_map
+istream utility
+istream variant
+istream vector
+istream version
+iterator cctype
+iterator cmath
+iterator compare
+iterator concepts
+iterator cstddef
+iterator cstdint
+iterator cstdio
+iterator cstdlib
+iterator cstring
+iterator cwchar
+iterator cwctype
+iterator exception
+iterator initializer_list
+iterator iosfwd
+iterator limits
+iterator new
+iterator tuple
+iterator type_traits
+iterator typeinfo
+iterator utility
+iterator variant
+iterator version
+latch atomic
+latch climits
+latch cmath
+latch compare
+latch cstddef
+latch cstdint
+latch cstdlib
+latch cstring
+latch ctime
+latch limits
+latch ratio
+latch type_traits
+latch version
+limits cstdint
+limits type_traits
+limits version
+list algorithm
+list array
+list atomic
+list bit
+list cctype
+list cerrno
+list climits
+list clocale
+list cmath
+list compare
+list concepts
+list cstdarg
+list cstddef
+list cstdint
+list cstdio
+list cstdlib
+list cstring
+list ctime
+list cwchar
+list cwctype
+list exception
+list execution
+list functional
+list initializer_list
+list ios
+list iosfwd
+list iterator
+list limits
+list locale
+list memory
+list mutex
+list new
+list optional
+list ratio
+list stdexcept
+list streambuf
+list string
+list string_view
+list system_error
+list tuple
+list type_traits
+list typeinfo
+list unordered_map
+list utility
+list variant
+list vector
+list version
+locale algorithm
+locale atomic
+locale bit
+locale cctype
+locale cerrno
+locale climits
+locale clocale
+locale cmath
+locale compare
+locale concepts
+locale cstdarg
+locale cstddef
+locale cstdint
+locale cstdio
+locale cstdlib
+locale cstring
+locale ctime
+locale cwchar
+locale cwctype
+locale exception
+locale execution
+locale initializer_list
+locale ios
+locale iosfwd
+locale iterator
+locale limits
+locale memory
+locale mutex
+locale new
+locale optional
+locale ratio
+locale stdexcept
+locale streambuf
+locale string
+locale string_view
+locale system_error
+locale tuple
+locale type_traits
+locale typeinfo
+locale utility
+locale variant
+locale version
+map algorithm
+map array
+map atomic
+map bit
+map cctype
+map cerrno
+map climits
+map clocale
+map cmath
+map compare
+map concepts
+map cstdarg
+map cstddef
+map cstdint
+map cstdio
+map cstdlib
+map cstring
+map ctime
+map cwchar
+map cwctype
+map exception
+map execution
+map functional
+map initializer_list
+map ios
+map iosfwd
+map iterator
+map limits
+map locale
+map memory
+map mutex
+map new
+map optional
+map ratio
+map stdexcept
+map streambuf
+map string
+map string_view
+map system_error
+map tuple
+map type_traits
+map typeinfo
+map unordered_map
+map utility
+map variant
+map vector
+map version
+mdspan version
+memory atomic
+memory cctype
+memory climits
+memory cmath
+memory compare
+memory concepts
+memory cstddef
+memory cstdint
+memory cstdio
+memory cstdlib
+memory cstring
+memory ctime
+memory cwchar
+memory cwctype
+memory exception
+memory initializer_list
+memory iosfwd
+memory iterator
+memory limits
+memory new
+memory ratio
+memory stdexcept
+memory tuple
+memory type_traits
+memory typeinfo
+memory utility
+memory variant
+memory version
+memory_resource cstddef
+memory_resource cstdint
+memory_resource cstdlib
+memory_resource exception
+memory_resource iosfwd
+memory_resource new
+memory_resource stdexcept
+memory_resource type_traits
+memory_resource typeinfo
+memory_resource version
+mutex algorithm
+mutex atomic
+mutex bit
+mutex cctype
+mutex cerrno
+mutex climits
+mutex cmath
+mutex compare
+mutex concepts
+mutex cstddef
+mutex cstdint
+mutex cstdio
+mutex cstdlib
+mutex cstring
+mutex ctime
+mutex cwchar
+mutex cwctype
+mutex exception
+mutex execution
+mutex initializer_list
+mutex iosfwd
+mutex iterator
+mutex limits
+mutex memory
+mutex new
+mutex optional
+mutex ratio
+mutex stdexcept
+mutex string
+mutex string_view
+mutex system_error
+mutex tuple
+mutex type_traits
+mutex typeinfo
+mutex utility
+mutex variant
+mutex version
+new cstddef
+new cstdint
+new cstdlib
+new type_traits
+new version
+numbers concepts
+numbers cstddef
+numbers cstdint
+numbers type_traits
+numbers version
+numeric algorithm
+numeric array
+numeric atomic
+numeric bit
+numeric cctype
+numeric cerrno
+numeric climits
+numeric clocale
+numeric cmath
+numeric compare
+numeric concepts
+numeric cstdarg
+numeric cstddef
+numeric cstdint
+numeric cstdio
+numeric cstdlib
+numeric cstring
+numeric ctime
+numeric cwchar
+numeric cwctype
+numeric exception
+numeric execution
+numeric functional
+numeric initializer_list
+numeric ios
+numeric iosfwd
+numeric iterator
+numeric limits
+numeric locale
+numeric memory
+numeric mutex
+numeric new
+numeric optional
+numeric ratio
+numeric stdexcept
+numeric streambuf
+numeric string
+numeric string_view
+numeric system_error
+numeric tuple
+numeric type_traits
+numeric typeinfo
+numeric unordered_map
+numeric utility
+numeric variant
+numeric vector
+numeric version
+optional atomic
+optional cctype
+optional climits
+optional cmath
+optional compare
+optional concepts
+optional cstddef
+optional cstdint
+optional cstdio
+optional cstdlib
+optional cstring
+optional ctime
+optional cwchar
+optional cwctype
+optional exception
+optional initializer_list
+optional iosfwd
+optional iterator
+optional limits
+optional memory
+optional new
+optional ratio
+optional stdexcept
+optional tuple
+optional type_traits
+optional typeinfo
+optional utility
+optional variant
+optional version
+ostream algorithm
+ostream array
+ostream atomic
+ostream bit
+ostream bitset
+ostream cctype
+ostream cerrno
+ostream climits
+ostream clocale
+ostream cmath
+ostream compare
+ostream concepts
+ostream cstdarg
+ostream cstddef
+ostream cstdint
+ostream cstdio
+ostream cstdlib
+ostream cstring
+ostream ctime
+ostream cwchar
+ostream cwctype
+ostream deque
+ostream exception
+ostream execution
+ostream format
+ostream functional
+ostream initializer_list
+ostream ios
+ostream iosfwd
+ostream iterator
+ostream limits
+ostream locale
+ostream memory
+ostream mutex
+ostream new
+ostream optional
+ostream print
+ostream queue
+ostream ratio
+ostream stack
+ostream stdexcept
+ostream streambuf
+ostream string
+ostream string_view
+ostream system_error
+ostream tuple
+ostream type_traits
+ostream typeinfo
+ostream unordered_map
+ostream utility
+ostream variant
+ostream vector
+ostream version
+print algorithm
+print array
+print atomic
+print bit
+print cctype
+print cerrno
+print climits
+print clocale
+print cmath
+print compare
+print concepts
+print cstdarg
+print cstddef
+print cstdint
+print cstdio
+print cstdlib
+print cstring
+print ctime
+print cwchar
+print cwctype
+print deque
+print exception
+print execution
+print format
+print functional
+print initializer_list
+print ios
+print iosfwd
+print iterator
+print limits
+print locale
+print memory
+print mutex
+print new
+print optional
+print queue
+print ratio
+print stack
+print stdexcept
+print streambuf
+print string
+print string_view
+print system_error
+print tuple
+print type_traits
+print typeinfo
+print unordered_map
+print utility
+print variant
+print vector
+print version
+queue algorithm
+queue array
+queue atomic
+queue bit
+queue cctype
+queue cerrno
+queue climits
+queue clocale
+queue cmath
+queue compare
+queue concepts
+queue cstdarg
+queue cstddef
+queue cstdint
+queue cstdio
+queue cstdlib
+queue cstring
+queue ctime
+queue cwchar
+queue cwctype
+queue deque
+queue exception
+queue execution
+queue functional
+queue initializer_list
+queue ios
+queue iosfwd
+queue iterator
+queue limits
+queue locale
+queue memory
+queue mutex
+queue new
+queue optional
+queue ratio
+queue stdexcept
+queue streambuf
+queue string
+queue string_view
+queue system_error
+queue tuple
+queue type_traits
+queue typeinfo
+queue unordered_map
+queue utility
+queue variant
+queue vector
+queue version
+random algorithm
+random array
+random atomic
+random bit
+random cctype
+random cerrno
+random climits
+random clocale
+random cmath
+random compare
+random concepts
+random cstdarg
+random cstddef
+random cstdint
+random cstdio
+random cstdlib
+random cstring
+random ctime
+random cwchar
+random cwctype
+random exception
+random execution
+random functional
+random initializer_list
+random ios
+random iosfwd
+random iterator
+random limits
+random locale
+random memory
+random mutex
+random new
+random numeric
+random optional
+random ratio
+random stdexcept
+random streambuf
+random string
+random string_view
+random system_error
+random tuple
+random type_traits
+random typeinfo
+random unordered_map
+random utility
+random variant
+random vector
+random version
+ranges cctype
+ranges cmath
+ranges compare
+ranges concepts
+ranges cstddef
+ranges cstdint
+ranges cstdio
+ranges cstdlib
+ranges cstring
+ranges cwchar
+ranges cwctype
+ranges exception
+ranges initializer_list
+ranges iosfwd
+ranges iterator
+ranges limits
+ranges new
+ranges tuple
+ranges type_traits
+ranges typeinfo
+ranges utility
+ranges variant
+ranges version
+ratio climits
+ratio cstdint
+ratio type_traits
+ratio version
+regex algorithm
+regex array
+regex atomic
+regex bit
+regex cctype
+regex cerrno
+regex climits
+regex clocale
+regex cmath
+regex compare
+regex concepts
+regex cstdarg
+regex cstddef
+regex cstdint
+regex cstdio
+regex cstdlib
+regex cstring
+regex ctime
+regex cwchar
+regex cwctype
+regex deque
+regex exception
+regex execution
+regex functional
+regex initializer_list
+regex ios
+regex iosfwd
+regex iterator
+regex limits
+regex locale
+regex memory
+regex mutex
+regex new
+regex optional
+regex ratio
+regex stdexcept
+regex streambuf
+regex string
+regex string_view
+regex system_error
+regex tuple
+regex type_traits
+regex typeinfo
+regex unordered_map
+regex utility
+regex variant
+regex vector
+regex version
+scoped_allocator atomic
+scoped_allocator cctype
+scoped_allocator climits
+scoped_allocator cmath
+scoped_allocator compare
+scoped_allocator concepts
+scoped_allocator cstddef
+scoped_allocator cstdint
+scoped_allocator cstdio
+scoped_allocator cstdlib
+scoped_allocator cstring
+scoped_allocator ctime
+scoped_allocator cwchar
+scoped_allocator cwctype
+scoped_allocator exception
+scoped_allocator initializer_list
+scoped_allocator iosfwd
+scoped_allocator iterator
+scoped_allocator limits
+scoped_allocator memory
+scoped_allocator new
+scoped_allocator ratio
+scoped_allocator stdexcept
+scoped_allocator tuple
+scoped_allocator type_traits
+scoped_allocator typeinfo
+scoped_allocator utility
+scoped_allocator variant
+scoped_allocator version
+semaphore atomic
+semaphore climits
+semaphore cmath
+semaphore compare
+semaphore cstddef
+semaphore cstdint
+semaphore cstdlib
+semaphore cstring
+semaphore ctime
+semaphore limits
+semaphore ratio
+semaphore type_traits
+semaphore version
+set algorithm
+set array
+set atomic
+set bit
+set cctype
+set cerrno
+set climits
+set clocale
+set cmath
+set compare
+set concepts
+set cstdarg
+set cstddef
+set cstdint
+set cstdio
+set cstdlib
+set cstring
+set ctime
+set cwchar
+set cwctype
+set exception
+set execution
+set functional
+set initializer_list
+set ios
+set iosfwd
+set iterator
+set limits
+set locale
+set memory
+set mutex
+set new
+set optional
+set ratio
+set stdexcept
+set streambuf
+set string
+set string_view
+set system_error
+set tuple
+set type_traits
+set typeinfo
+set unordered_map
+set utility
+set variant
+set vector
+set version
+shared_mutex algorithm
+shared_mutex atomic
+shared_mutex bit
+shared_mutex cctype
+shared_mutex cerrno
+shared_mutex climits
+shared_mutex cmath
+shared_mutex compare
+shared_mutex concepts
+shared_mutex cstddef
+shared_mutex cstdint
+shared_mutex cstdio
+shared_mutex cstdlib
+shared_mutex cstring
+shared_mutex ctime
+shared_mutex cwchar
+shared_mutex cwctype
+shared_mutex exception
+shared_mutex execution
+shared_mutex initializer_list
+shared_mutex iosfwd
+shared_mutex iterator
+shared_mutex limits
+shared_mutex memory
+shared_mutex new
+shared_mutex optional
+shared_mutex ratio
+shared_mutex stdexcept
+shared_mutex string
+shared_mutex string_view
+shared_mutex system_error
+shared_mutex tuple
+shared_mutex type_traits
+shared_mutex typeinfo
+shared_mutex utility
+shared_mutex variant
+shared_mutex version
+source_location cstdint
+source_location version
+span algorithm
+span array
+span atomic
+span bit
+span cctype
+span cerrno
+span climits
+span clocale
+span cmath
+span compare
+span concepts
+span cstdarg
+span cstddef
+span cstdint
+span cstdio
+span cstdlib
+span cstring
+span ctime
+span cwchar
+span cwctype
+span exception
+span execution
+span functional
+span initializer_list
+span ios
+span iosfwd
+span iterator
+span limits
+span locale
+span memory
+span mutex
+span new
+span optional
+span ratio
+span stdexcept
+span streambuf
+span string
+span string_view
+span system_error
+span tuple
+span type_traits
+span typeinfo
+span unordered_map
+span utility
+span variant
+span vector
+span version
+sstream algorithm
+sstream array
+sstream atomic
+sstream bit
+sstream bitset
+sstream cctype
+sstream cerrno
+sstream climits
+sstream clocale
+sstream cmath
+sstream compare
+sstream concepts
+sstream cstdarg
+sstream cstddef
+sstream cstdint
+sstream cstdio
+sstream cstdlib
+sstream cstring
+sstream ctime
+sstream cwchar
+sstream cwctype
+sstream deque
+sstream exception
+sstream execution
+sstream format
+sstream functional
+sstream initializer_list
+sstream ios
+sstream iosfwd
+sstream istream
+sstream iterator
+sstream limits
+sstream locale
+sstream memory
+sstream mutex
+sstream new
+sstream optional
+sstream ostream
+sstream print
+sstream queue
+sstream ratio
+sstream stack
+sstream stdexcept
+sstream streambuf
+sstream string
+sstream string_view
+sstream system_error
+sstream tuple
+sstream type_traits
+sstream typeinfo
+sstream unordered_map
+sstream utility
+sstream variant
+sstream vector
+sstream version
+stack algorithm
+stack array
+stack atomic
+stack bit
+stack cctype
+stack cerrno
+stack climits
+stack clocale
+stack cmath
+stack compare
+stack concepts
+stack cstdarg
+stack cstddef
+stack cstdint
+stack cstdio
+stack cstdlib
+stack cstring
+stack ctime
+stack cwchar
+stack cwctype
+stack deque
+stack exception
+stack execution
+stack functional
+stack initializer_list
+stack ios
+stack iosfwd
+stack iterator
+stack limits
+stack locale
+stack memory
+stack mutex
+stack new
+stack optional
+stack ratio
+stack stdexcept
+stack streambuf
+stack string
+stack string_view
+stack system_error
+stack tuple
+stack type_traits
+stack typeinfo
+stack unordered_map
+stack utility
+stack variant
+stack vector
+stack version
+stdexcept cstddef
+stdexcept cstdint
+stdexcept cstdlib
+stdexcept exception
+stdexcept iosfwd
+stdexcept new
+stdexcept type_traits
+stdexcept typeinfo
+stdexcept version
+stop_token iosfwd
+stop_token version
+streambuf algorithm
+streambuf atomic
+streambuf bit
+streambuf cctype
+streambuf cerrno
+streambuf climits
+streambuf clocale
+streambuf cmath
+streambuf compare
+streambuf concepts
+streambuf cstddef
+streambuf cstdint
+streambuf cstdio
+streambuf cstdlib
+streambuf cstring
+streambuf ctime
+streambuf cwchar
+streambuf cwctype
+streambuf exception
+streambuf execution
+streambuf initializer_list
+streambuf ios
+streambuf iosfwd
+streambuf iterator
+streambuf limits
+streambuf memory
+streambuf mutex
+streambuf new
+streambuf optional
+streambuf ratio
+streambuf stdexcept
+streambuf string
+streambuf string_view
+streambuf system_error
+streambuf tuple
+streambuf type_traits
+streambuf typeinfo
+streambuf utility
+streambuf variant
+streambuf version
+string algorithm
+string atomic
+string bit
+string cctype
+string climits
+string cmath
+string compare
+string concepts
+string cstddef
+string cstdint
+string cstdio
+string cstdlib
+string cstring
+string ctime
+string cwchar
+string cwctype
+string exception
+string execution
+string initializer_list
+string iosfwd
+string iterator
+string limits
+string memory
+string new
+string optional
+string ratio
+string stdexcept
+string string_view
+string tuple
+string type_traits
+string typeinfo
+string utility
+string variant
+string version
+string_view algorithm
+string_view atomic
+string_view bit
+string_view cctype
+string_view climits
+string_view cmath
+string_view compare
+string_view concepts
+string_view cstddef
+string_view cstdint
+string_view cstdio
+string_view cstdlib
+string_view cstring
+string_view ctime
+string_view cwchar
+string_view cwctype
+string_view exception
+string_view execution
+string_view initializer_list
+string_view iosfwd
+string_view iterator
+string_view limits
+string_view memory
+string_view new
+string_view optional
+string_view ratio
+string_view stdexcept
+string_view tuple
+string_view type_traits
+string_view typeinfo
+string_view utility
+string_view variant
+string_view version
+strstream algorithm
+strstream array
+strstream atomic
+strstream bit
+strstream bitset
+strstream cctype
+strstream cerrno
+strstream climits
+strstream clocale
+strstream cmath
+strstream compare
+strstream concepts
+strstream cstdarg
+strstream cstddef
+strstream cstdint
+strstream cstdio
+strstream cstdlib
+strstream cstring
+strstream ctime
+strstream cwchar
+strstream cwctype
+strstream deque
+strstream exception
+strstream execution
+strstream format
+strstream functional
+strstream initializer_list
+strstream ios
+strstream iosfwd
+strstream istream
+strstream iterator
+strstream limits
+strstream locale
+strstream memory
+strstream mutex
+strstream new
+strstream optional
+strstream ostream
+strstream print
+strstream queue
+strstream ratio
+strstream stack
+strstream stdexcept
+strstream streambuf
+strstream string
+strstream string_view
+strstream system_error
+strstream tuple
+strstream type_traits
+strstream typeinfo
+strstream unordered_map
+strstream utility
+strstream variant
+strstream vector
+strstream version
+syncstream algorithm
+syncstream array
+syncstream atomic
+syncstream bit
+syncstream bitset
+syncstream cctype
+syncstream cerrno
+syncstream climits
+syncstream clocale
+syncstream cmath
+syncstream compare
+syncstream concepts
+syncstream cstdarg
+syncstream cstddef
+syncstream cstdint
+syncstream cstdio
+syncstream cstdlib
+syncstream cstring
+syncstream ctime
+syncstream cwchar
+syncstream cwctype
+syncstream deque
+syncstream exception
+syncstream execution
+syncstream format
+syncstream functional
+syncstream initializer_list
+syncstream ios
+syncstream iosfwd
+syncstream iterator
+syncstream limits
+syncstream locale
+syncstream map
+syncstream memory
+syncstream mutex
+syncstream new
+syncstream optional
+syncstream ostream
+syncstream print
+syncstream queue
+syncstream ratio
+syncstream shared_mutex
+syncstream stack
+syncstream stdexcept
+syncstream streambuf
+syncstream string
+syncstream string_view
+syncstream system_error
+syncstream tuple
+syncstream type_traits
+syncstream typeinfo
+syncstream unordered_map
+syncstream utility
+syncstream variant
+syncstream vector
+syncstream version
+system_error algorithm
+system_error atomic
+system_error bit
+system_error cctype
+system_error cerrno
+system_error climits
+system_error cmath
+system_error compare
+system_error concepts
+system_error cstddef
+system_error cstdint
+system_error cstdio
+system_error cstdlib
+system_error cstring
+system_error ctime
+system_error cwchar
+system_error cwctype
+system_error exception
+system_error execution
+system_error initializer_list
+system_error iosfwd
+system_error iterator
+system_error limits
+system_error memory
+system_error new
+system_error optional
+system_error ratio
+system_error stdexcept
+system_error string
+system_error string_view
+system_error tuple
+system_error type_traits
+system_error typeinfo
+system_error utility
+system_error variant
+system_error version
+thread algorithm
+thread array
+thread atomic
+thread bit
+thread bitset
+thread cctype
+thread cerrno
+thread chrono
+thread climits
+thread clocale
+thread cmath
+thread compare
+thread concepts
+thread cstdarg
+thread cstddef
+thread cstdint
+thread cstdio
+thread cstdlib
+thread cstring
+thread ctime
+thread cwchar
+thread cwctype
+thread deque
+thread exception
+thread execution
+thread format
+thread forward_list
+thread functional
+thread initializer_list
+thread ios
+thread iosfwd
+thread istream
+thread iterator
+thread limits
+thread locale
+thread memory
+thread mutex
+thread new
+thread optional
+thread ostream
+thread print
+thread queue
+thread ratio
+thread sstream
+thread stack
+thread stdexcept
+thread streambuf
+thread string
+thread string_view
+thread system_error
+thread tuple
+thread type_traits
+thread typeinfo
+thread unordered_map
+thread utility
+thread variant
+thread vector
+thread version
+tuple cmath
+tuple compare
+tuple cstddef
+tuple cstdint
+tuple cstdlib
+tuple exception
+tuple initializer_list
+tuple iosfwd
+tuple limits
+tuple new
+tuple type_traits
+tuple typeinfo
+tuple utility
+tuple version
+type_traits cstdint
+type_traits version
+typeindex cmath
+typeindex compare
+typeindex cstddef
+typeindex cstdint
+typeindex cstdlib
+typeindex initializer_list
+typeindex iosfwd
+typeindex limits
+typeindex new
+typeindex type_traits
+typeindex typeinfo
+typeindex utility
+typeindex version
+typeinfo cstddef
+typeinfo cstdint
+typeinfo cstdlib
+typeinfo type_traits
+typeinfo version
+unordered_map algorithm
+unordered_map atomic
+unordered_map bit
+unordered_map cctype
+unordered_map climits
+unordered_map cmath
+unordered_map compare
+unordered_map concepts
+unordered_map cstddef
+unordered_map cstdint
+unordered_map cstdio
+unordered_map cstdlib
+unordered_map cstring
+unordered_map ctime
+unordered_map cwchar
+unordered_map cwctype
+unordered_map exception
+unordered_map execution
+unordered_map initializer_list
+unordered_map iosfwd
+unordered_map iterator
+unordered_map limits
+unordered_map memory
+unordered_map new
+unordered_map optional
+unordered_map ratio
+unordered_map stdexcept
+unordered_map tuple
+unordered_map type_traits
+unordered_map typeinfo
+unordered_map utility
+unordered_map variant
+unordered_map version
+unordered_set algorithm
+unordered_set array
+unordered_set atomic
+unordered_set bit
+unordered_set cctype
+unordered_set cerrno
+unordered_set climits
+unordered_set clocale
+unordered_set cmath
+unordered_set compare
+unordered_set concepts
+unordered_set cstdarg
+unordered_set cstddef
+unordered_set cstdint
+unordered_set cstdio
+unordered_set cstdlib
+unordered_set cstring
+unordered_set ctime
+unordered_set cwchar
+unordered_set cwctype
+unordered_set exception
+unordered_set execution
+unordered_set functional
+unordered_set initializer_list
+unordered_set ios
+unordered_set iosfwd
+unordered_set iterator
+unordered_set limits
+unordered_set locale
+unordered_set memory
+unordered_set mutex
+unordered_set new
+unordered_set optional
+unordered_set ratio
+unordered_set stdexcept
+unordered_set streambuf
+unordered_set string
+unordered_set string_view
+unordered_set system_error
+unordered_set tuple
+unordered_set type_traits
+unordered_set typeinfo
+unordered_set unordered_map
+unordered_set utility
+unordered_set variant
+unordered_set vector
+unordered_set version
+utility cmath
+utility compare
+utility cstddef
+utility cstdint
+utility cstdlib
+utility initializer_list
+utility iosfwd
+utility limits
+utility type_traits
+utility version
+valarray algorithm
+valarray array
+valarray atomic
+valarray bit
+valarray cctype
+valarray cerrno
+valarray climits
+valarray clocale
+valarray cmath
+valarray compare
+valarray concepts
+valarray cstdarg
+valarray cstddef
+valarray cstdint
+valarray cstdio
+valarray cstdlib
+valarray cstring
+valarray ctime
+valarray cwchar
+valarray cwctype
+valarray exception
+valarray execution
+valarray functional
+valarray initializer_list
+valarray ios
+valarray iosfwd
+valarray iterator
+valarray limits
+valarray locale
+valarray memory
+valarray mutex
+valarray new
+valarray optional
+valarray ratio
+valarray stdexcept
+valarray streambuf
+valarray string
+valarray string_view
+valarray system_error
+valarray tuple
+valarray type_traits
+valarray typeinfo
+valarray unordered_map
+valarray utility
+valarray variant
+valarray vector
+valarray version
+variant cmath
+variant compare
+variant cstddef
+variant cstdint
+variant cstdlib
+variant cstring
+variant exception
+variant initializer_list
+variant iosfwd
+variant limits
+variant new
+variant tuple
+variant type_traits
+variant typeinfo
+variant utility
+variant version
+vector algorithm
+vector array
+vector atomic
+vector bit
+vector cctype
+vector cerrno
+vector climits
+vector clocale
+vector cmath
+vector compare
+vector concepts
+vector cstdarg
+vector cstddef
+vector cstdint
+vector cstdio
+vector cstdlib
+vector cstring
+vector ctime
+vector cwchar
+vector cwctype
+vector exception
+vector execution
+vector initializer_list
+vector ios
+vector iosfwd
+vector iterator
+vector limits
+vector locale
+vector memory
+vector mutex
+vector new
+vector optional
+vector ratio
+vector stdexcept
+vector streambuf
+vector string
+vector string_view
+vector system_error
+vector tuple
+vector type_traits
+vector typeinfo
+vector utility
+vector variant
+vector version
diff --git a/libcxx/test/libcxx-03/transitive_includes/cxx17.csv b/libcxx/test/libcxx-03/transitive_includes/cxx17.csv
new file mode 100644
index 0000000000000..332cb62f35b5f
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/cxx17.csv
@@ -0,0 +1,2621 @@
+algorithm atomic
+algorithm bit
+algorithm cctype
+algorithm climits
+algorithm cmath
+algorithm compare
+algorithm concepts
+algorithm cstddef
+algorithm cstdint
+algorithm cstdio
+algorithm cstdlib
+algorithm cstring
+algorithm ctime
+algorithm cwchar
+algorithm cwctype
+algorithm exception
+algorithm initializer_list
+algorithm iosfwd
+algorithm iterator
+algorithm limits
+algorithm memory
+algorithm new
+algorithm optional
+algorithm ratio
+algorithm stdexcept
+algorithm tuple
+algorithm type_traits
+algorithm typeinfo
+algorithm utility
+algorithm variant
+algorithm version
+any algorithm
+any array
+any atomic
+any bit
+any cctype
+any cerrno
+any chrono
+any climits
+any clocale
+any cmath
+any compare
+any concepts
+any cstdarg
+any cstddef
+any cstdint
+any cstdio
+any cstdlib
+any cstring
+any ctime
+any cwchar
+any cwctype
+any exception
+any forward_list
+any functional
+any initializer_list
+any ios
+any iosfwd
+any iterator
+any limits
+any locale
+any memory
+any mutex
+any new
+any optional
+any ratio
+any stdexcept
+any streambuf
+any string
+any string_view
+any system_error
+any tuple
+any type_traits
+any typeinfo
+any unordered_map
+any utility
+any variant
+any vector
+any version
+array algorithm
+array atomic
+array bit
+array cctype
+array climits
+array cmath
+array compare
+array concepts
+array cstddef
+array cstdint
+array cstdio
+array cstdlib
+array cstring
+array ctime
+array cwchar
+array cwctype
+array exception
+array initializer_list
+array iosfwd
+array iterator
+array limits
+array memory
+array new
+array optional
+array ratio
+array stdexcept
+array tuple
+array type_traits
+array typeinfo
+array utility
+array variant
+array version
+atomic climits
+atomic cmath
+atomic compare
+atomic cstddef
+atomic cstdint
+atomic cstdlib
+atomic cstring
+atomic ctime
+atomic limits
+atomic ratio
+atomic type_traits
+atomic version
+barrier atomic
+barrier climits
+barrier cmath
+barrier compare
+barrier concepts
+barrier cstddef
+barrier cstdint
+barrier cstdlib
+barrier cstring
+barrier ctime
+barrier exception
+barrier initializer_list
+barrier iosfwd
+barrier iterator
+barrier limits
+barrier memory
+barrier new
+barrier ratio
+barrier stdexcept
+barrier tuple
+barrier type_traits
+barrier typeinfo
+barrier utility
+barrier variant
+barrier version
+bit cstdint
+bit cstdlib
+bit iosfwd
+bit limits
+bit type_traits
+bit version
+bitset algorithm
+bitset atomic
+bitset bit
+bitset cctype
+bitset climits
+bitset cmath
+bitset compare
+bitset concepts
+bitset cstddef
+bitset cstdint
+bitset cstdio
+bitset cstdlib
+bitset cstring
+bitset ctime
+bitset cwchar
+bitset cwctype
+bitset exception
+bitset initializer_list
+bitset iosfwd
+bitset iterator
+bitset limits
+bitset memory
+bitset new
+bitset optional
+bitset ratio
+bitset stdexcept
+bitset string
+bitset string_view
+bitset tuple
+bitset type_traits
+bitset typeinfo
+bitset utility
+bitset variant
+bitset version
+ccomplex algorithm
+ccomplex array
+ccomplex atomic
+ccomplex bit
+ccomplex bitset
+ccomplex cctype
+ccomplex cerrno
+ccomplex climits
+ccomplex clocale
+ccomplex cmath
+ccomplex compare
+ccomplex complex
+ccomplex concepts
+ccomplex cstdarg
+ccomplex cstddef
+ccomplex cstdint
+ccomplex cstdio
+ccomplex cstdlib
+ccomplex cstring
+ccomplex ctime
+ccomplex cwchar
+ccomplex cwctype
+ccomplex deque
+ccomplex exception
+ccomplex format
+ccomplex functional
+ccomplex initializer_list
+ccomplex ios
+ccomplex iosfwd
+ccomplex istream
+ccomplex iterator
+ccomplex limits
+ccomplex locale
+ccomplex memory
+ccomplex mutex
+ccomplex new
+ccomplex optional
+ccomplex ostream
+ccomplex print
+ccomplex queue
+ccomplex ratio
+ccomplex sstream
+ccomplex stack
+ccomplex stdexcept
+ccomplex streambuf
+ccomplex string
+ccomplex string_view
+ccomplex system_error
+ccomplex tuple
+ccomplex type_traits
+ccomplex typeinfo
+ccomplex unordered_map
+ccomplex utility
+ccomplex variant
+ccomplex vector
+ccomplex version
+charconv cerrno
+charconv cmath
+charconv concepts
+charconv cstddef
+charconv cstdint
+charconv cstdlib
+charconv cstring
+charconv initializer_list
+charconv iosfwd
+charconv limits
+charconv new
+charconv type_traits
+charconv version
+chrono algorithm
+chrono array
+chrono atomic
+chrono bit
+chrono cctype
+chrono cerrno
+chrono climits
+chrono clocale
+chrono cmath
+chrono compare
+chrono concepts
+chrono cstdarg
+chrono cstddef
+chrono cstdint
+chrono cstdio
+chrono cstdlib
+chrono cstring
+chrono ctime
+chrono cwchar
+chrono cwctype
+chrono exception
+chrono forward_list
+chrono functional
+chrono initializer_list
+chrono ios
+chrono iosfwd
+chrono iterator
+chrono limits
+chrono locale
+chrono memory
+chrono mutex
+chrono new
+chrono optional
+chrono ratio
+chrono stdexcept
+chrono streambuf
+chrono string
+chrono string_view
+chrono system_error
+chrono tuple
+chrono type_traits
+chrono typeinfo
+chrono unordered_map
+chrono utility
+chrono variant
+chrono vector
+chrono version
+cinttypes cstdint
+cmath cstdint
+cmath limits
+cmath type_traits
+cmath version
+codecvt algorithm
+codecvt atomic
+codecvt bit
+codecvt cctype
+codecvt cerrno
+codecvt climits
+codecvt clocale
+codecvt cmath
+codecvt compare
+codecvt concepts
+codecvt cstddef
+codecvt cstdint
+codecvt cstdio
+codecvt cstdlib
+codecvt cstring
+codecvt ctime
+codecvt cwchar
+codecvt cwctype
+codecvt exception
+codecvt initializer_list
+codecvt iosfwd
+codecvt iterator
+codecvt limits
+codecvt memory
+codecvt mutex
+codecvt new
+codecvt optional
+codecvt ratio
+codecvt stdexcept
+codecvt string
+codecvt string_view
+codecvt system_error
+codecvt tuple
+codecvt type_traits
+codecvt typeinfo
+codecvt utility
+codecvt variant
+codecvt version
+compare cmath
+compare cstddef
+compare cstdint
+compare limits
+compare type_traits
+compare version
+complex algorithm
+complex array
+complex atomic
+complex bit
+complex bitset
+complex cctype
+complex cerrno
+complex climits
+complex clocale
+complex cmath
+complex compare
+complex concepts
+complex cstdarg
+complex cstddef
+complex cstdint
+complex cstdio
+complex cstdlib
+complex cstring
+complex ctime
+complex cwchar
+complex cwctype
+complex deque
+complex exception
+complex format
+complex functional
+complex initializer_list
+complex ios
+complex iosfwd
+complex istream
+complex iterator
+complex limits
+complex locale
+complex memory
+complex mutex
+complex new
+complex optional
+complex ostream
+complex print
+complex queue
+complex ratio
+complex sstream
+complex stack
+complex stdexcept
+complex streambuf
+complex string
+complex string_view
+complex system_error
+complex tuple
+complex type_traits
+complex typeinfo
+complex unordered_map
+complex utility
+complex variant
+complex vector
+complex version
+concepts cstddef
+concepts cstdint
+concepts type_traits
+concepts version
+condition_variable algorithm
+condition_variable atomic
+condition_variable bit
+condition_variable cctype
+condition_variable cerrno
+condition_variable climits
+condition_variable cmath
+condition_variable compare
+condition_variable concepts
+condition_variable cstddef
+condition_variable cstdint
+condition_variable cstdio
+condition_variable cstdlib
+condition_variable cstring
+condition_variable ctime
+condition_variable cwchar
+condition_variable cwctype
+condition_variable exception
+condition_variable initializer_list
+condition_variable iosfwd
+condition_variable iterator
+condition_variable limits
+condition_variable memory
+condition_variable new
+condition_variable optional
+condition_variable ratio
+condition_variable stdexcept
+condition_variable string
+condition_variable string_view
+condition_variable system_error
+condition_variable tuple
+condition_variable type_traits
+condition_variable typeinfo
+condition_variable utility
+condition_variable variant
+condition_variable version
+coroutine cmath
+coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine iosfwd
+coroutine limits
+coroutine type_traits
+coroutine version
+cstddef version
+ctgmath algorithm
+ctgmath array
+ctgmath atomic
+ctgmath bit
+ctgmath bitset
+ctgmath cctype
+ctgmath cerrno
+ctgmath climits
+ctgmath clocale
+ctgmath cmath
+ctgmath compare
+ctgmath complex
+ctgmath concepts
+ctgmath cstdarg
+ctgmath cstddef
+ctgmath cstdint
+ctgmath cstdio
+ctgmath cstdlib
+ctgmath cstring
+ctgmath ctime
+ctgmath cwchar
+ctgmath cwctype
+ctgmath deque
+ctgmath exception
+ctgmath format
+ctgmath functional
+ctgmath initializer_list
+ctgmath ios
+ctgmath iosfwd
+ctgmath istream
+ctgmath iterator
+ctgmath limits
+ctgmath locale
+ctgmath memory
+ctgmath mutex
+ctgmath new
+ctgmath optional
+ctgmath ostream
+ctgmath print
+ctgmath queue
+ctgmath ratio
+ctgmath sstream
+ctgmath stack
+ctgmath stdexcept
+ctgmath streambuf
+ctgmath string
+ctgmath string_view
+ctgmath system_error
+ctgmath tuple
+ctgmath type_traits
+ctgmath typeinfo
+ctgmath unordered_map
+ctgmath utility
+ctgmath variant
+ctgmath vector
+ctgmath version
+cwchar cctype
+cwchar cstddef
+cwchar cwctype
+cwchar version
+cwctype cctype
+deque algorithm
+deque array
+deque atomic
+deque bit
+deque cctype
+deque cerrno
+deque climits
+deque clocale
+deque cmath
+deque compare
+deque concepts
+deque cstdarg
+deque cstddef
+deque cstdint
+deque cstdio
+deque cstdlib
+deque cstring
+deque ctime
+deque cwchar
+deque cwctype
+deque exception
+deque functional
+deque initializer_list
+deque ios
+deque iosfwd
+deque iterator
+deque limits
+deque locale
+deque memory
+deque mutex
+deque new
+deque optional
+deque ratio
+deque stdexcept
+deque streambuf
+deque string
+deque string_view
+deque system_error
+deque tuple
+deque type_traits
+deque typeinfo
+deque unordered_map
+deque utility
+deque variant
+deque vector
+deque version
+exception cstddef
+exception cstdint
+exception cstdlib
+exception new
+exception type_traits
+exception typeinfo
+exception version
+execution cstddef
+execution version
+expected version
+experimental/iterator algorithm
+experimental/iterator atomic
+experimental/iterator bit
+experimental/iterator bitset
+experimental/iterator cctype
+experimental/iterator cerrno
+experimental/iterator climits
+experimental/iterator clocale
+experimental/iterator cmath
+experimental/iterator compare
+experimental/iterator concepts
+experimental/iterator cstdarg
+experimental/iterator cstddef
+experimental/iterator cstdint
+experimental/iterator cstdio
+experimental/iterator cstdlib
+experimental/iterator cstring
+experimental/iterator ctime
+experimental/iterator cwchar
+experimental/iterator cwctype
+experimental/iterator exception
+experimental/iterator initializer_list
+experimental/iterator ios
+experimental/iterator iosfwd
+experimental/iterator iterator
+experimental/iterator limits
+experimental/iterator locale
+experimental/iterator memory
+experimental/iterator mutex
+experimental/iterator new
+experimental/iterator optional
+experimental/iterator ratio
+experimental/iterator stdexcept
+experimental/iterator streambuf
+experimental/iterator string
+experimental/iterator string_view
+experimental/iterator system_error
+experimental/iterator tuple
+experimental/iterator type_traits
+experimental/iterator typeinfo
+experimental/iterator utility
+experimental/iterator variant
+experimental/iterator version
+experimental/memory cstddef
+experimental/memory cstdint
+experimental/memory cstring
+experimental/memory limits
+experimental/memory type_traits
+experimental/memory version
+experimental/propagate_const cstddef
+experimental/propagate_const cstdint
+experimental/propagate_const type_traits
+experimental/propagate_const version
+experimental/simd cstddef
+experimental/simd cstdint
+experimental/simd limits
+experimental/simd type_traits
+experimental/simd version
+experimental/type_traits cstddef
+experimental/type_traits cstdint
+experimental/type_traits initializer_list
+experimental/type_traits type_traits
+experimental/type_traits version
+experimental/utility cmath
+experimental/utility compare
+experimental/utility cstddef
+experimental/utility cstdint
+experimental/utility cstdlib
+experimental/utility initializer_list
+experimental/utility iosfwd
+experimental/utility limits
+experimental/utility type_traits
+experimental/utility utility
+experimental/utility version
+filesystem algorithm
+filesystem array
+filesystem atomic
+filesystem bit
+filesystem bitset
+filesystem cctype
+filesystem cerrno
+filesystem climits
+filesystem clocale
+filesystem cmath
+filesystem compare
+filesystem concepts
+filesystem cstdarg
+filesystem cstddef
+filesystem cstdint
+filesystem cstdio
+filesystem cstdlib
+filesystem cstring
+filesystem ctime
+filesystem cwchar
+filesystem cwctype
+filesystem deque
+filesystem exception
+filesystem format
+filesystem functional
+filesystem initializer_list
+filesystem iomanip
+filesystem ios
+filesystem iosfwd
+filesystem istream
+filesystem iterator
+filesystem limits
+filesystem locale
+filesystem memory
+filesystem mutex
+filesystem new
+filesystem optional
+filesystem ostream
+filesystem print
+filesystem queue
+filesystem ratio
+filesystem stack
+filesystem stdexcept
+filesystem streambuf
+filesystem string
+filesystem string_view
+filesystem system_error
+filesystem tuple
+filesystem type_traits
+filesystem typeinfo
+filesystem unordered_map
+filesystem utility
+filesystem variant
+filesystem vector
+filesystem version
+flat_map cmath
+flat_map compare
+flat_map cstddef
+flat_map cstdint
+flat_map initializer_list
+flat_map limits
+flat_map type_traits
+flat_map version
+flat_set cmath
+flat_set compare
+flat_set cstddef
+flat_set cstdint
+flat_set initializer_list
+flat_set limits
+flat_set type_traits
+flat_set version
+format algorithm
+format array
+format atomic
+format bit
+format cctype
+format cerrno
+format climits
+format clocale
+format cmath
+format compare
+format concepts
+format cstdarg
+format cstddef
+format cstdint
+format cstdio
+format cstdlib
+format cstring
+format ctime
+format cwchar
+format cwctype
+format deque
+format exception
+format functional
+format initializer_list
+format ios
+format iosfwd
+format iterator
+format limits
+format locale
+format memory
+format mutex
+format new
+format optional
+format queue
+format ratio
+format stack
+format stdexcept
+format streambuf
+format string
+format string_view
+format system_error
+format tuple
+format type_traits
+format typeinfo
+format unordered_map
+format utility
+format variant
+format vector
+format version
+forward_list algorithm
+forward_list array
+forward_list atomic
+forward_list bit
+forward_list cctype
+forward_list cerrno
+forward_list climits
+forward_list clocale
+forward_list cmath
+forward_list compare
+forward_list concepts
+forward_list cstdarg
+forward_list cstddef
+forward_list cstdint
+forward_list cstdio
+forward_list cstdlib
+forward_list cstring
+forward_list ctime
+forward_list cwchar
+forward_list cwctype
+forward_list exception
+forward_list functional
+forward_list initializer_list
+forward_list ios
+forward_list iosfwd
+forward_list iterator
+forward_list limits
+forward_list locale
+forward_list memory
+forward_list mutex
+forward_list new
+forward_list optional
+forward_list ratio
+forward_list stdexcept
+forward_list streambuf
+forward_list string
+forward_list string_view
+forward_list system_error
+forward_list tuple
+forward_list type_traits
+forward_list typeinfo
+forward_list unordered_map
+forward_list utility
+forward_list variant
+forward_list vector
+forward_list version
+fstream algorithm
+fstream array
+fstream atomic
+fstream bit
+fstream bitset
+fstream cctype
+fstream cerrno
+fstream climits
+fstream clocale
+fstream cmath
+fstream compare
+fstream concepts
+fstream cstdarg
+fstream cstddef
+fstream cstdint
+fstream cstdio
+fstream cstdlib
+fstream cstring
+fstream ctime
+fstream cwchar
+fstream cwctype
+fstream deque
+fstream exception
+fstream filesystem
+fstream format
+fstream functional
+fstream initializer_list
+fstream iomanip
+fstream ios
+fstream iosfwd
+fstream istream
+fstream iterator
+fstream limits
+fstream locale
+fstream memory
+fstream mutex
+fstream new
+fstream optional
+fstream ostream
+fstream print
+fstream queue
+fstream ratio
+fstream stack
+fstream stdexcept
+fstream streambuf
+fstream string
+fstream string_view
+fstream system_error
+fstream tuple
+fstream type_traits
+fstream typeinfo
+fstream unordered_map
+fstream utility
+fstream variant
+fstream vector
+fstream version
+functional algorithm
+functional array
+functional atomic
+functional bit
+functional cctype
+functional cerrno
+functional climits
+functional clocale
+functional cmath
+functional compare
+functional concepts
+functional cstdarg
+functional cstddef
+functional cstdint
+functional cstdio
+functional cstdlib
+functional cstring
+functional ctime
+functional cwchar
+functional cwctype
+functional exception
+functional initializer_list
+functional ios
+functional iosfwd
+functional iterator
+functional limits
+functional locale
+functional memory
+functional mutex
+functional new
+functional optional
+functional ratio
+functional stdexcept
+functional streambuf
+functional string
+functional string_view
+functional system_error
+functional tuple
+functional type_traits
+functional typeinfo
+functional unordered_map
+functional utility
+functional variant
+functional vector
+functional version
+future algorithm
+future array
+future atomic
+future bit
+future bitset
+future cctype
+future cerrno
+future chrono
+future climits
+future clocale
+future cmath
+future compare
+future concepts
+future cstdarg
+future cstddef
+future cstdint
+future cstdio
+future cstdlib
+future cstring
+future ctime
+future cwchar
+future cwctype
+future deque
+future exception
+future format
+future forward_list
+future functional
+future initializer_list
+future ios
+future iosfwd
+future istream
+future iterator
+future limits
+future locale
+future memory
+future mutex
+future new
+future optional
+future ostream
+future print
+future queue
+future ratio
+future sstream
+future stack
+future stdexcept
+future streambuf
+future string
+future string_view
+future system_error
+future thread
+future tuple
+future type_traits
+future typeinfo
+future unordered_map
+future utility
+future variant
+future vector
+future version
+initializer_list cstddef
+initializer_list version
+iomanip algorithm
+iomanip array
+iomanip atomic
+iomanip bit
+iomanip bitset
+iomanip cctype
+iomanip cerrno
+iomanip climits
+iomanip clocale
+iomanip cmath
+iomanip compare
+iomanip concepts
+iomanip cstdarg
+iomanip cstddef
+iomanip cstdint
+iomanip cstdio
+iomanip cstdlib
+iomanip cstring
+iomanip ctime
+iomanip cwchar
+iomanip cwctype
+iomanip deque
+iomanip exception
+iomanip format
+iomanip functional
+iomanip initializer_list
+iomanip ios
+iomanip iosfwd
+iomanip istream
+iomanip iterator
+iomanip limits
+iomanip locale
+iomanip memory
+iomanip mutex
+iomanip new
+iomanip optional
+iomanip ostream
+iomanip print
+iomanip queue
+iomanip ratio
+iomanip stack
+iomanip stdexcept
+iomanip streambuf
+iomanip string
+iomanip string_view
+iomanip system_error
+iomanip tuple
+iomanip type_traits
+iomanip typeinfo
+iomanip unordered_map
+iomanip utility
+iomanip variant
+iomanip vector
+iomanip version
+ios algorithm
+ios atomic
+ios bit
+ios cctype
+ios cerrno
+ios climits
+ios clocale
+ios cmath
+ios compare
+ios concepts
+ios cstddef
+ios cstdint
+ios cstdio
+ios cstdlib
+ios cstring
+ios ctime
+ios cwchar
+ios cwctype
+ios exception
+ios initializer_list
+ios iosfwd
+ios iterator
+ios limits
+ios memory
+ios mutex
+ios new
+ios optional
+ios ratio
+ios stdexcept
+ios string
+ios string_view
+ios system_error
+ios tuple
+ios type_traits
+ios typeinfo
+ios utility
+ios variant
+ios version
+iosfwd version
+iostream algorithm
+iostream array
+iostream atomic
+iostream bit
+iostream bitset
+iostream cctype
+iostream cerrno
+iostream climits
+iostream clocale
+iostream cmath
+iostream compare
+iostream concepts
+iostream cstdarg
+iostream cstddef
+iostream cstdint
+iostream cstdio
+iostream cstdlib
+iostream cstring
+iostream ctime
+iostream cwchar
+iostream cwctype
+iostream deque
+iostream exception
+iostream format
+iostream functional
+iostream initializer_list
+iostream ios
+iostream iosfwd
+iostream istream
+iostream iterator
+iostream limits
+iostream locale
+iostream memory
+iostream mutex
+iostream new
+iostream optional
+iostream ostream
+iostream print
+iostream queue
+iostream ratio
+iostream stack
+iostream stdexcept
+iostream streambuf
+iostream string
+iostream string_view
+iostream system_error
+iostream tuple
+iostream type_traits
+iostream typeinfo
+iostream unordered_map
+iostream utility
+iostream variant
+iostream vector
+iostream version
+istream algorithm
+istream array
+istream atomic
+istream bit
+istream bitset
+istream cctype
+istream cerrno
+istream climits
+istream clocale
+istream cmath
+istream compare
+istream concepts
+istream cstdarg
+istream cstddef
+istream cstdint
+istream cstdio
+istream cstdlib
+istream cstring
+istream ctime
+istream cwchar
+istream cwctype
+istream deque
+istream exception
+istream format
+istream functional
+istream initializer_list
+istream ios
+istream iosfwd
+istream iterator
+istream limits
+istream locale
+istream memory
+istream mutex
+istream new
+istream optional
+istream ostream
+istream print
+istream queue
+istream ratio
+istream stack
+istream stdexcept
+istream streambuf
+istream string
+istream string_view
+istream system_error
+istream tuple
+istream type_traits
+istream typeinfo
+istream unordered_map
+istream utility
+istream variant
+istream vector
+istream version
+iterator cctype
+iterator cmath
+iterator compare
+iterator concepts
+iterator cstddef
+iterator cstdint
+iterator cstdio
+iterator cstdlib
+iterator cstring
+iterator cwchar
+iterator cwctype
+iterator exception
+iterator initializer_list
+iterator iosfwd
+iterator limits
+iterator new
+iterator tuple
+iterator type_traits
+iterator typeinfo
+iterator utility
+iterator variant
+iterator version
+latch atomic
+latch climits
+latch cmath
+latch compare
+latch cstddef
+latch cstdint
+latch cstdlib
+latch cstring
+latch ctime
+latch limits
+latch ratio
+latch type_traits
+latch version
+limits cstdint
+limits type_traits
+limits version
+list algorithm
+list array
+list atomic
+list bit
+list cctype
+list cerrno
+list climits
+list clocale
+list cmath
+list compare
+list concepts
+list cstdarg
+list cstddef
+list cstdint
+list cstdio
+list cstdlib
+list cstring
+list ctime
+list cwchar
+list cwctype
+list exception
+list functional
+list initializer_list
+list ios
+list iosfwd
+list iterator
+list limits
+list locale
+list memory
+list mutex
+list new
+list optional
+list ratio
+list stdexcept
+list streambuf
+list string
+list string_view
+list system_error
+list tuple
+list type_traits
+list typeinfo
+list unordered_map
+list utility
+list variant
+list vector
+list version
+locale algorithm
+locale atomic
+locale bit
+locale cctype
+locale cerrno
+locale climits
+locale clocale
+locale cmath
+locale compare
+locale concepts
+locale cstdarg
+locale cstddef
+locale cstdint
+locale cstdio
+locale cstdlib
+locale cstring
+locale ctime
+locale cwchar
+locale cwctype
+locale exception
+locale initializer_list
+locale ios
+locale iosfwd
+locale iterator
+locale limits
+locale memory
+locale mutex
+locale new
+locale optional
+locale ratio
+locale stdexcept
+locale streambuf
+locale string
+locale string_view
+locale system_error
+locale tuple
+locale type_traits
+locale typeinfo
+locale utility
+locale variant
+locale version
+map algorithm
+map array
+map atomic
+map bit
+map cctype
+map cerrno
+map climits
+map clocale
+map cmath
+map compare
+map concepts
+map cstdarg
+map cstddef
+map cstdint
+map cstdio
+map cstdlib
+map cstring
+map ctime
+map cwchar
+map cwctype
+map exception
+map functional
+map initializer_list
+map ios
+map iosfwd
+map iterator
+map limits
+map locale
+map memory
+map mutex
+map new
+map optional
+map ratio
+map stdexcept
+map streambuf
+map string
+map string_view
+map system_error
+map tuple
+map type_traits
+map typeinfo
+map unordered_map
+map utility
+map variant
+map vector
+map version
+mdspan version
+memory atomic
+memory cctype
+memory climits
+memory cmath
+memory compare
+memory concepts
+memory cstddef
+memory cstdint
+memory cstdio
+memory cstdlib
+memory cstring
+memory ctime
+memory cwchar
+memory cwctype
+memory exception
+memory initializer_list
+memory iosfwd
+memory iterator
+memory limits
+memory new
+memory ratio
+memory stdexcept
+memory tuple
+memory type_traits
+memory typeinfo
+memory utility
+memory variant
+memory version
+memory_resource algorithm
+memory_resource atomic
+memory_resource bit
+memory_resource cctype
+memory_resource cerrno
+memory_resource climits
+memory_resource cmath
+memory_resource compare
+memory_resource concepts
+memory_resource cstddef
+memory_resource cstdint
+memory_resource cstdio
+memory_resource cstdlib
+memory_resource cstring
+memory_resource ctime
+memory_resource cwchar
+memory_resource cwctype
+memory_resource exception
+memory_resource initializer_list
+memory_resource iosfwd
+memory_resource iterator
+memory_resource limits
+memory_resource memory
+memory_resource mutex
+memory_resource new
+memory_resource optional
+memory_resource ratio
+memory_resource stdexcept
+memory_resource string
+memory_resource string_view
+memory_resource system_error
+memory_resource tuple
+memory_resource type_traits
+memory_resource typeinfo
+memory_resource utility
+memory_resource variant
+memory_resource version
+mutex algorithm
+mutex atomic
+mutex bit
+mutex cctype
+mutex cerrno
+mutex climits
+mutex cmath
+mutex compare
+mutex concepts
+mutex cstddef
+mutex cstdint
+mutex cstdio
+mutex cstdlib
+mutex cstring
+mutex ctime
+mutex cwchar
+mutex cwctype
+mutex exception
+mutex initializer_list
+mutex iosfwd
+mutex iterator
+mutex limits
+mutex memory
+mutex new
+mutex optional
+mutex ratio
+mutex stdexcept
+mutex string
+mutex string_view
+mutex system_error
+mutex tuple
+mutex type_traits
+mutex typeinfo
+mutex utility
+mutex variant
+mutex version
+new cstddef
+new cstdint
+new cstdlib
+new type_traits
+new version
+numbers concepts
+numbers cstddef
+numbers cstdint
+numbers type_traits
+numbers version
+numeric algorithm
+numeric array
+numeric atomic
+numeric bit
+numeric cctype
+numeric cerrno
+numeric climits
+numeric clocale
+numeric cmath
+numeric compare
+numeric concepts
+numeric cstdarg
+numeric cstddef
+numeric cstdint
+numeric cstdio
+numeric cstdlib
+numeric cstring
+numeric ctime
+numeric cwchar
+numeric cwctype
+numeric exception
+numeric execution
+numeric functional
+numeric initializer_list
+numeric ios
+numeric iosfwd
+numeric iterator
+numeric limits
+numeric locale
+numeric memory
+numeric mutex
+numeric new
+numeric optional
+numeric ratio
+numeric stdexcept
+numeric streambuf
+numeric string
+numeric string_view
+numeric system_error
+numeric tuple
+numeric type_traits
+numeric typeinfo
+numeric unordered_map
+numeric utility
+numeric variant
+numeric vector
+numeric version
+optional atomic
+optional cctype
+optional climits
+optional cmath
+optional compare
+optional concepts
+optional cstddef
+optional cstdint
+optional cstdio
+optional cstdlib
+optional cstring
+optional ctime
+optional cwchar
+optional cwctype
+optional exception
+optional initializer_list
+optional iosfwd
+optional iterator
+optional limits
+optional memory
+optional new
+optional ratio
+optional stdexcept
+optional tuple
+optional type_traits
+optional typeinfo
+optional utility
+optional variant
+optional version
+ostream algorithm
+ostream array
+ostream atomic
+ostream bit
+ostream bitset
+ostream cctype
+ostream cerrno
+ostream climits
+ostream clocale
+ostream cmath
+ostream compare
+ostream concepts
+ostream cstdarg
+ostream cstddef
+ostream cstdint
+ostream cstdio
+ostream cstdlib
+ostream cstring
+ostream ctime
+ostream cwchar
+ostream cwctype
+ostream deque
+ostream exception
+ostream format
+ostream functional
+ostream initializer_list
+ostream ios
+ostream iosfwd
+ostream iterator
+ostream limits
+ostream locale
+ostream memory
+ostream mutex
+ostream new
+ostream optional
+ostream print
+ostream queue
+ostream ratio
+ostream stack
+ostream stdexcept
+ostream streambuf
+ostream string
+ostream string_view
+ostream system_error
+ostream tuple
+ostream type_traits
+ostream typeinfo
+ostream unordered_map
+ostream utility
+ostream variant
+ostream vector
+ostream version
+print algorithm
+print array
+print atomic
+print bit
+print cctype
+print cerrno
+print climits
+print clocale
+print cmath
+print compare
+print concepts
+print cstdarg
+print cstddef
+print cstdint
+print cstdio
+print cstdlib
+print cstring
+print ctime
+print cwchar
+print cwctype
+print deque
+print exception
+print format
+print functional
+print initializer_list
+print ios
+print iosfwd
+print iterator
+print limits
+print locale
+print memory
+print mutex
+print new
+print optional
+print queue
+print ratio
+print stack
+print stdexcept
+print streambuf
+print string
+print string_view
+print system_error
+print tuple
+print type_traits
+print typeinfo
+print unordered_map
+print utility
+print variant
+print vector
+print version
+queue algorithm
+queue array
+queue atomic
+queue bit
+queue cctype
+queue cerrno
+queue climits
+queue clocale
+queue cmath
+queue compare
+queue concepts
+queue cstdarg
+queue cstddef
+queue cstdint
+queue cstdio
+queue cstdlib
+queue cstring
+queue ctime
+queue cwchar
+queue cwctype
+queue deque
+queue exception
+queue functional
+queue initializer_list
+queue ios
+queue iosfwd
+queue iterator
+queue limits
+queue locale
+queue memory
+queue mutex
+queue new
+queue optional
+queue ratio
+queue stdexcept
+queue streambuf
+queue string
+queue string_view
+queue system_error
+queue tuple
+queue type_traits
+queue typeinfo
+queue unordered_map
+queue utility
+queue variant
+queue vector
+queue version
+random algorithm
+random array
+random atomic
+random bit
+random cctype
+random cerrno
+random climits
+random clocale
+random cmath
+random compare
+random concepts
+random cstdarg
+random cstddef
+random cstdint
+random cstdio
+random cstdlib
+random cstring
+random ctime
+random cwchar
+random cwctype
+random exception
+random execution
+random functional
+random initializer_list
+random ios
+random iosfwd
+random iterator
+random limits
+random locale
+random memory
+random mutex
+random new
+random numeric
+random optional
+random ratio
+random stdexcept
+random streambuf
+random string
+random string_view
+random system_error
+random tuple
+random type_traits
+random typeinfo
+random unordered_map
+random utility
+random variant
+random vector
+random version
+ranges cctype
+ranges cmath
+ranges compare
+ranges concepts
+ranges cstddef
+ranges cstdint
+ranges cstdio
+ranges cstdlib
+ranges cstring
+ranges cwchar
+ranges cwctype
+ranges exception
+ranges initializer_list
+ranges iosfwd
+ranges iterator
+ranges limits
+ranges new
+ranges tuple
+ranges type_traits
+ranges typeinfo
+ranges utility
+ranges variant
+ranges version
+ratio climits
+ratio cstdint
+ratio type_traits
+ratio version
+regex algorithm
+regex array
+regex atomic
+regex bit
+regex cctype
+regex cerrno
+regex climits
+regex clocale
+regex cmath
+regex compare
+regex concepts
+regex cstdarg
+regex cstddef
+regex cstdint
+regex cstdio
+regex cstdlib
+regex cstring
+regex ctime
+regex cwchar
+regex cwctype
+regex deque
+regex exception
+regex functional
+regex initializer_list
+regex ios
+regex iosfwd
+regex iterator
+regex limits
+regex locale
+regex memory
+regex mutex
+regex new
+regex optional
+regex ratio
+regex stdexcept
+regex streambuf
+regex string
+regex string_view
+regex system_error
+regex tuple
+regex type_traits
+regex typeinfo
+regex unordered_map
+regex utility
+regex variant
+regex vector
+regex version
+scoped_allocator atomic
+scoped_allocator cctype
+scoped_allocator climits
+scoped_allocator cmath
+scoped_allocator compare
+scoped_allocator concepts
+scoped_allocator cstddef
+scoped_allocator cstdint
+scoped_allocator cstdio
+scoped_allocator cstdlib
+scoped_allocator cstring
+scoped_allocator ctime
+scoped_allocator cwchar
+scoped_allocator cwctype
+scoped_allocator exception
+scoped_allocator initializer_list
+scoped_allocator iosfwd
+scoped_allocator iterator
+scoped_allocator limits
+scoped_allocator memory
+scoped_allocator new
+scoped_allocator ratio
+scoped_allocator stdexcept
+scoped_allocator tuple
+scoped_allocator type_traits
+scoped_allocator typeinfo
+scoped_allocator utility
+scoped_allocator variant
+scoped_allocator version
+semaphore atomic
+semaphore climits
+semaphore cmath
+semaphore compare
+semaphore cstddef
+semaphore cstdint
+semaphore cstdlib
+semaphore cstring
+semaphore ctime
+semaphore limits
+semaphore ratio
+semaphore type_traits
+semaphore version
+set algorithm
+set array
+set atomic
+set bit
+set cctype
+set cerrno
+set climits
+set clocale
+set cmath
+set compare
+set concepts
+set cstdarg
+set cstddef
+set cstdint
+set cstdio
+set cstdlib
+set cstring
+set ctime
+set cwchar
+set cwctype
+set exception
+set functional
+set initializer_list
+set ios
+set iosfwd
+set iterator
+set limits
+set locale
+set memory
+set mutex
+set new
+set optional
+set ratio
+set stdexcept
+set streambuf
+set string
+set string_view
+set system_error
+set tuple
+set type_traits
+set typeinfo
+set unordered_map
+set utility
+set variant
+set vector
+set version
+shared_mutex algorithm
+shared_mutex atomic
+shared_mutex bit
+shared_mutex cctype
+shared_mutex cerrno
+shared_mutex climits
+shared_mutex cmath
+shared_mutex compare
+shared_mutex concepts
+shared_mutex cstddef
+shared_mutex cstdint
+shared_mutex cstdio
+shared_mutex cstdlib
+shared_mutex cstring
+shared_mutex ctime
+shared_mutex cwchar
+shared_mutex cwctype
+shared_mutex exception
+shared_mutex initializer_list
+shared_mutex iosfwd
+shared_mutex iterator
+shared_mutex limits
+shared_mutex memory
+shared_mutex new
+shared_mutex optional
+shared_mutex ratio
+shared_mutex stdexcept
+shared_mutex string
+shared_mutex string_view
+shared_mutex system_error
+shared_mutex tuple
+shared_mutex type_traits
+shared_mutex typeinfo
+shared_mutex utility
+shared_mutex variant
+shared_mutex version
+source_location cstdint
+source_location version
+span algorithm
+span array
+span atomic
+span bit
+span cctype
+span cerrno
+span climits
+span clocale
+span cmath
+span compare
+span concepts
+span cstdarg
+span cstddef
+span cstdint
+span cstdio
+span cstdlib
+span cstring
+span ctime
+span cwchar
+span cwctype
+span exception
+span functional
+span initializer_list
+span ios
+span iosfwd
+span iterator
+span limits
+span locale
+span memory
+span mutex
+span new
+span optional
+span ratio
+span stdexcept
+span streambuf
+span string
+span string_view
+span system_error
+span tuple
+span type_traits
+span typeinfo
+span unordered_map
+span utility
+span variant
+span vector
+span version
+sstream algorithm
+sstream array
+sstream atomic
+sstream bit
+sstream bitset
+sstream cctype
+sstream cerrno
+sstream climits
+sstream clocale
+sstream cmath
+sstream compare
+sstream concepts
+sstream cstdarg
+sstream cstddef
+sstream cstdint
+sstream cstdio
+sstream cstdlib
+sstream cstring
+sstream ctime
+sstream cwchar
+sstream cwctype
+sstream deque
+sstream exception
+sstream format
+sstream functional
+sstream initializer_list
+sstream ios
+sstream iosfwd
+sstream istream
+sstream iterator
+sstream limits
+sstream locale
+sstream memory
+sstream mutex
+sstream new
+sstream optional
+sstream ostream
+sstream print
+sstream queue
+sstream ratio
+sstream stack
+sstream stdexcept
+sstream streambuf
+sstream string
+sstream string_view
+sstream system_error
+sstream tuple
+sstream type_traits
+sstream typeinfo
+sstream unordered_map
+sstream utility
+sstream variant
+sstream vector
+sstream version
+stack algorithm
+stack array
+stack atomic
+stack bit
+stack cctype
+stack cerrno
+stack climits
+stack clocale
+stack cmath
+stack compare
+stack concepts
+stack cstdarg
+stack cstddef
+stack cstdint
+stack cstdio
+stack cstdlib
+stack cstring
+stack ctime
+stack cwchar
+stack cwctype
+stack deque
+stack exception
+stack functional
+stack initializer_list
+stack ios
+stack iosfwd
+stack iterator
+stack limits
+stack locale
+stack memory
+stack mutex
+stack new
+stack optional
+stack ratio
+stack stdexcept
+stack streambuf
+stack string
+stack string_view
+stack system_error
+stack tuple
+stack type_traits
+stack typeinfo
+stack unordered_map
+stack utility
+stack variant
+stack vector
+stack version
+stdexcept cstddef
+stdexcept cstdint
+stdexcept cstdlib
+stdexcept exception
+stdexcept iosfwd
+stdexcept new
+stdexcept type_traits
+stdexcept typeinfo
+stdexcept version
+stop_token iosfwd
+stop_token version
+streambuf algorithm
+streambuf atomic
+streambuf bit
+streambuf cctype
+streambuf cerrno
+streambuf climits
+streambuf clocale
+streambuf cmath
+streambuf compare
+streambuf concepts
+streambuf cstddef
+streambuf cstdint
+streambuf cstdio
+streambuf cstdlib
+streambuf cstring
+streambuf ctime
+streambuf cwchar
+streambuf cwctype
+streambuf exception
+streambuf initializer_list
+streambuf ios
+streambuf iosfwd
+streambuf iterator
+streambuf limits
+streambuf memory
+streambuf mutex
+streambuf new
+streambuf optional
+streambuf ratio
+streambuf stdexcept
+streambuf string
+streambuf string_view
+streambuf system_error
+streambuf tuple
+streambuf type_traits
+streambuf typeinfo
+streambuf utility
+streambuf variant
+streambuf version
+string algorithm
+string atomic
+string bit
+string cctype
+string climits
+string cmath
+string compare
+string concepts
+string cstddef
+string cstdint
+string cstdio
+string cstdlib
+string cstring
+string ctime
+string cwchar
+string cwctype
+string exception
+string initializer_list
+string iosfwd
+string iterator
+string limits
+string memory
+string new
+string optional
+string ratio
+string stdexcept
+string string_view
+string tuple
+string type_traits
+string typeinfo
+string utility
+string variant
+string version
+string_view algorithm
+string_view atomic
+string_view bit
+string_view cctype
+string_view climits
+string_view cmath
+string_view compare
+string_view concepts
+string_view cstddef
+string_view cstdint
+string_view cstdio
+string_view cstdlib
+string_view cstring
+string_view ctime
+string_view cwchar
+string_view cwctype
+string_view exception
+string_view initializer_list
+string_view iosfwd
+string_view iterator
+string_view limits
+string_view memory
+string_view new
+string_view optional
+string_view ratio
+string_view stdexcept
+string_view tuple
+string_view type_traits
+string_view typeinfo
+string_view utility
+string_view variant
+string_view version
+strstream algorithm
+strstream array
+strstream atomic
+strstream bit
+strstream bitset
+strstream cctype
+strstream cerrno
+strstream climits
+strstream clocale
+strstream cmath
+strstream compare
+strstream concepts
+strstream cstdarg
+strstream cstddef
+strstream cstdint
+strstream cstdio
+strstream cstdlib
+strstream cstring
+strstream ctime
+strstream cwchar
+strstream cwctype
+strstream deque
+strstream exception
+strstream format
+strstream functional
+strstream initializer_list
+strstream ios
+strstream iosfwd
+strstream istream
+strstream iterator
+strstream limits
+strstream locale
+strstream memory
+strstream mutex
+strstream new
+strstream optional
+strstream ostream
+strstream print
+strstream queue
+strstream ratio
+strstream stack
+strstream stdexcept
+strstream streambuf
+strstream string
+strstream string_view
+strstream system_error
+strstream tuple
+strstream type_traits
+strstream typeinfo
+strstream unordered_map
+strstream utility
+strstream variant
+strstream vector
+strstream version
+syncstream algorithm
+syncstream array
+syncstream atomic
+syncstream bit
+syncstream bitset
+syncstream cctype
+syncstream cerrno
+syncstream climits
+syncstream clocale
+syncstream cmath
+syncstream compare
+syncstream concepts
+syncstream cstdarg
+syncstream cstddef
+syncstream cstdint
+syncstream cstdio
+syncstream cstdlib
+syncstream cstring
+syncstream ctime
+syncstream cwchar
+syncstream cwctype
+syncstream deque
+syncstream exception
+syncstream format
+syncstream functional
+syncstream initializer_list
+syncstream ios
+syncstream iosfwd
+syncstream iterator
+syncstream limits
+syncstream locale
+syncstream map
+syncstream memory
+syncstream mutex
+syncstream new
+syncstream optional
+syncstream ostream
+syncstream print
+syncstream queue
+syncstream ratio
+syncstream shared_mutex
+syncstream stack
+syncstream stdexcept
+syncstream streambuf
+syncstream string
+syncstream string_view
+syncstream system_error
+syncstream tuple
+syncstream type_traits
+syncstream typeinfo
+syncstream unordered_map
+syncstream utility
+syncstream variant
+syncstream vector
+syncstream version
+system_error algorithm
+system_error atomic
+system_error bit
+system_error cctype
+system_error cerrno
+system_error climits
+system_error cmath
+system_error compare
+system_error concepts
+system_error cstddef
+system_error cstdint
+system_error cstdio
+system_error cstdlib
+system_error cstring
+system_error ctime
+system_error cwchar
+system_error cwctype
+system_error exception
+system_error initializer_list
+system_error iosfwd
+system_error iterator
+system_error limits
+system_error memory
+system_error new
+system_error optional
+system_error ratio
+system_error stdexcept
+system_error string
+system_error string_view
+system_error tuple
+system_error type_traits
+system_error typeinfo
+system_error utility
+system_error variant
+system_error version
+thread algorithm
+thread array
+thread atomic
+thread bit
+thread bitset
+thread cctype
+thread cerrno
+thread chrono
+thread climits
+thread clocale
+thread cmath
+thread compare
+thread concepts
+thread cstdarg
+thread cstddef
+thread cstdint
+thread cstdio
+thread cstdlib
+thread cstring
+thread ctime
+thread cwchar
+thread cwctype
+thread deque
+thread exception
+thread format
+thread forward_list
+thread functional
+thread initializer_list
+thread ios
+thread iosfwd
+thread istream
+thread iterator
+thread limits
+thread locale
+thread memory
+thread mutex
+thread new
+thread optional
+thread ostream
+thread print
+thread queue
+thread ratio
+thread sstream
+thread stack
+thread stdexcept
+thread streambuf
+thread string
+thread string_view
+thread system_error
+thread tuple
+thread type_traits
+thread typeinfo
+thread unordered_map
+thread utility
+thread variant
+thread vector
+thread version
+tuple cmath
+tuple compare
+tuple cstddef
+tuple cstdint
+tuple cstdlib
+tuple exception
+tuple initializer_list
+tuple iosfwd
+tuple limits
+tuple new
+tuple type_traits
+tuple typeinfo
+tuple utility
+tuple version
+type_traits cstdint
+type_traits version
+typeindex cmath
+typeindex compare
+typeindex cstddef
+typeindex cstdint
+typeindex cstdlib
+typeindex initializer_list
+typeindex iosfwd
+typeindex limits
+typeindex new
+typeindex type_traits
+typeindex typeinfo
+typeindex utility
+typeindex version
+typeinfo cstddef
+typeinfo cstdint
+typeinfo cstdlib
+typeinfo type_traits
+typeinfo version
+unordered_map algorithm
+unordered_map atomic
+unordered_map bit
+unordered_map cctype
+unordered_map climits
+unordered_map cmath
+unordered_map compare
+unordered_map concepts
+unordered_map cstddef
+unordered_map cstdint
+unordered_map cstdio
+unordered_map cstdlib
+unordered_map cstring
+unordered_map ctime
+unordered_map cwchar
+unordered_map cwctype
+unordered_map exception
+unordered_map initializer_list
+unordered_map iosfwd
+unordered_map iterator
+unordered_map limits
+unordered_map memory
+unordered_map new
+unordered_map optional
+unordered_map ratio
+unordered_map stdexcept
+unordered_map tuple
+unordered_map type_traits
+unordered_map typeinfo
+unordered_map utility
+unordered_map variant
+unordered_map version
+unordered_set algorithm
+unordered_set array
+unordered_set atomic
+unordered_set bit
+unordered_set cctype
+unordered_set cerrno
+unordered_set climits
+unordered_set clocale
+unordered_set cmath
+unordered_set compare
+unordered_set concepts
+unordered_set cstdarg
+unordered_set cstddef
+unordered_set cstdint
+unordered_set cstdio
+unordered_set cstdlib
+unordered_set cstring
+unordered_set ctime
+unordered_set cwchar
+unordered_set cwctype
+unordered_set exception
+unordered_set functional
+unordered_set initializer_list
+unordered_set ios
+unordered_set iosfwd
+unordered_set iterator
+unordered_set limits
+unordered_set locale
+unordered_set memory
+unordered_set mutex
+unordered_set new
+unordered_set optional
+unordered_set ratio
+unordered_set stdexcept
+unordered_set streambuf
+unordered_set string
+unordered_set string_view
+unordered_set system_error
+unordered_set tuple
+unordered_set type_traits
+unordered_set typeinfo
+unordered_set unordered_map
+unordered_set utility
+unordered_set variant
+unordered_set vector
+unordered_set version
+utility cmath
+utility compare
+utility cstddef
+utility cstdint
+utility cstdlib
+utility initializer_list
+utility iosfwd
+utility limits
+utility type_traits
+utility version
+valarray algorithm
+valarray array
+valarray atomic
+valarray bit
+valarray cctype
+valarray cerrno
+valarray climits
+valarray clocale
+valarray cmath
+valarray compare
+valarray concepts
+valarray cstdarg
+valarray cstddef
+valarray cstdint
+valarray cstdio
+valarray cstdlib
+valarray cstring
+valarray ctime
+valarray cwchar
+valarray cwctype
+valarray exception
+valarray functional
+valarray initializer_list
+valarray ios
+valarray iosfwd
+valarray iterator
+valarray limits
+valarray locale
+valarray memory
+valarray mutex
+valarray new
+valarray optional
+valarray ratio
+valarray stdexcept
+valarray streambuf
+valarray string
+valarray string_view
+valarray system_error
+valarray tuple
+valarray type_traits
+valarray typeinfo
+valarray unordered_map
+valarray utility
+valarray variant
+valarray vector
+valarray version
+variant cmath
+variant compare
+variant cstddef
+variant cstdint
+variant cstdlib
+variant cstring
+variant exception
+variant initializer_list
+variant iosfwd
+variant limits
+variant new
+variant tuple
+variant type_traits
+variant typeinfo
+variant utility
+variant version
+vector algorithm
+vector array
+vector atomic
+vector bit
+vector cctype
+vector cerrno
+vector climits
+vector clocale
+vector cmath
+vector compare
+vector concepts
+vector cstdarg
+vector cstddef
+vector cstdint
+vector cstdio
+vector cstdlib
+vector cstring
+vector ctime
+vector cwchar
+vector cwctype
+vector exception
+vector initializer_list
+vector ios
+vector iosfwd
+vector iterator
+vector limits
+vector locale
+vector memory
+vector mutex
+vector new
+vector optional
+vector ratio
+vector stdexcept
+vector streambuf
+vector string
+vector string_view
+vector system_error
+vector tuple
+vector type_traits
+vector typeinfo
+vector utility
+vector variant
+vector version
diff --git a/libcxx/test/libcxx-03/transitive_includes/cxx20.csv b/libcxx/test/libcxx-03/transitive_includes/cxx20.csv
new file mode 100644
index 0000000000000..55c79acff5a8f
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/cxx20.csv
@@ -0,0 +1,2649 @@
+algorithm atomic
+algorithm bit
+algorithm cctype
+algorithm climits
+algorithm cmath
+algorithm compare
+algorithm concepts
+algorithm cstddef
+algorithm cstdint
+algorithm cstdio
+algorithm cstdlib
+algorithm cstring
+algorithm ctime
+algorithm cwchar
+algorithm cwctype
+algorithm exception
+algorithm initializer_list
+algorithm iosfwd
+algorithm iterator
+algorithm limits
+algorithm memory
+algorithm new
+algorithm optional
+algorithm ratio
+algorithm stdexcept
+algorithm tuple
+algorithm type_traits
+algorithm typeinfo
+algorithm utility
+algorithm variant
+algorithm version
+any atomic
+any cctype
+any climits
+any cmath
+any compare
+any concepts
+any cstddef
+any cstdint
+any cstdio
+any cstdlib
+any cstring
+any ctime
+any cwchar
+any cwctype
+any exception
+any initializer_list
+any iosfwd
+any iterator
+any limits
+any memory
+any new
+any ratio
+any stdexcept
+any tuple
+any type_traits
+any typeinfo
+any utility
+any variant
+any version
+array algorithm
+array atomic
+array bit
+array cctype
+array climits
+array cmath
+array compare
+array concepts
+array cstddef
+array cstdint
+array cstdio
+array cstdlib
+array cstring
+array ctime
+array cwchar
+array cwctype
+array exception
+array initializer_list
+array iosfwd
+array iterator
+array limits
+array memory
+array new
+array optional
+array ratio
+array stdexcept
+array tuple
+array type_traits
+array typeinfo
+array utility
+array variant
+array version
+atomic climits
+atomic cmath
+atomic compare
+atomic cstddef
+atomic cstdint
+atomic cstdlib
+atomic cstring
+atomic ctime
+atomic limits
+atomic ratio
+atomic type_traits
+atomic version
+barrier atomic
+barrier cctype
+barrier climits
+barrier cmath
+barrier compare
+barrier concepts
+barrier cstddef
+barrier cstdint
+barrier cstdio
+barrier cstdlib
+barrier cstring
+barrier ctime
+barrier cwchar
+barrier cwctype
+barrier exception
+barrier initializer_list
+barrier iosfwd
+barrier iterator
+barrier limits
+barrier memory
+barrier new
+barrier ratio
+barrier stdexcept
+barrier tuple
+barrier type_traits
+barrier typeinfo
+barrier utility
+barrier variant
+barrier version
+bit cstdint
+bit cstdlib
+bit iosfwd
+bit limits
+bit type_traits
+bit version
+bitset algorithm
+bitset atomic
+bitset bit
+bitset cctype
+bitset climits
+bitset cmath
+bitset compare
+bitset concepts
+bitset cstddef
+bitset cstdint
+bitset cstdio
+bitset cstdlib
+bitset cstring
+bitset ctime
+bitset cwchar
+bitset cwctype
+bitset exception
+bitset initializer_list
+bitset iosfwd
+bitset iterator
+bitset limits
+bitset memory
+bitset new
+bitset optional
+bitset ratio
+bitset stdexcept
+bitset string
+bitset string_view
+bitset tuple
+bitset type_traits
+bitset typeinfo
+bitset utility
+bitset variant
+bitset version
+ccomplex algorithm
+ccomplex array
+ccomplex atomic
+ccomplex bit
+ccomplex bitset
+ccomplex cctype
+ccomplex cerrno
+ccomplex climits
+ccomplex clocale
+ccomplex cmath
+ccomplex compare
+ccomplex complex
+ccomplex concepts
+ccomplex cstdarg
+ccomplex cstddef
+ccomplex cstdint
+ccomplex cstdio
+ccomplex cstdlib
+ccomplex cstring
+ccomplex ctime
+ccomplex cwchar
+ccomplex cwctype
+ccomplex deque
+ccomplex exception
+ccomplex format
+ccomplex functional
+ccomplex initializer_list
+ccomplex ios
+ccomplex iosfwd
+ccomplex istream
+ccomplex iterator
+ccomplex limits
+ccomplex locale
+ccomplex memory
+ccomplex mutex
+ccomplex new
+ccomplex optional
+ccomplex ostream
+ccomplex print
+ccomplex queue
+ccomplex ratio
+ccomplex sstream
+ccomplex stack
+ccomplex stdexcept
+ccomplex streambuf
+ccomplex string
+ccomplex string_view
+ccomplex system_error
+ccomplex tuple
+ccomplex type_traits
+ccomplex typeinfo
+ccomplex unordered_map
+ccomplex utility
+ccomplex variant
+ccomplex vector
+ccomplex version
+charconv cerrno
+charconv cmath
+charconv concepts
+charconv cstddef
+charconv cstdint
+charconv cstdlib
+charconv cstring
+charconv initializer_list
+charconv iosfwd
+charconv limits
+charconv new
+charconv type_traits
+charconv version
+chrono algorithm
+chrono array
+chrono atomic
+chrono bit
+chrono bitset
+chrono cctype
+chrono cerrno
+chrono charconv
+chrono climits
+chrono clocale
+chrono cmath
+chrono compare
+chrono concepts
+chrono cstdarg
+chrono cstddef
+chrono cstdint
+chrono cstdio
+chrono cstdlib
+chrono cstring
+chrono ctime
+chrono cwchar
+chrono cwctype
+chrono deque
+chrono exception
+chrono format
+chrono forward_list
+chrono functional
+chrono initializer_list
+chrono ios
+chrono iosfwd
+chrono istream
+chrono iterator
+chrono limits
+chrono locale
+chrono memory
+chrono mutex
+chrono new
+chrono optional
+chrono ostream
+chrono print
+chrono queue
+chrono ratio
+chrono sstream
+chrono stack
+chrono stdexcept
+chrono streambuf
+chrono string
+chrono string_view
+chrono system_error
+chrono tuple
+chrono type_traits
+chrono typeinfo
+chrono unordered_map
+chrono utility
+chrono variant
+chrono vector
+chrono version
+cinttypes cstdint
+cmath cstdint
+cmath limits
+cmath type_traits
+cmath version
+codecvt algorithm
+codecvt atomic
+codecvt bit
+codecvt cctype
+codecvt cerrno
+codecvt climits
+codecvt clocale
+codecvt cmath
+codecvt compare
+codecvt concepts
+codecvt cstddef
+codecvt cstdint
+codecvt cstdio
+codecvt cstdlib
+codecvt cstring
+codecvt ctime
+codecvt cwchar
+codecvt cwctype
+codecvt exception
+codecvt initializer_list
+codecvt iosfwd
+codecvt iterator
+codecvt limits
+codecvt memory
+codecvt mutex
+codecvt new
+codecvt optional
+codecvt ratio
+codecvt stdexcept
+codecvt string
+codecvt string_view
+codecvt system_error
+codecvt tuple
+codecvt type_traits
+codecvt typeinfo
+codecvt utility
+codecvt variant
+codecvt version
+compare cmath
+compare cstddef
+compare cstdint
+compare limits
+compare type_traits
+compare version
+complex algorithm
+complex array
+complex atomic
+complex bit
+complex bitset
+complex cctype
+complex cerrno
+complex climits
+complex clocale
+complex cmath
+complex compare
+complex concepts
+complex cstdarg
+complex cstddef
+complex cstdint
+complex cstdio
+complex cstdlib
+complex cstring
+complex ctime
+complex cwchar
+complex cwctype
+complex deque
+complex exception
+complex format
+complex functional
+complex initializer_list
+complex ios
+complex iosfwd
+complex istream
+complex iterator
+complex limits
+complex locale
+complex memory
+complex mutex
+complex new
+complex optional
+complex ostream
+complex print
+complex queue
+complex ratio
+complex sstream
+complex stack
+complex stdexcept
+complex streambuf
+complex string
+complex string_view
+complex system_error
+complex tuple
+complex type_traits
+complex typeinfo
+complex unordered_map
+complex utility
+complex variant
+complex vector
+complex version
+concepts cstddef
+concepts cstdint
+concepts type_traits
+concepts version
+condition_variable algorithm
+condition_variable atomic
+condition_variable bit
+condition_variable cctype
+condition_variable cerrno
+condition_variable climits
+condition_variable cmath
+condition_variable compare
+condition_variable concepts
+condition_variable cstddef
+condition_variable cstdint
+condition_variable cstdio
+condition_variable cstdlib
+condition_variable cstring
+condition_variable ctime
+condition_variable cwchar
+condition_variable cwctype
+condition_variable exception
+condition_variable initializer_list
+condition_variable iosfwd
+condition_variable iterator
+condition_variable limits
+condition_variable memory
+condition_variable new
+condition_variable optional
+condition_variable ratio
+condition_variable stdexcept
+condition_variable string
+condition_variable string_view
+condition_variable system_error
+condition_variable tuple
+condition_variable type_traits
+condition_variable typeinfo
+condition_variable utility
+condition_variable variant
+condition_variable version
+coroutine cmath
+coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine cstring
+coroutine iosfwd
+coroutine limits
+coroutine type_traits
+coroutine version
+cstddef version
+ctgmath algorithm
+ctgmath array
+ctgmath atomic
+ctgmath bit
+ctgmath bitset
+ctgmath cctype
+ctgmath cerrno
+ctgmath climits
+ctgmath clocale
+ctgmath cmath
+ctgmath compare
+ctgmath complex
+ctgmath concepts
+ctgmath cstdarg
+ctgmath cstddef
+ctgmath cstdint
+ctgmath cstdio
+ctgmath cstdlib
+ctgmath cstring
+ctgmath ctime
+ctgmath cwchar
+ctgmath cwctype
+ctgmath deque
+ctgmath exception
+ctgmath format
+ctgmath functional
+ctgmath initializer_list
+ctgmath ios
+ctgmath iosfwd
+ctgmath istream
+ctgmath iterator
+ctgmath limits
+ctgmath locale
+ctgmath memory
+ctgmath mutex
+ctgmath new
+ctgmath optional
+ctgmath ostream
+ctgmath print
+ctgmath queue
+ctgmath ratio
+ctgmath sstream
+ctgmath stack
+ctgmath stdexcept
+ctgmath streambuf
+ctgmath string
+ctgmath string_view
+ctgmath system_error
+ctgmath tuple
+ctgmath type_traits
+ctgmath typeinfo
+ctgmath unordered_map
+ctgmath utility
+ctgmath variant
+ctgmath vector
+ctgmath version
+cwchar cctype
+cwchar cstddef
+cwchar cwctype
+cwchar version
+cwctype cctype
+deque algorithm
+deque array
+deque atomic
+deque bit
+deque cctype
+deque cerrno
+deque climits
+deque clocale
+deque cmath
+deque compare
+deque concepts
+deque cstdarg
+deque cstddef
+deque cstdint
+deque cstdio
+deque cstdlib
+deque cstring
+deque ctime
+deque cwchar
+deque cwctype
+deque exception
+deque functional
+deque initializer_list
+deque ios
+deque iosfwd
+deque iterator
+deque limits
+deque locale
+deque memory
+deque mutex
+deque new
+deque optional
+deque ratio
+deque stdexcept
+deque streambuf
+deque string
+deque string_view
+deque system_error
+deque tuple
+deque type_traits
+deque typeinfo
+deque unordered_map
+deque utility
+deque variant
+deque vector
+deque version
+exception cstddef
+exception cstdint
+exception cstdlib
+exception new
+exception type_traits
+exception typeinfo
+exception version
+execution cstddef
+execution version
+expected version
+experimental/iterator algorithm
+experimental/iterator atomic
+experimental/iterator bit
+experimental/iterator bitset
+experimental/iterator cctype
+experimental/iterator cerrno
+experimental/iterator climits
+experimental/iterator clocale
+experimental/iterator cmath
+experimental/iterator compare
+experimental/iterator concepts
+experimental/iterator cstdarg
+experimental/iterator cstddef
+experimental/iterator cstdint
+experimental/iterator cstdio
+experimental/iterator cstdlib
+experimental/iterator cstring
+experimental/iterator ctime
+experimental/iterator cwchar
+experimental/iterator cwctype
+experimental/iterator exception
+experimental/iterator initializer_list
+experimental/iterator ios
+experimental/iterator iosfwd
+experimental/iterator iterator
+experimental/iterator limits
+experimental/iterator locale
+experimental/iterator memory
+experimental/iterator mutex
+experimental/iterator new
+experimental/iterator optional
+experimental/iterator ratio
+experimental/iterator stdexcept
+experimental/iterator streambuf
+experimental/iterator string
+experimental/iterator string_view
+experimental/iterator system_error
+experimental/iterator tuple
+experimental/iterator type_traits
+experimental/iterator typeinfo
+experimental/iterator utility
+experimental/iterator variant
+experimental/iterator version
+experimental/memory cstddef
+experimental/memory cstdint
+experimental/memory cstring
+experimental/memory limits
+experimental/memory type_traits
+experimental/memory version
+experimental/propagate_const cstddef
+experimental/propagate_const cstdint
+experimental/propagate_const type_traits
+experimental/propagate_const version
+experimental/simd cstddef
+experimental/simd cstdint
+experimental/simd limits
+experimental/simd type_traits
+experimental/simd version
+experimental/type_traits cstddef
+experimental/type_traits cstdint
+experimental/type_traits initializer_list
+experimental/type_traits type_traits
+experimental/type_traits version
+experimental/utility cmath
+experimental/utility compare
+experimental/utility cstddef
+experimental/utility cstdint
+experimental/utility cstdlib
+experimental/utility initializer_list
+experimental/utility iosfwd
+experimental/utility limits
+experimental/utility type_traits
+experimental/utility utility
+experimental/utility version
+filesystem algorithm
+filesystem array
+filesystem atomic
+filesystem bit
+filesystem bitset
+filesystem cctype
+filesystem cerrno
+filesystem climits
+filesystem clocale
+filesystem cmath
+filesystem compare
+filesystem concepts
+filesystem cstdarg
+filesystem cstddef
+filesystem cstdint
+filesystem cstdio
+filesystem cstdlib
+filesystem cstring
+filesystem ctime
+filesystem cwchar
+filesystem cwctype
+filesystem deque
+filesystem exception
+filesystem format
+filesystem functional
+filesystem initializer_list
+filesystem iomanip
+filesystem ios
+filesystem iosfwd
+filesystem istream
+filesystem iterator
+filesystem limits
+filesystem locale
+filesystem memory
+filesystem mutex
+filesystem new
+filesystem optional
+filesystem ostream
+filesystem print
+filesystem queue
+filesystem ratio
+filesystem stack
+filesystem stdexcept
+filesystem streambuf
+filesystem string
+filesystem string_view
+filesystem system_error
+filesystem tuple
+filesystem type_traits
+filesystem typeinfo
+filesystem unordered_map
+filesystem utility
+filesystem variant
+filesystem vector
+filesystem version
+flat_map cmath
+flat_map compare
+flat_map cstddef
+flat_map cstdint
+flat_map initializer_list
+flat_map limits
+flat_map type_traits
+flat_map version
+flat_set cmath
+flat_set compare
+flat_set cstddef
+flat_set cstdint
+flat_set initializer_list
+flat_set limits
+flat_set type_traits
+flat_set version
+format algorithm
+format array
+format atomic
+format bit
+format cctype
+format cerrno
+format climits
+format clocale
+format cmath
+format compare
+format concepts
+format cstdarg
+format cstddef
+format cstdint
+format cstdio
+format cstdlib
+format cstring
+format ctime
+format cwchar
+format cwctype
+format deque
+format exception
+format functional
+format initializer_list
+format ios
+format iosfwd
+format iterator
+format limits
+format locale
+format memory
+format mutex
+format new
+format optional
+format queue
+format ratio
+format stack
+format stdexcept
+format streambuf
+format string
+format string_view
+format system_error
+format tuple
+format type_traits
+format typeinfo
+format unordered_map
+format utility
+format variant
+format vector
+format version
+forward_list algorithm
+forward_list array
+forward_list atomic
+forward_list bit
+forward_list cctype
+forward_list cerrno
+forward_list climits
+forward_list clocale
+forward_list cmath
+forward_list compare
+forward_list concepts
+forward_list cstdarg
+forward_list cstddef
+forward_list cstdint
+forward_list cstdio
+forward_list cstdlib
+forward_list cstring
+forward_list ctime
+forward_list cwchar
+forward_list cwctype
+forward_list exception
+forward_list functional
+forward_list initializer_list
+forward_list ios
+forward_list iosfwd
+forward_list iterator
+forward_list limits
+forward_list locale
+forward_list memory
+forward_list mutex
+forward_list new
+forward_list optional
+forward_list ratio
+forward_list stdexcept
+forward_list streambuf
+forward_list string
+forward_list string_view
+forward_list system_error
+forward_list tuple
+forward_list type_traits
+forward_list typeinfo
+forward_list unordered_map
+forward_list utility
+forward_list variant
+forward_list vector
+forward_list version
+fstream algorithm
+fstream array
+fstream atomic
+fstream bit
+fstream bitset
+fstream cctype
+fstream cerrno
+fstream climits
+fstream clocale
+fstream cmath
+fstream compare
+fstream concepts
+fstream cstdarg
+fstream cstddef
+fstream cstdint
+fstream cstdio
+fstream cstdlib
+fstream cstring
+fstream ctime
+fstream cwchar
+fstream cwctype
+fstream deque
+fstream exception
+fstream filesystem
+fstream format
+fstream functional
+fstream initializer_list
+fstream iomanip
+fstream ios
+fstream iosfwd
+fstream istream
+fstream iterator
+fstream limits
+fstream locale
+fstream memory
+fstream mutex
+fstream new
+fstream optional
+fstream ostream
+fstream print
+fstream queue
+fstream ratio
+fstream stack
+fstream stdexcept
+fstream streambuf
+fstream string
+fstream string_view
+fstream system_error
+fstream tuple
+fstream type_traits
+fstream typeinfo
+fstream unordered_map
+fstream utility
+fstream variant
+fstream vector
+fstream version
+functional algorithm
+functional array
+functional atomic
+functional bit
+functional cctype
+functional cerrno
+functional climits
+functional clocale
+functional cmath
+functional compare
+functional concepts
+functional cstdarg
+functional cstddef
+functional cstdint
+functional cstdio
+functional cstdlib
+functional cstring
+functional ctime
+functional cwchar
+functional cwctype
+functional exception
+functional initializer_list
+functional ios
+functional iosfwd
+functional iterator
+functional limits
+functional locale
+functional memory
+functional mutex
+functional new
+functional optional
+functional ratio
+functional stdexcept
+functional streambuf
+functional string
+functional string_view
+functional system_error
+functional tuple
+functional type_traits
+functional typeinfo
+functional unordered_map
+functional utility
+functional variant
+functional vector
+functional version
+future algorithm
+future array
+future atomic
+future bit
+future bitset
+future cctype
+future cerrno
+future climits
+future clocale
+future cmath
+future compare
+future concepts
+future cstdarg
+future cstddef
+future cstdint
+future cstdio
+future cstdlib
+future cstring
+future ctime
+future cwchar
+future cwctype
+future deque
+future exception
+future format
+future functional
+future initializer_list
+future ios
+future iosfwd
+future istream
+future iterator
+future limits
+future locale
+future memory
+future mutex
+future new
+future optional
+future ostream
+future print
+future queue
+future ratio
+future sstream
+future stack
+future stdexcept
+future streambuf
+future string
+future string_view
+future system_error
+future thread
+future tuple
+future type_traits
+future typeinfo
+future unordered_map
+future utility
+future variant
+future vector
+future version
+initializer_list cstddef
+initializer_list version
+iomanip algorithm
+iomanip array
+iomanip atomic
+iomanip bit
+iomanip bitset
+iomanip cctype
+iomanip cerrno
+iomanip climits
+iomanip clocale
+iomanip cmath
+iomanip compare
+iomanip concepts
+iomanip cstdarg
+iomanip cstddef
+iomanip cstdint
+iomanip cstdio
+iomanip cstdlib
+iomanip cstring
+iomanip ctime
+iomanip cwchar
+iomanip cwctype
+iomanip deque
+iomanip exception
+iomanip format
+iomanip functional
+iomanip initializer_list
+iomanip ios
+iomanip iosfwd
+iomanip istream
+iomanip iterator
+iomanip limits
+iomanip locale
+iomanip memory
+iomanip mutex
+iomanip new
+iomanip optional
+iomanip ostream
+iomanip print
+iomanip queue
+iomanip ratio
+iomanip stack
+iomanip stdexcept
+iomanip streambuf
+iomanip string
+iomanip string_view
+iomanip system_error
+iomanip tuple
+iomanip type_traits
+iomanip typeinfo
+iomanip unordered_map
+iomanip utility
+iomanip variant
+iomanip vector
+iomanip version
+ios algorithm
+ios atomic
+ios bit
+ios cctype
+ios cerrno
+ios climits
+ios clocale
+ios cmath
+ios compare
+ios concepts
+ios cstddef
+ios cstdint
+ios cstdio
+ios cstdlib
+ios cstring
+ios ctime
+ios cwchar
+ios cwctype
+ios exception
+ios initializer_list
+ios iosfwd
+ios iterator
+ios limits
+ios memory
+ios mutex
+ios new
+ios optional
+ios ratio
+ios stdexcept
+ios string
+ios string_view
+ios system_error
+ios tuple
+ios type_traits
+ios typeinfo
+ios utility
+ios variant
+ios version
+iosfwd version
+iostream algorithm
+iostream array
+iostream atomic
+iostream bit
+iostream bitset
+iostream cctype
+iostream cerrno
+iostream climits
+iostream clocale
+iostream cmath
+iostream compare
+iostream concepts
+iostream cstdarg
+iostream cstddef
+iostream cstdint
+iostream cstdio
+iostream cstdlib
+iostream cstring
+iostream ctime
+iostream cwchar
+iostream cwctype
+iostream deque
+iostream exception
+iostream format
+iostream functional
+iostream initializer_list
+iostream ios
+iostream iosfwd
+iostream istream
+iostream iterator
+iostream limits
+iostream locale
+iostream memory
+iostream mutex
+iostream new
+iostream optional
+iostream ostream
+iostream print
+iostream queue
+iostream ratio
+iostream stack
+iostream stdexcept
+iostream streambuf
+iostream string
+iostream string_view
+iostream system_error
+iostream tuple
+iostream type_traits
+iostream typeinfo
+iostream unordered_map
+iostream utility
+iostream variant
+iostream vector
+iostream version
+istream algorithm
+istream array
+istream atomic
+istream bit
+istream bitset
+istream cctype
+istream cerrno
+istream climits
+istream clocale
+istream cmath
+istream compare
+istream concepts
+istream cstdarg
+istream cstddef
+istream cstdint
+istream cstdio
+istream cstdlib
+istream cstring
+istream ctime
+istream cwchar
+istream cwctype
+istream deque
+istream exception
+istream format
+istream functional
+istream initializer_list
+istream ios
+istream iosfwd
+istream iterator
+istream limits
+istream locale
+istream memory
+istream mutex
+istream new
+istream optional
+istream ostream
+istream print
+istream queue
+istream ratio
+istream stack
+istream stdexcept
+istream streambuf
+istream string
+istream string_view
+istream system_error
+istream tuple
+istream type_traits
+istream typeinfo
+istream unordered_map
+istream utility
+istream variant
+istream vector
+istream version
+iterator cctype
+iterator cmath
+iterator compare
+iterator concepts
+iterator cstddef
+iterator cstdint
+iterator cstdio
+iterator cstdlib
+iterator cstring
+iterator cwchar
+iterator cwctype
+iterator exception
+iterator initializer_list
+iterator iosfwd
+iterator limits
+iterator new
+iterator tuple
+iterator type_traits
+iterator typeinfo
+iterator utility
+iterator variant
+iterator version
+latch atomic
+latch climits
+latch cmath
+latch compare
+latch cstddef
+latch cstdint
+latch cstdlib
+latch cstring
+latch ctime
+latch limits
+latch ratio
+latch type_traits
+latch version
+limits cstdint
+limits type_traits
+limits version
+list algorithm
+list array
+list atomic
+list bit
+list cctype
+list cerrno
+list climits
+list clocale
+list cmath
+list compare
+list concepts
+list cstdarg
+list cstddef
+list cstdint
+list cstdio
+list cstdlib
+list cstring
+list ctime
+list cwchar
+list cwctype
+list exception
+list functional
+list initializer_list
+list ios
+list iosfwd
+list iterator
+list limits
+list locale
+list memory
+list mutex
+list new
+list optional
+list ratio
+list stdexcept
+list streambuf
+list string
+list string_view
+list system_error
+list tuple
+list type_traits
+list typeinfo
+list unordered_map
+list utility
+list variant
+list vector
+list version
+locale algorithm
+locale atomic
+locale bit
+locale cctype
+locale cerrno
+locale climits
+locale clocale
+locale cmath
+locale compare
+locale concepts
+locale cstdarg
+locale cstddef
+locale cstdint
+locale cstdio
+locale cstdlib
+locale cstring
+locale ctime
+locale cwchar
+locale cwctype
+locale exception
+locale initializer_list
+locale ios
+locale iosfwd
+locale iterator
+locale limits
+locale memory
+locale mutex
+locale new
+locale optional
+locale ratio
+locale stdexcept
+locale streambuf
+locale string
+locale string_view
+locale system_error
+locale tuple
+locale type_traits
+locale typeinfo
+locale utility
+locale variant
+locale version
+map algorithm
+map array
+map atomic
+map bit
+map cctype
+map cerrno
+map climits
+map clocale
+map cmath
+map compare
+map concepts
+map cstdarg
+map cstddef
+map cstdint
+map cstdio
+map cstdlib
+map cstring
+map ctime
+map cwchar
+map cwctype
+map exception
+map functional
+map initializer_list
+map ios
+map iosfwd
+map iterator
+map limits
+map locale
+map memory
+map mutex
+map new
+map optional
+map ratio
+map stdexcept
+map streambuf
+map string
+map string_view
+map system_error
+map tuple
+map type_traits
+map typeinfo
+map unordered_map
+map utility
+map variant
+map vector
+map version
+mdspan version
+memory atomic
+memory cctype
+memory climits
+memory cmath
+memory compare
+memory concepts
+memory cstddef
+memory cstdint
+memory cstdio
+memory cstdlib
+memory cstring
+memory ctime
+memory cwchar
+memory cwctype
+memory exception
+memory initializer_list
+memory iosfwd
+memory iterator
+memory limits
+memory new
+memory ratio
+memory stdexcept
+memory tuple
+memory type_traits
+memory typeinfo
+memory utility
+memory variant
+memory version
+memory_resource algorithm
+memory_resource atomic
+memory_resource bit
+memory_resource cctype
+memory_resource cerrno
+memory_resource climits
+memory_resource cmath
+memory_resource compare
+memory_resource concepts
+memory_resource cstddef
+memory_resource cstdint
+memory_resource cstdio
+memory_resource cstdlib
+memory_resource cstring
+memory_resource ctime
+memory_resource cwchar
+memory_resource cwctype
+memory_resource exception
+memory_resource initializer_list
+memory_resource iosfwd
+memory_resource iterator
+memory_resource limits
+memory_resource memory
+memory_resource mutex
+memory_resource new
+memory_resource optional
+memory_resource ratio
+memory_resource stdexcept
+memory_resource string
+memory_resource string_view
+memory_resource system_error
+memory_resource tuple
+memory_resource type_traits
+memory_resource typeinfo
+memory_resource utility
+memory_resource variant
+memory_resource version
+mutex algorithm
+mutex atomic
+mutex bit
+mutex cctype
+mutex cerrno
+mutex climits
+mutex cmath
+mutex compare
+mutex concepts
+mutex cstddef
+mutex cstdint
+mutex cstdio
+mutex cstdlib
+mutex cstring
+mutex ctime
+mutex cwchar
+mutex cwctype
+mutex exception
+mutex initializer_list
+mutex iosfwd
+mutex iterator
+mutex limits
+mutex memory
+mutex new
+mutex optional
+mutex ratio
+mutex stdexcept
+mutex string
+mutex string_view
+mutex system_error
+mutex tuple
+mutex type_traits
+mutex typeinfo
+mutex utility
+mutex variant
+mutex version
+new cstddef
+new cstdint
+new cstdlib
+new type_traits
+new version
+numbers concepts
+numbers cstddef
+numbers cstdint
+numbers type_traits
+numbers version
+numeric algorithm
+numeric array
+numeric atomic
+numeric bit
+numeric cctype
+numeric cerrno
+numeric climits
+numeric clocale
+numeric cmath
+numeric compare
+numeric concepts
+numeric cstdarg
+numeric cstddef
+numeric cstdint
+numeric cstdio
+numeric cstdlib
+numeric cstring
+numeric ctime
+numeric cwchar
+numeric cwctype
+numeric exception
+numeric execution
+numeric functional
+numeric initializer_list
+numeric ios
+numeric iosfwd
+numeric iterator
+numeric limits
+numeric locale
+numeric memory
+numeric mutex
+numeric new
+numeric optional
+numeric ratio
+numeric stdexcept
+numeric streambuf
+numeric string
+numeric string_view
+numeric system_error
+numeric tuple
+numeric type_traits
+numeric typeinfo
+numeric unordered_map
+numeric utility
+numeric variant
+numeric vector
+numeric version
+optional atomic
+optional cctype
+optional climits
+optional cmath
+optional compare
+optional concepts
+optional cstddef
+optional cstdint
+optional cstdio
+optional cstdlib
+optional cstring
+optional ctime
+optional cwchar
+optional cwctype
+optional exception
+optional initializer_list
+optional iosfwd
+optional iterator
+optional limits
+optional memory
+optional new
+optional ratio
+optional stdexcept
+optional tuple
+optional type_traits
+optional typeinfo
+optional utility
+optional variant
+optional version
+ostream algorithm
+ostream array
+ostream atomic
+ostream bit
+ostream bitset
+ostream cctype
+ostream cerrno
+ostream climits
+ostream clocale
+ostream cmath
+ostream compare
+ostream concepts
+ostream cstdarg
+ostream cstddef
+ostream cstdint
+ostream cstdio
+ostream cstdlib
+ostream cstring
+ostream ctime
+ostream cwchar
+ostream cwctype
+ostream deque
+ostream exception
+ostream format
+ostream functional
+ostream initializer_list
+ostream ios
+ostream iosfwd
+ostream iterator
+ostream limits
+ostream locale
+ostream memory
+ostream mutex
+ostream new
+ostream optional
+ostream print
+ostream queue
+ostream ratio
+ostream stack
+ostream stdexcept
+ostream streambuf
+ostream string
+ostream string_view
+ostream system_error
+ostream tuple
+ostream type_traits
+ostream typeinfo
+ostream unordered_map
+ostream utility
+ostream variant
+ostream vector
+ostream version
+print algorithm
+print array
+print atomic
+print bit
+print cctype
+print cerrno
+print climits
+print clocale
+print cmath
+print compare
+print concepts
+print cstdarg
+print cstddef
+print cstdint
+print cstdio
+print cstdlib
+print cstring
+print ctime
+print cwchar
+print cwctype
+print deque
+print exception
+print format
+print functional
+print initializer_list
+print ios
+print iosfwd
+print iterator
+print limits
+print locale
+print memory
+print mutex
+print new
+print optional
+print queue
+print ratio
+print stack
+print stdexcept
+print streambuf
+print string
+print string_view
+print system_error
+print tuple
+print type_traits
+print typeinfo
+print unordered_map
+print utility
+print variant
+print vector
+print version
+queue algorithm
+queue array
+queue atomic
+queue bit
+queue cctype
+queue cerrno
+queue climits
+queue clocale
+queue cmath
+queue compare
+queue concepts
+queue cstdarg
+queue cstddef
+queue cstdint
+queue cstdio
+queue cstdlib
+queue cstring
+queue ctime
+queue cwchar
+queue cwctype
+queue deque
+queue exception
+queue functional
+queue initializer_list
+queue ios
+queue iosfwd
+queue iterator
+queue limits
+queue locale
+queue memory
+queue mutex
+queue new
+queue optional
+queue ratio
+queue stdexcept
+queue streambuf
+queue string
+queue string_view
+queue system_error
+queue tuple
+queue type_traits
+queue typeinfo
+queue unordered_map
+queue utility
+queue variant
+queue vector
+queue version
+random algorithm
+random array
+random atomic
+random bit
+random cctype
+random cerrno
+random climits
+random clocale
+random cmath
+random compare
+random concepts
+random cstdarg
+random cstddef
+random cstdint
+random cstdio
+random cstdlib
+random cstring
+random ctime
+random cwchar
+random cwctype
+random exception
+random execution
+random functional
+random initializer_list
+random ios
+random iosfwd
+random iterator
+random limits
+random locale
+random memory
+random mutex
+random new
+random numeric
+random optional
+random ratio
+random stdexcept
+random streambuf
+random string
+random string_view
+random system_error
+random tuple
+random type_traits
+random typeinfo
+random unordered_map
+random utility
+random variant
+random vector
+random version
+ranges algorithm
+ranges array
+ranges atomic
+ranges bit
+ranges cctype
+ranges cerrno
+ranges climits
+ranges clocale
+ranges cmath
+ranges compare
+ranges concepts
+ranges cstdarg
+ranges cstddef
+ranges cstdint
+ranges cstdio
+ranges cstdlib
+ranges cstring
+ranges ctime
+ranges cwchar
+ranges cwctype
+ranges exception
+ranges functional
+ranges initializer_list
+ranges ios
+ranges iosfwd
+ranges iterator
+ranges limits
+ranges locale
+ranges memory
+ranges mutex
+ranges new
+ranges optional
+ranges ratio
+ranges span
+ranges stdexcept
+ranges streambuf
+ranges string
+ranges string_view
+ranges system_error
+ranges tuple
+ranges type_traits
+ranges typeinfo
+ranges unordered_map
+ranges utility
+ranges variant
+ranges vector
+ranges version
+ratio climits
+ratio cstdint
+ratio type_traits
+ratio version
+regex algorithm
+regex array
+regex atomic
+regex bit
+regex cctype
+regex cerrno
+regex climits
+regex clocale
+regex cmath
+regex compare
+regex concepts
+regex cstdarg
+regex cstddef
+regex cstdint
+regex cstdio
+regex cstdlib
+regex cstring
+regex ctime
+regex cwchar
+regex cwctype
+regex deque
+regex exception
+regex functional
+regex initializer_list
+regex ios
+regex iosfwd
+regex iterator
+regex limits
+regex locale
+regex memory
+regex mutex
+regex new
+regex optional
+regex ratio
+regex stdexcept
+regex streambuf
+regex string
+regex string_view
+regex system_error
+regex tuple
+regex type_traits
+regex typeinfo
+regex unordered_map
+regex utility
+regex variant
+regex vector
+regex version
+scoped_allocator atomic
+scoped_allocator cctype
+scoped_allocator climits
+scoped_allocator cmath
+scoped_allocator compare
+scoped_allocator concepts
+scoped_allocator cstddef
+scoped_allocator cstdint
+scoped_allocator cstdio
+scoped_allocator cstdlib
+scoped_allocator cstring
+scoped_allocator ctime
+scoped_allocator cwchar
+scoped_allocator cwctype
+scoped_allocator exception
+scoped_allocator initializer_list
+scoped_allocator iosfwd
+scoped_allocator iterator
+scoped_allocator limits
+scoped_allocator memory
+scoped_allocator new
+scoped_allocator ratio
+scoped_allocator stdexcept
+scoped_allocator tuple
+scoped_allocator type_traits
+scoped_allocator typeinfo
+scoped_allocator utility
+scoped_allocator variant
+scoped_allocator version
+semaphore atomic
+semaphore climits
+semaphore cmath
+semaphore compare
+semaphore cstddef
+semaphore cstdint
+semaphore cstdlib
+semaphore cstring
+semaphore ctime
+semaphore limits
+semaphore ratio
+semaphore type_traits
+semaphore version
+set algorithm
+set array
+set atomic
+set bit
+set cctype
+set cerrno
+set climits
+set clocale
+set cmath
+set compare
+set concepts
+set cstdarg
+set cstddef
+set cstdint
+set cstdio
+set cstdlib
+set cstring
+set ctime
+set cwchar
+set cwctype
+set exception
+set functional
+set initializer_list
+set ios
+set iosfwd
+set iterator
+set limits
+set locale
+set memory
+set mutex
+set new
+set optional
+set ratio
+set stdexcept
+set streambuf
+set string
+set string_view
+set system_error
+set tuple
+set type_traits
+set typeinfo
+set unordered_map
+set utility
+set variant
+set vector
+set version
+shared_mutex algorithm
+shared_mutex atomic
+shared_mutex bit
+shared_mutex cctype
+shared_mutex cerrno
+shared_mutex climits
+shared_mutex cmath
+shared_mutex compare
+shared_mutex concepts
+shared_mutex cstddef
+shared_mutex cstdint
+shared_mutex cstdio
+shared_mutex cstdlib
+shared_mutex cstring
+shared_mutex ctime
+shared_mutex cwchar
+shared_mutex cwctype
+shared_mutex exception
+shared_mutex initializer_list
+shared_mutex iosfwd
+shared_mutex iterator
+shared_mutex limits
+shared_mutex memory
+shared_mutex new
+shared_mutex optional
+shared_mutex ratio
+shared_mutex stdexcept
+shared_mutex string
+shared_mutex string_view
+shared_mutex system_error
+shared_mutex tuple
+shared_mutex type_traits
+shared_mutex typeinfo
+shared_mutex utility
+shared_mutex variant
+shared_mutex version
+source_location cstdint
+source_location version
+span algorithm
+span array
+span atomic
+span bit
+span cctype
+span cerrno
+span climits
+span clocale
+span cmath
+span compare
+span concepts
+span cstdarg
+span cstddef
+span cstdint
+span cstdio
+span cstdlib
+span cstring
+span ctime
+span cwchar
+span cwctype
+span exception
+span functional
+span initializer_list
+span ios
+span iosfwd
+span iterator
+span limits
+span locale
+span memory
+span mutex
+span new
+span optional
+span ratio
+span stdexcept
+span streambuf
+span string
+span string_view
+span system_error
+span tuple
+span type_traits
+span typeinfo
+span unordered_map
+span utility
+span variant
+span vector
+span version
+sstream algorithm
+sstream array
+sstream atomic
+sstream bit
+sstream bitset
+sstream cctype
+sstream cerrno
+sstream climits
+sstream clocale
+sstream cmath
+sstream compare
+sstream concepts
+sstream cstdarg
+sstream cstddef
+sstream cstdint
+sstream cstdio
+sstream cstdlib
+sstream cstring
+sstream ctime
+sstream cwchar
+sstream cwctype
+sstream deque
+sstream exception
+sstream format
+sstream functional
+sstream initializer_list
+sstream ios
+sstream iosfwd
+sstream istream
+sstream iterator
+sstream limits
+sstream locale
+sstream memory
+sstream mutex
+sstream new
+sstream optional
+sstream ostream
+sstream print
+sstream queue
+sstream ratio
+sstream stack
+sstream stdexcept
+sstream streambuf
+sstream string
+sstream string_view
+sstream system_error
+sstream tuple
+sstream type_traits
+sstream typeinfo
+sstream unordered_map
+sstream utility
+sstream variant
+sstream vector
+sstream version
+stack algorithm
+stack array
+stack atomic
+stack bit
+stack cctype
+stack cerrno
+stack climits
+stack clocale
+stack cmath
+stack compare
+stack concepts
+stack cstdarg
+stack cstddef
+stack cstdint
+stack cstdio
+stack cstdlib
+stack cstring
+stack ctime
+stack cwchar
+stack cwctype
+stack deque
+stack exception
+stack functional
+stack initializer_list
+stack ios
+stack iosfwd
+stack iterator
+stack limits
+stack locale
+stack memory
+stack mutex
+stack new
+stack optional
+stack ratio
+stack stdexcept
+stack streambuf
+stack string
+stack string_view
+stack system_error
+stack tuple
+stack type_traits
+stack typeinfo
+stack unordered_map
+stack utility
+stack variant
+stack vector
+stack version
+stdexcept cstddef
+stdexcept cstdint
+stdexcept cstdlib
+stdexcept exception
+stdexcept iosfwd
+stdexcept new
+stdexcept type_traits
+stdexcept typeinfo
+stdexcept version
+stop_token atomic
+stop_token climits
+stop_token cmath
+stop_token compare
+stop_token cstddef
+stop_token cstdint
+stop_token cstdlib
+stop_token cstring
+stop_token ctime
+stop_token iosfwd
+stop_token limits
+stop_token ratio
+stop_token type_traits
+stop_token version
+streambuf algorithm
+streambuf atomic
+streambuf bit
+streambuf cctype
+streambuf cerrno
+streambuf climits
+streambuf clocale
+streambuf cmath
+streambuf compare
+streambuf concepts
+streambuf cstddef
+streambuf cstdint
+streambuf cstdio
+streambuf cstdlib
+streambuf cstring
+streambuf ctime
+streambuf cwchar
+streambuf cwctype
+streambuf exception
+streambuf initializer_list
+streambuf ios
+streambuf iosfwd
+streambuf iterator
+streambuf limits
+streambuf memory
+streambuf mutex
+streambuf new
+streambuf optional
+streambuf ratio
+streambuf stdexcept
+streambuf string
+streambuf string_view
+streambuf system_error
+streambuf tuple
+streambuf type_traits
+streambuf typeinfo
+streambuf utility
+streambuf variant
+streambuf version
+string algorithm
+string atomic
+string bit
+string cctype
+string climits
+string cmath
+string compare
+string concepts
+string cstddef
+string cstdint
+string cstdio
+string cstdlib
+string cstring
+string ctime
+string cwchar
+string cwctype
+string exception
+string initializer_list
+string iosfwd
+string iterator
+string limits
+string memory
+string new
+string optional
+string ratio
+string stdexcept
+string string_view
+string tuple
+string type_traits
+string typeinfo
+string utility
+string variant
+string version
+string_view algorithm
+string_view atomic
+string_view bit
+string_view cctype
+string_view climits
+string_view cmath
+string_view compare
+string_view concepts
+string_view cstddef
+string_view cstdint
+string_view cstdio
+string_view cstdlib
+string_view cstring
+string_view ctime
+string_view cwchar
+string_view cwctype
+string_view exception
+string_view initializer_list
+string_view iosfwd
+string_view iterator
+string_view limits
+string_view memory
+string_view new
+string_view optional
+string_view ratio
+string_view stdexcept
+string_view tuple
+string_view type_traits
+string_view typeinfo
+string_view utility
+string_view variant
+string_view version
+strstream algorithm
+strstream array
+strstream atomic
+strstream bit
+strstream bitset
+strstream cctype
+strstream cerrno
+strstream climits
+strstream clocale
+strstream cmath
+strstream compare
+strstream concepts
+strstream cstdarg
+strstream cstddef
+strstream cstdint
+strstream cstdio
+strstream cstdlib
+strstream cstring
+strstream ctime
+strstream cwchar
+strstream cwctype
+strstream deque
+strstream exception
+strstream format
+strstream functional
+strstream initializer_list
+strstream ios
+strstream iosfwd
+strstream istream
+strstream iterator
+strstream limits
+strstream locale
+strstream memory
+strstream mutex
+strstream new
+strstream optional
+strstream ostream
+strstream print
+strstream queue
+strstream ratio
+strstream stack
+strstream stdexcept
+strstream streambuf
+strstream string
+strstream string_view
+strstream system_error
+strstream tuple
+strstream type_traits
+strstream typeinfo
+strstream unordered_map
+strstream utility
+strstream variant
+strstream vector
+strstream version
+syncstream algorithm
+syncstream array
+syncstream atomic
+syncstream bit
+syncstream bitset
+syncstream cctype
+syncstream cerrno
+syncstream climits
+syncstream clocale
+syncstream cmath
+syncstream compare
+syncstream concepts
+syncstream cstdarg
+syncstream cstddef
+syncstream cstdint
+syncstream cstdio
+syncstream cstdlib
+syncstream cstring
+syncstream ctime
+syncstream cwchar
+syncstream cwctype
+syncstream deque
+syncstream exception
+syncstream format
+syncstream functional
+syncstream initializer_list
+syncstream ios
+syncstream iosfwd
+syncstream iterator
+syncstream limits
+syncstream locale
+syncstream map
+syncstream memory
+syncstream mutex
+syncstream new
+syncstream optional
+syncstream ostream
+syncstream print
+syncstream queue
+syncstream ratio
+syncstream shared_mutex
+syncstream stack
+syncstream stdexcept
+syncstream streambuf
+syncstream string
+syncstream string_view
+syncstream system_error
+syncstream tuple
+syncstream type_traits
+syncstream typeinfo
+syncstream unordered_map
+syncstream utility
+syncstream variant
+syncstream vector
+syncstream version
+system_error algorithm
+system_error atomic
+system_error bit
+system_error cctype
+system_error cerrno
+system_error climits
+system_error cmath
+system_error compare
+system_error concepts
+system_error cstddef
+system_error cstdint
+system_error cstdio
+system_error cstdlib
+system_error cstring
+system_error ctime
+system_error cwchar
+system_error cwctype
+system_error exception
+system_error initializer_list
+system_error iosfwd
+system_error iterator
+system_error limits
+system_error memory
+system_error new
+system_error optional
+system_error ratio
+system_error stdexcept
+system_error string
+system_error string_view
+system_error tuple
+system_error type_traits
+system_error typeinfo
+system_error utility
+system_error variant
+system_error version
+thread algorithm
+thread array
+thread atomic
+thread bit
+thread bitset
+thread cctype
+thread cerrno
+thread climits
+thread clocale
+thread cmath
+thread compare
+thread concepts
+thread cstdarg
+thread cstddef
+thread cstdint
+thread cstdio
+thread cstdlib
+thread cstring
+thread ctime
+thread cwchar
+thread cwctype
+thread deque
+thread exception
+thread format
+thread functional
+thread initializer_list
+thread ios
+thread iosfwd
+thread istream
+thread iterator
+thread limits
+thread locale
+thread memory
+thread mutex
+thread new
+thread optional
+thread ostream
+thread print
+thread queue
+thread ratio
+thread sstream
+thread stack
+thread stdexcept
+thread streambuf
+thread string
+thread string_view
+thread system_error
+thread tuple
+thread type_traits
+thread typeinfo
+thread unordered_map
+thread utility
+thread variant
+thread vector
+thread version
+tuple cmath
+tuple compare
+tuple cstddef
+tuple cstdint
+tuple cstdlib
+tuple exception
+tuple initializer_list
+tuple iosfwd
+tuple limits
+tuple new
+tuple type_traits
+tuple typeinfo
+tuple utility
+tuple version
+type_traits cstdint
+type_traits version
+typeindex cmath
+typeindex compare
+typeindex cstddef
+typeindex cstdint
+typeindex cstdlib
+typeindex initializer_list
+typeindex iosfwd
+typeindex limits
+typeindex new
+typeindex type_traits
+typeindex typeinfo
+typeindex utility
+typeindex version
+typeinfo cstddef
+typeinfo cstdint
+typeinfo cstdlib
+typeinfo type_traits
+typeinfo version
+unordered_map algorithm
+unordered_map atomic
+unordered_map bit
+unordered_map cctype
+unordered_map climits
+unordered_map cmath
+unordered_map compare
+unordered_map concepts
+unordered_map cstddef
+unordered_map cstdint
+unordered_map cstdio
+unordered_map cstdlib
+unordered_map cstring
+unordered_map ctime
+unordered_map cwchar
+unordered_map cwctype
+unordered_map exception
+unordered_map initializer_list
+unordered_map iosfwd
+unordered_map iterator
+unordered_map limits
+unordered_map memory
+unordered_map new
+unordered_map optional
+unordered_map ratio
+unordered_map stdexcept
+unordered_map tuple
+unordered_map type_traits
+unordered_map typeinfo
+unordered_map utility
+unordered_map variant
+unordered_map version
+unordered_set algorithm
+unordered_set array
+unordered_set atomic
+unordered_set bit
+unordered_set cctype
+unordered_set cerrno
+unordered_set climits
+unordered_set clocale
+unordered_set cmath
+unordered_set compare
+unordered_set concepts
+unordered_set cstdarg
+unordered_set cstddef
+unordered_set cstdint
+unordered_set cstdio
+unordered_set cstdlib
+unordered_set cstring
+unordered_set ctime
+unordered_set cwchar
+unordered_set cwctype
+unordered_set exception
+unordered_set functional
+unordered_set initializer_list
+unordered_set ios
+unordered_set iosfwd
+unordered_set iterator
+unordered_set limits
+unordered_set locale
+unordered_set memory
+unordered_set mutex
+unordered_set new
+unordered_set optional
+unordered_set ratio
+unordered_set stdexcept
+unordered_set streambuf
+unordered_set string
+unordered_set string_view
+unordered_set system_error
+unordered_set tuple
+unordered_set type_traits
+unordered_set typeinfo
+unordered_set unordered_map
+unordered_set utility
+unordered_set variant
+unordered_set vector
+unordered_set version
+utility cmath
+utility compare
+utility cstddef
+utility cstdint
+utility cstdlib
+utility initializer_list
+utility iosfwd
+utility limits
+utility type_traits
+utility version
+valarray algorithm
+valarray array
+valarray atomic
+valarray bit
+valarray cctype
+valarray cerrno
+valarray climits
+valarray clocale
+valarray cmath
+valarray compare
+valarray concepts
+valarray cstdarg
+valarray cstddef
+valarray cstdint
+valarray cstdio
+valarray cstdlib
+valarray cstring
+valarray ctime
+valarray cwchar
+valarray cwctype
+valarray exception
+valarray functional
+valarray initializer_list
+valarray ios
+valarray iosfwd
+valarray iterator
+valarray limits
+valarray locale
+valarray memory
+valarray mutex
+valarray new
+valarray optional
+valarray ratio
+valarray stdexcept
+valarray streambuf
+valarray string
+valarray string_view
+valarray system_error
+valarray tuple
+valarray type_traits
+valarray typeinfo
+valarray unordered_map
+valarray utility
+valarray variant
+valarray vector
+valarray version
+variant cmath
+variant compare
+variant cstddef
+variant cstdint
+variant cstdlib
+variant cstring
+variant exception
+variant initializer_list
+variant iosfwd
+variant limits
+variant new
+variant tuple
+variant type_traits
+variant typeinfo
+variant utility
+variant version
+vector algorithm
+vector array
+vector atomic
+vector bit
+vector cctype
+vector cerrno
+vector climits
+vector clocale
+vector cmath
+vector compare
+vector concepts
+vector cstdarg
+vector cstddef
+vector cstdint
+vector cstdio
+vector cstdlib
+vector cstring
+vector ctime
+vector cwchar
+vector cwctype
+vector exception
+vector initializer_list
+vector ios
+vector iosfwd
+vector iterator
+vector limits
+vector locale
+vector memory
+vector mutex
+vector new
+vector optional
+vector ratio
+vector stdexcept
+vector streambuf
+vector string
+vector string_view
+vector system_error
+vector tuple
+vector type_traits
+vector typeinfo
+vector utility
+vector variant
+vector version
diff --git a/libcxx/test/libcxx-03/transitive_includes/cxx23.csv b/libcxx/test/libcxx-03/transitive_includes/cxx23.csv
new file mode 100644
index 0000000000000..cb23c7a98de1b
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/cxx23.csv
@@ -0,0 +1,1166 @@
+algorithm cctype
+algorithm climits
+algorithm compare
+algorithm cstdint
+algorithm cstring
+algorithm ctime
+algorithm cwchar
+algorithm cwctype
+algorithm initializer_list
+algorithm iosfwd
+algorithm limits
+algorithm optional
+algorithm ratio
+algorithm tuple
+algorithm version
+any cstdint
+any cstring
+any initializer_list
+any limits
+any typeinfo
+any version
+array cctype
+array compare
+array cstdint
+array cwchar
+array cwctype
+array initializer_list
+array limits
+array stdexcept
+array version
+atomic climits
+atomic cstdint
+atomic cstring
+atomic ctime
+atomic limits
+atomic ratio
+atomic version
+barrier climits
+barrier cstdint
+barrier cstring
+barrier ctime
+barrier limits
+barrier ratio
+barrier version
+bit cstdint
+bit limits
+bit version
+bitset cctype
+bitset climits
+bitset compare
+bitset cstdint
+bitset cstdio
+bitset cstring
+bitset cwchar
+bitset cwctype
+bitset initializer_list
+bitset iosfwd
+bitset limits
+bitset stdexcept
+bitset string
+bitset string_view
+bitset tuple
+bitset version
+ccomplex bitset
+ccomplex cctype
+ccomplex cerrno
+ccomplex climits
+ccomplex clocale
+ccomplex cmath
+ccomplex compare
+ccomplex complex
+ccomplex cstddef
+ccomplex cstdint
+ccomplex cstdio
+ccomplex cstdlib
+ccomplex cstring
+ccomplex ctime
+ccomplex cwchar
+ccomplex cwctype
+ccomplex initializer_list
+ccomplex ios
+ccomplex iosfwd
+ccomplex istream
+ccomplex limits
+ccomplex locale
+ccomplex ratio
+ccomplex sstream
+ccomplex stdexcept
+ccomplex streambuf
+ccomplex string
+ccomplex string_view
+ccomplex tuple
+ccomplex typeinfo
+ccomplex version
+charconv cerrno
+charconv cstdint
+charconv initializer_list
+charconv limits
+charconv version
+chrono array
+chrono bitset
+chrono cctype
+chrono cerrno
+chrono climits
+chrono clocale
+chrono cmath
+chrono compare
+chrono cstddef
+chrono cstdint
+chrono cstdio
+chrono cstdlib
+chrono cstring
+chrono ctime
+chrono cwchar
+chrono cwctype
+chrono format
+chrono forward_list
+chrono initializer_list
+chrono ios
+chrono iosfwd
+chrono istream
+chrono limits
+chrono locale
+chrono optional
+chrono ratio
+chrono sstream
+chrono stdexcept
+chrono streambuf
+chrono string
+chrono string_view
+chrono tuple
+chrono typeinfo
+chrono version
+cinttypes cstdint
+cmath limits
+cmath version
+codecvt cctype
+codecvt climits
+codecvt clocale
+codecvt compare
+codecvt cstddef
+codecvt cstdint
+codecvt cstdio
+codecvt cstdlib
+codecvt cstring
+codecvt cwchar
+codecvt cwctype
+codecvt initializer_list
+codecvt iosfwd
+codecvt limits
+codecvt stdexcept
+codecvt string
+codecvt string_view
+codecvt tuple
+codecvt typeinfo
+codecvt version
+compare cstdint
+compare limits
+compare version
+complex bitset
+complex cctype
+complex cerrno
+complex climits
+complex clocale
+complex cmath
+complex compare
+complex cstddef
+complex cstdint
+complex cstdio
+complex cstdlib
+complex cstring
+complex ctime
+complex cwchar
+complex cwctype
+complex initializer_list
+complex ios
+complex iosfwd
+complex istream
+complex limits
+complex locale
+complex ratio
+complex sstream
+complex stdexcept
+complex streambuf
+complex string
+complex string_view
+complex tuple
+complex typeinfo
+complex version
+concepts version
+condition_variable atomic
+condition_variable cerrno
+condition_variable climits
+condition_variable cstdint
+condition_variable cstring
+condition_variable ctime
+condition_variable initializer_list
+condition_variable limits
+condition_variable ratio
+condition_variable typeinfo
+condition_variable version
+coroutine compare
+coroutine cstdint
+coroutine cstring
+coroutine limits
+coroutine version
+cstddef version
+ctgmath bitset
+ctgmath cctype
+ctgmath cerrno
+ctgmath climits
+ctgmath clocale
+ctgmath cmath
+ctgmath compare
+ctgmath complex
+ctgmath cstddef
+ctgmath cstdint
+ctgmath cstdio
+ctgmath cstdlib
+ctgmath cstring
+ctgmath ctime
+ctgmath cwchar
+ctgmath cwctype
+ctgmath initializer_list
+ctgmath ios
+ctgmath iosfwd
+ctgmath istream
+ctgmath limits
+ctgmath locale
+ctgmath ratio
+ctgmath sstream
+ctgmath stdexcept
+ctgmath streambuf
+ctgmath string
+ctgmath string_view
+ctgmath tuple
+ctgmath typeinfo
+ctgmath version
+cwchar cctype
+cwchar cwctype
+cwctype cctype
+deque cctype
+deque compare
+deque cstdint
+deque cstring
+deque cwchar
+deque cwctype
+deque initializer_list
+deque limits
+deque stdexcept
+deque tuple
+deque version
+exception cstdint
+exception cstdlib
+exception typeinfo
+exception version
+execution version
+expected cstdint
+expected initializer_list
+expected version
+experimental/iterator bitset
+experimental/iterator cctype
+experimental/iterator cerrno
+experimental/iterator climits
+experimental/iterator clocale
+experimental/iterator compare
+experimental/iterator concepts
+experimental/iterator cstddef
+experimental/iterator cstdint
+experimental/iterator cstdio
+experimental/iterator cstdlib
+experimental/iterator cstring
+experimental/iterator ctime
+experimental/iterator cwchar
+experimental/iterator cwctype
+experimental/iterator initializer_list
+experimental/iterator ios
+experimental/iterator iosfwd
+experimental/iterator iterator
+experimental/iterator limits
+experimental/iterator locale
+experimental/iterator ratio
+experimental/iterator stdexcept
+experimental/iterator streambuf
+experimental/iterator string
+experimental/iterator string_view
+experimental/iterator tuple
+experimental/iterator typeinfo
+experimental/iterator variant
+experimental/iterator version
+experimental/memory cstdint
+experimental/memory cstring
+experimental/memory version
+experimental/propagate_const version
+experimental/simd cstdint
+experimental/simd limits
+experimental/simd version
+experimental/type_traits cstdint
+experimental/type_traits initializer_list
+experimental/type_traits type_traits
+experimental/type_traits version
+experimental/utility compare
+experimental/utility cstdint
+experimental/utility initializer_list
+experimental/utility limits
+experimental/utility utility
+experimental/utility version
+filesystem cctype
+filesystem cerrno
+filesystem climits
+filesystem clocale
+filesystem compare
+filesystem cstddef
+filesystem cstdint
+filesystem cstdio
+filesystem cstdlib
+filesystem cstring
+filesystem ctime
+filesystem cwchar
+filesystem cwctype
+filesystem initializer_list
+filesystem iomanip
+filesystem ios
+filesystem iosfwd
+filesystem limits
+filesystem locale
+filesystem ratio
+filesystem stdexcept
+filesystem streambuf
+filesystem string
+filesystem string_view
+filesystem tuple
+filesystem typeinfo
+filesystem version
+flat_map cctype
+flat_map climits
+flat_map compare
+flat_map cstdint
+flat_map cstring
+flat_map cwchar
+flat_map cwctype
+flat_map initializer_list
+flat_map limits
+flat_map optional
+flat_map stdexcept
+flat_map tuple
+flat_map version
+flat_set cctype
+flat_set climits
+flat_set compare
+flat_set cstdint
+flat_set cstring
+flat_set cwchar
+flat_set cwctype
+flat_set initializer_list
+flat_set limits
+flat_set optional
+flat_set stdexcept
+flat_set tuple
+flat_set version
+format array
+format cctype
+format cerrno
+format climits
+format clocale
+format cmath
+format compare
+format cstddef
+format cstdint
+format cstdio
+format cstdlib
+format cstring
+format cwchar
+format cwctype
+format initializer_list
+format iosfwd
+format limits
+format optional
+format stdexcept
+format string
+format string_view
+format tuple
+format typeinfo
+format version
+forward_list cctype
+forward_list compare
+forward_list cstdint
+forward_list cwchar
+forward_list cwctype
+forward_list initializer_list
+forward_list limits
+forward_list tuple
+forward_list version
+fstream bitset
+fstream cctype
+fstream cerrno
+fstream climits
+fstream clocale
+fstream compare
+fstream cstddef
+fstream cstdint
+fstream cstdio
+fstream cstdlib
+fstream cstring
+fstream ctime
+fstream cwchar
+fstream cwctype
+fstream filesystem
+fstream initializer_list
+fstream iomanip
+fstream ios
+fstream iosfwd
+fstream istream
+fstream limits
+fstream locale
+fstream ratio
+fstream stdexcept
+fstream streambuf
+fstream string
+fstream string_view
+fstream tuple
+fstream typeinfo
+fstream version
+functional array
+functional cctype
+functional compare
+functional cstdint
+functional cstring
+functional cwchar
+functional cwctype
+functional initializer_list
+functional limits
+functional optional
+functional stdexcept
+functional tuple
+functional typeinfo
+functional unordered_map
+functional version
+future bitset
+future cctype
+future cerrno
+future climits
+future clocale
+future compare
+future cstddef
+future cstdint
+future cstdio
+future cstdlib
+future cstring
+future ctime
+future cwchar
+future cwctype
+future initializer_list
+future ios
+future iosfwd
+future istream
+future limits
+future locale
+future ratio
+future sstream
+future stdexcept
+future streambuf
+future string
+future string_view
+future tuple
+future typeinfo
+future version
+initializer_list version
+iomanip cctype
+iomanip cerrno
+iomanip climits
+iomanip clocale
+iomanip compare
+iomanip cstddef
+iomanip cstdint
+iomanip cstdio
+iomanip cstdlib
+iomanip cstring
+iomanip ctime
+iomanip cwchar
+iomanip cwctype
+iomanip initializer_list
+iomanip ios
+iomanip iosfwd
+iomanip limits
+iomanip locale
+iomanip ratio
+iomanip stdexcept
+iomanip streambuf
+iomanip string
+iomanip string_view
+iomanip tuple
+iomanip typeinfo
+iomanip version
+ios cctype
+ios cerrno
+ios climits
+ios clocale
+ios compare
+ios cstddef
+ios cstdint
+ios cstdio
+ios cstdlib
+ios cstring
+ios ctime
+ios cwchar
+ios cwctype
+ios initializer_list
+ios iosfwd
+ios limits
+ios ratio
+ios stdexcept
+ios string
+ios string_view
+ios tuple
+ios typeinfo
+ios version
+iosfwd version
+iostream array
+iostream bitset
+iostream cctype
+iostream cerrno
+iostream climits
+iostream clocale
+iostream cmath
+iostream compare
+iostream cstddef
+iostream cstdint
+iostream cstdio
+iostream cstdlib
+iostream cstring
+iostream ctime
+iostream cwchar
+iostream cwctype
+iostream format
+iostream initializer_list
+iostream ios
+iostream iosfwd
+iostream istream
+iostream limits
+iostream locale
+iostream optional
+iostream ostream
+iostream print
+iostream ratio
+iostream stdexcept
+iostream streambuf
+iostream string
+iostream string_view
+iostream tuple
+iostream typeinfo
+iostream version
+istream bitset
+istream cctype
+istream cerrno
+istream climits
+istream clocale
+istream compare
+istream cstddef
+istream cstdint
+istream cstdio
+istream cstdlib
+istream cstring
+istream ctime
+istream cwchar
+istream cwctype
+istream initializer_list
+istream ios
+istream iosfwd
+istream limits
+istream locale
+istream ratio
+istream stdexcept
+istream streambuf
+istream string
+istream string_view
+istream tuple
+istream typeinfo
+istream version
+iterator cctype
+iterator compare
+iterator concepts
+iterator cstdint
+iterator cstdio
+iterator cstring
+iterator cwchar
+iterator cwctype
+iterator initializer_list
+iterator iosfwd
+iterator limits
+iterator variant
+iterator version
+latch climits
+latch cstdint
+latch cstring
+latch ctime
+latch limits
+latch ratio
+latch version
+limits version
+list cctype
+list compare
+list cstdint
+list cstring
+list cwchar
+list cwctype
+list initializer_list
+list limits
+list tuple
+list version
+locale cctype
+locale cerrno
+locale climits
+locale clocale
+locale compare
+locale cstddef
+locale cstdint
+locale cstdio
+locale cstdlib
+locale cstring
+locale ctime
+locale cwchar
+locale cwctype
+locale initializer_list
+locale ios
+locale iosfwd
+locale limits
+locale ratio
+locale stdexcept
+locale streambuf
+locale string
+locale string_view
+locale tuple
+locale typeinfo
+locale version
+map cctype
+map compare
+map cstdint
+map cstring
+map cwchar
+map cwctype
+map initializer_list
+map limits
+map optional
+map stdexcept
+map tuple
+map version
+mdspan array
+mdspan cctype
+mdspan compare
+mdspan concepts
+mdspan cstdint
+mdspan cwchar
+mdspan cwctype
+mdspan initializer_list
+mdspan limits
+mdspan span
+mdspan stdexcept
+mdspan version
+memory compare
+memory cstdint
+memory cstring
+memory initializer_list
+memory limits
+memory tuple
+memory typeinfo
+memory version
+memory_resource cerrno
+memory_resource climits
+memory_resource compare
+memory_resource cstdint
+memory_resource ctime
+memory_resource limits
+memory_resource ratio
+memory_resource tuple
+memory_resource version
+mutex cerrno
+mutex climits
+mutex compare
+mutex cstdint
+mutex ctime
+mutex limits
+mutex ratio
+mutex tuple
+mutex typeinfo
+mutex version
+new version
+numbers version
+numeric climits
+numeric compare
+numeric cstdint
+numeric cstring
+numeric ctime
+numeric initializer_list
+numeric limits
+numeric optional
+numeric ratio
+numeric tuple
+numeric version
+optional compare
+optional cstdint
+optional cstring
+optional initializer_list
+optional limits
+optional version
+ostream array
+ostream bitset
+ostream cctype
+ostream cerrno
+ostream climits
+ostream clocale
+ostream cmath
+ostream compare
+ostream cstddef
+ostream cstdint
+ostream cstdio
+ostream cstdlib
+ostream cstring
+ostream ctime
+ostream cwchar
+ostream cwctype
+ostream format
+ostream initializer_list
+ostream ios
+ostream iosfwd
+ostream limits
+ostream locale
+ostream optional
+ostream print
+ostream ratio
+ostream stdexcept
+ostream streambuf
+ostream string
+ostream string_view
+ostream tuple
+ostream typeinfo
+ostream version
+print array
+print cctype
+print cerrno
+print climits
+print clocale
+print cmath
+print compare
+print cstddef
+print cstdint
+print cstdio
+print cstdlib
+print cstring
+print cwchar
+print cwctype
+print format
+print initializer_list
+print iosfwd
+print limits
+print optional
+print stdexcept
+print string
+print string_view
+print tuple
+print typeinfo
+print version
+queue array
+queue cctype
+queue cerrno
+queue climits
+queue clocale
+queue compare
+queue cstddef
+queue cstdint
+queue cstdio
+queue cstdlib
+queue cstring
+queue cwchar
+queue cwctype
+queue deque
+queue initializer_list
+queue iosfwd
+queue limits
+queue stdexcept
+queue string
+queue string_view
+queue tuple
+queue typeinfo
+queue vector
+queue version
+random cctype
+random climits
+random cmath
+random compare
+random cstdint
+random cstdio
+random cstring
+random ctime
+random cwchar
+random cwctype
+random initializer_list
+random iosfwd
+random limits
+random numeric
+random optional
+random ratio
+random stdexcept
+random string
+random string_view
+random tuple
+random version
+ranges cctype
+ranges compare
+ranges concepts
+ranges cstdint
+ranges cstdio
+ranges cstring
+ranges cwchar
+ranges cwctype
+ranges initializer_list
+ranges iosfwd
+ranges iterator
+ranges limits
+ranges optional
+ranges span
+ranges stdexcept
+ranges tuple
+ranges variant
+ranges version
+ratio climits
+ratio cstdint
+ratio version
+regex array
+regex cctype
+regex cerrno
+regex climits
+regex clocale
+regex compare
+regex cstddef
+regex cstdint
+regex cstdio
+regex cstdlib
+regex cstring
+regex cwchar
+regex cwctype
+regex deque
+regex initializer_list
+regex iosfwd
+regex limits
+regex stdexcept
+regex string
+regex string_view
+regex tuple
+regex typeinfo
+regex vector
+regex version
+scoped_allocator compare
+scoped_allocator cstdint
+scoped_allocator limits
+scoped_allocator tuple
+scoped_allocator version
+semaphore climits
+semaphore cstdint
+semaphore cstring
+semaphore ctime
+semaphore limits
+semaphore ratio
+semaphore version
+set cctype
+set compare
+set cstdint
+set cstring
+set cwchar
+set cwctype
+set initializer_list
+set limits
+set optional
+set tuple
+set version
+shared_mutex cerrno
+shared_mutex climits
+shared_mutex cstdint
+shared_mutex ctime
+shared_mutex limits
+shared_mutex ratio
+shared_mutex version
+source_location cstdint
+source_location version
+span initializer_list
+span limits
+span stdexcept
+span version
+sstream bitset
+sstream cctype
+sstream cerrno
+sstream climits
+sstream clocale
+sstream compare
+sstream cstddef
+sstream cstdint
+sstream cstdio
+sstream cstdlib
+sstream cstring
+sstream ctime
+sstream cwchar
+sstream cwctype
+sstream initializer_list
+sstream ios
+sstream iosfwd
+sstream istream
+sstream limits
+sstream locale
+sstream ratio
+sstream stdexcept
+sstream streambuf
+sstream string
+sstream string_view
+sstream tuple
+sstream typeinfo
+sstream version
+stack cctype
+stack compare
+stack cstdint
+stack cstring
+stack cwchar
+stack cwctype
+stack deque
+stack initializer_list
+stack limits
+stack stdexcept
+stack tuple
+stack version
+stop_token atomic
+stop_token climits
+stop_token cstdint
+stop_token cstring
+stop_token ctime
+stop_token limits
+stop_token ratio
+stop_token version
+streambuf cctype
+streambuf cerrno
+streambuf climits
+streambuf clocale
+streambuf compare
+streambuf cstddef
+streambuf cstdint
+streambuf cstdio
+streambuf cstdlib
+streambuf cstring
+streambuf ctime
+streambuf cwchar
+streambuf cwctype
+streambuf initializer_list
+streambuf ios
+streambuf iosfwd
+streambuf limits
+streambuf ratio
+streambuf stdexcept
+streambuf string
+streambuf string_view
+streambuf tuple
+streambuf typeinfo
+streambuf version
+string cctype
+string climits
+string compare
+string cstdint
+string cstdio
+string cstring
+string cwchar
+string cwctype
+string initializer_list
+string iosfwd
+string limits
+string stdexcept
+string string_view
+string tuple
+string version
+string_view cctype
+string_view compare
+string_view cstdint
+string_view cstdio
+string_view cstring
+string_view cwchar
+string_view cwctype
+string_view initializer_list
+string_view iosfwd
+string_view limits
+string_view stdexcept
+string_view version
+strstream bitset
+strstream cctype
+strstream cerrno
+strstream climits
+strstream clocale
+strstream compare
+strstream cstddef
+strstream cstdint
+strstream cstdio
+strstream cstdlib
+strstream cstring
+strstream ctime
+strstream cwchar
+strstream cwctype
+strstream initializer_list
+strstream ios
+strstream iosfwd
+strstream istream
+strstream limits
+strstream locale
+strstream ratio
+strstream stdexcept
+strstream streambuf
+strstream string
+strstream string_view
+strstream tuple
+strstream typeinfo
+strstream version
+syncstream array
+syncstream bitset
+syncstream cctype
+syncstream cerrno
+syncstream climits
+syncstream clocale
+syncstream cmath
+syncstream compare
+syncstream cstddef
+syncstream cstdint
+syncstream cstdio
+syncstream cstdlib
+syncstream cstring
+syncstream ctime
+syncstream cwchar
+syncstream cwctype
+syncstream format
+syncstream initializer_list
+syncstream ios
+syncstream iosfwd
+syncstream limits
+syncstream locale
+syncstream map
+syncstream optional
+syncstream ostream
+syncstream print
+syncstream ratio
+syncstream shared_mutex
+syncstream stdexcept
+syncstream streambuf
+syncstream string
+syncstream string_view
+syncstream tuple
+syncstream typeinfo
+syncstream version
+system_error cctype
+system_error cerrno
+system_error climits
+system_error compare
+system_error cstdint
+system_error cstdio
+system_error cstring
+system_error cwchar
+system_error cwctype
+system_error initializer_list
+system_error iosfwd
+system_error limits
+system_error stdexcept
+system_error string
+system_error string_view
+system_error tuple
+system_error version
+thread array
+thread atomic
+thread bitset
+thread cctype
+thread cerrno
+thread climits
+thread clocale
+thread compare
+thread cstddef
+thread cstdint
+thread cstdio
+thread cstdlib
+thread cstring
+thread ctime
+thread cwchar
+thread cwctype
+thread initializer_list
+thread ios
+thread iosfwd
+thread istream
+thread limits
+thread locale
+thread ratio
+thread sstream
+thread stdexcept
+thread streambuf
+thread string
+thread string_view
+thread tuple
+thread typeinfo
+thread version
+tuple compare
+tuple cstdint
+tuple limits
+tuple version
+type_traits cstdint
+type_traits version
+typeindex compare
+typeindex cstdint
+typeindex limits
+typeindex typeinfo
+typeindex version
+typeinfo cstdint
+typeinfo version
+unordered_map compare
+unordered_map cstdint
+unordered_map cstring
+unordered_map initializer_list
+unordered_map limits
+unordered_map optional
+unordered_map stdexcept
+unordered_map tuple
+unordered_map version
+unordered_set compare
+unordered_set cstdint
+unordered_set cstring
+unordered_set initializer_list
+unordered_set limits
+unordered_set optional
+unordered_set tuple
+unordered_set version
+utility compare
+utility cstdint
+utility initializer_list
+utility limits
+utility version
+valarray cmath
+valarray cstdint
+valarray initializer_list
+valarray limits
+valarray version
+variant compare
+variant cstdint
+variant cstring
+variant initializer_list
+variant limits
+variant version
+vector array
+vector cctype
+vector cerrno
+vector climits
+vector clocale
+vector compare
+vector cstddef
+vector cstdint
+vector cstdio
+vector cstdlib
+vector cstring
+vector cwchar
+vector cwctype
+vector initializer_list
+vector iosfwd
+vector limits
+vector stdexcept
+vector string
+vector string_view
+vector tuple
+vector typeinfo
+vector version
diff --git a/libcxx/test/libcxx-03/transitive_includes/cxx26.csv b/libcxx/test/libcxx-03/transitive_includes/cxx26.csv
new file mode 100644
index 0000000000000..ce8f0261f2b27
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/cxx26.csv
@@ -0,0 +1,1167 @@
+algorithm cctype
+algorithm climits
+algorithm compare
+algorithm cstdint
+algorithm cstring
+algorithm ctime
+algorithm cwchar
+algorithm cwctype
+algorithm initializer_list
+algorithm iosfwd
+algorithm limits
+algorithm optional
+algorithm ratio
+algorithm tuple
+algorithm version
+any cstdint
+any cstring
+any initializer_list
+any limits
+any typeinfo
+any version
+array cctype
+array compare
+array cstdint
+array cwchar
+array cwctype
+array initializer_list
+array limits
+array stdexcept
+array version
+atomic climits
+atomic cstdint
+atomic cstring
+atomic ctime
+atomic limits
+atomic ratio
+atomic version
+barrier climits
+barrier cstdint
+barrier cstring
+barrier ctime
+barrier limits
+barrier ratio
+barrier version
+bit cstdint
+bit limits
+bit version
+bitset cctype
+bitset climits
+bitset compare
+bitset cstdint
+bitset cstdio
+bitset cstring
+bitset cwchar
+bitset cwctype
+bitset initializer_list
+bitset iosfwd
+bitset limits
+bitset stdexcept
+bitset string
+bitset string_view
+bitset tuple
+bitset version
+ccomplex bitset
+ccomplex cctype
+ccomplex cerrno
+ccomplex climits
+ccomplex clocale
+ccomplex cmath
+ccomplex compare
+ccomplex complex
+ccomplex cstddef
+ccomplex cstdint
+ccomplex cstdio
+ccomplex cstdlib
+ccomplex cstring
+ccomplex ctime
+ccomplex cwchar
+ccomplex cwctype
+ccomplex initializer_list
+ccomplex ios
+ccomplex iosfwd
+ccomplex istream
+ccomplex limits
+ccomplex locale
+ccomplex ratio
+ccomplex sstream
+ccomplex stdexcept
+ccomplex streambuf
+ccomplex string
+ccomplex string_view
+ccomplex tuple
+ccomplex typeinfo
+ccomplex version
+charconv cerrno
+charconv cstdint
+charconv initializer_list
+charconv limits
+charconv version
+chrono array
+chrono bitset
+chrono cctype
+chrono cerrno
+chrono climits
+chrono clocale
+chrono cmath
+chrono compare
+chrono cstddef
+chrono cstdint
+chrono cstdio
+chrono cstdlib
+chrono cstring
+chrono ctime
+chrono cwchar
+chrono cwctype
+chrono format
+chrono forward_list
+chrono initializer_list
+chrono ios
+chrono iosfwd
+chrono istream
+chrono limits
+chrono locale
+chrono optional
+chrono ratio
+chrono sstream
+chrono stdexcept
+chrono streambuf
+chrono string
+chrono string_view
+chrono tuple
+chrono typeinfo
+chrono version
+cinttypes cstdint
+cmath limits
+cmath version
+codecvt cctype
+codecvt climits
+codecvt clocale
+codecvt compare
+codecvt cstddef
+codecvt cstdint
+codecvt cstdio
+codecvt cstdlib
+codecvt cstring
+codecvt cwchar
+codecvt cwctype
+codecvt initializer_list
+codecvt iosfwd
+codecvt limits
+codecvt stdexcept
+codecvt string
+codecvt string_view
+codecvt tuple
+codecvt typeinfo
+codecvt version
+compare cstdint
+compare limits
+compare version
+complex bitset
+complex cctype
+complex cerrno
+complex climits
+complex clocale
+complex cmath
+complex compare
+complex cstddef
+complex cstdint
+complex cstdio
+complex cstdlib
+complex cstring
+complex ctime
+complex cwchar
+complex cwctype
+complex initializer_list
+complex ios
+complex iosfwd
+complex istream
+complex limits
+complex locale
+complex ratio
+complex sstream
+complex stdexcept
+complex streambuf
+complex string
+complex string_view
+complex tuple
+complex typeinfo
+complex version
+concepts version
+condition_variable atomic
+condition_variable cerrno
+condition_variable climits
+condition_variable cstdint
+condition_variable cstring
+condition_variable ctime
+condition_variable initializer_list
+condition_variable limits
+condition_variable ratio
+condition_variable typeinfo
+condition_variable version
+coroutine compare
+coroutine cstdint
+coroutine cstring
+coroutine limits
+coroutine version
+cstddef version
+ctgmath bitset
+ctgmath cctype
+ctgmath cerrno
+ctgmath climits
+ctgmath clocale
+ctgmath cmath
+ctgmath compare
+ctgmath complex
+ctgmath cstddef
+ctgmath cstdint
+ctgmath cstdio
+ctgmath cstdlib
+ctgmath cstring
+ctgmath ctime
+ctgmath cwchar
+ctgmath cwctype
+ctgmath initializer_list
+ctgmath ios
+ctgmath iosfwd
+ctgmath istream
+ctgmath limits
+ctgmath locale
+ctgmath ratio
+ctgmath sstream
+ctgmath stdexcept
+ctgmath streambuf
+ctgmath string
+ctgmath string_view
+ctgmath tuple
+ctgmath typeinfo
+ctgmath version
+cwchar cctype
+cwchar cwctype
+cwctype cctype
+deque cctype
+deque compare
+deque cstdint
+deque cstring
+deque cwchar
+deque cwctype
+deque initializer_list
+deque limits
+deque stdexcept
+deque tuple
+deque version
+exception cstdint
+exception cstdlib
+exception typeinfo
+exception version
+execution version
+expected cstdint
+expected initializer_list
+expected version
+experimental/iterator bitset
+experimental/iterator cctype
+experimental/iterator cerrno
+experimental/iterator climits
+experimental/iterator clocale
+experimental/iterator compare
+experimental/iterator concepts
+experimental/iterator cstddef
+experimental/iterator cstdint
+experimental/iterator cstdio
+experimental/iterator cstdlib
+experimental/iterator cstring
+experimental/iterator ctime
+experimental/iterator cwchar
+experimental/iterator cwctype
+experimental/iterator initializer_list
+experimental/iterator ios
+experimental/iterator iosfwd
+experimental/iterator iterator
+experimental/iterator limits
+experimental/iterator locale
+experimental/iterator ratio
+experimental/iterator stdexcept
+experimental/iterator streambuf
+experimental/iterator string
+experimental/iterator string_view
+experimental/iterator tuple
+experimental/iterator typeinfo
+experimental/iterator variant
+experimental/iterator version
+experimental/memory cstdint
+experimental/memory cstring
+experimental/memory version
+experimental/propagate_const version
+experimental/simd cstdint
+experimental/simd limits
+experimental/simd version
+experimental/type_traits cstdint
+experimental/type_traits initializer_list
+experimental/type_traits type_traits
+experimental/type_traits version
+experimental/utility compare
+experimental/utility cstdint
+experimental/utility cstring
+experimental/utility initializer_list
+experimental/utility limits
+experimental/utility utility
+experimental/utility version
+filesystem cctype
+filesystem cerrno
+filesystem climits
+filesystem clocale
+filesystem compare
+filesystem cstddef
+filesystem cstdint
+filesystem cstdio
+filesystem cstdlib
+filesystem cstring
+filesystem ctime
+filesystem cwchar
+filesystem cwctype
+filesystem initializer_list
+filesystem iomanip
+filesystem ios
+filesystem iosfwd
+filesystem limits
+filesystem locale
+filesystem ratio
+filesystem stdexcept
+filesystem streambuf
+filesystem string
+filesystem string_view
+filesystem tuple
+filesystem typeinfo
+filesystem version
+flat_map cctype
+flat_map climits
+flat_map compare
+flat_map cstdint
+flat_map cstring
+flat_map cwchar
+flat_map cwctype
+flat_map initializer_list
+flat_map limits
+flat_map optional
+flat_map stdexcept
+flat_map tuple
+flat_map version
+flat_set cctype
+flat_set climits
+flat_set compare
+flat_set cstdint
+flat_set cstring
+flat_set cwchar
+flat_set cwctype
+flat_set initializer_list
+flat_set limits
+flat_set optional
+flat_set stdexcept
+flat_set tuple
+flat_set version
+format array
+format cctype
+format cerrno
+format climits
+format clocale
+format cmath
+format compare
+format cstddef
+format cstdint
+format cstdio
+format cstdlib
+format cstring
+format cwchar
+format cwctype
+format initializer_list
+format iosfwd
+format limits
+format optional
+format stdexcept
+format string
+format string_view
+format tuple
+format typeinfo
+format version
+forward_list cctype
+forward_list compare
+forward_list cstdint
+forward_list cwchar
+forward_list cwctype
+forward_list initializer_list
+forward_list limits
+forward_list tuple
+forward_list version
+fstream bitset
+fstream cctype
+fstream cerrno
+fstream climits
+fstream clocale
+fstream compare
+fstream cstddef
+fstream cstdint
+fstream cstdio
+fstream cstdlib
+fstream cstring
+fstream ctime
+fstream cwchar
+fstream cwctype
+fstream initializer_list
+fstream iomanip
+fstream ios
+fstream iosfwd
+fstream istream
+fstream limits
+fstream locale
+fstream ratio
+fstream stdexcept
+fstream streambuf
+fstream string
+fstream string_view
+fstream tuple
+fstream typeinfo
+fstream version
+functional array
+functional cctype
+functional compare
+functional cstdint
+functional cstring
+functional cwchar
+functional cwctype
+functional initializer_list
+functional limits
+functional optional
+functional stdexcept
+functional tuple
+functional typeinfo
+functional unordered_map
+functional version
+future bitset
+future cctype
+future cerrno
+future climits
+future clocale
+future compare
+future cstddef
+future cstdint
+future cstdio
+future cstdlib
+future cstring
+future ctime
+future cwchar
+future cwctype
+future initializer_list
+future ios
+future iosfwd
+future istream
+future limits
+future locale
+future ratio
+future sstream
+future stdexcept
+future streambuf
+future string
+future string_view
+future tuple
+future typeinfo
+future version
+initializer_list version
+iomanip cctype
+iomanip cerrno
+iomanip climits
+iomanip clocale
+iomanip compare
+iomanip cstddef
+iomanip cstdint
+iomanip cstdio
+iomanip cstdlib
+iomanip cstring
+iomanip ctime
+iomanip cwchar
+iomanip cwctype
+iomanip initializer_list
+iomanip ios
+iomanip iosfwd
+iomanip limits
+iomanip locale
+iomanip ratio
+iomanip stdexcept
+iomanip streambuf
+iomanip string
+iomanip string_view
+iomanip tuple
+iomanip typeinfo
+iomanip version
+ios cctype
+ios cerrno
+ios climits
+ios clocale
+ios compare
+ios cstddef
+ios cstdint
+ios cstdio
+ios cstdlib
+ios cstring
+ios ctime
+ios cwchar
+ios cwctype
+ios initializer_list
+ios iosfwd
+ios limits
+ios ratio
+ios stdexcept
+ios string
+ios string_view
+ios tuple
+ios typeinfo
+ios version
+iosfwd version
+iostream array
+iostream bitset
+iostream cctype
+iostream cerrno
+iostream climits
+iostream clocale
+iostream cmath
+iostream compare
+iostream cstddef
+iostream cstdint
+iostream cstdio
+iostream cstdlib
+iostream cstring
+iostream ctime
+iostream cwchar
+iostream cwctype
+iostream format
+iostream initializer_list
+iostream ios
+iostream iosfwd
+iostream istream
+iostream limits
+iostream locale
+iostream optional
+iostream ostream
+iostream print
+iostream ratio
+iostream stdexcept
+iostream streambuf
+iostream string
+iostream string_view
+iostream tuple
+iostream typeinfo
+iostream version
+istream bitset
+istream cctype
+istream cerrno
+istream climits
+istream clocale
+istream compare
+istream cstddef
+istream cstdint
+istream cstdio
+istream cstdlib
+istream cstring
+istream ctime
+istream cwchar
+istream cwctype
+istream initializer_list
+istream ios
+istream iosfwd
+istream limits
+istream locale
+istream ratio
+istream stdexcept
+istream streambuf
+istream string
+istream string_view
+istream tuple
+istream typeinfo
+istream version
+iterator cctype
+iterator compare
+iterator concepts
+iterator cstdint
+iterator cstdio
+iterator cstring
+iterator cwchar
+iterator cwctype
+iterator initializer_list
+iterator iosfwd
+iterator limits
+iterator variant
+iterator version
+latch climits
+latch cstdint
+latch cstring
+latch ctime
+latch limits
+latch ratio
+latch version
+limits version
+list cctype
+list compare
+list cstdint
+list cstring
+list cwchar
+list cwctype
+list initializer_list
+list limits
+list tuple
+list version
+locale cctype
+locale cerrno
+locale climits
+locale clocale
+locale compare
+locale cstddef
+locale cstdint
+locale cstdio
+locale cstdlib
+locale cstring
+locale ctime
+locale cwchar
+locale cwctype
+locale initializer_list
+locale ios
+locale iosfwd
+locale limits
+locale ratio
+locale stdexcept
+locale streambuf
+locale string
+locale string_view
+locale tuple
+locale typeinfo
+locale version
+map cctype
+map compare
+map cstdint
+map cstring
+map cwchar
+map cwctype
+map initializer_list
+map limits
+map optional
+map stdexcept
+map tuple
+map version
+mdspan array
+mdspan cctype
+mdspan compare
+mdspan concepts
+mdspan cstdint
+mdspan cwchar
+mdspan cwctype
+mdspan initializer_list
+mdspan limits
+mdspan span
+mdspan stdexcept
+mdspan version
+memory compare
+memory cstdint
+memory cstring
+memory initializer_list
+memory limits
+memory tuple
+memory typeinfo
+memory version
+memory_resource cerrno
+memory_resource climits
+memory_resource compare
+memory_resource cstdint
+memory_resource ctime
+memory_resource limits
+memory_resource ratio
+memory_resource tuple
+memory_resource version
+mutex cerrno
+mutex climits
+mutex compare
+mutex cstdint
+mutex ctime
+mutex limits
+mutex ratio
+mutex tuple
+mutex typeinfo
+mutex version
+new version
+numbers version
+numeric climits
+numeric compare
+numeric cstdint
+numeric cstring
+numeric ctime
+numeric initializer_list
+numeric limits
+numeric optional
+numeric ratio
+numeric tuple
+numeric version
+optional compare
+optional cstdint
+optional cstring
+optional initializer_list
+optional limits
+optional version
+ostream array
+ostream bitset
+ostream cctype
+ostream cerrno
+ostream climits
+ostream clocale
+ostream cmath
+ostream compare
+ostream cstddef
+ostream cstdint
+ostream cstdio
+ostream cstdlib
+ostream cstring
+ostream ctime
+ostream cwchar
+ostream cwctype
+ostream format
+ostream initializer_list
+ostream ios
+ostream iosfwd
+ostream limits
+ostream locale
+ostream optional
+ostream print
+ostream ratio
+ostream stdexcept
+ostream streambuf
+ostream string
+ostream string_view
+ostream tuple
+ostream typeinfo
+ostream version
+print array
+print cctype
+print cerrno
+print climits
+print clocale
+print cmath
+print compare
+print cstddef
+print cstdint
+print cstdio
+print cstdlib
+print cstring
+print cwchar
+print cwctype
+print format
+print initializer_list
+print iosfwd
+print limits
+print optional
+print stdexcept
+print string
+print string_view
+print tuple
+print typeinfo
+print version
+queue array
+queue cctype
+queue cerrno
+queue climits
+queue clocale
+queue compare
+queue cstddef
+queue cstdint
+queue cstdio
+queue cstdlib
+queue cstring
+queue cwchar
+queue cwctype
+queue deque
+queue initializer_list
+queue iosfwd
+queue limits
+queue stdexcept
+queue string
+queue string_view
+queue tuple
+queue typeinfo
+queue vector
+queue version
+random cctype
+random climits
+random cmath
+random compare
+random cstdint
+random cstdio
+random cstring
+random ctime
+random cwchar
+random cwctype
+random initializer_list
+random iosfwd
+random limits
+random numeric
+random optional
+random ratio
+random stdexcept
+random string
+random string_view
+random tuple
+random version
+ranges cctype
+ranges compare
+ranges concepts
+ranges cstdint
+ranges cstdio
+ranges cstring
+ranges cwchar
+ranges cwctype
+ranges initializer_list
+ranges iosfwd
+ranges iterator
+ranges limits
+ranges optional
+ranges span
+ranges stdexcept
+ranges tuple
+ranges variant
+ranges version
+ratio climits
+ratio cstdint
+ratio version
+regex array
+regex cctype
+regex cerrno
+regex climits
+regex clocale
+regex compare
+regex cstddef
+regex cstdint
+regex cstdio
+regex cstdlib
+regex cstring
+regex cwchar
+regex cwctype
+regex deque
+regex initializer_list
+regex iosfwd
+regex limits
+regex stdexcept
+regex string
+regex string_view
+regex tuple
+regex typeinfo
+regex vector
+regex version
+scoped_allocator compare
+scoped_allocator cstdint
+scoped_allocator limits
+scoped_allocator tuple
+scoped_allocator version
+semaphore climits
+semaphore cstdint
+semaphore cstring
+semaphore ctime
+semaphore limits
+semaphore ratio
+semaphore version
+set cctype
+set compare
+set cstdint
+set cstring
+set cwchar
+set cwctype
+set initializer_list
+set limits
+set optional
+set tuple
+set version
+shared_mutex cerrno
+shared_mutex climits
+shared_mutex cstdint
+shared_mutex ctime
+shared_mutex limits
+shared_mutex ratio
+shared_mutex version
+source_location cstdint
+source_location version
+span initializer_list
+span limits
+span stdexcept
+span version
+sstream bitset
+sstream cctype
+sstream cerrno
+sstream climits
+sstream clocale
+sstream compare
+sstream cstddef
+sstream cstdint
+sstream cstdio
+sstream cstdlib
+sstream cstring
+sstream ctime
+sstream cwchar
+sstream cwctype
+sstream initializer_list
+sstream ios
+sstream iosfwd
+sstream istream
+sstream limits
+sstream locale
+sstream ratio
+sstream stdexcept
+sstream streambuf
+sstream string
+sstream string_view
+sstream tuple
+sstream typeinfo
+sstream version
+stack cctype
+stack compare
+stack cstdint
+stack cstring
+stack cwchar
+stack cwctype
+stack deque
+stack initializer_list
+stack limits
+stack stdexcept
+stack tuple
+stack version
+stop_token atomic
+stop_token climits
+stop_token cstdint
+stop_token cstring
+stop_token ctime
+stop_token limits
+stop_token ratio
+stop_token version
+streambuf cctype
+streambuf cerrno
+streambuf climits
+streambuf clocale
+streambuf compare
+streambuf cstddef
+streambuf cstdint
+streambuf cstdio
+streambuf cstdlib
+streambuf cstring
+streambuf ctime
+streambuf cwchar
+streambuf cwctype
+streambuf initializer_list
+streambuf ios
+streambuf iosfwd
+streambuf limits
+streambuf ratio
+streambuf stdexcept
+streambuf string
+streambuf string_view
+streambuf tuple
+streambuf typeinfo
+streambuf version
+string cctype
+string climits
+string compare
+string cstdint
+string cstdio
+string cstring
+string cwchar
+string cwctype
+string initializer_list
+string iosfwd
+string limits
+string stdexcept
+string string_view
+string tuple
+string version
+string_view cctype
+string_view compare
+string_view cstdint
+string_view cstdio
+string_view cstring
+string_view cwchar
+string_view cwctype
+string_view initializer_list
+string_view iosfwd
+string_view limits
+string_view stdexcept
+string_view version
+strstream bitset
+strstream cctype
+strstream cerrno
+strstream climits
+strstream clocale
+strstream compare
+strstream cstddef
+strstream cstdint
+strstream cstdio
+strstream cstdlib
+strstream cstring
+strstream ctime
+strstream cwchar
+strstream cwctype
+strstream initializer_list
+strstream ios
+strstream iosfwd
+strstream istream
+strstream limits
+strstream locale
+strstream ratio
+strstream stdexcept
+strstream streambuf
+strstream string
+strstream string_view
+strstream tuple
+strstream typeinfo
+strstream version
+syncstream array
+syncstream bitset
+syncstream cctype
+syncstream cerrno
+syncstream climits
+syncstream clocale
+syncstream cmath
+syncstream compare
+syncstream cstddef
+syncstream cstdint
+syncstream cstdio
+syncstream cstdlib
+syncstream cstring
+syncstream ctime
+syncstream cwchar
+syncstream cwctype
+syncstream format
+syncstream initializer_list
+syncstream ios
+syncstream iosfwd
+syncstream limits
+syncstream locale
+syncstream map
+syncstream optional
+syncstream ostream
+syncstream print
+syncstream ratio
+syncstream shared_mutex
+syncstream stdexcept
+syncstream streambuf
+syncstream string
+syncstream string_view
+syncstream tuple
+syncstream typeinfo
+syncstream version
+system_error cctype
+system_error cerrno
+system_error climits
+system_error compare
+system_error cstdint
+system_error cstdio
+system_error cstring
+system_error cwchar
+system_error cwctype
+system_error initializer_list
+system_error iosfwd
+system_error limits
+system_error stdexcept
+system_error string
+system_error string_view
+system_error tuple
+system_error version
+thread array
+thread atomic
+thread bitset
+thread cctype
+thread cerrno
+thread climits
+thread clocale
+thread compare
+thread cstddef
+thread cstdint
+thread cstdio
+thread cstdlib
+thread cstring
+thread ctime
+thread cwchar
+thread cwctype
+thread initializer_list
+thread ios
+thread iosfwd
+thread istream
+thread limits
+thread locale
+thread ratio
+thread sstream
+thread stdexcept
+thread streambuf
+thread string
+thread string_view
+thread tuple
+thread typeinfo
+thread version
+tuple compare
+tuple cstdint
+tuple limits
+tuple version
+type_traits cstdint
+type_traits version
+typeindex compare
+typeindex cstdint
+typeindex limits
+typeindex typeinfo
+typeindex version
+typeinfo cstdint
+typeinfo version
+unordered_map compare
+unordered_map cstdint
+unordered_map cstring
+unordered_map initializer_list
+unordered_map limits
+unordered_map optional
+unordered_map stdexcept
+unordered_map tuple
+unordered_map version
+unordered_set compare
+unordered_set cstdint
+unordered_set cstring
+unordered_set initializer_list
+unordered_set limits
+unordered_set optional
+unordered_set tuple
+unordered_set version
+utility compare
+utility cstdint
+utility cstring
+utility initializer_list
+utility limits
+utility version
+valarray cmath
+valarray cstdint
+valarray initializer_list
+valarray limits
+valarray version
+variant compare
+variant cstdint
+variant cstring
+variant initializer_list
+variant limits
+variant version
+vector array
+vector cctype
+vector cerrno
+vector climits
+vector clocale
+vector compare
+vector cstddef
+vector cstdint
+vector cstdio
+vector cstdlib
+vector cstring
+vector cwchar
+vector cwctype
+vector initializer_list
+vector iosfwd
+vector limits
+vector stdexcept
+vector string
+vector string_view
+vector tuple
+vector typeinfo
+vector version
diff --git a/libcxx/test/libcxx-03/transitive_includes/to_csv.py b/libcxx/test/libcxx-03/transitive_includes/to_csv.py
new file mode 100755
index 0000000000000..69d94deedf6f5
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes/to_csv.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+from typing import List, Tuple, Optional
+import argparse
+import io
+import itertools
+import os
+import pathlib
+import re
+import sys
+
+libcxx_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
+sys.path.append(os.path.join(libcxx_root, "utils"))
+from libcxx.header_information import Header
+
+def parse_line(line: str) -> Tuple[int, str]:
+ """
+ Parse a single line of --trace-includes output.
+
+ Returns the inclusion level and the raw file name being included.
+ """
+ match = re.match(r"(\.+) (.+)", line)
+ if not match:
+ raise ArgumentError(f"Line {line} contains invalid data.")
+
+ # The number of periods in front of the header name is the nesting level of
+ # that header.
+ return (len(match.group(1)), match.group(2))
+
+def make_cxx_v1_relative(header: str) -> Optional[str]:
+ """
+ Returns the path of the header as relative to <whatever>/c++/v1, or None if the path
+ doesn't contain c++/v1.
+
+ We use that heuristic to figure out which headers are libc++ headers.
+ """
+ # On Windows, the path separators can either be forward slash or backslash.
+ # If it is a backslash, Clang prints it escaped as two consecutive
+ # backslashes, and they need to be escaped in the RE. (Use a raw string for
+ # the pattern to avoid needing another level of escaping on the Python string
+ # literal level.)
+ pathsep = r"(?:/|\\\\)"
+ CXX_V1_REGEX = r"^.*c\+\+" + pathsep + r"v[0-9]+" + pathsep + r"(.+)$"
+ match = re.match(CXX_V1_REGEX, header)
+ if not match:
+ return None
+ else:
+ return match.group(1)
+
+def parse_file(file: io.TextIOBase) -> List[Tuple[Header, Header]]:
+ """
+ Parse a file containing --trace-includes output to generate a list of the
+ transitive includes contained in it.
+ """
+ result = []
+ includer = None
+ for line in file.readlines():
+ (level, header) = parse_line(line)
+ relative = make_cxx_v1_relative(header)
+
+ # Not a libc++ header
+ if relative is None:
+ continue
+
+ # If we're at the first level, remember this header as being the one who includes other headers.
+ # There's usually exactly one, except if the compiler is passed a file with `-include`.
+ if level == 1:
+ includer = Header(relative)
+ continue
+
+ # Otherwise, take note that this header is being included by the top-level includer.
+ else:
+ assert includer is not None
+ result.append((includer, Header(relative)))
+ return result
+
+def print_csv(includes: List[Tuple[Header, Header]]) -> None:
+ """
+ Print the transitive includes as space-delimited CSV.
+
+ This function only prints public libc++ headers that are not C compatibility headers.
+ """
+ # Sort and group by includer
+ by_includer = lambda t: t[0]
+ includes = itertools.groupby(sorted(includes, key=by_includer), key=by_includer)
+
+ for (includer, includees) in includes:
+ includees = map(lambda t: t[1], includees)
+ for h in sorted(set(includees)):
+ if h.is_public() and not h.is_C_compatibility():
+ print(f"{includer} {h}")
+
+def main(argv):
+ parser = argparse.ArgumentParser(
+ description="""
+ Given a list of headers produced by --trace-includes, produce a list of libc++ headers in that output.
+
+ Note that -fshow-skipped-includes must also be passed to the compiler in order to get sufficient
+ information for this script to run.
+
+ The output of this script is provided in space-delimited CSV format where each line contains:
+
+ <header performing inclusion> <header being included>
+ """)
+ parser.add_argument("inputs", type=argparse.FileType("r"), nargs='+', default=None,
+ help="One or more files containing the result of --trace-includes")
+ args = parser.parse_args(argv)
+
+ includes = [line for file in args.inputs for line in parse_file(file)]
+ print_csv(includes)
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/libcxx/test/libcxx-03/type_traits/convert_to_integral.pass.cpp b/libcxx/test/libcxx-03/type_traits/convert_to_integral.pass.cpp
new file mode 100644
index 0000000000000..f1036b3929f06
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/convert_to_integral.pass.cpp
@@ -0,0 +1,123 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// TODO: Make this test pass for all standards.
+// XFAIL: c++03
+
+// <type_traits>
+
+// __convert_to_integral(Tp)
+
+// Test that the __convert_to_integral functions properly converts Tp to the
+// correct type and value for integral, enum and user defined types.
+
+#include "test_macros.h"
+
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__utility/convert_to_integral.h>
+#include <limits>
+#include <type_traits>
+#include <cstdint>
+#include <cassert>
+
+#include "user_defined_integral.h"
+
+template <class T>
+struct EnumType
+{
+ enum type : T {E_zero, E_one};
+};
+
+
+template <class From, class To>
+void check_integral_types()
+{
+ typedef std::numeric_limits<From> Limits;
+ const From max = Limits::max();
+ const From min = Limits::min();
+ {
+ auto ret = std::__convert_to_integral((From)max);
+ assert(ret == max);
+ ret = std::__convert_to_integral((From)min);
+ assert(ret == min);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+ }
+ {
+ UserDefinedIntegral<From> f(max);
+ auto ret = std::__convert_to_integral(f);
+ assert(ret == max);
+ f.value = min;
+ ret = std::__convert_to_integral(f);
+ assert(ret == min);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+ }
+ {
+ typedef typename EnumType<From>::type Enum;
+ Enum e(static_cast<Enum>(max));
+ auto ret = std::__convert_to_integral(e);
+ assert(ret == max);
+ e = static_cast<Enum>(min);
+ ret = std::__convert_to_integral(min);
+ assert(ret == min);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+ }
+}
+
+
+template <class From, class To>
+void check_enum_types()
+{
+ auto ret = std::__convert_to_integral((From)1);
+ assert(ret == 1);
+ static_assert(std::is_same<decltype(ret), To>::value, "");
+}
+
+
+enum enum1 { zero = 0, one = 1 };
+enum enum2 : unsigned long {
+ value = std::numeric_limits<unsigned long>::max()
+};
+
+int main(int, char**)
+{
+ check_integral_types<bool, int>();
+ check_integral_types<char, int>();
+ check_integral_types<signed char, int>();
+ check_integral_types<unsigned char, int>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ check_integral_types<wchar_t, decltype(((wchar_t)1) + 1)>();
+#endif
+ check_integral_types<char16_t, int>();
+ // On some platforms, unsigned int and long are the same size. These
+ // platforms have a choice of making std::uint32_t an int or a long. However
+ // char32_t must promote to an unsigned int on these platforms [conv.prom].
+ // Use the following logic to make the test work on such platforms.
+ // (sizeof(std::uint32_t) == sizeof(unsigned int)) ? unsigned int : std::uint32_t;
+ typedef std::conditional<sizeof(std::uint32_t) == sizeof(unsigned int),
+ unsigned int, std::uint32_t>::type char_integral;
+ check_integral_types<char32_t, char_integral>();
+ check_integral_types<short, int>();
+ check_integral_types<unsigned short, int>();
+ check_integral_types<int, int>();
+ check_integral_types<unsigned, unsigned>();
+ check_integral_types<long, long>();
+ check_integral_types<unsigned long, unsigned long>();
+ check_integral_types<long long, long long>();
+ check_integral_types<unsigned long long, unsigned long long>();
+#ifndef TEST_HAS_NO_INT128
+ check_integral_types<__int128_t, __int128_t>();
+ check_integral_types<__uint128_t, __uint128_t>();
+#endif
+ // TODO(ericwf): Not standard
+ typedef std::underlying_type<enum1>::type Enum1UT;
+ check_enum_types<enum1, decltype(((Enum1UT)1) + 1)>();
+ typedef std::underlying_type<enum2>::type Enum2UT;
+ check_enum_types<enum2, decltype(((Enum2UT)1) + 1)>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/type_traits/datasizeof.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/datasizeof.compile.pass.cpp
new file mode 100644
index 0000000000000..67a4dccb0f5fe
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/datasizeof.compile.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__type_traits/datasizeof.h>
+#include <cstdint>
+#include <type_traits>
+
+static_assert(std::__datasizeof_v<std::int8_t> == 1, "");
+static_assert(std::__datasizeof_v<std::int16_t> == 2, "");
+static_assert(std::__datasizeof_v<std::int32_t> == 4, "");
+static_assert(std::__datasizeof_v<std::int64_t> == 8, "");
+
+struct NonStandardLayout {
+ virtual ~NonStandardLayout();
+};
+
+static_assert(!std::is_standard_layout<NonStandardLayout>::value, "");
+static_assert(std::__datasizeof_v<NonStandardLayout> == sizeof(void*), "");
+
+struct Empty {};
+
+static_assert(std::__datasizeof_v<Empty> == 0, "");
+
+struct FinalEmpty final {};
+
+static_assert(std::__datasizeof_v<FinalEmpty> == 0, "");
+
+struct OneBytePadding final {
+ OneBytePadding() {}
+
+ std::int16_t a;
+ std::int8_t b;
+};
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+static_assert(std::__datasizeof_v<OneBytePadding> == 4, "");
+#else
+static_assert(std::__datasizeof_v<OneBytePadding> == 3, "");
+#endif
+
+struct InBetweenPadding {
+ InBetweenPadding() {}
+
+ std::int32_t a;
+ std::int8_t b;
+ std::int16_t c;
+};
+
+static_assert(std::__datasizeof_v<InBetweenPadding> == 8, "");
+
+struct NoDataButNoPadding {
+ OneBytePadding v;
+};
+
+static_assert(std::__datasizeof_v<NoDataButNoPadding> == 4, "");
diff --git a/libcxx/test/libcxx-03/type_traits/desugars_to.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/desugars_to.compile.pass.cpp
new file mode 100644
index 0000000000000..4ed6d15ee9e95
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/desugars_to.compile.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: FROZEN-CXX03-HEADERS-FIXME
+
+// This test requires variable templates
+// UNSUPPORTED: gcc && c++11
+
+#include <__type_traits/desugars_to.h>
+
+struct Tag {};
+struct Operation {};
+
+namespace std {
+template <>
+bool const __desugars_to_v<Tag, Operation> = true;
+}
+
+void tests() {
+ // Make sure that __desugars_to is false by default
+ {
+ struct Foo {};
+ static_assert(!std::__desugars_to_v<Tag, Foo>, "");
+ }
+
+ // Make sure that __desugars_to bypasses const and ref qualifiers on the operation
+ {
+ static_assert(std::__desugars_to_v<Tag, Operation>, ""); // no quals
+ static_assert(std::__desugars_to_v<Tag, Operation const>, "");
+
+ static_assert(std::__desugars_to_v<Tag, Operation&>, "");
+ static_assert(std::__desugars_to_v<Tag, Operation const&>, "");
+
+ static_assert(std::__desugars_to_v<Tag, Operation&&>, "");
+ static_assert(std::__desugars_to_v<Tag, Operation const&&>, "");
+ }
+}
diff --git a/libcxx/test/libcxx-03/type_traits/is_always_bitcastable.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_always_bitcastable.compile.pass.cpp
new file mode 100644
index 0000000000000..9bbb85f2fe30c
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_always_bitcastable.compile.pass.cpp
@@ -0,0 +1,219 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// <type_traits>
+//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+//
+// __is_always_bitcastable<_From, _To>
+
+#include "test_macros.h"
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__type_traits/is_always_bitcastable.h>
+
+#include <climits>
+#include <cstdint>
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+#include <cwchar>
+#endif
+#include "type_algorithms.h"
+
+// To test pointers to functions.
+void Func1() {}
+using FuncPtr1 = decltype(&Func1);
+int Func2() { return 0; }
+using FuncPtr2 = decltype(&Func2);
+
+template <bool Expected, class T, class U>
+constexpr void check_one() {
+ static_assert(std::__is_always_bitcastable<T, U>::value == Expected);
+}
+
+template <bool Expected, class T, class U>
+constexpr void check_with_volatile() {
+ check_one<Expected, T, U>();
+ check_one<Expected, volatile T, U>();
+ check_one<Expected, T, volatile U>();
+ check_one<Expected, volatile T, volatile U>();
+}
+
+template <bool Expected, class T, class U>
+constexpr void check_with_cv() {
+ check_with_volatile<Expected, T, U>();
+ check_with_volatile<Expected, const T, U>();
+ check_with_volatile<Expected, T, const U>();
+ check_with_volatile<Expected, const T, const U>();
+}
+
+template <bool Expected, class Types1, class Types2 = Types1>
+constexpr void check() {
+ types::for_each(Types1{}, []<class T>() {
+ types::for_each(Types2{}, []<class U>() {
+ check_with_cv<Expected, T, U>();
+ });
+ });
+}
+
+template <bool Expected, class Types1, class Types2>
+constexpr void check_both_ways() {
+ check<Expected, Types1, Types2>();
+ check<Expected, Types2, Types1>();
+}
+
+constexpr void test() {
+ // Arithmetic types.
+ {
+ // Bit-castable arithmetic types.
+
+ // 8-bit types.
+ using integral_8 = types::type_list<char8_t, std::int8_t, std::uint8_t>;
+ using chars = types::type_list<char, unsigned char, signed char>;
+#if CHAR_BIT == 8
+ check<true, types::concatenate_t<integral_8, chars>>();
+#else
+ check<true, integral_8>();
+ check<true, chars>();
+#endif
+
+ // 16-bit types.
+ using integral_16 = types::type_list<char16_t, std::int16_t, std::uint16_t>;
+#if !defined(TEST_HAS_NO_WIDE_CHARACTERS) && __WCHAR_WIDTH__ == 16
+ check<true, types::concatenate_t<integral_16, types::type_list<wchar_t>>>();
+#else
+ check<true, integral_16>();
+#endif
+
+ // 32-bit types.
+ using integral_32 = types::type_list<char32_t, std::int32_t, std::uint32_t>;
+#if !defined(TEST_HAS_NO_WIDE_CHARACTERS) && __WCHAR_WIDTH__ == 32
+ check<true, types::concatenate_t<integral_32, types::type_list<wchar_t>>>();
+#else
+ check<true, integral_32>();
+#endif
+
+ // 64-bit types.
+ using integral_64 = types::type_list<std::int64_t, std::uint64_t>;
+ check<true, integral_64>();
+
+ // 128-bit types.
+#ifndef TEST_HAS_NO_INT128
+ check<true, types::type_list<__int128_t, __uint128_t>>();
+#endif
+
+ // Bool.
+ check<true, types::type_list<bool>, types::concatenate_t<types::type_list<bool>, integral_8>>();
+
+ // Non-bit-castable arithmetic types.
+
+ // Floating-point.
+ check_both_ways<false, types::floating_point_types, types::integral_types>();
+ check_both_ways<false, types::type_list<float>, types::type_list<double, long double>>();
+ check_both_ways<false, types::type_list<double>, types::type_list<float, long double>>();
+ check_both_ways<false, types::type_list<long double>, types::type_list<float, double>>();
+
+ // Different sizes.
+ check_both_ways<false, integral_8, types::concatenate_t<integral_16, integral_32, integral_64>>();
+ check_both_ways<false, integral_16, types::concatenate_t<integral_8, integral_32, integral_64>>();
+ check_both_ways<false, integral_32, types::concatenate_t<integral_8, integral_16, integral_64>>();
+ check_both_ways<false, integral_64, types::concatenate_t<integral_8, integral_16, integral_32>>();
+
+ // Different representations -- can convert from bool to other integral types, but not vice versa.
+ check<true, types::type_list<bool>, integral_8>();
+ using larger_than_bool = types::concatenate_t<
+ integral_16,
+ integral_32,
+ integral_64,
+ types::floating_point_types>;
+ check<false, types::type_list<bool>, larger_than_bool>();
+ check<false, types::concatenate_t<integral_8, larger_than_bool>, types::type_list<bool>>();
+
+ // Different representations -- floating point vs. integral.
+ check_both_ways<false, types::floating_point_types, types::integral_types>();
+ }
+
+ // Enumerations.
+ {
+ enum E1 { Value1 };
+ enum E2 { Value2 };
+ check<true, types::type_list<E1>>();
+ check_both_ways<false, types::type_list<E1>, types::type_list<E2>>();
+
+ enum class ScopedE1 { Value1 };
+ enum class ScopedE2 { Value1 };
+ check<true, types::type_list<ScopedE1>>();
+ check_both_ways<false, types::type_list<ScopedE1>, types::type_list<ScopedE2>>();
+ }
+
+ // Pointers.
+ {
+ check<true, types::type_list<int*>>();
+ check_both_ways<false, types::type_list<int*>, types::type_list<const int*, long*, void*>>();
+
+ check<true, types::type_list<FuncPtr1>>();
+ check_both_ways<false, types::type_list<FuncPtr1>, types::type_list<FuncPtr2>>();
+ }
+
+ // Pointers to members.
+ {
+ struct S {
+ int mem_obj1 = 0;
+ long mem_obj2 = 0;
+ void MemFunc1() {}
+ int MemFunc2() { return 0; }
+ };
+ using MemObjPtr1 = decltype(&S::mem_obj1);
+ using MemObjPtr2 = decltype(&S::mem_obj2);
+ using MemFuncPtr1 = decltype(&S::MemFunc1);
+ using MemFuncPtr2 = decltype(&S::MemFunc2);
+
+ check<true, types::type_list<MemObjPtr1>>();
+ check<true, types::type_list<MemFuncPtr1>>();
+ check_both_ways<false, types::type_list<MemObjPtr1>, types::type_list<MemObjPtr2>>();
+ check_both_ways<false, types::type_list<MemFuncPtr1>, types::type_list<MemFuncPtr2>>();
+ }
+
+ // Trivial classes.
+ {
+ struct S1 {};
+ check<true, types::type_list<S1>>();
+
+ struct S2 {};
+ check_both_ways<false, types::type_list<S1>, types::type_list<S2>>();
+
+ // Having a `volatile` member doesn't prevent a class type from being considered trivially copyable. This is
+ // unfortunate behavior but it is consistent with the Standard.
+ struct VolatileMembersS {
+ volatile int x;
+ };
+ check<true, types::type_list<VolatileMembersS>>();
+ }
+
+ // Trivial unions.
+ {
+ union U1 {};
+ check<true, types::type_list<U1>>();
+
+ union U2 {};
+ check_both_ways<false, types::type_list<U1>, types::type_list<U2>>();
+
+ union VolatileMembersU {
+ volatile int x;
+ };
+ check<true, types::type_list<VolatileMembersU>>();
+ }
+
+ // References are not objects, and thus are not bit-castable.
+ {
+ check_both_ways<false, types::type_list<int&>, types::type_list<int&>>();
+ }
+
+ // Arrays.
+ {
+ check<true, types::type_list<int[8]>>();
+ }
+}
diff --git a/libcxx/test/libcxx-03/type_traits/is_callable.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_callable.compile.pass.cpp
new file mode 100644
index 0000000000000..d7bd701aa706a
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_callable.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <__type_traits/is_callable.h>
+
+struct Functor {
+ void operator()();
+};
+
+int func();
+
+struct NotFunctor {
+ bool compare();
+};
+
+struct ArgumentFunctor {
+ bool operator()(int, int);
+};
+
+static_assert(std::__is_callable<Functor>::value, "");
+static_assert(std::__is_callable<decltype(func)>::value, "");
+static_assert(!std::__is_callable<NotFunctor>::value, "");
+static_assert(!std::__is_callable<NotFunctor,
+ decltype(&NotFunctor::compare)>::value, "");
+static_assert(std::__is_callable<ArgumentFunctor, int, int>::value, "");
+static_assert(!std::__is_callable<ArgumentFunctor, int>::value, "");
diff --git a/libcxx/test/libcxx-03/type_traits/is_constant_evaluated.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_constant_evaluated.pass.cpp
new file mode 100644
index 0000000000000..a538c52a534e7
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_constant_evaluated.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+
+// <type_traits>
+
+// __libcpp_is_constant_evaluated()
+
+// returns false when there's no constant evaluation support from the compiler.
+// as well as when called not in a constexpr context
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__type_traits/is_constant_evaluated.h>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main (int, char**) {
+ ASSERT_SAME_TYPE(decltype(std::__libcpp_is_constant_evaluated()), bool);
+ ASSERT_NOEXCEPT(std::__libcpp_is_constant_evaluated());
+
+#if !defined(_LIBCPP_CXX03_LANG)
+ static_assert(std::__libcpp_is_constant_evaluated(), "");
+#endif
+
+ bool p = std::__libcpp_is_constant_evaluated();
+ assert(!p);
+
+ return 0;
+ }
diff --git a/libcxx/test/libcxx-03/type_traits/is_implicitly_default_constructible.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_implicitly_default_constructible.pass.cpp
new file mode 100644
index 0000000000000..ff0ab6f68df67
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_implicitly_default_constructible.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
+
+// <type_traits>
+
+// __is_implicitly_default_constructible<Tp>
+
+#include <__type_traits/is_implicitly_default_constructible.h>
+
+struct ExplicitlyDefaultConstructible1 {
+ explicit ExplicitlyDefaultConstructible1() = default;
+};
+
+struct ExplicitlyDefaultConstructible2 {
+ explicit ExplicitlyDefaultConstructible2() { }
+};
+
+struct ImplicitlyDefaultConstructible1 {
+ ImplicitlyDefaultConstructible1() { }
+};
+
+struct ImplicitlyDefaultConstructible2 {
+ ImplicitlyDefaultConstructible2() = default;
+};
+
+struct NonDefaultConstructible1 {
+ NonDefaultConstructible1() = delete;
+};
+
+struct NonDefaultConstructible2 {
+ explicit NonDefaultConstructible2() = delete;
+};
+
+struct NonDefaultConstructible3 {
+ NonDefaultConstructible3(NonDefaultConstructible3&&) { }
+};
+
+struct ProtectedDefaultConstructible {
+protected:
+ ProtectedDefaultConstructible() = default;
+};
+
+struct PrivateDefaultConstructible {
+private:
+ PrivateDefaultConstructible() = default;
+};
+
+struct Base { };
+
+struct ProtectedDefaultConstructibleWithBase : Base {
+protected:
+ ProtectedDefaultConstructibleWithBase() = default;
+};
+
+struct PrivateDefaultConstructibleWithBase : Base {
+private:
+ PrivateDefaultConstructibleWithBase() = default;
+};
+
+static_assert(!std::__is_implicitly_default_constructible<ExplicitlyDefaultConstructible1>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<ExplicitlyDefaultConstructible2>::value, "");
+static_assert(std::__is_implicitly_default_constructible<ImplicitlyDefaultConstructible1>::value, "");
+static_assert(std::__is_implicitly_default_constructible<ImplicitlyDefaultConstructible2>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<NonDefaultConstructible1>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<NonDefaultConstructible2>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<NonDefaultConstructible3>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<ProtectedDefaultConstructible>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<PrivateDefaultConstructible>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<ProtectedDefaultConstructibleWithBase>::value, "");
+static_assert(!std::__is_implicitly_default_constructible<PrivateDefaultConstructibleWithBase>::value, "");
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/type_traits/is_pointer.arc.pass.mm b/libcxx/test/libcxx-03/type_traits/is_pointer.arc.pass.mm
new file mode 100644
index 0000000000000..865141186aa80
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_pointer.arc.pass.mm
@@ -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
+// REQUIRES: has-fobjc-arc
+// ADDITIONAL_COMPILE_FLAGS: -fobjc-arc
+
+// <type_traits>
+
+// std::is_pointer
+
+// Test that we correctly handle Objective-C++ ARC qualifiers on pointers.
+
+#include <type_traits>
+#include "test_macros.h"
+
+
+template <typename T>
+void assert_is_pointer() {
+ static_assert(std::is_pointer<T>::value, "");
+#if TEST_STD_VER > 14
+ static_assert(std::is_pointer_v<T>, "");
+#endif
+}
+
+template <typename T>
+void test_is_pointer() {
+ assert_is_pointer<T>();
+
+ assert_is_pointer<T __weak>();
+ assert_is_pointer<T __strong>();
+ assert_is_pointer<T __autoreleasing>();
+ assert_is_pointer<T __unsafe_unretained>();
+
+ assert_is_pointer<T __weak const>();
+ assert_is_pointer<T __strong const>();
+ assert_is_pointer<T __autoreleasing const>();
+ assert_is_pointer<T __unsafe_unretained const>();
+
+ assert_is_pointer<T __weak volatile>();
+ assert_is_pointer<T __strong volatile>();
+ assert_is_pointer<T __autoreleasing volatile>();
+ assert_is_pointer<T __unsafe_unretained volatile>();
+
+ assert_is_pointer<T __weak const volatile>();
+ assert_is_pointer<T __strong const volatile>();
+ assert_is_pointer<T __autoreleasing const volatile>();
+ assert_is_pointer<T __unsafe_unretained const volatile>();
+}
+
+ at class Foo;
+
+int main(int, char**) {
+ test_is_pointer<id>();
+ test_is_pointer<id const>();
+ test_is_pointer<id volatile>();
+ test_is_pointer<id const volatile>();
+
+ test_is_pointer<Foo*>();
+ test_is_pointer<Foo const*>();
+ test_is_pointer<Foo volatile*>();
+ test_is_pointer<Foo const volatile*>();
+
+ test_is_pointer<void*>();
+ test_is_pointer<void const*>();
+ test_is_pointer<void volatile*>();
+ test_is_pointer<void const volatile*>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/type_traits/is_replaceable.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_replaceable.compile.pass.cpp
new file mode 100644
index 0000000000000..7735538cccae4
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_replaceable.compile.pass.cpp
@@ -0,0 +1,313 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__type_traits/is_replaceable.h>
+#include <array>
+#include <deque>
+#include <exception>
+#include <expected>
+#include <memory>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <variant>
+#include <vector>
+
+#include "constexpr_char_traits.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+# include <locale>
+#endif
+
+template <class T>
+struct NonPropagatingStatefulMoveAssignAlloc : std::allocator<T> {
+ using propagate_on_container_move_assignment = std::false_type;
+ using is_always_equal = std::false_type;
+ template <class U>
+ struct rebind {
+ using other = NonPropagatingStatefulMoveAssignAlloc<U>;
+ };
+};
+
+template <class T>
+struct NonPropagatingStatefulCopyAssignAlloc : std::allocator<T> {
+ using propagate_on_container_copy_assignment = std::false_type;
+ using is_always_equal = std::false_type;
+ template <class U>
+ struct rebind {
+ using other = NonPropagatingStatefulCopyAssignAlloc<U>;
+ };
+};
+
+template <class T>
+struct NonPropagatingStatelessMoveAssignAlloc : std::allocator<T> {
+ using propagate_on_container_move_assignment = std::false_type;
+ using is_always_equal = std::true_type;
+ template <class U>
+ struct rebind {
+ using other = NonPropagatingStatelessMoveAssignAlloc<U>;
+ };
+};
+
+template <class T>
+struct NonPropagatingStatelessCopyAssignAlloc : std::allocator<T> {
+ using propagate_on_container_copy_assignment = std::false_type;
+ using is_always_equal = std::true_type;
+ template <class U>
+ struct rebind {
+ using other = NonPropagatingStatelessCopyAssignAlloc<U>;
+ };
+};
+
+template <class T>
+struct NonReplaceableStatelessAlloc : std::allocator<T> {
+ // Ensure that we don't consider an allocator that is a member of a container to be
+ // replaceable if it's not replaceable, even if it always compares equal and always propagates.
+ using propagate_on_container_move_assignment = std::true_type;
+ using propagate_on_container_copy_assignment = std::true_type;
+ using is_always_equal = std::true_type;
+ NonReplaceableStatelessAlloc() = default;
+ NonReplaceableStatelessAlloc(NonReplaceableStatelessAlloc const&) {}
+ NonReplaceableStatelessAlloc(NonReplaceableStatelessAlloc&&) = default;
+ template <class U>
+ struct rebind {
+ using other = NonReplaceableStatelessAlloc<U>;
+ };
+};
+static_assert(!std::__is_replaceable<NonReplaceableStatelessAlloc<int> >::value, "");
+
+static_assert(!std::__is_replaceable<test_allocator<char> >::value, ""); // we use that property below
+
+struct Empty {};
+static_assert(std::__is_replaceable<char>::value, "");
+static_assert(std::__is_replaceable<int>::value, "");
+static_assert(std::__is_replaceable<double>::value, "");
+static_assert(std::__is_replaceable<Empty>::value, "");
+
+struct TriviallyCopyable {
+ char c;
+ int i;
+ Empty s;
+};
+static_assert(std::__is_replaceable<TriviallyCopyable>::value, "");
+
+struct NotTriviallyCopyable {
+ NotTriviallyCopyable(const NotTriviallyCopyable&);
+ ~NotTriviallyCopyable();
+};
+static_assert(!std::__is_replaceable<NotTriviallyCopyable>::value, "");
+
+struct MoveOnlyTriviallyCopyable {
+ MoveOnlyTriviallyCopyable(const MoveOnlyTriviallyCopyable&) = delete;
+ MoveOnlyTriviallyCopyable& operator=(const MoveOnlyTriviallyCopyable&) = delete;
+ MoveOnlyTriviallyCopyable(MoveOnlyTriviallyCopyable&&) = default;
+ MoveOnlyTriviallyCopyable& operator=(MoveOnlyTriviallyCopyable&&) = default;
+};
+static_assert(std::__is_replaceable<MoveOnlyTriviallyCopyable>::value, "");
+
+struct CustomCopyAssignment {
+ CustomCopyAssignment(const CustomCopyAssignment&) = default;
+ CustomCopyAssignment(CustomCopyAssignment&&) = default;
+ CustomCopyAssignment& operator=(const CustomCopyAssignment&);
+ CustomCopyAssignment& operator=(CustomCopyAssignment&&) = default;
+};
+static_assert(!std::__is_replaceable<CustomCopyAssignment>::value, "");
+
+struct CustomMoveAssignment {
+ CustomMoveAssignment(const CustomMoveAssignment&) = default;
+ CustomMoveAssignment(CustomMoveAssignment&&) = default;
+ CustomMoveAssignment& operator=(const CustomMoveAssignment&) = default;
+ CustomMoveAssignment& operator=(CustomMoveAssignment&&);
+};
+static_assert(!std::__is_replaceable<CustomMoveAssignment>::value, "");
+
+// library-internal types
+// ----------------------
+
+// __split_buffer
+static_assert(std::__is_replaceable<std::__split_buffer<int> >::value, "");
+static_assert(std::__is_replaceable<std::__split_buffer<NotTriviallyCopyable> >::value, "");
+static_assert(!std::__is_replaceable<std::__split_buffer<int, NonPropagatingStatefulCopyAssignAlloc<int> > >::value,
+ "");
+static_assert(!std::__is_replaceable<std::__split_buffer<int, NonPropagatingStatefulMoveAssignAlloc<int> > >::value,
+ "");
+static_assert(std::__is_replaceable<std::__split_buffer<int, NonPropagatingStatelessCopyAssignAlloc<int> > >::value,
+ "");
+static_assert(std::__is_replaceable<std::__split_buffer<int, NonPropagatingStatelessMoveAssignAlloc<int> > >::value,
+ "");
+
+// standard library types
+// ----------------------
+
+// array
+static_assert(std::__is_replaceable<std::array<int, 0> >::value, "");
+static_assert(std::__is_replaceable<std::array<NotTriviallyCopyable, 0> >::value, "");
+static_assert(std::__is_replaceable<std::array<std::unique_ptr<int>, 0> >::value, "");
+
+static_assert(std::__is_replaceable<std::array<int, 1> >::value, "");
+static_assert(!std::__is_replaceable<std::array<NotTriviallyCopyable, 1> >::value, "");
+static_assert(std::__is_replaceable<std::array<std::unique_ptr<int>, 1> >::value, "");
+
+// basic_string
+struct MyChar {
+ char c;
+};
+template <class T>
+struct NotReplaceableCharTraits : constexpr_char_traits<T> {
+ NotReplaceableCharTraits(const NotReplaceableCharTraits&);
+ NotReplaceableCharTraits& operator=(const NotReplaceableCharTraits&);
+ ~NotReplaceableCharTraits();
+};
+
+static_assert(std::__is_replaceable<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::value,
+ "");
+static_assert(
+ std::__is_replaceable<std::basic_string<char, NotReplaceableCharTraits<char>, std::allocator<char> > >::value, "");
+static_assert(
+ std::__is_replaceable<std::basic_string<MyChar, constexpr_char_traits<MyChar>, std::allocator<MyChar> > >::value,
+ "");
+static_assert(!std::__is_replaceable<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >::value,
+ "");
+static_assert(!std::__is_replaceable<
+ std::basic_string<char, std::char_traits<char>, NonReplaceableStatelessAlloc<char> > >::value,
+ "");
+static_assert(std::__is_replaceable<
+ std::basic_string<MyChar, NotReplaceableCharTraits<MyChar>, std::allocator<MyChar> > >::value,
+ "");
+static_assert(
+ !std::__is_replaceable<
+ std::basic_string<char, std::char_traits<char>, NonPropagatingStatefulCopyAssignAlloc<char> > >::value,
+ "");
+static_assert(
+ !std::__is_replaceable<
+ std::basic_string<char, std::char_traits<char>, NonPropagatingStatefulMoveAssignAlloc<char> > >::value,
+ "");
+static_assert(
+ std::__is_replaceable<
+ std::basic_string<char, std::char_traits<char>, NonPropagatingStatelessCopyAssignAlloc<char> > >::value,
+ "");
+static_assert(
+ std::__is_replaceable<
+ std::basic_string<char, std::char_traits<char>, NonPropagatingStatelessMoveAssignAlloc<char> > >::value,
+ "");
+
+// deque
+static_assert(std::__is_replaceable<std::deque<int> >::value, "");
+static_assert(std::__is_replaceable<std::deque<NotTriviallyCopyable> >::value, "");
+static_assert(!std::__is_replaceable<std::deque<int, test_allocator<int> > >::value, "");
+static_assert(!std::__is_replaceable<std::deque<int, NonReplaceableStatelessAlloc<int> > >::value, "");
+static_assert(!std::__is_replaceable<std::deque<int, NonPropagatingStatefulCopyAssignAlloc<int> > >::value, "");
+static_assert(!std::__is_replaceable<std::deque<int, NonPropagatingStatefulMoveAssignAlloc<int> > >::value, "");
+static_assert(std::__is_replaceable<std::deque<int, NonPropagatingStatelessCopyAssignAlloc<int> > >::value, "");
+static_assert(std::__is_replaceable<std::deque<int, NonPropagatingStatelessMoveAssignAlloc<int> > >::value, "");
+
+// exception_ptr
+#ifndef _LIBCPP_ABI_MICROSOFT
+static_assert(std::__is_replaceable<std::exception_ptr>::value, "");
+#endif
+
+// expected
+#if TEST_STD_VER >= 23
+static_assert(std::__is_replaceable<std::expected<int, int> >::value);
+static_assert(!std::__is_replaceable<std::expected<CustomCopyAssignment, int>>::value);
+static_assert(!std::__is_replaceable<std::expected<int, CustomCopyAssignment>>::value);
+static_assert(!std::__is_replaceable<std::expected<CustomCopyAssignment, CustomCopyAssignment>>::value);
+#endif
+
+// locale
+#ifndef TEST_HAS_NO_LOCALIZATION
+static_assert(std::__is_replaceable<std::locale>::value, "");
+#endif
+
+// optional
+#if TEST_STD_VER >= 17
+static_assert(std::__is_replaceable<std::optional<int>>::value, "");
+static_assert(!std::__is_replaceable<std::optional<CustomCopyAssignment>>::value, "");
+#endif
+
+// pair
+static_assert(std::__is_replaceable<std::pair<int, int> >::value, "");
+static_assert(!std::__is_replaceable<std::pair<CustomCopyAssignment, int> >::value, "");
+static_assert(!std::__is_replaceable<std::pair<int, CustomCopyAssignment> >::value, "");
+static_assert(!std::__is_replaceable<std::pair<CustomCopyAssignment, CustomCopyAssignment> >::value, "");
+
+// shared_ptr
+static_assert(std::__is_replaceable<std::shared_ptr<int> >::value, "");
+
+// tuple
+#if TEST_STD_VER >= 11
+static_assert(std::__is_replaceable<std::tuple<> >::value, "");
+
+static_assert(std::__is_replaceable<std::tuple<int> >::value, "");
+static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment> >::value, "");
+
+static_assert(std::__is_replaceable<std::tuple<int, int> >::value, "");
+static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment, int> >::value, "");
+static_assert(!std::__is_replaceable<std::tuple<int, CustomCopyAssignment> >::value, "");
+static_assert(!std::__is_replaceable<std::tuple<CustomCopyAssignment, CustomCopyAssignment> >::value, "");
+#endif // TEST_STD_VER >= 11
+
+// unique_ptr
+struct NonReplaceableDeleter {
+ NonReplaceableDeleter(const NonReplaceableDeleter&);
+ NonReplaceableDeleter& operator=(const NonReplaceableDeleter&);
+ ~NonReplaceableDeleter();
+
+ template <class T>
+ void operator()(T*);
+};
+
+struct NonReplaceablePointer {
+ struct pointer {
+ pointer(const pointer&);
+ pointer& operator=(const pointer&);
+ ~pointer();
+ };
+
+ template <class T>
+ void operator()(T*);
+};
+
+static_assert(std::__is_replaceable<std::unique_ptr<int> >::value, "");
+static_assert(std::__is_replaceable<std::unique_ptr<CustomCopyAssignment> >::value, "");
+static_assert(std::__is_replaceable<std::unique_ptr<int[]> >::value, "");
+static_assert(!std::__is_replaceable<std::unique_ptr<int, NonReplaceableDeleter> >::value, "");
+static_assert(!std::__is_replaceable<std::unique_ptr<int[], NonReplaceableDeleter> >::value, "");
+static_assert(!std::__is_replaceable<std::unique_ptr<int, NonReplaceablePointer> >::value, "");
+static_assert(!std::__is_replaceable<std::unique_ptr<int[], NonReplaceablePointer> >::value, "");
+
+// variant
+#if TEST_STD_VER >= 17
+static_assert(std::__is_replaceable<std::variant<int> >::value, "");
+static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment> >::value, "");
+
+static_assert(std::__is_replaceable<std::variant<int, int> >::value, "");
+static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment, int> >::value, "");
+static_assert(!std::__is_replaceable<std::variant<int, CustomCopyAssignment> >::value, "");
+static_assert(!std::__is_replaceable<std::variant<CustomCopyAssignment, CustomCopyAssignment> >::value, "");
+#endif // TEST_STD_VER >= 17
+
+// vector
+static_assert(std::__is_replaceable<std::vector<int> >::value, "");
+static_assert(std::__is_replaceable<std::vector<CustomCopyAssignment> >::value, "");
+static_assert(!std::__is_replaceable<std::vector<int, test_allocator<int> > >::value, "");
+static_assert(!std::__is_replaceable<std::vector<int, NonReplaceableStatelessAlloc<int> > >::value, "");
+static_assert(!std::__is_replaceable<std::vector<int, NonPropagatingStatefulCopyAssignAlloc<int> > >::value, "");
+static_assert(!std::__is_replaceable<std::vector<int, NonPropagatingStatefulMoveAssignAlloc<int> > >::value, "");
+static_assert(std::__is_replaceable<std::vector<int, NonPropagatingStatelessCopyAssignAlloc<int> > >::value, "");
+static_assert(std::__is_replaceable<std::vector<int, NonPropagatingStatelessMoveAssignAlloc<int> > >::value, "");
+
+// weak_ptr
+static_assert(std::__is_replaceable<std::weak_ptr<CustomCopyAssignment> >::value, "");
+
+// TODO: Mark all the replaceable STL types as such
diff --git a/libcxx/test/libcxx-03/type_traits/is_scalar.objc.pass.mm b/libcxx/test/libcxx-03/type_traits/is_scalar.objc.pass.mm
new file mode 100644
index 0000000000000..951a90d6ced2c
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_scalar.objc.pass.mm
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-fblocks
+// ADDITIONAL_COMPILE_FLAGS: -fblocks
+
+// <type_traits>
+
+// std::is_scalar
+
+// Make sure we report that blocks are scalar types.
+
+#include <type_traits>
+
+struct Foo { };
+template <int> struct Arg { };
+
+static_assert(std::is_scalar<void (^)(void)>::value, "");
+static_assert(std::is_scalar<void (^)()>::value, "");
+static_assert(std::is_scalar<void (^)(Arg<0>)>::value, "");
+static_assert(std::is_scalar<void (^)(Arg<0>, Arg<1>)>::value, "");
+static_assert(std::is_scalar<void (^)(Arg<0>, Arg<1>, Arg<2>)>::value, "");
+static_assert(std::is_scalar<Foo (^)(void)>::value, "");
+static_assert(std::is_scalar<Foo (^)()>::value, "");
+static_assert(std::is_scalar<Foo (^)(Arg<0>)>::value, "");
+static_assert(std::is_scalar<Foo (^)(Arg<0>, Arg<1>)>::value, "");
+static_assert(std::is_scalar<Foo (^)(Arg<0>, Arg<1>, Arg<2>)>::value, "");
+
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/type_traits/is_specialization.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_specialization.compile.pass.cpp
new file mode 100644
index 0000000000000..73dfc773aa774
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_specialization.compile.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
+
+// template <class _Tp, template <class...> class _Template>
+// inline constexpr bool __is_specialization_v = true if and only if _Tp is a specialization of _Template
+//
+// Note instantiation for certain type combinations are ill-formed. These are
+// tested in is_specialization.verify.cpp.
+
+#include <__type_traits/is_specialization.h>
+#include <string_view>
+#include <tuple>
+#include <utility>
+
+#include "test_macros.h"
+
+// Simple types
+static_assert(std::__is_specialization_v<std::pair<int, int>, std::pair>);
+static_assert(!std::__is_specialization_v<std::pair<int, int>, std::tuple>);
+static_assert(!std::__is_specialization_v<std::pair<int, int>, std::basic_string_view>);
+
+static_assert(std::__is_specialization_v<std::tuple<int>, std::tuple>);
+static_assert(std::__is_specialization_v<std::tuple<int, float>, std::tuple>);
+static_assert(std::__is_specialization_v<std::tuple<int, float, void*>, std::tuple>);
+
+static_assert(std::__is_specialization_v<std::string_view, std::basic_string_view>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::__is_specialization_v<std::wstring_view, std::basic_string_view>);
+#endif
+
+// Nested types
+static_assert(std::__is_specialization_v<std::pair<std::tuple<int>, int>, std::pair>);
+static_assert(!std::__is_specialization_v<std::pair<std::tuple<int>, int>, std::tuple>);
+
+// cvref _Tp is not a specialization.
+static_assert(!std::__is_specialization_v<const std::pair<int, int>, std::pair>);
+static_assert(!std::__is_specialization_v<volatile std::pair<int, int>, std::pair>);
+static_assert(!std::__is_specialization_v<const volatile std::pair<int, int>, std::pair>);
+
+static_assert(!std::__is_specialization_v<std::pair<int, int>&, std::pair>);
+static_assert(!std::__is_specialization_v<const std::pair<int, int>&, std::pair>);
+static_assert(!std::__is_specialization_v<volatile std::pair<int, int>&, std::pair>);
+static_assert(!std::__is_specialization_v<const volatile std::pair<int, int>&, std::pair>);
+
+static_assert(!std::__is_specialization_v<std::pair<int, int>&&, std::pair>);
+static_assert(!std::__is_specialization_v<const std::pair<int, int>&&, std::pair>);
+static_assert(!std::__is_specialization_v<volatile std::pair<int, int>&&, std::pair>);
+static_assert(!std::__is_specialization_v<const volatile std::pair<int, int>&&, std::pair>);
diff --git a/libcxx/test/libcxx-03/type_traits/is_specialization.verify.cpp b/libcxx/test/libcxx-03/type_traits/is_specialization.verify.cpp
new file mode 100644
index 0000000000000..51bff6df96a53
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_specialization.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// template <class _Tp, template <class...> class _Template>
+// inline constexpr bool __is_specialization_v = true if and only if _Tp is a specialization of _Template
+//
+// Tests the ill-formed instantiations.
+
+#include <__type_traits/is_specialization.h>
+#include <array>
+#include <utility>
+
+// expected-error-re@*:* {{{{could not match _Size against 'type-parameter-0-0'|different template parameters|template argument for non-type template parameter must be an expression}}}}
+static_assert(!std::__is_specialization_v<std::pair<int, std::size_t>, std::array>);
diff --git a/libcxx/test/libcxx-03/type_traits/is_trivially_comparable.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_trivially_comparable.compile.pass.cpp
new file mode 100644
index 0000000000000..e9b53080fcd6d
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_trivially_comparable.compile.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_equality_comparable.h>
+#include <__type_traits/is_signed.h>
+#include <cstdint>
+
+enum Enum : int {};
+enum class EnumClass : int {};
+
+static_assert(std::__libcpp_is_trivially_equality_comparable<int, int>::value, "");
+static_assert(std::__libcpp_is_trivially_equality_comparable<const int, int>::value, "");
+static_assert(std::__libcpp_is_trivially_equality_comparable<int, const int>::value, "");
+
+static_assert(std::__libcpp_is_trivially_equality_comparable<unsigned int, unsigned int>::value, "");
+static_assert(std::__libcpp_is_trivially_equality_comparable<const unsigned int, unsigned int>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<unsigned int, int>::value, "");
+
+static_assert(!std::__libcpp_is_trivially_equality_comparable<std::int32_t, std::int64_t>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<std::int64_t, std::int32_t>::value, "");
+
+static_assert(std::__libcpp_is_trivially_equality_comparable<int*, int*>::value, "");
+static_assert(std::__libcpp_is_trivially_equality_comparable<int*, void*>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<int*, long*>::value, "");
+
+static_assert(!std::__libcpp_is_trivially_equality_comparable<Enum, int>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<EnumClass, int>::value, "");
+
+static_assert(!std::__libcpp_is_trivially_equality_comparable<float, int>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<double, long long>::value, "");
+
+static_assert(!std::__libcpp_is_trivially_equality_comparable<float, int>::value, "");
+
+static_assert(!std::__libcpp_is_trivially_equality_comparable<float, float>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<double, double>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<long double, long double>::value, "");
+
+static_assert(std::__libcpp_is_trivially_equality_comparable<
+ char,
+ typename std::conditional<std::is_signed<char>::value, signed char, unsigned char>::type>::value,
+ "");
+static_assert(std::__libcpp_is_trivially_equality_comparable<char16_t, std::uint_least16_t>::value, "");
+
+struct S {
+ char c;
+};
+
+struct S2 {
+ char c;
+};
+
+struct VirtualBase : virtual S {};
+struct NonVirtualBase : S, S2 {};
+
+static_assert(!std::__libcpp_is_trivially_equality_comparable<S*, VirtualBase*>::value, "");
+static_assert(!std::__libcpp_is_trivially_equality_comparable<S2*, VirtualBase*>::value, "");
+
+// This is trivially_equality_comparable, but we can't detect it currently
+static_assert(!std::__libcpp_is_trivially_equality_comparable<S*, NonVirtualBase*>::value, "");
diff --git a/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp b/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp
new file mode 100644
index 0000000000000..8066925f2900a
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/is_trivially_relocatable.compile.pass.cpp
@@ -0,0 +1,243 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__type_traits/is_trivially_relocatable.h>
+#include <array>
+#include <deque>
+#include <exception>
+#include <expected>
+#include <memory>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <variant>
+#include <vector>
+
+#include "constexpr_char_traits.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+# include <locale>
+#endif
+
+static_assert(std::__libcpp_is_trivially_relocatable<char>::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<int>::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<double>::value, "");
+
+struct Empty {};
+static_assert(std::__libcpp_is_trivially_relocatable<Empty>::value, "");
+
+struct TriviallyCopyable {
+ char c;
+ int i;
+ Empty s;
+};
+static_assert(std::__libcpp_is_trivially_relocatable<TriviallyCopyable>::value, "");
+
+struct NotTriviallyCopyable {
+ NotTriviallyCopyable(const NotTriviallyCopyable&);
+ ~NotTriviallyCopyable();
+};
+static_assert(!std::__libcpp_is_trivially_relocatable<NotTriviallyCopyable>::value, "");
+
+struct MoveOnlyTriviallyCopyable {
+ MoveOnlyTriviallyCopyable(const MoveOnlyTriviallyCopyable&) = delete;
+ MoveOnlyTriviallyCopyable& operator=(const MoveOnlyTriviallyCopyable&) = delete;
+ MoveOnlyTriviallyCopyable(MoveOnlyTriviallyCopyable&&) = default;
+ MoveOnlyTriviallyCopyable& operator=(MoveOnlyTriviallyCopyable&&) = default;
+};
+static_assert(std::__libcpp_is_trivially_relocatable<MoveOnlyTriviallyCopyable>::value, "");
+
+struct NonTrivialMoveConstructor {
+ NonTrivialMoveConstructor(NonTrivialMoveConstructor&&);
+};
+static_assert(!std::__libcpp_is_trivially_relocatable<NonTrivialMoveConstructor>::value, "");
+
+struct NonTrivialDestructor {
+ ~NonTrivialDestructor() {}
+};
+static_assert(!std::__libcpp_is_trivially_relocatable<NonTrivialDestructor>::value, "");
+
+// library-internal types
+// ----------------------
+
+// __split_buffer
+static_assert(std::__libcpp_is_trivially_relocatable<std::__split_buffer<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::__split_buffer<NotTriviallyCopyable> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::__split_buffer<int, test_allocator<int> > >::value, "");
+
+// standard library types
+// ----------------------
+
+// array
+static_assert(std::__libcpp_is_trivially_relocatable<std::array<int, 0> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::array<NotTriviallyCopyable, 0> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::array<std::unique_ptr<int>, 0> >::value, "");
+
+static_assert(std::__libcpp_is_trivially_relocatable<std::array<int, 1> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::array<NotTriviallyCopyable, 1> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::array<std::unique_ptr<int>, 1> >::value, "");
+
+// basic_string
+#if !__has_feature(address_sanitizer) || !_LIBCPP_INSTRUMENTED_WITH_ASAN
+struct MyChar {
+ char c;
+};
+template <class T>
+struct NotTriviallyRelocatableCharTraits : constexpr_char_traits<T> {
+ NotTriviallyRelocatableCharTraits(const NotTriviallyRelocatableCharTraits&);
+ NotTriviallyRelocatableCharTraits& operator=(const NotTriviallyRelocatableCharTraits&);
+ ~NotTriviallyRelocatableCharTraits();
+};
+
+static_assert(std::__libcpp_is_trivially_relocatable<
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::value,
+ "");
+static_assert(std::__libcpp_is_trivially_relocatable<
+ std::basic_string<char, NotTriviallyRelocatableCharTraits<char>, std::allocator<char> > >::value,
+ "");
+static_assert(std::__libcpp_is_trivially_relocatable<
+ std::basic_string<MyChar, constexpr_char_traits<MyChar>, std::allocator<MyChar> > >::value,
+ "");
+static_assert(
+ std::__libcpp_is_trivially_relocatable<
+ std::basic_string<MyChar, NotTriviallyRelocatableCharTraits<MyChar>, std::allocator<MyChar> > >::value,
+ "");
+static_assert(!std::__libcpp_is_trivially_relocatable<
+ std::basic_string<char, std::char_traits<char>, test_allocator<char> > >::value,
+ "");
+static_assert(
+ !std::__libcpp_is_trivially_relocatable<
+ std::basic_string<MyChar, NotTriviallyRelocatableCharTraits<MyChar>, test_allocator<MyChar> > >::value,
+ "");
+#endif
+
+// deque
+static_assert(std::__libcpp_is_trivially_relocatable<std::deque<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::deque<NotTriviallyCopyable> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::deque<int, test_allocator<int> > >::value, "");
+
+// exception_ptr
+#ifndef _LIBCPP_ABI_MICROSOFT // FIXME: Is this also the case on windows?
+static_assert(std::__libcpp_is_trivially_relocatable<std::exception_ptr>::value, "");
+#endif
+
+// expected
+#if TEST_STD_VER >= 23
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, int> >::value);
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, int>>::value);
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, std::unique_ptr<int>>>::value);
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, std::unique_ptr<int>>>::value);
+
+static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<int, NotTriviallyCopyable>>::value);
+static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<NotTriviallyCopyable, int>>::value);
+static_assert(
+ !std::__libcpp_is_trivially_relocatable<std::expected<NotTriviallyCopyable, NotTriviallyCopyable>>::value);
+#endif
+
+// locale
+#ifndef TEST_HAS_NO_LOCALIZATION
+static_assert(std::__libcpp_is_trivially_relocatable<std::locale>::value, "");
+#endif
+
+// optional
+#if TEST_STD_VER >= 17
+static_assert(std::__libcpp_is_trivially_relocatable<std::optional<int>>::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::optional<NotTriviallyCopyable>>::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::optional<std::unique_ptr<int>>>::value, "");
+#endif // TEST_STD_VER >= 17
+
+// pair
+static_assert(std::__libcpp_is_trivially_relocatable<std::pair<int, int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<NotTriviallyCopyable, int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<int, NotTriviallyCopyable> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
+ "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::pair<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
+ "");
+
+// shared_ptr
+static_assert(std::__libcpp_is_trivially_relocatable<std::shared_ptr<NotTriviallyCopyable> >::value, "");
+
+// tuple
+#if TEST_STD_VER >= 11
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<> >::value, "");
+
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int> > >::value, "");
+
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int, int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<int, NotTriviallyCopyable> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
+ "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
+ "");
+#endif // TEST_STD_VER >= 11
+
+// unique_ptr
+struct NotTriviallyRelocatableDeleter {
+ NotTriviallyRelocatableDeleter(const NotTriviallyRelocatableDeleter&);
+ NotTriviallyRelocatableDeleter& operator=(const NotTriviallyRelocatableDeleter&);
+ ~NotTriviallyRelocatableDeleter();
+
+ template <class T>
+ void operator()(T*);
+};
+
+struct NotTriviallyRelocatablePointer {
+ struct pointer {
+ pointer(const pointer&);
+ pointer& operator=(const pointer&);
+ ~pointer();
+ };
+
+ template <class T>
+ void operator()(T*);
+};
+
+static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<NotTriviallyCopyable> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[]> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int, NotTriviallyRelocatableDeleter> >::value,
+ "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[], NotTriviallyRelocatableDeleter> >::value,
+ "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int, NotTriviallyRelocatablePointer> >::value,
+ "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[], NotTriviallyRelocatablePointer> >::value,
+ "");
+
+// variant
+#if TEST_STD_VER >= 17
+static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int> > >::value, "");
+
+static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int, int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, int> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<int, NotTriviallyCopyable> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
+ "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
+ "");
+#endif // TEST_STD_VER >= 17
+
+// vector
+static_assert(std::__libcpp_is_trivially_relocatable<std::vector<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::vector<NotTriviallyCopyable> >::value, "");
+static_assert(!std::__libcpp_is_trivially_relocatable<std::vector<int, test_allocator<int> > >::value, "");
+
+// weak_ptr
+static_assert(std::__libcpp_is_trivially_relocatable<std::weak_ptr<NotTriviallyCopyable> >::value, "");
+
+// TODO: Mark all the trivially relocatable STL types as such
diff --git a/libcxx/test/libcxx-03/type_traits/lazy_metafunctions.pass.cpp b/libcxx/test/libcxx-03/type_traits/lazy_metafunctions.pass.cpp
new file mode 100644
index 0000000000000..669bcdb58d7ba
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/lazy_metafunctions.pass.cpp
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <type_traits>
+
+// __lazy_enable_if, __lazy_not, _And and _Or
+
+// Test the libc++ lazy meta-programming helpers in <type_traits>
+
+#include <__type_traits/conjunction.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/negation.h>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class Type>
+struct Identity : Type {
+
+};
+
+typedef std::true_type TrueT;
+typedef std::false_type FalseT;
+
+typedef Identity<TrueT> LazyTrueT;
+typedef Identity<FalseT> LazyFalseT;
+
+// A type that cannot be instantiated
+template <class T>
+struct CannotInst {
+ static_assert(std::is_same<T, T>::value == false, "");
+};
+
+
+template <int Value>
+struct NextInt {
+ typedef NextInt<Value + 1> type;
+ static const int value = Value;
+};
+
+template <int Value>
+const int NextInt<Value>::value;
+
+
+template <class Type>
+struct HasTypeImp {
+ template <class Up, class = typename Up::type>
+ static TrueT test(int);
+ template <class>
+ static FalseT test(...);
+
+ typedef decltype(test<Type>(0)) type;
+};
+
+// A metafunction that returns True if Type has a nested 'type' typedef
+// and false otherwise.
+template <class Type>
+struct HasType : HasTypeImp<Type>::type {};
+
+
+void LazyNotTest() {
+ {
+ typedef std::_Not<LazyTrueT> NotT;
+ static_assert(std::is_same<typename NotT::type, FalseT>::value, "");
+ static_assert(NotT::value == false, "");
+ }
+ {
+ typedef std::_Not<LazyFalseT> NotT;
+ static_assert(std::is_same<typename NotT::type, TrueT>::value, "");
+ static_assert(NotT::value == true, "");
+ }
+ {
+ // Check that CannotInst<int> is not instantiated.
+ typedef std::_Not<CannotInst<int> > NotT;
+
+ static_assert(std::is_same<NotT, NotT>::value, "");
+
+ }
+}
+
+void LazyAndTest() {
+ { // Test that it acts as the identity function for a single value
+ static_assert(std::_And<LazyFalseT>::value == false, "");
+ static_assert(std::_And<LazyTrueT>::value == true, "");
+ }
+ {
+ static_assert(std::_And<LazyTrueT, LazyTrueT>::value == true, "");
+ static_assert(std::_And<LazyTrueT, LazyFalseT>::value == false, "");
+ static_assert(std::_And<LazyFalseT, LazyTrueT>::value == false, "");
+ static_assert(std::_And<LazyFalseT, LazyFalseT>::value == false, "");
+ }
+ { // Test short circuiting - CannotInst<T> should never be instantiated.
+ static_assert(std::_And<LazyFalseT, CannotInst<int>>::value == false, "");
+ static_assert(std::_And<LazyTrueT, LazyFalseT, CannotInst<int>>::value == false, "");
+ }
+}
+
+
+void LazyOrTest() {
+ { // Test that it acts as the identity function for a single value
+ static_assert(std::_Or<LazyFalseT>::value == false, "");
+ static_assert(std::_Or<LazyTrueT>::value == true, "");
+ }
+ {
+ static_assert(std::_Or<LazyTrueT, LazyTrueT>::value == true, "");
+ static_assert(std::_Or<LazyTrueT, LazyFalseT>::value == true, "");
+ static_assert(std::_Or<LazyFalseT, LazyTrueT>::value == true, "");
+ static_assert(std::_Or<LazyFalseT, LazyFalseT>::value == false, "");
+ }
+ { // Test short circuiting - CannotInst<T> should never be instantiated.
+ static_assert(std::_Or<LazyTrueT, CannotInst<int>>::value == true, "");
+ static_assert(std::_Or<LazyFalseT, LazyTrueT, CannotInst<int>>::value == true, "");
+ }
+}
+
+
+int main(int, char**) {
+
+ LazyNotTest();
+ LazyAndTest();
+ LazyOrTest();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/type_traits/no_specializations.verify.cpp b/libcxx/test/libcxx-03/type_traits/no_specializations.verify.cpp
new file mode 100644
index 0000000000000..897ae89365014
--- /dev/null
+++ b/libcxx/test/libcxx-03/type_traits/no_specializations.verify.cpp
@@ -0,0 +1,197 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Check that user-specializations are diagnosed
+// See [meta.rqmts]/4, [meta.trans.other]/5, [meta.trans.other]/7
+
+#include <type_traits>
+
+#include "test_macros.h"
+
+#if !__has_warning("-Winvalid-specialization")
+// expected-no-diagnostics
+#else
+struct S {};
+
+# define SPECIALIZE_TRAIT(Trait) \
+ template <> \
+ struct std::Trait<S>
+
+SPECIALIZE_TRAIT(add_const); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_cv); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_volatile); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_lvalue_reference); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_rvalue_reference); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(add_pointer); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(decay); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(invoke_result); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(make_unsigned); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_all_extents); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_const); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_cv); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_extent); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_pointer); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_reference); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(remove_volatile); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(underlying_type); // expected-error {{cannot be specialized}}
+
+# if TEST_STD_VER <= 17
+SPECIALIZE_TRAIT(result_of); // expected-error {{cannot be specialized}}
+# endif
+
+# if TEST_STD_VER >= 20
+SPECIALIZE_TRAIT(remove_cvref); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(type_identity); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(unwrap_reference); // expected-error {{cannot be specialized}}
+SPECIALIZE_TRAIT(unwrap_ref_decay); // expected-error {{cannot be specialized}}
+# endif
+
+# undef SPECIALIZE_TRAIT
+# define SPECIALIZE_UTT(Trait) \
+ template <> \
+ struct std::Trait<S>; \
+ template <> \
+ inline constexpr bool std::Trait##_v<S> = false
+
+# define SPECIALIZE_BTT(Trait) \
+ template <> \
+ struct std::Trait<S, S>; \
+ template <> \
+ inline constexpr bool std::Trait##_v<S, S> = false
+
+SPECIALIZE_UTT(alignment_of); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(conjunction); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(disjunction); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(extent); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(has_unique_object_representations); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_abstract); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_aggregate); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_arithmetic); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_array); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_base_of); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_class); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_compound); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_const); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_convertible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_copy_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_copy_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_default_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_destructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_empty); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_enum); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_final); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_floating_point); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_function); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_fundamental); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_integral); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_invocable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_invocable_r); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_lvalue_reference); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_member_pointer); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_member_object_pointer); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_member_function_pointer); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_move_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_move_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_copy_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_copy_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_default_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_destructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_move_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_move_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_invocable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_invocable_r); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_nothrow_swappable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_swappable_with); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_null_pointer); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_object); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_pod); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_pointer); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_polymorphic); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_reference); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_rvalue_reference); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_same); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_scalar); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_signed); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_standard_layout); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_swappable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_swappable_with); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivial); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_trivially_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_copy_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_copy_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_copyable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_default_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_destructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_move_assignable); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_trivially_move_constructible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_union); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_unsigned); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_void); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_volatile); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(negation); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(rank); // expected-error 2 {{cannot be specialized}}
+
+# if TEST_STD_VER <= 17
+SPECIALIZE_UTT(is_literal_type); // expected-error 2 {{cannot be specialized}}
+# endif
+
+# if TEST_STD_VER >= 20
+SPECIALIZE_UTT(is_bounded_array); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_BTT(is_nothrow_convertible); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_unbounded_array); // expected-error 2 {{cannot be specialized}}
+# endif
+
+# if TEST_STD_VER >= 23
+SPECIALIZE_UTT(is_implicit_lifetime); // expected-error 2 {{cannot be specialized}}
+SPECIALIZE_UTT(is_scoped_enum); // expected-error 2 {{cannot be specialized}}
+# if __has_builtin(__reference_constructs_from_temporary)
+SPECIALIZE_BTT(reference_constructs_from_temporary); // expected-error 2 {{cannot be specialized}}
+# endif
+# if __has_builtin(__reference_converts_from_temporary)
+SPECIALIZE_BTT(reference_converts_from_temporary); // expected-error 2 {{cannot be specialized}}
+# endif
+# endif
+
+# if TEST_STD_VER >= 26
+SPECIALIZE_BTT(is_virtual_base_of); // expected-error 2 {{cannot be specialized}}
+# endif
+
+# undef SPECIALIZE_UTT
+# undef SPECIALIZE_BTT
+
+template <>
+struct std::aligned_storage<1, 3>; // expected-error {{cannot be specialized}}
+
+template <>
+struct std::aligned_union<1, S>; // expected-error {{cannot be specialized}}
+
+template <>
+struct std::conditional<true, S, S>; // expected-error {{cannot be specialized}}
+
+template <>
+struct std::enable_if<true, S>; // expected-error {{cannot be specialized}}
+
+# if TEST_STD_VER >= 20
+template <>
+struct std::integral_constant<S, {}>; // expected-error {{cannot be specialized}}
+
+template <>
+struct std::common_reference<S>; // expected-error {{cannot be specialized}}
+template <>
+struct std::common_reference<S, S>; // expected-error {{cannot be specialized}}
+template <>
+struct std::common_reference<S, S, S>; // expected-error {{cannot be specialized}}
+# endif
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/any/allocator.pass.cpp b/libcxx/test/libcxx-03/utilities/any/allocator.pass.cpp
new file mode 100644
index 0000000000000..eab3ca8826493
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/any/allocator.pass.cpp
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <any>
+
+// Check that we're consistently using std::allocator_traits to
+// allocate/deallocate/construct/destroy objects in std::any.
+// See https://llvm.org/PR45099 for details.
+
+#include <any>
+#include <cassert>
+#include <cstddef>
+#include <memory>
+#include <new>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+
+// Make sure we don't fit in std::any's SBO
+struct Large { char big[sizeof(std::any) + 1]; };
+
+// Make sure we fit in std::any's SBO
+struct Small { };
+
+bool Large_was_allocated = false;
+bool Large_was_constructed = false;
+bool Large_was_destroyed = false;
+bool Large_was_deallocated = false;
+
+bool Small_was_constructed = false;
+bool Small_was_destroyed = false;
+
+template <>
+struct std::allocator<Large> {
+ using value_type = Large;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+ using propagate_on_container_move_assignment = std::true_type;
+ using is_always_equal = std::true_type;
+
+ Large* allocate(std::size_t n) {
+ Large_was_allocated = true;
+ return static_cast<Large*>(::operator new(n * sizeof(Large)));
+ }
+
+ template <typename... Args>
+ void construct(Large* p, Args&&... args) {
+ new (p) Large(std::forward<Args>(args)...);
+ Large_was_constructed = true;
+ }
+
+ void destroy(Large* p) {
+ p->~Large();
+ Large_was_destroyed = true;
+ }
+
+ void deallocate(Large* p, std::size_t) {
+ Large_was_deallocated = true;
+ return ::operator delete(p);
+ }
+};
+
+template <>
+struct std::allocator<Small> {
+ using value_type = Small;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+ using propagate_on_container_move_assignment = std::true_type;
+ using is_always_equal = std::true_type;
+
+ Small* allocate(std::size_t) {
+ assert(false);
+ return nullptr;
+ }
+
+ template <typename... Args>
+ void construct(Small* p, Args&&... args) {
+ new (p) Small(std::forward<Args>(args)...);
+ Small_was_constructed = true;
+ }
+
+ void destroy(Small* p) {
+ p->~Small();
+ Small_was_destroyed = true;
+ }
+
+ void deallocate(Small*, std::size_t) { assert(false); }
+};
+
+int main(int, char**) {
+ // Test large types
+ {
+ {
+ std::any a = Large();
+ (void)a;
+
+ assert(Large_was_allocated);
+ assert(Large_was_constructed);
+ }
+
+ assert(Large_was_destroyed);
+ assert(Large_was_deallocated);
+ }
+
+ // Test small types
+ {
+ {
+ std::any a = Small();
+ (void)a;
+
+ assert(Small_was_constructed);
+ }
+
+ assert(Small_was_destroyed);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/any/size_and_alignment.pass.cpp b/libcxx/test/libcxx-03/utilities/any/size_and_alignment.pass.cpp
new file mode 100644
index 0000000000000..230ff8c2a06c7
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/any/size_and_alignment.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <any>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+ static_assert(sizeof(std::any) == sizeof(void*)*4, "");
+ static_assert(alignof(std::any) == alignof(void*), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/any/small_type.pass.cpp b/libcxx/test/libcxx-03/utilities/any/small_type.pass.cpp
new file mode 100644
index 0000000000000..65c7d34ff6ea8
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/any/small_type.pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <any>
+#include "test_macros.h"
+#include "any_helpers.h"
+
+constexpr std::size_t BufferSize = (sizeof(void*) * 3);
+constexpr std::size_t BufferAlignment = alignof(void*);
+// Clang doesn't like "alignof(BufferAlignment * 2)" due to PR13986.
+// So we create "DoubleBufferAlignment" instead.
+constexpr std::size_t DoubleBufferAlignment = BufferAlignment * 2;
+
+class SmallThrowsDtor
+{
+public:
+ SmallThrowsDtor() {}
+ SmallThrowsDtor(SmallThrowsDtor const &) noexcept {}
+ SmallThrowsDtor(SmallThrowsDtor &&) noexcept {}
+ ~SmallThrowsDtor() noexcept(false) {}
+};
+
+
+struct alignas(1) MaxSizeType {
+ char buff[BufferSize];
+};
+
+struct alignas(BufferAlignment) MaxAlignType {
+};
+
+struct alignas(BufferAlignment) MaxSizeAndAlignType {
+ char buff[BufferSize];
+};
+
+
+struct alignas(1) OverSizeType {
+ char buff[BufferSize + 1];
+};
+
+struct alignas(DoubleBufferAlignment) OverAlignedType {
+};
+
+struct alignas(DoubleBufferAlignment) OverSizeAndAlignedType {
+ char buff[BufferSize + 1];
+};
+
+int main(int, char**)
+{
+ using std::__any_imp::_IsSmallObject;
+ static_assert(_IsSmallObject<small>::value, "");
+ static_assert(_IsSmallObject<void*>::value, "");
+ static_assert(!_IsSmallObject<SmallThrowsDtor>::value, "");
+ static_assert(!_IsSmallObject<large>::value, "");
+ {
+ // Check a type that meets the size requirement *exactly* and has
+ // a lesser alignment requirement is considered small.
+ typedef MaxSizeType T;
+ static_assert(sizeof(T) == BufferSize, "");
+ static_assert(alignof(T) < BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the alignment requirement *exactly* and has
+ // a lesser size is considered small.
+ typedef MaxAlignType T;
+ static_assert(sizeof(T) < BufferSize, "");
+ static_assert(alignof(T) == BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the size and alignment requirements *exactly*
+ // is considered small.
+ typedef MaxSizeAndAlignType T;
+ static_assert(sizeof(T) == BufferSize, "");
+ static_assert(alignof(T) == BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the alignment requirements but is over-sized
+ // is not considered small.
+ typedef OverSizeType T;
+ static_assert(sizeof(T) > BufferSize, "");
+ static_assert(alignof(T) < BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the size requirements but is over-aligned
+ // is not considered small.
+ typedef OverAlignedType T;
+ static_assert(sizeof(T) < BufferSize, "");
+ static_assert(alignof(T) > BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that exceeds both the size an alignment requirements
+ // is not considered small.
+ typedef OverSizeAndAlignedType T;
+ static_assert(sizeof(T) > BufferSize, "");
+ static_assert(alignof(T) > BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/assert.exception_guard.no_exceptions.pass.cpp b/libcxx/test/libcxx-03/utilities/assert.exception_guard.no_exceptions.pass.cpp
new file mode 100644
index 0000000000000..c6ddb8bd252a4
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/assert.exception_guard.no_exceptions.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03
+// REQUIRES: libcpp-hardening-mode=debug
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -fno-exceptions
+
+#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/libcxx/test/libcxx-03/utilities/exception_guard.no_exceptions.pass.cpp b/libcxx/test/libcxx-03/utilities/exception_guard.no_exceptions.pass.cpp
new file mode 100644
index 0000000000000..60cf4f7814597
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/exception_guard.no_exceptions.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
+
+// ADDITIONAL_COMPILE_FLAGS: -fno-exceptions
+
+#include <__utility/exception_guard.h>
+#include <utility>
+
+int main(int, char**) {
+ auto guard = std::__make_exception_guard([] {});
+ auto guard2 = std::move(guard);
+ guard2.__complete();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/exception_guard.odr.sh.cpp b/libcxx/test/libcxx-03/utilities/exception_guard.odr.sh.cpp
new file mode 100644
index 0000000000000..fb51a4bf4ed27
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/exception_guard.odr.sh.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This test relies on `typeid` and thus requires `-frtti`.
+// UNSUPPORTED: no-rtti
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// Make sure that we don't get ODR violations with __exception_guard when
+// linking together TUs compiled with different values of -f[no-]exceptions.
+
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.except.o -O1 -fexceptions
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.noexcept.o -O1 -fno-exceptions
+// RUN: %{cxx} %{flags} %{link_flags} -o %t.exe %t.except.o %t.noexcept.o
+// RUN: %{run}
+
+#include <__utility/exception_guard.h>
+#include <cassert>
+#include <cstring>
+#include <typeinfo>
+
+struct Rollback {
+ void operator()() {}
+};
+
+#if defined(__cpp_exceptions) && __cpp_exceptions >= 199711L
+
+const char* func();
+
+int main(int, char**) {
+ assert(std::strcmp(typeid(std::__exception_guard<Rollback>).name(), func()) != 0);
+
+ return 0;
+}
+
+#else
+
+const char* func() { return typeid(std::__exception_guard<Rollback>).name(); }
+
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/exception_guard.pass.cpp b/libcxx/test/libcxx-03/utilities/exception_guard.pass.cpp
new file mode 100644
index 0000000000000..0728959c7277b
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/exception_guard.pass.cpp
@@ -0,0 +1,161 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// UNSUPPORTED: no-exceptions
+
+#include <__utility/exception_guard.h>
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ // Make sure the transaction is rolled back if it is not marked as complete when
+ // it goes out of scope.
+ {
+ bool rolled_back = false;
+ {
+ auto rollback = [&] { rolled_back = true; };
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ }
+ assert(rolled_back);
+ }
+
+ // Make sure the transaction is not rolled back if it is marked as complete when
+ // it goes out of scope.
+ {
+ bool rolled_back = false;
+ {
+ auto rollback = [&] { rolled_back = true; };
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ g.__complete();
+ }
+ assert(!rolled_back);
+ }
+
+ // Make sure that we will perform the right number of rollbacks when a transaction has
+ // been moved around
+ {
+ // When we don't complete it (exactly 1 rollback should happen)
+ {
+ int rollbacks = 0;
+ {
+ auto rollback = [&] { ++rollbacks; };
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ auto other = std::move(g);
+ }
+ assert(rollbacks == 1);
+ }
+
+ // When we do complete it (no rollbacks should happen)
+ {
+ int rollbacks = 0;
+ {
+ auto rollback = [&] { ++rollbacks; };
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ auto other = std::move(g);
+ other.__complete();
+ }
+ assert(rollbacks == 0);
+ }
+ }
+
+ // Basic properties of the type
+ {
+ struct Rollback { void operator()() const { } };
+ using Transaction = std::__exception_guard<Rollback>;
+
+ static_assert(!std::is_default_constructible<Transaction>::value, "");
+
+ static_assert(!std::is_copy_constructible<Transaction>::value, "");
+ static_assert( std::is_move_constructible<Transaction>::value, "");
+
+ static_assert(!std::is_copy_assignable<Transaction>::value, "");
+ static_assert(!std::is_move_assignable<Transaction>::value, "");
+
+ // Check noexcept-ness of a few operations
+ {
+ struct ThrowOnMove {
+ ThrowOnMove(ThrowOnMove&&) noexcept(false) { }
+ void operator()() const { }
+ };
+ using ThrowOnMoveTransaction = std::__exception_guard<ThrowOnMove>;
+
+ ASSERT_NOEXCEPT(std::declval<Transaction>().__complete());
+ static_assert( std::is_nothrow_move_constructible<Transaction>::value, "");
+ static_assert(!std::is_nothrow_move_constructible<ThrowOnMoveTransaction>::value, "");
+ }
+ }
+
+ return true;
+}
+
+void test_exceptions() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ // Make sure the rollback is performed when an exception is thrown during the
+ // lifetime of the transaction.
+ {
+ bool rolled_back = false;
+ auto rollback = [&] { rolled_back = true; };
+ try {
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ throw 0;
+ } catch (...) { }
+ assert(rolled_back);
+ }
+
+ // Make sure we don't roll back if an exception is thrown but the transaction
+ // has been marked as complete when that happens.
+ {
+ bool rolled_back = false;
+ auto rollback = [&] { rolled_back = true; };
+ try {
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ g.__complete();
+ throw 0;
+ } catch (...) { }
+ assert(!rolled_back);
+ }
+
+ // Make sure __exception_guard does not rollback if the transaction is marked as
+ // completed within a destructor.
+ {
+ struct S {
+ explicit S(bool& x) : x_(x) { }
+
+ ~S() {
+ auto rollback = [this]{ x_ = true; };
+ std::__exception_guard<decltype(rollback)> g(rollback);
+ g.__complete();
+ }
+
+ bool& x_;
+ };
+
+ bool rolled_back = false;
+ try {
+ S s(rolled_back);
+ throw 0;
+ } catch (...) {
+ assert(!rolled_back);
+ }
+ }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+ test();
+ test_exceptions();
+#if TEST_STD_VER > 17
+ static_assert(test(), "");
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/and_then.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/and_then.mandates.verify.cpp
new file mode 100644
index 0000000000000..c46ab633295c1
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/and_then.mandates.verify.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, c++20
+
+// Test the mandates
+// template<class F> constexpr auto and_then(F&& f) &;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+// template<class F> constexpr auto and_then(F&& f) const &;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+// template<class F> constexpr auto and_then(F&& f) &&;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+// template<class F> constexpr auto and_then(F&& f) const &&;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+#include <expected>
+#include <utility>
+
+struct NotSameAsInt {};
+
+int lval_return_not_std_expected(int&) { return 0; }
+int clval_return_not_std_expected(const int&) { return 0; }
+int rval_return_not_std_expected(int&&) { return 0; }
+int crval_return_not_std_expected(const int&&) { return 0; }
+
+std::expected<int, NotSameAsInt> lval_error_type_not_same_as_int(int&) { return {}; }
+std::expected<int, NotSameAsInt> clval_error_type_not_same_as_int(const int&) { return {}; }
+std::expected<int, NotSameAsInt> rval_error_type_not_same_as_int(int&&) { return {}; }
+std::expected<int, NotSameAsInt> crval_error_type_not_same_as_int(const int&&) { return {}; }
+
+// clang-format off
+void test() {
+ // Test & overload
+ {
+ // U is not a specialization of std::expected
+ {
+ std::expected<int, int> f1(1);
+ f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ std::expected<int, int> f1(1);
+ f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
+ }
+ }
+
+ // Test const& overload
+ {
+ // U is not a specialization of std::expected
+ {
+ const std::expected<int, int> f1(1);
+ f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ const std::expected<int, int> f1(1);
+ f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
+
+ }
+ }
+
+ // Test && overload
+ {
+ // U is not a specialization of std::expected
+ {
+ std::expected<int, int> f1(1);
+ std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ std::expected<int, int> f1(1);
+ std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
+ }
+ }
+
+ // Test const&& overload
+ {
+ // U is not a specialization of std::expected
+ {
+ const std::expected<int, int> f1(1);
+ std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ const std::expected<int, int> f1(1);
+ std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
+ }
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.arrow.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.arrow.pass.cpp
new file mode 100644
index 0000000000000..47481bcbef8a8
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.arrow.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// constexpr const T* operator->() const noexcept;
+// constexpr T* operator->() noexcept;
+//
+// Preconditions: has_value() is true.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::expected<int, int> e{std::unexpect, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(e.operator->(), "expected::operator-> requires the expected to contain a value");
+ TEST_LIBCPP_ASSERT_FAILURE(std::as_const(e).operator->(), "expected::operator-> requires the expected to contain a value");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.deref.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.deref.pass.cpp
new file mode 100644
index 0000000000000..5ab43d38ccb15
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.deref.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// constexpr const T& operator*() const & noexcept;
+// constexpr T& operator*() & noexcept;
+// constexpr T&& operator*() && noexcept;
+// constexpr const T&& operator*() const && noexcept;
+//
+// Preconditions: has_value() is true.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::expected<int, int> e{std::unexpect, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(*e, "expected::operator* requires the expected to contain a value");
+ TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(e), "expected::operator* requires the expected to contain a value");
+ TEST_LIBCPP_ASSERT_FAILURE(*std::move(e), "expected::operator* requires the expected to contain a value");
+ TEST_LIBCPP_ASSERT_FAILURE(*std::move(std::as_const(e)), "expected::operator* requires the expected to contain a value");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.error.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.error.pass.cpp
new file mode 100644
index 0000000000000..92bf305994c18
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/assert.error.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// constexpr const E& error() const & noexcept;
+// constexpr E& error() & noexcept;
+// constexpr E&& error() && noexcept;
+// constexpr const E&& error() const && noexcept;
+//
+// Preconditions: has_value() is false.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::expected<int, int> e{std::in_place, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(e.error(), "expected::error requires the expected to contain an error");
+ TEST_LIBCPP_ASSERT_FAILURE(std::as_const(e).error(), "expected::error requires the expected to contain an error");
+ TEST_LIBCPP_ASSERT_FAILURE(std::move(e).error(), "expected::error requires the expected to contain an error");
+ TEST_LIBCPP_ASSERT_FAILURE(std::move(std::as_const(e)).error(), "expected::error requires the expected to contain an error");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/error_or.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/error_or.mandates.verify.cpp
new file mode 100644
index 0000000000000..d833f72f1c54f
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/error_or.mandates.verify.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
+
+// Test the mandates
+// template<class G = E> constexpr E error_or(G&&) const &;
+// Mandates: is_copy_constructible_v<G> is true and is_convertible_v<U, E> is true.
+
+// template<class G = E> constexpr E error_or(G&&) &&;
+// Mandates: is_move_constructible_v<G> is true and is_convertible_v<U, E> is true.
+
+#include <expected>
+#include <utility>
+
+struct NonCopyable {
+ NonCopyable(int) {}
+ NonCopyable(const NonCopyable&) = delete;
+};
+
+struct NonMovable {
+ NonMovable(int) {}
+ NonMovable(NonMovable&&) = delete;
+};
+
+struct NotConvertibleFromInt {};
+
+// clang-format off
+void test() {
+ // const & overload
+ // !is_copy_constructible_v<G>,
+ {
+ const std::expected<int, NonCopyable> f1(std::unexpect, 0);
+ f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonCopyable>::error_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be copy constructible}}
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+ }
+
+ // const & overload
+ // !is_convertible_v<U, T>
+ {
+ const std::expected<int, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
+ f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
+ // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
+
+ }
+
+ // && overload
+ // !is_move_constructible_v<T>,
+ {
+ std::expected<int, NonMovable> f1(std::unexpect, 0);
+ std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonMovable>::error_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be move constructible}}
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+ }
+
+ // && overload
+ // !is_convertible_v<U, T>
+ {
+ std::expected<int, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
+ std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}}
+ //expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
+ // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..8c2b71f3c5f23
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/no_unique_address.compile.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
+
+// clang-cl and cl currently don't support [[no_unique_address]]
+// XFAIL: msvc
+
+// test [[no_unique_address]] is applied to the union
+
+#include <__type_traits/datasizeof.h>
+#include <expected>
+#include <optional>
+#include <memory>
+
+struct Empty {};
+
+struct A {
+ int x_;
+ int y_;
+};
+
+struct B : public A {
+ int z_;
+ short z2_;
+ virtual ~B() = default;
+};
+
+struct BoolWithPadding {
+ explicit operator bool() { return b; }
+
+private:
+ alignas(1024) bool b = false;
+};
+
+static_assert(sizeof(std::expected<Empty, Empty>) == sizeof(bool));
+static_assert(sizeof(std::expected<Empty, A>) == 2 * sizeof(int) + alignof(std::expected<Empty, A>));
+static_assert(sizeof(std::expected<Empty, B>) == sizeof(B));
+static_assert(sizeof(std::expected<A, Empty>) == 2 * sizeof(int) + alignof(std::expected<A, Empty>));
+static_assert(sizeof(std::expected<A, A>) == 2 * sizeof(int) + alignof(std::expected<A, A>));
+static_assert(sizeof(std::expected<B, Empty>) == sizeof(B));
+static_assert(sizeof(std::expected<B, B>) == sizeof(B));
+
+// Check that `expected`'s datasize is large enough for the parameter type(s).
+static_assert(sizeof(std::expected<BoolWithPadding, Empty>) ==
+ std::__datasizeof_v<std::expected<BoolWithPadding, Empty>>);
+static_assert(sizeof(std::expected<Empty, BoolWithPadding>) ==
+ std::__datasizeof_v<std::expected<Empty, BoolWithPadding>>);
+
+// In this case, there should be tail padding in the `expected` because `A`
+// itself does _not_ have tail padding.
+static_assert(sizeof(std::expected<A, A>) > std::__datasizeof_v<std::expected<A, A>>);
+
+// Test with some real types.
+static_assert(sizeof(std::expected<std::optional<int>, int>) == 8);
+static_assert(std::__datasizeof_v<std::expected<std::optional<int>, int>> == 8);
+
+static_assert(sizeof(std::expected<int, std::optional<int>>) == 8);
+static_assert(std::__datasizeof_v<std::expected<int, std::optional<int>>> == 8);
+
+static_assert(sizeof(std::expected<int, int>) == 8);
+static_assert(std::__datasizeof_v<std::expected<int, int>> == 5);
+
+// clang-format off
+static_assert(std::__datasizeof_v<int> == 4);
+static_assert(std::__datasizeof_v<std::expected<int, int>> == 5);
+static_assert(std::__datasizeof_v<std::expected<std::expected<int, int>, int>> == 8);
+static_assert(std::__datasizeof_v<std::expected<std::expected<std::expected<int, int>, int>, int>> == 9);
+static_assert(std::__datasizeof_v<std::expected<std::expected<std::expected<std::expected<int, int>, int>, int>, int>> == 12);
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp
new file mode 100644
index 0000000000000..4f8c4ef821d5f
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/noexcept.extension.compile.pass.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// test libc++ noexcept extensions on operations of std::expected<T, E>
+
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../types.h"
+
+// expected();
+static_assert(std::is_nothrow_default_constructible_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_default_constructible_v<std::expected<DefaultMayThrow, int>>);
+
+// expected(const expected&)
+static_assert(std::is_nothrow_copy_constructible_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_copy_constructible_v<std::expected<CopyMayThrow, int>>);
+static_assert(!std::is_nothrow_copy_constructible_v<std::expected<int, CopyMayThrow>>);
+
+// expected(const expected<OtherT, OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<long, long>,
+ const std::expected<int, int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromCopyIntMayThrow, long>,
+ const std::expected<int, int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<long, ConvertFromCopyIntMayThrow>,
+ const std::expected<int, int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromCopyIntMayThrow, ConvertFromCopyIntMayThrow>, //
+ const std::expected<int, int>&>);
+
+// expected(expected<OtherT, OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<long, long>,
+ std::expected<int, int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromMoveIntMayThrow, long>,
+ std::expected<int, int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<long, ConvertFromMoveIntMayThrow>,
+ std::expected<int, int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromMoveIntMayThrow, ConvertFromMoveIntMayThrow>, //
+ std::expected<int, int>&&>);
+
+// expected(U&&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<int, int>,
+ const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromCopyIntMayThrow, int>,
+ const int&>);
+
+// expected(const unexpected<OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<int, long>,
+ const std::unexpected<int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<int, ConvertFromCopyIntMayThrow>,
+ const std::unexpected<int>&>);
+
+// expected(unexpected<OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<int, long>,
+ std::unexpected<int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<int, ConvertFromMoveIntMayThrow>,
+ std::unexpected<int>&&>);
+
+// expected(in_place_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<int, int>,
+ std::in_place_t,
+ const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromCopyIntMayThrow, int>,
+ std::in_place_t,
+ const int&>);
+
+// expected(in_place_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromInitializerListNoexcept, int>,
+ std::in_place_t,
+ std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<ConvertFromInitializerListMayThrow, int>,
+ std::in_place_t,
+ std::initializer_list<int>>);
+
+// expected(unexpect_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<int, int>,
+ std::unexpect_t,
+ const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<int, ConvertFromCopyIntMayThrow>,
+ std::unexpect_t,
+ const int&>);
+
+// expected(unexpect_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<int, ConvertFromInitializerListNoexcept>,
+ std::unexpect_t,
+ std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<int, ConvertFromInitializerListMayThrow>,
+ std::unexpect_t,
+ std::initializer_list<int>>);
+
+// expected& operator=(const expected&)
+static_assert(std::is_nothrow_copy_assignable_v<std::expected<int, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<CopyConstructMayThrow, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<CopyAssignMayThrow, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<int, CopyConstructMayThrow>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<int, CopyAssignMayThrow>>);
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/or_else.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/or_else.mandates.verify.cpp
new file mode 100644
index 0000000000000..af1fa53307960
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/or_else.mandates.verify.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test the mandates
+// template<class F> constexpr auto or_else(F&& f) &;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+// template<class F> constexpr auto or_else(F&& f) const &;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+// template<class F> constexpr auto or_else(F&& f) &&;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+// template<class F> constexpr auto or_else(F&& f) const &&;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+#include <expected>
+#include <utility>
+
+struct NotSameAsInt {};
+
+int lval_return_not_std_expected(int&) { return 0; }
+int clval_return_not_std_expected(const int&) { return 0; }
+int rval_return_not_std_expected(int&&) { return 0; }
+int crval_return_not_std_expected(const int&&) { return 0; }
+
+std::expected<NotSameAsInt, int> lval_error_type_not_same_as_int(int&) { return {}; }
+std::expected<NotSameAsInt, int> clval_error_type_not_same_as_int(const int&) { return {}; }
+std::expected<NotSameAsInt, int> rval_error_type_not_same_as_int(int&&) { return {}; }
+std::expected<NotSameAsInt, int> crval_error_type_not_same_as_int(const int&&) { return {}; }
+
+// clang-format off
+void test() {
+ // Test & overload
+ {
+ // G is not a specialization of std::expected
+ {
+ std::expected<int, int> f1(std::unexpected<int>(1));
+ f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ std::expected<int, int> f1(std::unexpected<int>(1));
+ f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must have the same value_type as this expected}}
+ }
+ }
+
+ // Test const& overload
+ {
+ // G is not a specialization of std::expected
+ {
+ const std::expected<int, int> f1(std::unexpected<int>(1));
+ f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ const std::expected<int, int> f1(std::unexpected<int>(1));
+ f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must have the same value_type as this expected}}
+ }
+ }
+
+ // Test && overload
+ {
+ // G is not a specialization of std::expected
+ {
+ std::expected<int, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ std::expected<int, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}}
+ }
+ }
+
+ // Test const&& overload
+ {
+ // G is not a specialization of std::expected
+ {
+ const std::expected<int, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ const std::expected<int, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}}
+ }
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/transform_error.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/transform_error.mandates.verify.cpp
new file mode 100644
index 0000000000000..61374094b7adf
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/transform_error.mandates.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// Clang-18 fixed some spurious clang diagnostics. Once clang-18 is the
+// minimum required version these obsolete tests can be removed.
+// TODO(LLVM-20) remove spurious clang diagnostic tests.
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// With clang-cl, some warnings have a 'which is a Microsoft extension' suffix
+// which break the tests. But #102851 will turn it into an error, making the test pass.
+// However, upstream libcxx buildbots do not build clang from source while testing, so
+// this tests still expected to fail on these bots.
+//
+// TODO(LLVM 22): Remove '0-1' from 'expected-error-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}}}'
+// and remove 'expected-warning-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}, which is a Microsoft extension}}'
+// once LLVM 22 releases. See https://github.com/llvm/llvm-project/issues/104885.
+
+// Test the mandates
+
+// template<class F> constexpr auto transform_error(F&& f) &;
+// template<class F> constexpr auto transform_error(F&& f) const &;
+//
+// Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>
+// G is a valid template argument for unexpected ([expected.un.general]) and the declaration
+// G g(invoke(std::forward<F>(f), error())); is well-formed.
+
+// template<class F> constexpr auto transform_error(F&& f) &&;
+// template<class F> constexpr auto transform_error(F&& f) const &&;
+//
+// Let G be remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>.
+// G is a valid template argument for unexpected ([expected.un.general]) and the declaration
+// G g(invoke(std::forward<F>(f), std::move(error()))); is well-formed.
+
+#include <expected>
+#include <utility>
+
+static int val;
+
+template <class T>
+std::unexpected<int> return_unexpected(T) {
+ return std::unexpected<int>(1);
+}
+
+template <class T>
+int& return_no_object(T) {
+ return val;
+}
+
+// clang-format off
+void test() {
+
+ // Test & overload
+ {
+ std::expected<int, int> e;
+ e.transform_error(return_unexpected<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}[expected.object.general] A program that instantiates the definition of template expected<T, E> for {{.*}} is ill-formed.}}
+ // expected-error-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}}}
+
+ e.transform_error(return_no_object<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}[expected.object.general] A program that instantiates the definition of template expected<T, E> for {{.*}} is ill-formed.}}
+ // expected-warning-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}, which is a Microsoft extension}}
+ }
+
+ // Test const& overload
+ {
+ const std::expected<int, int> e;
+ e.transform_error(return_unexpected<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ e.transform_error(return_no_object<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ }
+
+ // Test && overload
+ {
+ std::expected<int, int> e;
+ std::move(e).transform_error(return_unexpected<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ std::move(e).transform_error(return_no_object<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ }
+
+ // Test const&& overload
+ {
+ const std::expected<int, int> e;
+ std::move(e).transform_error(return_unexpected<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ std::move(e).transform_error(return_no_object<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/value.observers.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/value.observers.verify.cpp
new file mode 100644
index 0000000000000..d2b62a9b6ab99
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/value.observers.verify.cpp
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test the mandates
+// constexpr T& value() & ;
+// constexpr const T& value() const &;
+// Mandates: is_copy_constructible_v<E> is true.
+
+// constexpr T&& value() &&;
+// constexpr const T&& value() const &&;
+// Mandates: is_copy_constructible_v<E> is true and is_constructible_v<E, decltype(std::move(error()))> is true.
+
+#include <expected>
+#include <utility>
+
+#include "MoveOnly.h"
+
+struct CopyConstructible {
+ constexpr CopyConstructible() = default;
+ constexpr CopyConstructible(const CopyConstructible&) = default;
+};
+
+struct CopyConstructibleButNotMoveConstructible {
+ constexpr CopyConstructibleButNotMoveConstructible() = default;
+ constexpr CopyConstructibleButNotMoveConstructible(const CopyConstructibleButNotMoveConstructible&) = default;
+ constexpr CopyConstructibleButNotMoveConstructible(CopyConstructibleButNotMoveConstructible&&) = delete;
+ constexpr CopyConstructibleButNotMoveConstructible(const CopyConstructibleButNotMoveConstructible&&) = delete;
+};
+
+struct CopyConstructibleAndMoveConstructible {
+ constexpr CopyConstructibleAndMoveConstructible() = default;
+ constexpr CopyConstructibleAndMoveConstructible(const CopyConstructibleAndMoveConstructible&) = default;
+ constexpr CopyConstructibleAndMoveConstructible(CopyConstructibleAndMoveConstructible&&) = default;
+};
+
+// clang-format off
+void test() {
+
+ // Test & overload
+ {
+ // is_copy_constructible_v<E> is true.
+ {
+ std::expected<int, CopyConstructible> e;
+ [[maybe_unused]] auto val = e.value();
+ }
+
+ // is_copy_constructible_v<E> is false.
+ {
+ std::expected<int, MoveOnly> e;
+ [[maybe_unused]] auto val = e.value();
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be copy constructible}}
+ }
+ }
+
+ // Test const& overload
+ {
+ // is_copy_constructible_v<E> is true.
+ {
+ const std::expected<int, CopyConstructible> e;
+ [[maybe_unused]] auto val = e.value();
+ }
+
+ // is_copy_constructible_v<E> is false.
+ {
+ const std::expected<int, MoveOnly> e;
+ [[maybe_unused]] auto val = e.value();
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be copy constructible}}
+ }
+ }
+
+ // Test && overload
+ {
+ // is_copy_constructible_v<E> is false.
+ {
+ std::expected<int, MoveOnly> e;
+ [[maybe_unused]] auto val = std::move(e).value();
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be both copy constructible and constructible from decltype(std::move(error()))}}
+ }
+
+ // is_copy_constructible_v<E> is true and is_constructible_v<E, decltype(std::move(error()))> is true.
+ {
+ std::expected<int, CopyConstructibleAndMoveConstructible> e;
+ [[maybe_unused]] auto val = std::move(e).value();
+ }
+
+ // is_copy_constructible_v<E> is true and is_constructible_v<E, decltype(std::move(error()))> is false.
+ {
+ std::expected<int, CopyConstructibleButNotMoveConstructible> e;
+ [[maybe_unused]] auto val = std::move(e).value();
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be both copy constructible and constructible from decltype(std::move(error()))}}
+ }
+ }
+
+ // Test const&& overload
+ {
+ // is_copy_constructible_v<E> is false.
+ {
+ const std::expected<int, MoveOnly> e;
+ [[maybe_unused]] auto val = std::move(e).value();
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be both copy constructible and constructible from decltype(std::move(error()))}}
+ }
+
+ // is_copy_constructible_v<E> is true and is_constructible_v<E, decltype(std::move(error()))> is true.
+ {
+ const std::expected<int, CopyConstructibleAndMoveConstructible> e;
+ [[maybe_unused]] auto val = std::move(e).value();
+ }
+
+ // is_copy_constructible_v<E> is true and is_constructible_v<E, decltype(std::move(error()))> is false.
+ {
+ const std::expected<int, CopyConstructibleButNotMoveConstructible> e;
+ [[maybe_unused]] auto val = std::move(e).value();
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be both copy constructible and constructible from decltype(std::move(error()))}}
+ }
+ }
+// These diagnostics happen when we try to construct bad_expected_access from the non copy-constructible error type.
+#if _LIBCPP_HAS_EXCEPTIONS
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+#endif
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.expected/value_or.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.expected/value_or.mandates.verify.cpp
new file mode 100644
index 0000000000000..5d26f36f35d38
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.expected/value_or.mandates.verify.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
+
+// Test the mandates
+// template<class U> constexpr T value_or(U&& v) const &;
+// Mandates: is_copy_constructible_v<T> is true and is_convertible_v<U, T> is true.
+
+// template<class U> constexpr T value_or(U&& v) &&;
+// Mandates: is_move_constructible_v<T> is true and is_convertible_v<U, T> is true.
+
+#include <expected>
+#include <utility>
+
+struct NonCopyable {
+ NonCopyable(int) {}
+ NonCopyable(const NonCopyable&) = delete;
+};
+
+struct NonMovable {
+ NonMovable(int) {}
+ NonMovable(NonMovable&&) = delete;
+};
+
+struct NotConvertibleFromInt {};
+
+void test() {
+ // const & overload
+ // !is_copy_constructible_v<T>,
+ {
+ const std::expected<NonCopyable, int> f1{5};
+ f1.value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NonCopyable, int>::value_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}value_type has to be copy constructible}}
+ }
+
+ // const & overload
+ // !is_convertible_v<U, T>
+ {
+ const std::expected<NotConvertibleFromInt, int> f1{std::in_place};
+ f1.value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NotConvertibleFromInt, int>::value_or<int>' requested here}}
+ //expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to value_type}}
+ }
+
+ // && overload
+ // !is_move_constructible_v<T>,
+ {
+ std::expected<NonMovable, int> f1{5};
+ std::move(f1).value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NonMovable, int>::value_or<int>' requested here}}
+ //expected-error-re@*:* {{static assertion failed {{.*}}value_type has to be move constructible}}
+ }
+
+ // && overload
+ // !is_convertible_v<U, T>
+ {
+ std::expected<NotConvertibleFromInt, int> f1{std::in_place};
+ std::move(f1).value_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<NotConvertibleFromInt, int>::value_or<int>' requested here}}
+ //expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to value_type}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/class.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/class.mandates.verify.cpp
new file mode 100644
index 0000000000000..f859ce0d53c27
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/class.mandates.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// A program that instantiates the definition of unexpected for a non-object type, an array type, a specialization of unexpected, or a cv-qualified type is ill-formed.
+
+#include <expected>
+
+
+
+template class std::unexpected<int[2]>; // expected-error-re@*:* {{static assertion failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<const int>; // expected-error-re@*:* {{static assertion failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<int&>; // expected-error-re@*:* {{static assertion failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<std::unexpected<int>>; // expected-error-re@*:* {{static assertion failed {{.*}}[expected.un.general]}}
+
+template class std::unexpected<volatile int>; // expected-error-re@*:* {{static assertion failed {{.*}}[expected.un.general]}}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.cpp
new file mode 100644
index 0000000000000..162ecd5e36fc9
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/noexcept.extension.compile.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// test libc++ noexcept extensions on operations of std::unexpected<E>
+
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../types.h"
+
+// unexpected(Error&&);
+static_assert(std::is_nothrow_constructible_v< //
+ std::unexpected<int>,
+ const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::unexpected<ConvertFromCopyIntMayThrow>,
+ const int&>);
+
+
+// unexpected(in_place_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::unexpected<int>,
+ std::in_place_t,
+ const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::unexpected<ConvertFromCopyIntMayThrow>,
+ std::in_place_t,
+ const int&>);
+
+// unexpected(in_place_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::unexpected<ConvertFromInitializerListNoexcept>,
+ std::in_place_t,
+ std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::unexpected<ConvertFromInitializerListMayThrow>,
+ std::in_place_t,
+ std::initializer_list<int>>);
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/swap.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/swap.mandates.verify.cpp
new file mode 100644
index 0000000000000..f87dff2db51f1
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.unexpected/swap.mandates.verify.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
+
+// Test the mandates
+// constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
+// Mandates: is_swappable_v<E> is true.
+
+#include <expected>
+
+struct Foo {};
+
+void swap(Foo&, Foo&) = delete;
+
+void test() {
+ std::unexpected<Foo> f1{Foo{}};
+ f1.swap(f1); // expected-note{{in instantiation of member function 'std::unexpected<Foo>::swap' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}unexpected::swap requires is_swappable_v<E> to be true}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/and_then.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/and_then.mandates.verify.cpp
new file mode 100644
index 0000000000000..e1a7ec5ff4d72
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/and_then.mandates.verify.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test the mandates
+// template<class F> constexpr auto and_then(F&& f) &;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+// template<class F> constexpr auto and_then(F&& f) const &;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+// template<class F> constexpr auto and_then(F&& f) &&;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+// template<class F> constexpr auto and_then(F&& f) const &&;
+// Mandates:
+// Let U be std::remove_cvref_t<std::invoke_result<F>>
+// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
+
+#include <expected>
+#include <utility>
+
+struct NotSameAsInt {};
+
+int lval_return_not_std_expected(void) { return 0; }
+int clval_return_not_std_expected(void) { return 0; }
+int rval_return_not_std_expected(void) { return 0; }
+int crval_return_not_std_expected(void) { return 0; }
+
+std::expected<int, NotSameAsInt> lval_error_type_not_same_as_int(void) { return {}; }
+std::expected<int, NotSameAsInt> clval_error_type_not_same_as_int(void) { return {}; }
+std::expected<int, NotSameAsInt> rval_error_type_not_same_as_int(void) { return {}; }
+std::expected<int, NotSameAsInt> crval_error_type_not_same_as_int(void) { return {}; }
+
+// clang-format off
+void test() {
+ // Test & overload
+ {
+ // U is not a specialization of std::expected
+ {
+ std::expected<void, int> f1;
+ f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ std::expected<void, int> f1;
+ f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must have the same error_type as this expected}}
+ }
+ }
+
+ // Test const& overload
+ {
+ // U is not a specialization of std::expected
+ {
+ const std::expected<void, int> f1;
+ f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ const std::expected<void, int> f1;
+ f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must have the same error_type as this expected}}
+ }
+ }
+
+ // Test && overload
+ {
+ // U is not a specialization of std::expected
+ {
+ std::expected<void, int> f1;
+ std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ std::expected<void, int> f1;
+ std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must have the same error_type as this expected}}
+ }
+ }
+
+ // Test const&& overload
+ {
+ // U is not a specialization of std::expected
+ {
+ const std::expected<void, int> f1;
+ std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<int (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ // expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
+ }
+
+ // !std::is_same_v<U:error_type, E>
+ {
+ const std::expected<void, int> f1;
+ std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::and_then<std::expected<int, NotSameAsInt> (&)()>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f() must have the same error_type as this expected}}
+ }
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/assert.deref.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/assert.deref.pass.cpp
new file mode 100644
index 0000000000000..6f1ba075b3245
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/assert.deref.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// constexpr void operator*() const noexcept;
+//
+// Preconditions: has_value() is true.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::expected<void, int> e{std::unexpect, 5};
+ TEST_LIBCPP_ASSERT_FAILURE(*e, "expected::operator* requires the expected to contain a value");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/assert.error.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/assert.error.pass.cpp
new file mode 100644
index 0000000000000..a1c92ff85f33a
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/assert.error.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+// constexpr const E& error() const & noexcept;
+// constexpr E& error() & noexcept;
+// constexpr E&& error() && noexcept;
+// constexpr const E&& error() const && noexcept;
+//
+// Preconditions: has_value() is false.
+
+#include <expected>
+#include <utility>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ std::expected<void, int> e{std::in_place};
+ TEST_LIBCPP_ASSERT_FAILURE(e.error(), "expected::error requires the expected to contain an error");
+ TEST_LIBCPP_ASSERT_FAILURE(std::as_const(e).error(), "expected::error requires the expected to contain an error");
+ TEST_LIBCPP_ASSERT_FAILURE(std::move(e).error(), "expected::error requires the expected to contain an error");
+ TEST_LIBCPP_ASSERT_FAILURE(std::move(std::as_const(e)).error(), "expected::error requires the expected to contain an error");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/error_or.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/error_or.mandates.verify.cpp
new file mode 100644
index 0000000000000..21f93b8285d2e
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/error_or.mandates.verify.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
+
+// Test the mandates
+// template<class G = E> constexpr E error_or(G&&) const &;
+// Mandates: is_copy_constructible_v<G> is true and is_convertible_v<U, E> is true.
+
+// template<class G = E> constexpr E error_or(G&&) &&;
+// Mandates: is_move_constructible_v<G> is true and is_convertible_v<U, E> is true.
+
+#include <expected>
+#include <utility>
+
+struct NonCopyable {
+ NonCopyable(int) {}
+ NonCopyable(const NonCopyable&) = delete;
+};
+
+struct NonMovable {
+ NonMovable(int) {}
+ NonMovable(NonMovable&&) = delete;
+};
+
+struct NotConvertibleFromInt {};
+
+// clang-format off
+void test() {
+ // const & overload
+ // !is_copy_constructible_v<G>,
+ {
+ const std::expected<void, NonCopyable> f1(std::unexpect, 0);
+ f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonCopyable>::error_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be copy constructible}}
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+ }
+
+ // const & overload
+ // !is_convertible_v<U, T>
+ {
+ const std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
+ f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
+ // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
+ }
+
+ // && overload
+ // !is_move_constructible_v<T>,
+ {
+ std::expected<void, NonMovable> f1(std::unexpect, 0);
+ std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NonMovable>::error_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be move constructible}}
+ // expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
+ }
+
+ // && overload
+ // !is_convertible_v<U, T>
+ {
+ std::expected<void, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
+ std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<void, NotConvertibleFromInt>::error_or<int>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
+ // expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/no_unique_address.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/no_unique_address.compile.pass.cpp
new file mode 100644
index 0000000000000..c4aae3356a9a2
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/no_unique_address.compile.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// clang-cl and cl currently don't support [[no_unique_address]]
+// XFAIL: msvc
+
+// test [[no_unique_address]] is applied to the union
+// In particular, we ensure that we reuse tail padding in the T
+// to store the discriminator whenever we can.
+
+#include <__type_traits/datasizeof.h>
+#include <expected>
+#include <optional>
+#include <memory>
+
+struct Empty {};
+
+struct A {
+ int x_;
+ int y_;
+};
+
+struct B : public A {
+ int z_;
+ short z2_;
+ virtual ~B() = default;
+};
+
+struct BoolWithPadding {
+ explicit operator bool() { return b; }
+
+private:
+ alignas(1024) bool b = false;
+};
+
+static_assert(sizeof(std::expected<void, Empty>) == sizeof(bool));
+static_assert(sizeof(std::expected<void, A>) == 2 * sizeof(int) + alignof(std::expected<void, A>));
+static_assert(sizeof(std::expected<void, B>) == sizeof(B));
+
+// Check that `expected`'s datasize is large enough for the parameter type(s).
+static_assert(sizeof(std::expected<void, BoolWithPadding>) ==
+ std::__datasizeof_v<std::expected<void, BoolWithPadding>>);
+
+// In this case, there should be tail padding in the `expected` because `A`
+// itself does _not_ have tail padding.
+static_assert(sizeof(std::expected<void, A>) > std::__datasizeof_v<std::expected<void, A>>);
+
+// Test with some real types.
+static_assert(sizeof(std::expected<void, std::optional<int>>) == 8);
+static_assert(std::__datasizeof_v<std::expected<void, std::optional<int>>> == 8);
+
+static_assert(sizeof(std::expected<void, int>) == 8);
+static_assert(std::__datasizeof_v<std::expected<void, int>> == 5);
+
+// clang-format off
+static_assert(std::__datasizeof_v<int> == 4);
+static_assert(std::__datasizeof_v<std::expected<void, int>> == 5);
+static_assert(std::__datasizeof_v<std::expected<void, std::expected<void, int>>> == 8);
+static_assert(std::__datasizeof_v<std::expected<void, std::expected<void, std::expected<void, int>>>> == 9);
+static_assert(std::__datasizeof_v<std::expected<void, std::expected<void, std::expected<void, std::expected<void, int>>>>> == 12);
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/noexcept.extension.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/noexcept.extension.compile.pass.cpp
new file mode 100644
index 0000000000000..2d5cee942dfd4
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/noexcept.extension.compile.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
+
+// test libc++ noexcept extensions on operations of std::expected<void, E>
+
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "../types.h"
+
+// expected(const expected&)
+static_assert(std::is_nothrow_copy_constructible_v<std::expected<void, int>>);
+static_assert(!std::is_nothrow_copy_constructible_v<std::expected<void, CopyMayThrow>>);
+
+
+// expected(const expected<OtherT, OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<void, long>,
+ const std::expected<void, int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<void, ConvertFromCopyIntMayThrow>,
+ const std::expected<void, int>&>);
+
+
+// expected(expected<OtherT, OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<void, long>,
+ std::expected<void, int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<void, ConvertFromMoveIntMayThrow>,
+ std::expected<void, int>&&>);
+
+// expected(const unexpected<OtherE>&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<void, long>,
+ const std::unexpected<int>&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<void, ConvertFromCopyIntMayThrow>,
+ const std::unexpected<int>&>);
+
+// expected(unexpected<OtherE>&&)
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<void, long>,
+ std::unexpected<int>&&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<void, ConvertFromMoveIntMayThrow>,
+ std::unexpected<int>&&>);
+
+
+// expected(unexpect_t, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<void, int>,
+ std::unexpect_t,
+ const int&>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<void, ConvertFromCopyIntMayThrow>,
+ std::unexpect_t,
+ const int&>);
+
+// expected(unexpect_t, initializer_list<U>, _Args&&...);
+static_assert(std::is_nothrow_constructible_v< //
+ std::expected<void, ConvertFromInitializerListNoexcept>,
+ std::unexpect_t,
+ std::initializer_list<int>>);
+static_assert(!std::is_nothrow_constructible_v< //
+ std::expected<void, ConvertFromInitializerListMayThrow>,
+ std::unexpect_t,
+ std::initializer_list<int>>);
+
+// expected& operator=(const expected&)
+static_assert(std::is_nothrow_copy_assignable_v<std::expected<void, int>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<void, CopyConstructMayThrow>>);
+static_assert(!std::is_nothrow_copy_assignable_v<std::expected<void, CopyAssignMayThrow>>);
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/or_else.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/or_else.mandates.verify.cpp
new file mode 100644
index 0000000000000..3046d09d6af55
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/or_else.mandates.verify.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test the mandates
+// template<class F> constexpr auto or_else(F&& f) &;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+// template<class F> constexpr auto or_else(F&& f) const &;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+// template<class F> constexpr auto or_else(F&& f) &&;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+// template<class F> constexpr auto or_else(F&& f) const &&;
+// Mandates:
+// Let G be std::remove_cvref_t<std::invoke_result<F, decltype(error())>>
+// G is a specialization of std::expected and std::is_same_v<G:value_type, T> is true
+
+#include <expected>
+#include <utility>
+
+struct NotSameAsInt {};
+
+int lval_return_not_std_expected(int&) { return 0; }
+int clval_return_not_std_expected(const int&) { return 0; }
+int rval_return_not_std_expected(int&&) { return 0; }
+int crval_return_not_std_expected(const int&&) { return 0; }
+
+std::expected<NotSameAsInt, int> lval_error_type_not_same_as_int(int&) { return {}; }
+std::expected<NotSameAsInt, int> clval_error_type_not_same_as_int(const int&) { return {}; }
+std::expected<NotSameAsInt, int> rval_error_type_not_same_as_int(int&&) { return {}; }
+std::expected<NotSameAsInt, int> crval_error_type_not_same_as_int(const int&&) { return {}; }
+
+// clang-format off
+void test() {
+ // Test & overload
+ {
+ // G is not a specialization of std::expected
+ {
+ std::expected<void, int> f1(std::unexpected<int>(1));
+ f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ std::expected<void, int> f1(std::unexpected<int>(1));
+ f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must have the same value_type as this expected}}
+ }
+ }
+
+ // Test const& overload
+ {
+ // G is not a specialization of std::expected
+ {
+ const std::expected<void, int> f1(std::unexpected<int>(1));
+ f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(const int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ const std::expected<void, int> f1(std::unexpected<int>(1));
+ f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must have the same value_type as this expected}}
+ }
+ }
+
+ // Test && overload
+ {
+ // G is not a specialization of std::expected
+ {
+ std::expected<void, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ std::expected<void, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}}
+ }
+ }
+
+ // Test const&& overload
+ {
+ // G is not a specialization of std::expected
+ {
+ const std::expected<void, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<int (&)(const int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
+ }
+
+ // !std::is_same_v<G:value_type, T>
+ {
+ const std::expected<void, int> f1(std::unexpected<int>(1));
+ std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<void, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &&)>' requested here}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}}
+ }
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/transform_error.mandates.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/transform_error.mandates.verify.cpp
new file mode 100644
index 0000000000000..16233cd90d219
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/transform_error.mandates.verify.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Clang-18 fixed some spurious clang diagnostics. Once clang-18 is the
+// minumum required version these obsolete tests can be removed.
+// TODO(LLVM-20) remove spurious clang diagnostic tests.
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// With clang-cl, some warnings have a 'which is a Microsoft extension' suffix
+// which break the tests. But #102851 will turn it into an error, making the test pass.
+// However, upstream libcxx buildbots do not build clang from source while testing, so
+// this tests still expected to fail on these bots.
+//
+// TODO(LLVM 22): Remove '0-1' from 'expected-error-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}}}'
+// and remove 'expected-warning-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}, which is a Microsoft extension}}'
+// and remove 'expected-error-re@*:* 0-1 {{call to deleted constructor of {{.*}}}}'
+// once LLVM 22 releases. See See https://github.com/llvm/llvm-project/issues/104885.
+
+// Test the mandates
+
+// template<class F> constexpr auto transform_error(F&& f) &;
+// template<class F> constexpr auto transform_error(F&& f) const &;
+//
+// Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>
+// G is a valid template argument for unexpected ([expected.un.general]) and the declaration
+// G g(invoke(std::forward<F>(f), error())); is well-formed.
+
+// template<class F> constexpr auto transform_error(F&& f) &&;
+// template<class F> constexpr auto transform_error(F&& f) const &&;
+//
+// Let G be remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>.
+// G is a valid template argument for unexpected ([expected.un.general]) and the declaration
+// G g(invoke(std::forward<F>(f), std::move(error()))); is well-formed.
+
+#include <expected>
+#include <utility>
+
+static int val;
+
+template <class T>
+std::unexpected<int> return_unexpected(T) {
+ return std::unexpected<int>(1);
+}
+
+template <class T>
+int& return_no_object(T) {
+ return val;
+}
+
+// clang-format off
+void test() {
+
+ // Test & overload
+ {
+ std::expected<void, int> e;
+ e.transform_error(return_unexpected<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}A program that instantiates expected<T, E> with a E that is not a valid argument for unexpected<E> is ill-formed}}
+ // expected-error-re@*:* 0-1 {{call to deleted constructor of {{.*}}}}
+ // expected-error-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}}}
+
+ e.transform_error(return_no_object<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}A program that instantiates expected<T, E> with a E that is not a valid argument for unexpected<E> is ill-formed}}
+ // expected-warning-re@*:* 0-1 {{union member {{.*}} has reference type {{.*}}, which is a Microsoft extension}}
+ }
+
+ // Test const& overload
+ {
+ const std::expected<void, int> e;
+ e.transform_error(return_unexpected<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ e.transform_error(return_no_object<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ // expected-error-re@*:* 0-1 {{call to deleted constructor of {{.*}}}}
+ }
+
+ // Test && overload
+ {
+ std::expected<void, int> e;
+ std::move(e).transform_error(return_unexpected<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ std::move(e).transform_error(return_no_object<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ }
+
+ // Test const&& overload
+ {
+ const std::expected<void, int> e;
+ std::move(e).transform_error(return_unexpected<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ std::move(e).transform_error(return_no_object<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}}
+ // expected-error-re@*:* 0-1 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}}
+ }
+}
+// clang-format on
diff --git a/libcxx/test/libcxx-03/utilities/expected/expected.void/value.lwg3940.verify.cpp b/libcxx/test/libcxx-03/utilities/expected/expected.void/value.lwg3940.verify.cpp
new file mode 100644
index 0000000000000..253ef1d5483b8
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/expected.void/value.lwg3940.verify.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, c++20
+// UNSUPPORTED: no-rtti
+// UNSUPPORTED: no-exceptions
+
+// constexpr void value() const &;
+// Mandates: is_copy_constructible_v<E> is true.
+
+// constexpr void value() &&;
+// Mandates: is_copy_constructible_v<E> is true and is_move_constructible_v<E> is true.
+
+#include <expected>
+
+#include "MoveOnly.h"
+
+struct CopyOnly {
+ CopyOnly() = default;
+ CopyOnly(const CopyOnly&) = default;
+ CopyOnly(CopyOnly&&) = delete;
+};
+
+void test() {
+ // MoveOnly type as error_type
+ std::expected<void, MoveOnly> e(std::unexpect, 5);
+
+ e.value(); // expected-note {{in instantiation of member function 'std::expected<void, MoveOnly>::value' requested here}}
+ // expected-error@*:* {{static assertion failed due to requirement 'is_copy_constructible_v<MoveOnly>'}}
+ // expected-error@*:* {{call to deleted constructor of 'MoveOnly'}}
+
+ std::move(e)
+ .value(); // expected-note {{in instantiation of member function 'std::expected<void, MoveOnly>::value' requested here}}
+ // expected-error@*:* {{static assertion failed due to requirement 'is_copy_constructible_v<MoveOnly>'}}
+
+ // CopyOnly type as error_type
+ std::expected<void, CopyOnly> e2(std::unexpect);
+ // expected-error@*:* {{call to deleted constructor of 'CopyOnly'}}
+
+ e2.value();
+
+ std::move(e2)
+ .value(); // expected-note {{in instantiation of member function 'std::expected<void, CopyOnly>::value' requested here}}
+ // expected-error@*:* {{static assertion failed due to requirement 'is_move_constructible_v<CopyOnly>'}}
+ // expected-error@*:* {{call to deleted constructor of 'CopyOnly'}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/expected/types.h b/libcxx/test/libcxx-03/utilities/expected/types.h
new file mode 100644
index 0000000000000..52b4e6e6c1ba0
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expected/types.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_LIBCXX_UTILITIES_EXPECTED_TYPES_H
+#define TEST_LIBCXX_UTILITIES_EXPECTED_TYPES_H
+
+#include <initializer_list>
+
+struct DefaultMayThrow {
+ DefaultMayThrow();
+};
+
+struct CopyMayThrow {
+ CopyMayThrow(const CopyMayThrow&);
+};
+
+struct ConvertFromCopyIntMayThrow {
+ ConvertFromCopyIntMayThrow(const int&);
+ ConvertFromCopyIntMayThrow(int&&) noexcept;
+};
+
+struct ConvertFromMoveIntMayThrow {
+ ConvertFromMoveIntMayThrow(const int&) noexcept;
+ ConvertFromMoveIntMayThrow(int&&);
+};
+
+struct ConvertFromInitializerListNoexcept {
+ ConvertFromInitializerListNoexcept(std::initializer_list<int>) noexcept;
+};
+
+struct ConvertFromInitializerListMayThrow {
+ ConvertFromInitializerListMayThrow(std::initializer_list<int>);
+};
+
+struct CopyConstructMayThrow {
+ CopyConstructMayThrow(const CopyConstructMayThrow&);
+ CopyConstructMayThrow& operator=(CopyConstructMayThrow const&) noexcept;
+};
+
+struct CopyAssignMayThrow {
+ CopyAssignMayThrow(const CopyAssignMayThrow&) noexcept;
+ CopyAssignMayThrow& operator=(CopyAssignMayThrow const&);
+};
+
+
+#endif // TEST_LIBCXX_UTILITIES_EXPECTED_TYPES_H
diff --git a/libcxx/test/libcxx-03/utilities/expol/policies.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/expol/policies.compile.pass.cpp
new file mode 100644
index 0000000000000..8217b948e4dc0
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/expol/policies.compile.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure we don't allow copying the execution policies in any way to avoid users relying on it.
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+#include <execution>
+#include <type_traits>
+
+#include "test_macros.h"
+
+static_assert(!std::is_default_constructible_v<std::execution::sequenced_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::sequenced_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::sequenced_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::sequenced_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::sequenced_policy>);
+
+static_assert(!std::is_default_constructible_v<std::execution::parallel_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::parallel_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::parallel_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::parallel_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::parallel_policy>);
+
+static_assert(!std::is_default_constructible_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::parallel_unsequenced_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::parallel_unsequenced_policy>);
+
+#if TEST_STD_VER >= 20
+static_assert(!std::is_default_constructible_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_copy_constructible_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_move_constructible_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_copy_assignable_v<std::execution::unsequenced_policy>);
+static_assert(!std::is_move_assignable_v<std::execution::unsequenced_policy>);
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/format/enable_insertable.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/format/enable_insertable.compile.pass.cpp
new file mode 100644
index 0000000000000..064d7cf720d85
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/enable_insertable.compile.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
+
+// <format>
+
+#include <format>
+#include <array>
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <map>
+#include <queue>
+#include <set>
+#include <span>
+#include <stack>
+#include <string>
+#include <string_view>
+
+#include "test_macros.h"
+
+template <class CharT>
+struct no_value_type {
+ using iterator = CharT*;
+ iterator end();
+ void insert(iterator, CharT*, CharT*);
+};
+
+template <class CharT>
+struct no_end {
+ using value_type = CharT;
+ using iterator = CharT*;
+ void insert(iterator, CharT*, CharT*);
+};
+
+template <class CharT>
+struct no_insert {
+ using value_type = CharT;
+ using iterator = CharT*;
+ iterator end();
+};
+
+template <class CharT>
+struct no_specialization {
+ using value_type = CharT;
+ using iterator = CharT*;
+ iterator end();
+ void insert(iterator, CharT*, CharT*);
+};
+
+template <class CharT>
+struct valid {
+ using value_type = CharT;
+ using iterator = CharT*;
+ iterator end();
+ void insert(iterator, CharT*, CharT*);
+};
+
+template <>
+inline constexpr bool std::__format::__enable_insertable<no_value_type<char>> = true;
+template <>
+inline constexpr bool std::__format::__enable_insertable<no_end<char>> = true;
+template <>
+inline constexpr bool std::__format::__enable_insertable<no_insert<char>> = true;
+template <>
+inline constexpr bool std::__format::__enable_insertable<valid<char>> = true;
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+template <>
+inline constexpr bool std::__format::__enable_insertable<no_value_type<wchar_t>> = true;
+template <>
+inline constexpr bool std::__format::__enable_insertable<no_end<wchar_t>> = true;
+template <>
+inline constexpr bool std::__format::__enable_insertable<no_insert<wchar_t>> = true;
+template <>
+inline constexpr bool std::__format::__enable_insertable<valid<wchar_t>> = true;
+#endif
+
+static_assert(!std::__format::__insertable<no_value_type<char>>);
+static_assert(!std::__format::__insertable<no_end<char>>);
+static_assert(!std::__format::__insertable<no_insert<char>>);
+static_assert(!std::__format::__insertable<no_specialization<char>>);
+static_assert(std::__format::__insertable<valid<char>>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__format::__insertable<no_value_type<wchar_t>>);
+static_assert(!std::__format::__insertable<no_end<wchar_t>>);
+static_assert(!std::__format::__insertable<no_insert<wchar_t>>);
+static_assert(!std::__format::__insertable<no_specialization<wchar_t>>);
+static_assert(std::__format::__insertable<valid<wchar_t>>);
+#endif
+
+template <>
+inline constexpr bool std::__format::__enable_insertable<valid<signed char>> = true;
+template <>
+inline constexpr bool std::__format::__enable_insertable<valid<unsigned char>> = true;
+
+static_assert(!std::__format::__insertable<valid<signed char>>);
+static_assert(!std::__format::__insertable<valid<unsigned char>>);
+
+static_assert(std::__format::__insertable<std::string>);
+static_assert(!std::__format::__insertable<std::string_view>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::__format::__insertable<std::wstring>);
+static_assert(!std::__format::__insertable<std::wstring_view>);
+#endif
+
+static_assert(!std::__format::__insertable<std::array<char, 1>>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__format::__insertable<std::array<wchar_t, 1>>);
+#endif
+
+static_assert(std::__format::__insertable<std::vector<char>>);
+static_assert(std::__format::__insertable<std::deque<char>>);
+static_assert(!std::__format::__insertable<std::forward_list<char>>);
+static_assert(std::__format::__insertable<std::list<char>>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::__format::__insertable<std::vector<wchar_t>>);
+static_assert(std::__format::__insertable<std::deque<wchar_t>>);
+static_assert(!std::__format::__insertable<std::forward_list<wchar_t>>);
+static_assert(std::__format::__insertable<std::list<wchar_t>>);
+#endif
+
+static_assert(!std::__format::__insertable<std::set<char>>);
+static_assert(!std::__format::__insertable<std::map<char, char>>);
+static_assert(!std::__format::__insertable<std::multiset<char>>);
+static_assert(!std::__format::__insertable<std::multimap<char, char>>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__format::__insertable<std::set<wchar_t>>);
+static_assert(!std::__format::__insertable<std::map<wchar_t, wchar_t>>);
+static_assert(!std::__format::__insertable<std::multiset<wchar_t>>);
+static_assert(!std::__format::__insertable<std::multimap<wchar_t, wchar_t>>);
+#endif
+
+static_assert(!std::__format::__insertable<std::stack<char>>);
+static_assert(!std::__format::__insertable<std::queue<char>>);
+static_assert(!std::__format::__insertable<std::priority_queue<char>>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__format::__insertable<std::stack<wchar_t>>);
+static_assert(!std::__format::__insertable<std::queue<wchar_t>>);
+static_assert(!std::__format::__insertable<std::priority_queue<wchar_t>>);
+#endif
+
+static_assert(!std::__format::__insertable<std::span<char>>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::__format::__insertable<std::span<wchar_t>>);
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp
new file mode 100644
index 0000000000000..8ecca81cdfe58
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/arg_t.compile.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
+
+// <format>
+
+// namespace __format { enum class __arg_t : uint8_t{...}; }
+
+#include <format>
+
+#include <cstdint>
+#include <type_traits>
+
+#include "test_macros.h"
+
+static_assert(std::is_same_v<std::underlying_type_t<std::__format::__arg_t>, std::uint8_t>);
+
+static_assert(std::uint8_t(std::__format::__arg_t::__none) == 0);
+static_assert(std::uint8_t(std::__format::__arg_t::__boolean) == 1);
+static_assert(std::uint8_t(std::__format::__arg_t::__char_type) == 2);
+static_assert(std::uint8_t(std::__format::__arg_t::__int) == 3);
+static_assert(std::uint8_t(std::__format::__arg_t::__long_long) == 4);
+static_assert(std::uint8_t(std::__format::__arg_t::__i128) == 5);
+static_assert(std::uint8_t(std::__format::__arg_t::__unsigned) == 6);
+static_assert(std::uint8_t(std::__format::__arg_t::__unsigned_long_long) == 7);
+static_assert(std::uint8_t(std::__format::__arg_t::__u128) == 8);
+static_assert(std::uint8_t(std::__format::__arg_t::__float) == 9);
+static_assert(std::uint8_t(std::__format::__arg_t::__double) == 10);
+static_assert(std::uint8_t(std::__format::__arg_t::__long_double) == 11);
+static_assert(std::uint8_t(std::__format::__arg_t::__const_char_type_ptr) == 12);
+static_assert(std::uint8_t(std::__format::__arg_t::__string_view) == 13);
+static_assert(std::uint8_t(std::__format::__arg_t::__ptr) == 14);
+static_assert(std::uint8_t(std::__format::__arg_t::__handle) == 15);
diff --git a/libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/assert.array.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/assert.array.pass.cpp
new file mode 100644
index 0000000000000..1e9b1d93eb06f
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.arguments/format.arg/assert.array.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// <format>
+
+// Formatting non-null-terminated character arrays.
+
+// REQUIRES: std-at-least-c++20, has-unix-headers, libcpp-hardening-mode={{extensive|debug}}
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <format>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ {
+ const char non_null_terminated[3]{'1', '2', '3'};
+ TEST_LIBCPP_ASSERT_FAILURE(std::format("{}", non_null_terminated), "formatting a non-null-terminated array");
+ }
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ {
+ const wchar_t non_null_terminated[3]{L'1', L'2', L'3'};
+ TEST_LIBCPP_ASSERT_FAILURE(std::format(L"{}", non_null_terminated), "formatting a non-null-terminated array");
+ }
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/format/format.formatter/format.context/types.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.formatter/format.context/types.compile.pass.cpp
new file mode 100644
index 0000000000000..cd06c509ffda2
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.formatter/format.context/types.compile.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <format>
+
+// Class typedefs:
+// template<class Out, class charT>
+// class basic_format_context {
+// public:
+// using iterator = Out
+// using char_type = charT;
+// template<class T> using formatter_type = formatter<T, charT>;
+// }
+//
+// Namespace std typedefs:
+// using format_context = basic_format_context<unspecified, char>;
+// using wformat_context = basic_format_context<unspecified, wchar_t>;
+
+#include <format>
+#include <iterator>
+#include <string_view>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class OutIt, class CharT>
+constexpr void test() {
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<OutIt, CharT>::iterator,
+ OutIt>);
+ static_assert(
+ std::is_same_v<
+ typename std::basic_format_context<OutIt, CharT>::char_type, CharT>);
+ static_assert(std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<bool>,
+ std::formatter<bool, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<CharT>,
+ std::formatter<CharT, CharT>>);
+ static_assert(std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<int>,
+ std::formatter<int, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<unsigned>,
+ std::formatter<unsigned, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<long long>,
+ std::formatter<long long, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<OutIt, CharT>::
+ template formatter_type<unsigned long long>,
+ std::formatter<unsigned long long, CharT>>);
+#ifndef TEST_HAS_NO_INT128
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<__int128_t>,
+ std::formatter<__int128_t, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<__uint128_t>,
+ std::formatter<__uint128_t, CharT>>);
+#endif
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<float>,
+ std::formatter<float, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<double>,
+ std::formatter<double, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<long double>,
+ std::formatter<long double, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<const CharT*>,
+ std::formatter<const CharT*, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<OutIt, CharT>::
+ template formatter_type<std::basic_string_view<CharT>>,
+ std::formatter<std::basic_string_view<CharT>, CharT>>);
+ static_assert(
+ std::is_same_v<typename std::basic_format_context<
+ OutIt, CharT>::template formatter_type<const void*>,
+ std::formatter<const void*, CharT>>);
+}
+
+constexpr void test() {
+ test<std::back_insert_iterator<std::__format::__output_buffer<char>>, char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<std::back_insert_iterator<std::__format::__output_buffer<wchar_t>>,
+ wchar_t>();
+#endif
+}
+
+template <class, class>
+constexpr bool is_basic_format_context_specialization = false;
+template <class It, class CharT>
+constexpr bool is_basic_format_context_specialization<std::basic_format_context<It, CharT>, CharT> = true;
+
+static_assert(is_basic_format_context_specialization<std::format_context, char>);
+static_assert(
+ std::is_same_v<
+ std::format_context,
+ std::basic_format_context<
+ std::back_insert_iterator<std::__format::__output_buffer<char>>,
+ char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(is_basic_format_context_specialization<std::wformat_context, wchar_t>);
+LIBCPP_STATIC_ASSERT(
+ std::is_same_v<
+ std::wformat_context,
+ std::basic_format_context<
+ std::back_insert_iterator< std::__format::__output_buffer<wchar_t>>,
+ wchar_t>>);
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/format/format.functions/ascii.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.functions/ascii.pass.cpp
new file mode 100644
index 0000000000000..818fc72fabecb
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.functions/ascii.pass.cpp
@@ -0,0 +1,161 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: GCC-ALWAYS_INLINE-FIXME
+
+// REQUIRES: libcpp-has-no-unicode
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// <format>
+
+// Tests Unicode is ignored and handled as ASCII.
+
+#include <format>
+#include <cassert>
+#include <vector>
+
+#include "test_macros.h"
+
+// Note the comment annotations are from the Unicode test
+static void test_char() {
+ //*** 1-byte code points ***
+ assert(std::format("{:*^3}", " ") == "* *");
+ assert(std::format("{:*^3}", "~") == "*~*");
+
+ //*** 2-byte code points ***
+ assert(std::format("{:*^4}", "\u00a1") == "*\u00a1*"); // INVERTED EXCLAMATION MARK
+ assert(std::format("{:*^4}", "\u07ff") == "*\u07ff*"); // NKO TAMAN SIGN
+
+ //*** 3-byte code points ***
+ assert(std::format("{:*^5}", "\u0800") == "*\u0800*"); // SAMARITAN LETTER ALAF
+ assert(std::format("{:*^5}", "\ufffd") == "*\ufffd*"); // REPLACEMENT CHARACTER
+
+ // 2 column ranges
+ assert(std::format("{:*^5}", "\u1100") == "*\u1100*"); // HANGUL CHOSEONG KIYEOK
+ assert(std::format("{:*^5}", "\u115f") == "*\u115f*"); // HANGUL CHOSEONG FILLER
+
+ assert(std::format("{:*^5}", "\u2329") == "*\u2329*"); // LEFT-POINTING ANGLE BRACKET
+ assert(std::format("{:*^5}", "\u232a") == "*\u232a*"); // RIGHT-POINTING ANGLE BRACKET
+
+ assert(std::format("{:*^5}", "\u2e80") == "*\u2e80*"); // CJK RADICAL REPEAT
+ assert(std::format("{:*^5}", "\u303e") == "*\u303e*"); // IDEOGRAPHIC VARIATION INDICATOR
+
+ assert(std::format("{:*^5}", "\u3040") == "*\u3040*"); // U+3041 HIRAGANA LETTER SMALL A
+ assert(std::format("{:*^5}", "\ua4cf") == "*\ua4cf*"); // U+A4D0 LISU LETTER BA
+
+ assert(std::format("{:*^5}", "\uac00") == "*\uac00*"); // <Hangul Syllable, First>
+ assert(std::format("{:*^5}", "\ud7a3") == "*\ud7a3*"); // Hangul Syllable Hih
+
+ assert(std::format("{:*^5}", "\uf900") == "*\uf900*"); // CJK COMPATIBILITY IDEOGRAPH-F900
+ assert(std::format("{:*^5}", "\ufaff") == "*\ufaff*"); // U+FB00 LATIN SMALL LIGATURE FF
+
+ assert(std::format("{:*^5}", "\ufe10") == "*\ufe10*"); // PRESENTATION FORM FOR VERTICAL COMMA
+ assert(std::format("{:*^5}", "\ufe19") == "*\ufe19*"); // PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
+
+ assert(std::format("{:*^5}", "\ufe30") == "*\ufe30*"); // PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+ assert(std::format("{:*^5}", "\ufe6f") == "*\ufe6f*"); // U+FE70 ARABIC FATHATAN ISOLATED FORM
+
+ assert(std::format("{:*^5}", "\uff00") == "*\uff00*"); // U+FF01 FULLWIDTH EXCLAMATION MARK
+ assert(std::format("{:*^5}", "\uff60") == "*\uff60*"); // FULLWIDTH RIGHT WHITE PARENTHESIS
+
+ assert(std::format("{:*^5}", "\uffe0") == "*\uffe0*"); // FULLWIDTH CENT SIGN
+ assert(std::format("{:*^5}", "\uffe6") == "*\uffe6*"); // FULLWIDTH WON SIGN
+
+ //*** 4-byte code points ***
+ assert(std::format("{:*^6}", "\U00010000") == "*\U00010000*"); // LINEAR B SYLLABLE B008 A
+ assert(std::format("{:*^6}", "\U0010FFFF") == "*\U0010FFFF*"); // Undefined Character
+
+ // 2 column ranges
+ assert(std::format("{:*^6}", "\U0001f300") == "*\U0001f300*"); // CYCLONE
+ assert(std::format("{:*^6}", "\U0001f64f") == "*\U0001f64f*"); // PERSON WITH FOLDED HANDS
+ assert(std::format("{:*^6}", "\U0001f900") == "*\U0001f900*"); // CIRCLED CROSS FORMEE WITH FOUR DOTS
+ assert(std::format("{:*^6}", "\U0001f9ff") == "*\U0001f9ff*"); // NAZAR AMULET
+ assert(std::format("{:*^6}", "\U00020000") == "*\U00020000*"); // <CJK Ideograph Extension B, First>
+ assert(std::format("{:*^6}", "\U0002fffd") == "*\U0002fffd*"); // Undefined Character
+ assert(std::format("{:*^6}", "\U00030000") == "*\U00030000*"); // <CJK Ideograph Extension G, First>
+ assert(std::format("{:*^6}", "\U0003fffd") == "*\U0003fffd*"); // Undefined Character
+}
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+// Note the comment annotations are from the Unicode test
+static void test_wchar_t() {
+ if constexpr (sizeof(wchar_t) == 2) {
+ // TODO FMT Add these tests.
+ } else {
+ //*** 1-byte code points ***
+ assert(std::format(L"{:*^3}", L" ") == L"* *");
+ assert(std::format(L"{:*^3}", L"~") == L"*~*");
+
+ //*** 2-byte code points ***
+ assert(std::format(L"{:*^3}", L"\u00a1") == L"*\u00a1*"); // INVERTED EXCLAMATION MARK
+ assert(std::format(L"{:*^3}", L"\u07ff") == L"*\u07ff*"); // NKO TAMAN SIGN
+
+ //*** 3-byte code points ***
+ assert(std::format(L"{:*^3}", L"\u0800") == L"*\u0800*"); // SAMARITAN LETTER ALAF
+ assert(std::format(L"{:*^3}", L"\ufffd") == L"*\ufffd*"); // REPLACEMENT CHARACTER
+
+ // 2 column ranges
+ assert(std::format(L"{:*^3}", L"\u1100") == L"*\u1100*"); // HANGUL CHOSEONG KIYEOK
+ assert(std::format(L"{:*^3}", L"\u115f") == L"*\u115f*"); // HANGUL CHOSEONG FILLER
+
+ assert(std::format(L"{:*^3}", L"\u2329") == L"*\u2329*"); // LEFT-POINTING ANGLE BRACKET
+ assert(std::format(L"{:*^3}", L"\u232a") == L"*\u232a*"); // RIGHT-POINTING ANGLE BRACKET
+
+ assert(std::format(L"{:*^3}", L"\u2e80") == L"*\u2e80*"); // CJK RADICAL REPEAT
+ assert(std::format(L"{:*^3}", L"\u303e") == L"*\u303e*"); // IDEOGRAPHIC VARIATION INDICATOR
+
+ assert(std::format(L"{:*^3}", L"\u3040") == L"*\u3040*"); // U+3041 HIRAGANA LETTER SMALL A
+ assert(std::format(L"{:*^3}", L"\ua4cf") == L"*\ua4cf*"); // U+A4D0 LISU LETTER BA
+
+ assert(std::format(L"{:*^3}", L"\uac00") == L"*\uac00*"); // <Hangul Syllable, First>
+ assert(std::format(L"{:*^3}", L"\ud7a3") == L"*\ud7a3*"); // Hangul Syllable Hih
+
+ assert(std::format(L"{:*^3}", L"\uf900") == L"*\uf900*"); // CJK COMPATIBILITY IDEOGRAPH-F900
+ assert(std::format(L"{:*^3}", L"\ufaff") == L"*\ufaff*"); // U+FB00 LATIN SMALL LIGATURE FF
+
+ assert(std::format(L"{:*^3}", L"\ufe10") == L"*\ufe10*"); // PRESENTATION FORM FOR VERTICAL COMMA
+ assert(std::format(L"{:*^3}", L"\ufe19") == L"*\ufe19*"); // PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
+
+ assert(std::format(L"{:*^3}", L"\ufe30") == L"*\ufe30*"); // PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+ assert(std::format(L"{:*^3}", L"\ufe6f") == L"*\ufe6f*"); // U+FE70 ARABIC FATHATAN ISOLATED FORM
+
+ assert(std::format(L"{:*^3}", L"\uff00") == L"*\uff00*"); // U+FF01 FULLWIDTH EXCLAMATION MARK
+ assert(std::format(L"{:*^3}", L"\uff60") == L"*\uff60*"); // FULLWIDTH RIGHT WHITE PARENTHESIS
+
+ assert(std::format(L"{:*^3}", L"\uffe0") == L"*\uffe0*"); // FULLWIDTH CENT SIGN
+ assert(std::format(L"{:*^3}", L"\uffe6") == L"*\uffe6*"); // FULLWIDTH WON SIGN
+
+ //*** 4-byte code points ***
+ assert(std::format(L"{:*^3}", L"\U00010000") == L"*\U00010000*"); // LINEAR B SYLLABLE B008 A
+ assert(std::format(L"{:*^3}", L"\U0010FFFF") == L"*\U0010FFFF*"); // Undefined Character
+
+ // 2 column ranges
+ assert(std::format(L"{:*^3}", L"\U0001f300") == L"*\U0001f300*"); // CYCLONE
+ assert(std::format(L"{:*^3}", L"\U0001f64f") == L"*\U0001f64f*"); // PERSON WITH FOLDED HANDS
+ assert(std::format(L"{:*^3}", L"\U0001f900") == L"*\U0001f900*"); // CIRCLED CROSS FORMEE WITH FOUR DOTS
+ assert(std::format(L"{:*^3}", L"\U0001f9ff") == L"*\U0001f9ff*"); // NAZAR AMULET
+ assert(std::format(L"{:*^3}", L"\U00020000") == L"*\U00020000*"); // <CJK Ideograph Extension B, First>
+ assert(std::format(L"{:*^3}", L"\U0002fffd") == L"*\U0002fffd*"); // Undefined Character
+ assert(std::format(L"{:*^3}", L"\U00030000") == L"*\U00030000*"); // <CJK Ideograph Extension G, First>
+ assert(std::format(L"{:*^3}", L"\U0003fffd") == L"*\U0003fffd*"); // Undefined Character
+ }
+}
+#endif
+
+int main(int, char**) {
+ test_char();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_wchar_t();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/format/format.functions/escaped_output.ascii.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.functions/escaped_output.ascii.pass.cpp
new file mode 100644
index 0000000000000..7d1cce5db8337
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.functions/escaped_output.ascii.pass.cpp
@@ -0,0 +1,352 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: GCC-ALWAYS_INLINE-FIXME
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// REQUIRES: libcpp-has-no-unicode
+
+// <format>
+
+// This test the debug string type for the formatter specializations for char
+// and string types. This tests ASCII strings, the tests assume every char32_t value is valid ASCII.
+
+#include <cassert>
+#include <concepts>
+#include <iterator>
+#include <list>
+#include <vector>
+
+#include "test_macros.h"
+#include "make_string.h"
+#include "test_format_string.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
+
+#ifndef TEST_HAS_NO_LOCALIZATION
+# include <iostream>
+#endif
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+auto test_format = []<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_WRITE_CONCATENATED(
+ "\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
+ }
+#ifndef TEST_HAS_NO_LOCALIZATION
+ {
+ std::basic_string<CharT> out = std::format(std::locale(), fmt, std::forward<Args>(args)...);
+ assert(out == expected);
+ }
+#endif // TEST_HAS_NO_LOCALIZATION
+};
+
+auto test_format_to =
+ []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ {
+ std::basic_string<CharT> out(expected.size(), CharT(' '));
+ auto it = std::format_to(out.begin(), fmt, std::forward<Args>(args)...);
+ assert(it == out.end());
+ assert(out == expected);
+ }
+#ifndef TEST_HAS_NO_LOCALIZATION
+ {
+ std::basic_string<CharT> out(expected.size(), CharT(' '));
+ auto it = std::format_to(out.begin(), std::locale(), fmt, std::forward<Args>(args)...);
+ assert(it == out.end());
+ assert(out == expected);
+ }
+#endif // TEST_HAS_NO_LOCALIZATION
+ {
+ std::list<CharT> out;
+ std::format_to(std::back_inserter(out), fmt, std::forward<Args>(args)...);
+ assert(std::equal(out.begin(), out.end(), expected.begin(), expected.end()));
+ }
+ {
+ std::vector<CharT> out;
+ std::format_to(std::back_inserter(out), fmt, std::forward<Args>(args)...);
+ assert(std::equal(out.begin(), out.end(), expected.begin(), expected.end()));
+ }
+ {
+ assert(expected.size() < 4096 && "Update the size of the buffer.");
+ CharT out[4096];
+ CharT* it = std::format_to(out, fmt, std::forward<Args>(args)...);
+ assert(std::distance(out, it) == int(expected.size()));
+ // Convert to std::string since output contains '\0' for boolean tests.
+ assert(std::basic_string<CharT>(out, it) == expected);
+ }
+ };
+
+auto test_formatted_size =
+ []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ {
+ std::size_t size = std::formatted_size(fmt, std::forward<Args>(args)...);
+ assert(size == expected.size());
+ }
+#ifndef TEST_HAS_NO_LOCALIZATION
+ {
+ std::size_t size = std::formatted_size(std::locale(), fmt, std::forward<Args>(args)...);
+ assert(size == expected.size());
+ }
+#endif // TEST_HAS_NO_LOCALIZATION
+ };
+
+auto test_format_to_n =
+ []<class CharT, class... Args>(
+ std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
+ {
+ std::size_t n = expected.size();
+ std::basic_string<CharT> out(n, CharT(' '));
+ std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...);
+ assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));
+ assert(result.out == out.end());
+ assert(out == expected);
+ }
+#ifndef TEST_HAS_NO_LOCALIZATION
+ {
+ std::size_t n = expected.size();
+ std::basic_string<CharT> out(n, CharT(' '));
+ std::format_to_n_result result =
+ std::format_to_n(out.begin(), n, std::locale(), fmt, std::forward<Args>(args)...);
+ assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));
+ assert(result.out == out.end());
+ assert(out == expected);
+ }
+#endif // TEST_HAS_NO_LOCALIZATION
+ {
+ std::ptrdiff_t n = 0;
+ std::basic_string<CharT> out;
+ std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...);
+ assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));
+ assert(result.out == out.end());
+ assert(out.empty());
+ }
+ {
+ std::ptrdiff_t n = expected.size() / 2;
+ std::basic_string<CharT> out(n, CharT(' '));
+ std::format_to_n_result result = std::format_to_n(out.begin(), n, fmt, std::forward<Args>(args)...);
+ assert(result.size == static_cast<std::ptrdiff_t>(expected.size()));
+ assert(result.out == out.end());
+ assert(out == expected.substr(0, n));
+ }
+ };
+
+template <class CharT>
+void test_char() {
+ // *** P2286 examples ***
+ test_format(SV("['\\'', '\"']"), SV("[{:?}, {:?}]"), CharT('\''), CharT('"'));
+
+ // *** Special cases ***
+ test_format(SV("'\\t'"), SV("{:?}"), CharT('\t'));
+ test_format(SV("'\\n'"), SV("{:?}"), CharT('\n'));
+ test_format(SV("'\\r'"), SV("{:?}"), CharT('\r'));
+ test_format(SV("'\\\\'"), SV("{:?}"), CharT('\\'));
+
+ test_format(SV("'\\\''"), SV("{:?}"), CharT('\''));
+ test_format(SV("'\"'"), SV("{:?}"), CharT('"')); // only special for string
+
+ test_format(SV("' '"), SV("{:?}"), CharT(' '));
+
+ // *** Printable ***
+ test_format(SV("'a'"), SV("{:?}"), CharT('a'));
+ test_format(SV("'b'"), SV("{:?}"), CharT('b'));
+ test_format(SV("'c'"), SV("{:?}"), CharT('c'));
+
+ // *** Non-printable ***
+
+ // Control
+ test_format(SV("'\\u{0}'"), SV("{:?}"), CharT('\0'));
+ test_format(SV("'\\u{1f}'"), SV("{:?}"), CharT('\x1f'));
+
+ // Ill-formed
+ if constexpr (sizeof(CharT) == 1)
+ test_format(SV("'\x80'"), SV("{:?}"), CharT('\x80'));
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ if constexpr (sizeof(CharT) > 1) {
+ using V = std::basic_string_view<CharT>;
+
+ // Unicode fitting in a 16-bit wchar_t
+
+ // *** Non-printable ***
+
+ // Space_Separator
+ test_format(V{L"'\xa0'"}, L"{:?}", L'\xa0'); // NO-BREAK SPACE
+ test_format(V{L"'\x3000'"}, L"{:?}", L'\x3000'); // IDEOGRAPHIC SPACE
+
+ // Line_Separator
+ test_format(V{L"'\x2028'"}, L"{:?}", L'\x2028'); // LINE SEPARATOR
+
+ // Paragraph_Separator
+ test_format(V{L"'\x2029'"}, L"{:?}", L'\x2029'); // PARAGRAPH SEPARATOR
+
+ // Format
+ test_format(V{L"'\xad'"}, L"{:?}", L'\xad'); // SOFT HYPHEN
+ test_format(V{L"'\x600'"}, L"{:?}", L'\x600'); // ARABIC NUMBER SIGN
+ test_format(V{L"'\xfeff'"}, L"{:?}", L'\xfeff'); // ZERO WIDTH NO-BREAK SPACE
+
+ if constexpr (sizeof(CharT) == 2) {
+ // Incomplete surrogate pair in UTF-16
+ test_format(V{L"'\xd800'"}, L"{:?}", L'\xd800'); // <surrogate-D800>
+ test_format(V{L"'\xdfff'"}, L"{:?}", L'\xdfff'); // <surrogate-DFFF>
+ } else {
+ test_format(V{L"'\xd800'"}, L"{:?}", L'\xd800'); // <surrogate-D800>
+ test_format(V{L"'\xdfff'"}, L"{:?}", L'\xdfff'); // <surrogate-DFFF>
+ }
+
+ // Private_Use
+ test_format(V{L"'\xe000'"}, L"{:?}", L'\xe000'); // <private-use-E000>
+ test_format(V{L"'\xf8ff'"}, L"{:?}", L'\xf8ff'); // <private-use-F8FF>
+
+ // Unassigned
+ test_format(V{L"'\x378'"}, L"{:?}", L'\x378'); // <reserved-0378>
+ test_format(V{L"'\x1774'"}, L"{:?}", L'\x1774'); // <reserved-1774>
+ test_format(V{L"'\xffff'"}, L"{:?}", L'\xffff'); // <noncharacter-FFFF>
+
+ // Grapheme Extended
+ test_format(V{L"'\x300'"}, L"{:?}", L'\x300'); // COMBINING GRAVE ACCENT
+ test_format(V{L"'\xfe20'"}, L"{:?}", L'\xfe20'); // VARIATION SELECTOR-1
+ }
+# ifndef TEST_SHORT_WCHAR
+ if constexpr (sizeof(CharT) > 2) {
+ static_assert(sizeof(CharT) == 4, "add support for unexpected size");
+ // Unicode fitting in a 32-bit wchar_t
+
+ constexpr wchar_t x = 0x1ffff;
+ constexpr std::uint32_t y = 0x1ffff;
+ static_assert(x == y);
+
+ using V = std::basic_string_view<CharT>;
+
+ // *** Non-printable ***
+ // Format
+ test_format(V{L"'\x110bd'"}, L"{:?}", L'\x110bd'); // KAITHI NUMBER SIGN
+ test_format(V{L"'\xe007f'"}, L"{:?}", L'\xe007f'); // CANCEL TAG
+
+ // Private_Use
+ test_format(V{L"'\xf0000'"}, L"{:?}", L'\xf0000'); // <private-use-F0000>
+ test_format(V{L"'\xffffd'"}, L"{:?}", L'\xffffd'); // <private-use-FFFFD>
+
+ test_format(V{L"'\x100000'"}, L"{:?}", L'\x100000'); // <private-use-100000>
+ test_format(V{L"'\x10fffd'"}, L"{:?}", L'\x10fffd'); // <private-use-10FFFD>
+
+ // Unassigned
+ test_format(V{L"'\x1000c'"}, L"{:?}", L'\x1000c'); // <reserved-1000c>
+ test_format(V{L"'\xfffff'"}, L"{:?}", L'\xfffff'); // <noncharacter-FFFFF>
+ test_format(V{L"'\x10fffe'"}, L"{:?}", L'\x10fffe'); // <noncharacter-10FFFE>
+
+ // Grapheme Extended
+ test_format(V{L"'\x101fd'"}, L"{:?}", L'\x101fd'); // COMBINING OLD PERMIC LETTER AN
+ test_format(V{L"'\xe0100'"}, L"{:?}", L'\xe0100'); // VARIATION SELECTOR-17
+
+ // Ill-formed
+ test_format(V{L"'\x110000'"}, L"{:?}", L'\x110000');
+ test_format(V{L"'\xffffffff'"}, L"{:?}", L'\xffffffff');
+ }
+# endif // TEST_SHORT_WCHAR
+#endif // TEST_HAS_NO_WIDE_CHARACTERS
+}
+
+template <class CharT>
+void test_string() {
+ // *** P2286 examples ***
+ test_format(SV("[h\tllo]"), SV("[{}]"), SV("h\tllo"));
+ test_format(SV(R"(["h\tllo"])"), SV("[{:?}]"), SV("h\tllo"));
+ test_format(SV(R"(["Спасибо, Виктор ♥!"])"), SV("[{:?}]"), SV("Спасибо, Виктор ♥!"));
+
+ test_format(SV(R"(["\u{0} \n \t \u{2} \u{1b}"])"), SV("[{:?}]"), SV("\0 \n \t \x02 \x1b"));
+
+ if constexpr (sizeof(CharT) == 1) {
+ // Ill-formend UTF-8, but valid as ASCII
+ test_format(SV("[\"\xc3\"]"), SV("[{:?}]"), SV("\xc3"));
+ test_format(SV("[\"\xc3\x28\"]"), SV("[{:?}]"), SV("\xc3\x28"));
+ } else {
+ // Valid UTF-16 and UTF-32
+ test_format(SV("[\"\u00c3\"]"), SV("[{:?}]"), L"\xc3"); // LATIN CAPITAL LETTER A WITH TILDE
+ test_format(SV("[\"\u00c3(\"]"), SV("[{:?}]"), L"\xc3\x28");
+ }
+
+ test_format(SV("[\"🤷🏻\u200d♂\ufe0f\"]"), SV("[{:?}]"), SV("🤷🏻♂️"));
+
+ // *** Special cases ***
+ test_format(SV(R"("\t\n\r\\'\" ")"), SV("{:?}"), SV("\t\n\r\\'\" "));
+
+ // *** Printable ***
+ test_format(SV(R"("abcdefg")"), SV("{:?}"), SV("abcdefg"));
+
+ // *** Non-printable ***
+
+ // Control
+ test_format(SV(R"("\u{0}\u{1f}")"), SV("{:?}"), SV("\0\x1f"));
+
+ // Ill-formed UTF-8, valid ASCII
+ test_format(SV("\"\x80\""), SV("{:?}"), SV("\x80"));
+}
+
+template <class CharT, class TestFunction>
+void test_format_functions(TestFunction check) {
+ // LATIN SMALL LETTER O WITH DIAERESIS is encoded in two chars or 1 wchar_t
+ // due to the range of the value.
+ // 8 + sizeof(CharT) == 1 is not considered an constant expression
+
+ // *** align-fill & width ***
+ check(SV(R"(***"hellö")"),
+ SV("{:*>{}?}"),
+ SV("hellö"),
+ sizeof(CharT) == 1 ? 11 : 10); // ö is LATIN SMALL LETTER O WITH DIAERESIS
+ check(SV(R"(*"hellö"**)"), SV("{:*^{}?}"), SV("hellö"), sizeof(CharT) == 1 ? 11 : 10);
+ check(SV(R"("hellö"***)"), SV("{:*<{}?}"), SV("hellö"), sizeof(CharT) == 1 ? 11 : 10);
+
+ check(SV("\"hello\u0308\""), SV("{:*>{}?}"), SV("hello\u0308"), sizeof(CharT) == 1 ? 9 : 8);
+ check(SV("***\"hello\u0308\""), SV("{:*>{}?}"), SV("hello\u0308"), sizeof(CharT) == 1 ? 12 : 11);
+ check(SV("*\"hello\u0308\"**"), SV("{:*^{}?}"), SV("hello\u0308"), sizeof(CharT) == 1 ? 12 : 11);
+ check(SV("\"hello\u0308\"***"), SV("{:*<{}?}"), SV("hello\u0308"), sizeof(CharT) == 1 ? 12 : 11);
+
+ // *** width ***
+ check(SV(R"("hello" )"), SV("{:10?}"), SV("hello"));
+
+ // *** precision ***
+ check(SV(R"("hell)"), SV("{:.5?}"), SV("hello"));
+ check(SV(R"("hello)"), SV("{:.6?}"), SV("hello"));
+ check(SV(R"("hello")"), SV("{:.7?}"), SV("hello"));
+
+ // *** width & precision ***
+ check(SV(R"("hell#########################)"), SV("{:#<30.5?}"), SV("hello"));
+ check(SV(R"("hello########################)"), SV("{:#<30.6?}"), SV("hello"));
+ check(SV(R"("hello"#######################)"), SV("{:#<30.7?}"), SV("hello"));
+}
+
+template <class CharT>
+void test() {
+ test_char<CharT>();
+
+ test_string<CharT>();
+
+ test_format_functions<CharT>(test_format);
+ test_format_functions<CharT>(test_format_to);
+ test_format_functions<CharT>(test_formatted_size);
+ test_format_functions<CharT>(test_format_to_n);
+}
+
+int main(int, char**) {
+ test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/code_point_width_estimation.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/code_point_width_estimation.pass.cpp
new file mode 100644
index 0000000000000..e119e42b00287
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/code_point_width_estimation.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
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// <format>
+
+// Tests the implementation of the extended grapheme cluster boundaries per
+// https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
+//
+// The tests are based on the test data provided by Unicode
+// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
+
+#include <cassert>
+#include <format>
+#include <functional>
+#include <numeric>
+
+#include "test_macros.h"
+
+TEST_DIAGNOSTIC_PUSH
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__format/width_estimation_table.h>
+TEST_DIAGNOSTIC_POP
+
+// [format.string.std]/12
+//
+// - U+4DC0 - U+4DFF (Yijing Hexagram Symbols)
+// - U+1F300 - U+1F5FF (Miscellaneous Symbols and Pictographs)
+// - U+1F900 - U+1F9FF (Supplemental Symbols and Pictographs)
+static void constexpr test_hardcoded_values() {
+ auto test = [](char32_t c) { assert(std::__width_estimation_table::__estimated_width(c) == 2); };
+ for (char32_t c = 0x4DC0; c <= 0x4DFF; ++c)
+ test(c);
+ for (char32_t c = 0x1F300; c <= 0x1F5FF; ++c)
+ test(c);
+ for (char32_t c = 0x1F900; c <= 0x1F9FF; ++c)
+ test(c);
+}
+
+static void constexpr test_invalid_values() {
+ auto test = [](char32_t c) { assert(std::__width_estimation_table::__estimated_width(c) == 1); };
+
+ // The surrogate range
+ for (char32_t c = 0xD800; c <= 0xDFFF; ++c)
+ test(c);
+
+ // The first 256 non valid code points
+ for (char32_t c = 0x110000; c <= 0x1100FF; ++c)
+ test(c);
+}
+
+static void constexpr test_optimization_boundaries() {
+ // Entries after the table have a width of 1.
+ static_assert(*(std::end(std::__width_estimation_table::__entries) - 1) == ((0x3c000u << 14) | 16381u),
+ "validate whether the optimizations in __estimated_width are still valid");
+ assert(std::__width_estimation_table::__estimated_width(0x3fffd) == 2);
+ assert(std::__width_estimation_table::__estimated_width(0x3fffe) == 1);
+
+ // Entries before the table have a width of 1.
+ static_assert(std::__width_estimation_table::__entries[0] >> 14 == 0x1100,
+ "validate whether the optimizations in __estimated_width are still valid");
+ assert(std::__width_estimation_table::__estimated_width(0x10FF) == 1);
+ assert(std::__width_estimation_table::__estimated_width(0x1100) == 2);
+}
+
+static constexpr bool test() {
+ test_hardcoded_values();
+ test_invalid_values();
+ test_optimization_boundaries();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/concepts_precision.h b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/concepts_precision.h
new file mode 100644
index 0000000000000..80751ead14b49
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/concepts_precision.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIBCXX_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_CONCEPTS_PRECISION_H
+#define LIBCXX_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_CONCEPTS_PRECISION_H
+
+template <class T>
+concept has_precision = requires(T parser) {
+ parser.__precision;
+};
+
+template <class T>
+concept has_precision_as_arg = requires(T parser) {
+ parser.__precision_as_arg;
+};
+
+#endif // LIBCXX_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_CONCEPTS_PRECISION_H
diff --git a/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/escaped_output.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/escaped_output.pass.cpp
new file mode 100644
index 0000000000000..d24db360173b1
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/escaped_output.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: GCC-ALWAYS_INLINE-FIXME
+
+// <format>
+
+// Tests the properties of the Unicode escaped output table.
+// The libc++ algorithm has size and speed optimizations based on the properties
+// of Unicode. This means updating the Unicode tables has a likilihood of
+// breaking test. This is an assert; it requires validating whether the
+// assumptions of the size and speed optimizations are still valid.
+
+#include <algorithm>
+#include <cassert>
+#include <format>
+#include <functional>
+#include <numeric>
+
+// Contains the entries for [format.string.escaped]/2.2.1.2.1
+// CE is a Unicode encoding and C corresponds to a UCS scalar value whose
+// Unicode property General_Category has a value in the groups Separator (Z)
+// or Other (C), as described by table 12 of UAX #44
+//
+// Separator (Z) consists of General_Category
+// - Zs Space_Separator,
+// - Zl Line_Separator,
+// - Zp Paragraph_Separator.
+//
+// Other (C) consists of General_Category
+// - Cc Control,
+// - Cf Format,
+// - Cs Surrogate,
+// - Co Private_Use,
+// - Cn Unassigned.
+inline constexpr int Zs = 17;
+inline constexpr int Zl = 1;
+inline constexpr int Zp = 1;
+inline constexpr int Z = Zs + Zl + Zp;
+
+inline constexpr int Cc = 65;
+inline constexpr int Cf = 170;
+inline constexpr int Cs = 2'048;
+inline constexpr int Co = 137'468;
+inline constexpr int Cn = 819'533;
+inline constexpr int C = Cc + Cf + Cs + Co + Cn;
+
+// This is the final part of the Unicode properties table:
+//
+// 31350..323AF ; Lo # [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF
+// 323B0..E0000 ; Cn # [711761] <reserved-323B0>..<reserved-E0000>
+// E0001 ; Cf # LANGUAGE TAG
+// E0002..E001F ; Cn # [30] <reserved-E0002>..<reserved-E001F>
+// E0020..E007F ; Cf # [96] TAG SPACE..CANCEL TAG
+// E0080..E00FF ; Cn # [128] <reserved-E0080>..<reserved-E00FF>
+// E0100..E01EF ; Mn # [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
+// E01F0..EFFFF ; Cn # [65040] <reserved-E01F0>..<noncharacter-EFFFF>
+// F0000..FFFFD ; Co # [65534] <private-use-F0000>..<private-use-FFFFD>
+// FFFFE..FFFFF ; Cn # [2] <noncharacter-FFFFE>..<noncharacter-FFFFF>
+// 100000..10FFFD; Co # [65534] <private-use-100000>..<private-use-10FFFD>
+// 10FFFE..10FFFF; Cn # [2] <noncharacter-10FFFE>..<noncharacter-10FFFF>
+//
+// It can be observed all entries in the range 323B0..10FFFF are in the
+// categories Cf, Co, Cn, except a small range with the property Mn.
+// In order to reduce the size of the table only the entires in the range
+// [0000, 323B0) are stored in the table. The entries in the range
+// [323B0, 10FFFF] use a hand-crafted algorithm.
+//
+// This means a number of entries are omitted
+inline constexpr int excluded = ((0x10FFFF - 0x323B0) + 1) - 240;
+
+inline constexpr int entries = Z + C - excluded;
+
+static constexpr int count_entries() {
+ return std::transform_reduce(
+ std::begin(std::__escaped_output_table::__entries),
+ std::end(std::__escaped_output_table::__entries),
+ 0,
+ std::plus{},
+ [](auto entry) { return 1 + static_cast<int>(entry & 0x3fffu); });
+}
+static_assert(count_entries() == entries);
+
+int main(int, char**) {
+ for (char32_t c = 0x31350; c <= 0x323AF; ++c) // 31350..323AF ; Lo # [4192]
+ assert(std::__escaped_output_table::__needs_escape(c) == false);
+
+ for (char32_t c = 0x323B0; c <= 0xE00FF; ++c) // 323B0..E00FF ; C
+ assert(std::__escaped_output_table::__needs_escape(c) == true);
+
+ for (char32_t c = 0xE0100; c <= 0xE01EF; ++c) // E0100..E01EF ; Mn # [240]
+ assert(std::__escaped_output_table::__needs_escape(c) == false);
+
+ for (char32_t c = 0xE01F0; c <= 0x10FFFF; ++c) // E01F0..10FFFF; C
+ assert(std::__escaped_output_table::__needs_escape(c) == true);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.h b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.h
new file mode 100644
index 0000000000000..9664622ab4e40
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.h
@@ -0,0 +1,3382 @@
+// -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING, this entire header is generated by
+// utils/generate_extended_grapheme_cluster_test.py
+// DO NOT MODIFY!
+
+// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+//
+// See Terms of Use <https://www.unicode.org/copyright.html>
+// for definitions of Unicode Inc.'s Data Files and Software.
+//
+// NOTICE TO USER: Carefully read the following legal agreement.
+// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
+// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
+// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+// TERMS AND CONDITIONS OF THIS AGREEMENT.
+// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
+// THE DATA FILES OR SOFTWARE.
+//
+// COPYRIGHT AND PERMISSION NOTICE
+//
+// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved.
+// Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of the Unicode data files and any associated documentation
+// (the "Data Files") or Unicode software and any associated documentation
+// (the "Software") to deal in the Data Files or Software
+// without restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, and/or sell copies of
+// the Data Files or Software, and to permit persons to whom the Data Files
+// or Software are furnished to do so, provided that either
+// (a) this copyright and permission notice appear with all copies
+// of the Data Files or Software, or
+// (b) this copyright and permission notice appear in associated
+// Documentation.
+//
+// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
+// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+//
+// Except as contained in this notice, the name of a copyright holder
+// shall not be used in advertising or otherwise to promote the sale,
+// use or other dealings in these Data Files or Software without prior
+// written authorization of the copyright holder.
+
+#ifndef LIBCXX_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_EXTENDED_GRAPHEME_CLUSTER_H
+#define LIBCXX_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_EXTENDED_GRAPHEME_CLUSTER_H
+
+#include <array>
+#include <string_view>
+#include <vector>
+
+#include "test_macros.h"
+
+template <class CharT>
+struct data {
+ /// The input to parse.
+ std::basic_string_view<CharT> input;
+
+ /// The first code point all extended grapheme clusters in the input.
+ std::vector<char32_t> code_points;
+
+ /// The offset of the last code units of the extended grapheme clusters in the input.
+ ///
+ /// The vector has the same number of entries as \ref code_points.
+ std::vector<std::size_t> breaks;
+};
+
+/// The data for UTF-8.
+std::array<data<char>, 1093> data_utf8 = {{
+ {"\U00000020\U00000020", {32, 32}, {1, 2}},
+ {"\U00000020\U00000308\U00000020", {32, 32}, {3, 4}},
+ {"\U00000020\U0000000d", {32, 13}, {1, 2}},
+ {"\U00000020\U00000308\U0000000d", {32, 13}, {3, 4}},
+ {"\U00000020\U0000000a", {32, 10}, {1, 2}},
+ {"\U00000020\U00000308\U0000000a", {32, 10}, {3, 4}},
+ {"\U00000020\U00000001", {32, 1}, {1, 2}},
+ {"\U00000020\U00000308\U00000001", {32, 1}, {3, 4}},
+ {"\U00000020\U0000200c", {32}, {4}},
+ {"\U00000020\U00000308\U0000200c", {32}, {6}},
+ {"\U00000020\U0001f1e6", {32, 127462}, {1, 5}},
+ {"\U00000020\U00000308\U0001f1e6", {32, 127462}, {3, 7}},
+ {"\U00000020\U00000600", {32, 1536}, {1, 3}},
+ {"\U00000020\U00000308\U00000600", {32, 1536}, {3, 5}},
+ {"\U00000020\U00000a03", {32}, {4}},
+ {"\U00000020\U00000308\U00000a03", {32}, {6}},
+ {"\U00000020\U00001100", {32, 4352}, {1, 4}},
+ {"\U00000020\U00000308\U00001100", {32, 4352}, {3, 6}},
+ {"\U00000020\U00001160", {32, 4448}, {1, 4}},
+ {"\U00000020\U00000308\U00001160", {32, 4448}, {3, 6}},
+ {"\U00000020\U000011a8", {32, 4520}, {1, 4}},
+ {"\U00000020\U00000308\U000011a8", {32, 4520}, {3, 6}},
+ {"\U00000020\U0000ac00", {32, 44032}, {1, 4}},
+ {"\U00000020\U00000308\U0000ac00", {32, 44032}, {3, 6}},
+ {"\U00000020\U0000ac01", {32, 44033}, {1, 4}},
+ {"\U00000020\U00000308\U0000ac01", {32, 44033}, {3, 6}},
+ {"\U00000020\U00000903", {32}, {4}},
+ {"\U00000020\U00000308\U00000903", {32}, {6}},
+ {"\U00000020\U00000904", {32, 2308}, {1, 4}},
+ {"\U00000020\U00000308\U00000904", {32, 2308}, {3, 6}},
+ {"\U00000020\U00000d4e", {32, 3406}, {1, 4}},
+ {"\U00000020\U00000308\U00000d4e", {32, 3406}, {3, 6}},
+ {"\U00000020\U00000915", {32, 2325}, {1, 4}},
+ {"\U00000020\U00000308\U00000915", {32, 2325}, {3, 6}},
+ {"\U00000020\U0000231a", {32, 8986}, {1, 4}},
+ {"\U00000020\U00000308\U0000231a", {32, 8986}, {3, 6}},
+ {"\U00000020\U00000300", {32}, {3}},
+ {"\U00000020\U00000308\U00000300", {32}, {5}},
+ {"\U00000020\U00000900", {32}, {4}},
+ {"\U00000020\U00000308\U00000900", {32}, {6}},
+ {"\U00000020\U0000094d", {32}, {4}},
+ {"\U00000020\U00000308\U0000094d", {32}, {6}},
+ {"\U00000020\U0000200d", {32}, {4}},
+ {"\U00000020\U00000308\U0000200d", {32}, {6}},
+ {"\U00000020\U00000378", {32, 888}, {1, 3}},
+ {"\U00000020\U00000308\U00000378", {32, 888}, {3, 5}},
+ {"\U0000000d\U00000020", {13, 32}, {1, 2}},
+ {"\U0000000d\U00000308\U00000020", {13, 776, 32}, {1, 3, 4}},
+ {"\U0000000d\U0000000d", {13, 13}, {1, 2}},
+ {"\U0000000d\U00000308\U0000000d", {13, 776, 13}, {1, 3, 4}},
+ {"\U0000000d\U0000000a", {13}, {2}},
+ {"\U0000000d\U00000308\U0000000a", {13, 776, 10}, {1, 3, 4}},
+ {"\U0000000d\U00000001", {13, 1}, {1, 2}},
+ {"\U0000000d\U00000308\U00000001", {13, 776, 1}, {1, 3, 4}},
+ {"\U0000000d\U0000200c", {13, 8204}, {1, 4}},
+ {"\U0000000d\U00000308\U0000200c", {13, 776}, {1, 6}},
+ {"\U0000000d\U0001f1e6", {13, 127462}, {1, 5}},
+ {"\U0000000d\U00000308\U0001f1e6", {13, 776, 127462}, {1, 3, 7}},
+ {"\U0000000d\U00000600", {13, 1536}, {1, 3}},
+ {"\U0000000d\U00000308\U00000600", {13, 776, 1536}, {1, 3, 5}},
+ {"\U0000000d\U00000a03", {13, 2563}, {1, 4}},
+ {"\U0000000d\U00000308\U00000a03", {13, 776}, {1, 6}},
+ {"\U0000000d\U00001100", {13, 4352}, {1, 4}},
+ {"\U0000000d\U00000308\U00001100", {13, 776, 4352}, {1, 3, 6}},
+ {"\U0000000d\U00001160", {13, 4448}, {1, 4}},
+ {"\U0000000d\U00000308\U00001160", {13, 776, 4448}, {1, 3, 6}},
+ {"\U0000000d\U000011a8", {13, 4520}, {1, 4}},
+ {"\U0000000d\U00000308\U000011a8", {13, 776, 4520}, {1, 3, 6}},
+ {"\U0000000d\U0000ac00", {13, 44032}, {1, 4}},
+ {"\U0000000d\U00000308\U0000ac00", {13, 776, 44032}, {1, 3, 6}},
+ {"\U0000000d\U0000ac01", {13, 44033}, {1, 4}},
+ {"\U0000000d\U00000308\U0000ac01", {13, 776, 44033}, {1, 3, 6}},
+ {"\U0000000d\U00000903", {13, 2307}, {1, 4}},
+ {"\U0000000d\U00000308\U00000903", {13, 776}, {1, 6}},
+ {"\U0000000d\U00000904", {13, 2308}, {1, 4}},
+ {"\U0000000d\U00000308\U00000904", {13, 776, 2308}, {1, 3, 6}},
+ {"\U0000000d\U00000d4e", {13, 3406}, {1, 4}},
+ {"\U0000000d\U00000308\U00000d4e", {13, 776, 3406}, {1, 3, 6}},
+ {"\U0000000d\U00000915", {13, 2325}, {1, 4}},
+ {"\U0000000d\U00000308\U00000915", {13, 776, 2325}, {1, 3, 6}},
+ {"\U0000000d\U0000231a", {13, 8986}, {1, 4}},
+ {"\U0000000d\U00000308\U0000231a", {13, 776, 8986}, {1, 3, 6}},
+ {"\U0000000d\U00000300", {13, 768}, {1, 3}},
+ {"\U0000000d\U00000308\U00000300", {13, 776}, {1, 5}},
+ {"\U0000000d\U00000900", {13, 2304}, {1, 4}},
+ {"\U0000000d\U00000308\U00000900", {13, 776}, {1, 6}},
+ {"\U0000000d\U0000094d", {13, 2381}, {1, 4}},
+ {"\U0000000d\U00000308\U0000094d", {13, 776}, {1, 6}},
+ {"\U0000000d\U0000200d", {13, 8205}, {1, 4}},
+ {"\U0000000d\U00000308\U0000200d", {13, 776}, {1, 6}},
+ {"\U0000000d\U00000378", {13, 888}, {1, 3}},
+ {"\U0000000d\U00000308\U00000378", {13, 776, 888}, {1, 3, 5}},
+ {"\U0000000a\U00000020", {10, 32}, {1, 2}},
+ {"\U0000000a\U00000308\U00000020", {10, 776, 32}, {1, 3, 4}},
+ {"\U0000000a\U0000000d", {10, 13}, {1, 2}},
+ {"\U0000000a\U00000308\U0000000d", {10, 776, 13}, {1, 3, 4}},
+ {"\U0000000a\U0000000a", {10, 10}, {1, 2}},
+ {"\U0000000a\U00000308\U0000000a", {10, 776, 10}, {1, 3, 4}},
+ {"\U0000000a\U00000001", {10, 1}, {1, 2}},
+ {"\U0000000a\U00000308\U00000001", {10, 776, 1}, {1, 3, 4}},
+ {"\U0000000a\U0000200c", {10, 8204}, {1, 4}},
+ {"\U0000000a\U00000308\U0000200c", {10, 776}, {1, 6}},
+ {"\U0000000a\U0001f1e6", {10, 127462}, {1, 5}},
+ {"\U0000000a\U00000308\U0001f1e6", {10, 776, 127462}, {1, 3, 7}},
+ {"\U0000000a\U00000600", {10, 1536}, {1, 3}},
+ {"\U0000000a\U00000308\U00000600", {10, 776, 1536}, {1, 3, 5}},
+ {"\U0000000a\U00000a03", {10, 2563}, {1, 4}},
+ {"\U0000000a\U00000308\U00000a03", {10, 776}, {1, 6}},
+ {"\U0000000a\U00001100", {10, 4352}, {1, 4}},
+ {"\U0000000a\U00000308\U00001100", {10, 776, 4352}, {1, 3, 6}},
+ {"\U0000000a\U00001160", {10, 4448}, {1, 4}},
+ {"\U0000000a\U00000308\U00001160", {10, 776, 4448}, {1, 3, 6}},
+ {"\U0000000a\U000011a8", {10, 4520}, {1, 4}},
+ {"\U0000000a\U00000308\U000011a8", {10, 776, 4520}, {1, 3, 6}},
+ {"\U0000000a\U0000ac00", {10, 44032}, {1, 4}},
+ {"\U0000000a\U00000308\U0000ac00", {10, 776, 44032}, {1, 3, 6}},
+ {"\U0000000a\U0000ac01", {10, 44033}, {1, 4}},
+ {"\U0000000a\U00000308\U0000ac01", {10, 776, 44033}, {1, 3, 6}},
+ {"\U0000000a\U00000903", {10, 2307}, {1, 4}},
+ {"\U0000000a\U00000308\U00000903", {10, 776}, {1, 6}},
+ {"\U0000000a\U00000904", {10, 2308}, {1, 4}},
+ {"\U0000000a\U00000308\U00000904", {10, 776, 2308}, {1, 3, 6}},
+ {"\U0000000a\U00000d4e", {10, 3406}, {1, 4}},
+ {"\U0000000a\U00000308\U00000d4e", {10, 776, 3406}, {1, 3, 6}},
+ {"\U0000000a\U00000915", {10, 2325}, {1, 4}},
+ {"\U0000000a\U00000308\U00000915", {10, 776, 2325}, {1, 3, 6}},
+ {"\U0000000a\U0000231a", {10, 8986}, {1, 4}},
+ {"\U0000000a\U00000308\U0000231a", {10, 776, 8986}, {1, 3, 6}},
+ {"\U0000000a\U00000300", {10, 768}, {1, 3}},
+ {"\U0000000a\U00000308\U00000300", {10, 776}, {1, 5}},
+ {"\U0000000a\U00000900", {10, 2304}, {1, 4}},
+ {"\U0000000a\U00000308\U00000900", {10, 776}, {1, 6}},
+ {"\U0000000a\U0000094d", {10, 2381}, {1, 4}},
+ {"\U0000000a\U00000308\U0000094d", {10, 776}, {1, 6}},
+ {"\U0000000a\U0000200d", {10, 8205}, {1, 4}},
+ {"\U0000000a\U00000308\U0000200d", {10, 776}, {1, 6}},
+ {"\U0000000a\U00000378", {10, 888}, {1, 3}},
+ {"\U0000000a\U00000308\U00000378", {10, 776, 888}, {1, 3, 5}},
+ {"\U00000001\U00000020", {1, 32}, {1, 2}},
+ {"\U00000001\U00000308\U00000020", {1, 776, 32}, {1, 3, 4}},
+ {"\U00000001\U0000000d", {1, 13}, {1, 2}},
+ {"\U00000001\U00000308\U0000000d", {1, 776, 13}, {1, 3, 4}},
+ {"\U00000001\U0000000a", {1, 10}, {1, 2}},
+ {"\U00000001\U00000308\U0000000a", {1, 776, 10}, {1, 3, 4}},
+ {"\U00000001\U00000001", {1, 1}, {1, 2}},
+ {"\U00000001\U00000308\U00000001", {1, 776, 1}, {1, 3, 4}},
+ {"\U00000001\U0000200c", {1, 8204}, {1, 4}},
+ {"\U00000001\U00000308\U0000200c", {1, 776}, {1, 6}},
+ {"\U00000001\U0001f1e6", {1, 127462}, {1, 5}},
+ {"\U00000001\U00000308\U0001f1e6", {1, 776, 127462}, {1, 3, 7}},
+ {"\U00000001\U00000600", {1, 1536}, {1, 3}},
+ {"\U00000001\U00000308\U00000600", {1, 776, 1536}, {1, 3, 5}},
+ {"\U00000001\U00000a03", {1, 2563}, {1, 4}},
+ {"\U00000001\U00000308\U00000a03", {1, 776}, {1, 6}},
+ {"\U00000001\U00001100", {1, 4352}, {1, 4}},
+ {"\U00000001\U00000308\U00001100", {1, 776, 4352}, {1, 3, 6}},
+ {"\U00000001\U00001160", {1, 4448}, {1, 4}},
+ {"\U00000001\U00000308\U00001160", {1, 776, 4448}, {1, 3, 6}},
+ {"\U00000001\U000011a8", {1, 4520}, {1, 4}},
+ {"\U00000001\U00000308\U000011a8", {1, 776, 4520}, {1, 3, 6}},
+ {"\U00000001\U0000ac00", {1, 44032}, {1, 4}},
+ {"\U00000001\U00000308\U0000ac00", {1, 776, 44032}, {1, 3, 6}},
+ {"\U00000001\U0000ac01", {1, 44033}, {1, 4}},
+ {"\U00000001\U00000308\U0000ac01", {1, 776, 44033}, {1, 3, 6}},
+ {"\U00000001\U00000903", {1, 2307}, {1, 4}},
+ {"\U00000001\U00000308\U00000903", {1, 776}, {1, 6}},
+ {"\U00000001\U00000904", {1, 2308}, {1, 4}},
+ {"\U00000001\U00000308\U00000904", {1, 776, 2308}, {1, 3, 6}},
+ {"\U00000001\U00000d4e", {1, 3406}, {1, 4}},
+ {"\U00000001\U00000308\U00000d4e", {1, 776, 3406}, {1, 3, 6}},
+ {"\U00000001\U00000915", {1, 2325}, {1, 4}},
+ {"\U00000001\U00000308\U00000915", {1, 776, 2325}, {1, 3, 6}},
+ {"\U00000001\U0000231a", {1, 8986}, {1, 4}},
+ {"\U00000001\U00000308\U0000231a", {1, 776, 8986}, {1, 3, 6}},
+ {"\U00000001\U00000300", {1, 768}, {1, 3}},
+ {"\U00000001\U00000308\U00000300", {1, 776}, {1, 5}},
+ {"\U00000001\U00000900", {1, 2304}, {1, 4}},
+ {"\U00000001\U00000308\U00000900", {1, 776}, {1, 6}},
+ {"\U00000001\U0000094d", {1, 2381}, {1, 4}},
+ {"\U00000001\U00000308\U0000094d", {1, 776}, {1, 6}},
+ {"\U00000001\U0000200d", {1, 8205}, {1, 4}},
+ {"\U00000001\U00000308\U0000200d", {1, 776}, {1, 6}},
+ {"\U00000001\U00000378", {1, 888}, {1, 3}},
+ {"\U00000001\U00000308\U00000378", {1, 776, 888}, {1, 3, 5}},
+ {"\U0000200c\U00000020", {8204, 32}, {3, 4}},
+ {"\U0000200c\U00000308\U00000020", {8204, 32}, {5, 6}},
+ {"\U0000200c\U0000000d", {8204, 13}, {3, 4}},
+ {"\U0000200c\U00000308\U0000000d", {8204, 13}, {5, 6}},
+ {"\U0000200c\U0000000a", {8204, 10}, {3, 4}},
+ {"\U0000200c\U00000308\U0000000a", {8204, 10}, {5, 6}},
+ {"\U0000200c\U00000001", {8204, 1}, {3, 4}},
+ {"\U0000200c\U00000308\U00000001", {8204, 1}, {5, 6}},
+ {"\U0000200c\U0000200c", {8204}, {6}},
+ {"\U0000200c\U00000308\U0000200c", {8204}, {8}},
+ {"\U0000200c\U0001f1e6", {8204, 127462}, {3, 7}},
+ {"\U0000200c\U00000308\U0001f1e6", {8204, 127462}, {5, 9}},
+ {"\U0000200c\U00000600", {8204, 1536}, {3, 5}},
+ {"\U0000200c\U00000308\U00000600", {8204, 1536}, {5, 7}},
+ {"\U0000200c\U00000a03", {8204}, {6}},
+ {"\U0000200c\U00000308\U00000a03", {8204}, {8}},
+ {"\U0000200c\U00001100", {8204, 4352}, {3, 6}},
+ {"\U0000200c\U00000308\U00001100", {8204, 4352}, {5, 8}},
+ {"\U0000200c\U00001160", {8204, 4448}, {3, 6}},
+ {"\U0000200c\U00000308\U00001160", {8204, 4448}, {5, 8}},
+ {"\U0000200c\U000011a8", {8204, 4520}, {3, 6}},
+ {"\U0000200c\U00000308\U000011a8", {8204, 4520}, {5, 8}},
+ {"\U0000200c\U0000ac00", {8204, 44032}, {3, 6}},
+ {"\U0000200c\U00000308\U0000ac00", {8204, 44032}, {5, 8}},
+ {"\U0000200c\U0000ac01", {8204, 44033}, {3, 6}},
+ {"\U0000200c\U00000308\U0000ac01", {8204, 44033}, {5, 8}},
+ {"\U0000200c\U00000903", {8204}, {6}},
+ {"\U0000200c\U00000308\U00000903", {8204}, {8}},
+ {"\U0000200c\U00000904", {8204, 2308}, {3, 6}},
+ {"\U0000200c\U00000308\U00000904", {8204, 2308}, {5, 8}},
+ {"\U0000200c\U00000d4e", {8204, 3406}, {3, 6}},
+ {"\U0000200c\U00000308\U00000d4e", {8204, 3406}, {5, 8}},
+ {"\U0000200c\U00000915", {8204, 2325}, {3, 6}},
+ {"\U0000200c\U00000308\U00000915", {8204, 2325}, {5, 8}},
+ {"\U0000200c\U0000231a", {8204, 8986}, {3, 6}},
+ {"\U0000200c\U00000308\U0000231a", {8204, 8986}, {5, 8}},
+ {"\U0000200c\U00000300", {8204}, {5}},
+ {"\U0000200c\U00000308\U00000300", {8204}, {7}},
+ {"\U0000200c\U00000900", {8204}, {6}},
+ {"\U0000200c\U00000308\U00000900", {8204}, {8}},
+ {"\U0000200c\U0000094d", {8204}, {6}},
+ {"\U0000200c\U00000308\U0000094d", {8204}, {8}},
+ {"\U0000200c\U0000200d", {8204}, {6}},
+ {"\U0000200c\U00000308\U0000200d", {8204}, {8}},
+ {"\U0000200c\U00000378", {8204, 888}, {3, 5}},
+ {"\U0000200c\U00000308\U00000378", {8204, 888}, {5, 7}},
+ {"\U0001f1e6\U00000020", {127462, 32}, {4, 5}},
+ {"\U0001f1e6\U00000308\U00000020", {127462, 32}, {6, 7}},
+ {"\U0001f1e6\U0000000d", {127462, 13}, {4, 5}},
+ {"\U0001f1e6\U00000308\U0000000d", {127462, 13}, {6, 7}},
+ {"\U0001f1e6\U0000000a", {127462, 10}, {4, 5}},
+ {"\U0001f1e6\U00000308\U0000000a", {127462, 10}, {6, 7}},
+ {"\U0001f1e6\U00000001", {127462, 1}, {4, 5}},
+ {"\U0001f1e6\U00000308\U00000001", {127462, 1}, {6, 7}},
+ {"\U0001f1e6\U0000200c", {127462}, {7}},
+ {"\U0001f1e6\U00000308\U0000200c", {127462}, {9}},
+ {"\U0001f1e6\U0001f1e6", {127462}, {8}},
+ {"\U0001f1e6\U00000308\U0001f1e6", {127462, 127462}, {6, 10}},
+ {"\U0001f1e6\U00000600", {127462, 1536}, {4, 6}},
+ {"\U0001f1e6\U00000308\U00000600", {127462, 1536}, {6, 8}},
+ {"\U0001f1e6\U00000a03", {127462}, {7}},
+ {"\U0001f1e6\U00000308\U00000a03", {127462}, {9}},
+ {"\U0001f1e6\U00001100", {127462, 4352}, {4, 7}},
+ {"\U0001f1e6\U00000308\U00001100", {127462, 4352}, {6, 9}},
+ {"\U0001f1e6\U00001160", {127462, 4448}, {4, 7}},
+ {"\U0001f1e6\U00000308\U00001160", {127462, 4448}, {6, 9}},
+ {"\U0001f1e6\U000011a8", {127462, 4520}, {4, 7}},
+ {"\U0001f1e6\U00000308\U000011a8", {127462, 4520}, {6, 9}},
+ {"\U0001f1e6\U0000ac00", {127462, 44032}, {4, 7}},
+ {"\U0001f1e6\U00000308\U0000ac00", {127462, 44032}, {6, 9}},
+ {"\U0001f1e6\U0000ac01", {127462, 44033}, {4, 7}},
+ {"\U0001f1e6\U00000308\U0000ac01", {127462, 44033}, {6, 9}},
+ {"\U0001f1e6\U00000903", {127462}, {7}},
+ {"\U0001f1e6\U00000308\U00000903", {127462}, {9}},
+ {"\U0001f1e6\U00000904", {127462, 2308}, {4, 7}},
+ {"\U0001f1e6\U00000308\U00000904", {127462, 2308}, {6, 9}},
+ {"\U0001f1e6\U00000d4e", {127462, 3406}, {4, 7}},
+ {"\U0001f1e6\U00000308\U00000d4e", {127462, 3406}, {6, 9}},
+ {"\U0001f1e6\U00000915", {127462, 2325}, {4, 7}},
+ {"\U0001f1e6\U00000308\U00000915", {127462, 2325}, {6, 9}},
+ {"\U0001f1e6\U0000231a", {127462, 8986}, {4, 7}},
+ {"\U0001f1e6\U00000308\U0000231a", {127462, 8986}, {6, 9}},
+ {"\U0001f1e6\U00000300", {127462}, {6}},
+ {"\U0001f1e6\U00000308\U00000300", {127462}, {8}},
+ {"\U0001f1e6\U00000900", {127462}, {7}},
+ {"\U0001f1e6\U00000308\U00000900", {127462}, {9}},
+ {"\U0001f1e6\U0000094d", {127462}, {7}},
+ {"\U0001f1e6\U00000308\U0000094d", {127462}, {9}},
+ {"\U0001f1e6\U0000200d", {127462}, {7}},
+ {"\U0001f1e6\U00000308\U0000200d", {127462}, {9}},
+ {"\U0001f1e6\U00000378", {127462, 888}, {4, 6}},
+ {"\U0001f1e6\U00000308\U00000378", {127462, 888}, {6, 8}},
+ {"\U00000600\U00000020", {1536}, {3}},
+ {"\U00000600\U00000308\U00000020", {1536, 32}, {4, 5}},
+ {"\U00000600\U0000000d", {1536, 13}, {2, 3}},
+ {"\U00000600\U00000308\U0000000d", {1536, 13}, {4, 5}},
+ {"\U00000600\U0000000a", {1536, 10}, {2, 3}},
+ {"\U00000600\U00000308\U0000000a", {1536, 10}, {4, 5}},
+ {"\U00000600\U00000001", {1536, 1}, {2, 3}},
+ {"\U00000600\U00000308\U00000001", {1536, 1}, {4, 5}},
+ {"\U00000600\U0000200c", {1536}, {5}},
+ {"\U00000600\U00000308\U0000200c", {1536}, {7}},
+ {"\U00000600\U0001f1e6", {1536}, {6}},
+ {"\U00000600\U00000308\U0001f1e6", {1536, 127462}, {4, 8}},
+ {"\U00000600\U00000600", {1536}, {4}},
+ {"\U00000600\U00000308\U00000600", {1536, 1536}, {4, 6}},
+ {"\U00000600\U00000a03", {1536}, {5}},
+ {"\U00000600\U00000308\U00000a03", {1536}, {7}},
+ {"\U00000600\U00001100", {1536}, {5}},
+ {"\U00000600\U00000308\U00001100", {1536, 4352}, {4, 7}},
+ {"\U00000600\U00001160", {1536}, {5}},
+ {"\U00000600\U00000308\U00001160", {1536, 4448}, {4, 7}},
+ {"\U00000600\U000011a8", {1536}, {5}},
+ {"\U00000600\U00000308\U000011a8", {1536, 4520}, {4, 7}},
+ {"\U00000600\U0000ac00", {1536}, {5}},
+ {"\U00000600\U00000308\U0000ac00", {1536, 44032}, {4, 7}},
+ {"\U00000600\U0000ac01", {1536}, {5}},
+ {"\U00000600\U00000308\U0000ac01", {1536, 44033}, {4, 7}},
+ {"\U00000600\U00000903", {1536}, {5}},
+ {"\U00000600\U00000308\U00000903", {1536}, {7}},
+ {"\U00000600\U00000904", {1536}, {5}},
+ {"\U00000600\U00000308\U00000904", {1536, 2308}, {4, 7}},
+ {"\U00000600\U00000d4e", {1536}, {5}},
+ {"\U00000600\U00000308\U00000d4e", {1536, 3406}, {4, 7}},
+ {"\U00000600\U00000915", {1536}, {5}},
+ {"\U00000600\U00000308\U00000915", {1536, 2325}, {4, 7}},
+ {"\U00000600\U0000231a", {1536}, {5}},
+ {"\U00000600\U00000308\U0000231a", {1536, 8986}, {4, 7}},
+ {"\U00000600\U00000300", {1536}, {4}},
+ {"\U00000600\U00000308\U00000300", {1536}, {6}},
+ {"\U00000600\U00000900", {1536}, {5}},
+ {"\U00000600\U00000308\U00000900", {1536}, {7}},
+ {"\U00000600\U0000094d", {1536}, {5}},
+ {"\U00000600\U00000308\U0000094d", {1536}, {7}},
+ {"\U00000600\U0000200d", {1536}, {5}},
+ {"\U00000600\U00000308\U0000200d", {1536}, {7}},
+ {"\U00000600\U00000378", {1536}, {4}},
+ {"\U00000600\U00000308\U00000378", {1536, 888}, {4, 6}},
+ {"\U00000a03\U00000020", {2563, 32}, {3, 4}},
+ {"\U00000a03\U00000308\U00000020", {2563, 32}, {5, 6}},
+ {"\U00000a03\U0000000d", {2563, 13}, {3, 4}},
+ {"\U00000a03\U00000308\U0000000d", {2563, 13}, {5, 6}},
+ {"\U00000a03\U0000000a", {2563, 10}, {3, 4}},
+ {"\U00000a03\U00000308\U0000000a", {2563, 10}, {5, 6}},
+ {"\U00000a03\U00000001", {2563, 1}, {3, 4}},
+ {"\U00000a03\U00000308\U00000001", {2563, 1}, {5, 6}},
+ {"\U00000a03\U0000200c", {2563}, {6}},
+ {"\U00000a03\U00000308\U0000200c", {2563}, {8}},
+ {"\U00000a03\U0001f1e6", {2563, 127462}, {3, 7}},
+ {"\U00000a03\U00000308\U0001f1e6", {2563, 127462}, {5, 9}},
+ {"\U00000a03\U00000600", {2563, 1536}, {3, 5}},
+ {"\U00000a03\U00000308\U00000600", {2563, 1536}, {5, 7}},
+ {"\U00000a03\U00000a03", {2563}, {6}},
+ {"\U00000a03\U00000308\U00000a03", {2563}, {8}},
+ {"\U00000a03\U00001100", {2563, 4352}, {3, 6}},
+ {"\U00000a03\U00000308\U00001100", {2563, 4352}, {5, 8}},
+ {"\U00000a03\U00001160", {2563, 4448}, {3, 6}},
+ {"\U00000a03\U00000308\U00001160", {2563, 4448}, {5, 8}},
+ {"\U00000a03\U000011a8", {2563, 4520}, {3, 6}},
+ {"\U00000a03\U00000308\U000011a8", {2563, 4520}, {5, 8}},
+ {"\U00000a03\U0000ac00", {2563, 44032}, {3, 6}},
+ {"\U00000a03\U00000308\U0000ac00", {2563, 44032}, {5, 8}},
+ {"\U00000a03\U0000ac01", {2563, 44033}, {3, 6}},
+ {"\U00000a03\U00000308\U0000ac01", {2563, 44033}, {5, 8}},
+ {"\U00000a03\U00000903", {2563}, {6}},
+ {"\U00000a03\U00000308\U00000903", {2563}, {8}},
+ {"\U00000a03\U00000904", {2563, 2308}, {3, 6}},
+ {"\U00000a03\U00000308\U00000904", {2563, 2308}, {5, 8}},
+ {"\U00000a03\U00000d4e", {2563, 3406}, {3, 6}},
+ {"\U00000a03\U00000308\U00000d4e", {2563, 3406}, {5, 8}},
+ {"\U00000a03\U00000915", {2563, 2325}, {3, 6}},
+ {"\U00000a03\U00000308\U00000915", {2563, 2325}, {5, 8}},
+ {"\U00000a03\U0000231a", {2563, 8986}, {3, 6}},
+ {"\U00000a03\U00000308\U0000231a", {2563, 8986}, {5, 8}},
+ {"\U00000a03\U00000300", {2563}, {5}},
+ {"\U00000a03\U00000308\U00000300", {2563}, {7}},
+ {"\U00000a03\U00000900", {2563}, {6}},
+ {"\U00000a03\U00000308\U00000900", {2563}, {8}},
+ {"\U00000a03\U0000094d", {2563}, {6}},
+ {"\U00000a03\U00000308\U0000094d", {2563}, {8}},
+ {"\U00000a03\U0000200d", {2563}, {6}},
+ {"\U00000a03\U00000308\U0000200d", {2563}, {8}},
+ {"\U00000a03\U00000378", {2563, 888}, {3, 5}},
+ {"\U00000a03\U00000308\U00000378", {2563, 888}, {5, 7}},
+ {"\U00001100\U00000020", {4352, 32}, {3, 4}},
+ {"\U00001100\U00000308\U00000020", {4352, 32}, {5, 6}},
+ {"\U00001100\U0000000d", {4352, 13}, {3, 4}},
+ {"\U00001100\U00000308\U0000000d", {4352, 13}, {5, 6}},
+ {"\U00001100\U0000000a", {4352, 10}, {3, 4}},
+ {"\U00001100\U00000308\U0000000a", {4352, 10}, {5, 6}},
+ {"\U00001100\U00000001", {4352, 1}, {3, 4}},
+ {"\U00001100\U00000308\U00000001", {4352, 1}, {5, 6}},
+ {"\U00001100\U0000200c", {4352}, {6}},
+ {"\U00001100\U00000308\U0000200c", {4352}, {8}},
+ {"\U00001100\U0001f1e6", {4352, 127462}, {3, 7}},
+ {"\U00001100\U00000308\U0001f1e6", {4352, 127462}, {5, 9}},
+ {"\U00001100\U00000600", {4352, 1536}, {3, 5}},
+ {"\U00001100\U00000308\U00000600", {4352, 1536}, {5, 7}},
+ {"\U00001100\U00000a03", {4352}, {6}},
+ {"\U00001100\U00000308\U00000a03", {4352}, {8}},
+ {"\U00001100\U00001100", {4352}, {6}},
+ {"\U00001100\U00000308\U00001100", {4352, 4352}, {5, 8}},
+ {"\U00001100\U00001160", {4352}, {6}},
+ {"\U00001100\U00000308\U00001160", {4352, 4448}, {5, 8}},
+ {"\U00001100\U000011a8", {4352, 4520}, {3, 6}},
+ {"\U00001100\U00000308\U000011a8", {4352, 4520}, {5, 8}},
+ {"\U00001100\U0000ac00", {4352}, {6}},
+ {"\U00001100\U00000308\U0000ac00", {4352, 44032}, {5, 8}},
+ {"\U00001100\U0000ac01", {4352}, {6}},
+ {"\U00001100\U00000308\U0000ac01", {4352, 44033}, {5, 8}},
+ {"\U00001100\U00000903", {4352}, {6}},
+ {"\U00001100\U00000308\U00000903", {4352}, {8}},
+ {"\U00001100\U00000904", {4352, 2308}, {3, 6}},
+ {"\U00001100\U00000308\U00000904", {4352, 2308}, {5, 8}},
+ {"\U00001100\U00000d4e", {4352, 3406}, {3, 6}},
+ {"\U00001100\U00000308\U00000d4e", {4352, 3406}, {5, 8}},
+ {"\U00001100\U00000915", {4352, 2325}, {3, 6}},
+ {"\U00001100\U00000308\U00000915", {4352, 2325}, {5, 8}},
+ {"\U00001100\U0000231a", {4352, 8986}, {3, 6}},
+ {"\U00001100\U00000308\U0000231a", {4352, 8986}, {5, 8}},
+ {"\U00001100\U00000300", {4352}, {5}},
+ {"\U00001100\U00000308\U00000300", {4352}, {7}},
+ {"\U00001100\U00000900", {4352}, {6}},
+ {"\U00001100\U00000308\U00000900", {4352}, {8}},
+ {"\U00001100\U0000094d", {4352}, {6}},
+ {"\U00001100\U00000308\U0000094d", {4352}, {8}},
+ {"\U00001100\U0000200d", {4352}, {6}},
+ {"\U00001100\U00000308\U0000200d", {4352}, {8}},
+ {"\U00001100\U00000378", {4352, 888}, {3, 5}},
+ {"\U00001100\U00000308\U00000378", {4352, 888}, {5, 7}},
+ {"\U00001160\U00000020", {4448, 32}, {3, 4}},
+ {"\U00001160\U00000308\U00000020", {4448, 32}, {5, 6}},
+ {"\U00001160\U0000000d", {4448, 13}, {3, 4}},
+ {"\U00001160\U00000308\U0000000d", {4448, 13}, {5, 6}},
+ {"\U00001160\U0000000a", {4448, 10}, {3, 4}},
+ {"\U00001160\U00000308\U0000000a", {4448, 10}, {5, 6}},
+ {"\U00001160\U00000001", {4448, 1}, {3, 4}},
+ {"\U00001160\U00000308\U00000001", {4448, 1}, {5, 6}},
+ {"\U00001160\U0000200c", {4448}, {6}},
+ {"\U00001160\U00000308\U0000200c", {4448}, {8}},
+ {"\U00001160\U0001f1e6", {4448, 127462}, {3, 7}},
+ {"\U00001160\U00000308\U0001f1e6", {4448, 127462}, {5, 9}},
+ {"\U00001160\U00000600", {4448, 1536}, {3, 5}},
+ {"\U00001160\U00000308\U00000600", {4448, 1536}, {5, 7}},
+ {"\U00001160\U00000a03", {4448}, {6}},
+ {"\U00001160\U00000308\U00000a03", {4448}, {8}},
+ {"\U00001160\U00001100", {4448, 4352}, {3, 6}},
+ {"\U00001160\U00000308\U00001100", {4448, 4352}, {5, 8}},
+ {"\U00001160\U00001160", {4448}, {6}},
+ {"\U00001160\U00000308\U00001160", {4448, 4448}, {5, 8}},
+ {"\U00001160\U000011a8", {4448}, {6}},
+ {"\U00001160\U00000308\U000011a8", {4448, 4520}, {5, 8}},
+ {"\U00001160\U0000ac00", {4448, 44032}, {3, 6}},
+ {"\U00001160\U00000308\U0000ac00", {4448, 44032}, {5, 8}},
+ {"\U00001160\U0000ac01", {4448, 44033}, {3, 6}},
+ {"\U00001160\U00000308\U0000ac01", {4448, 44033}, {5, 8}},
+ {"\U00001160\U00000903", {4448}, {6}},
+ {"\U00001160\U00000308\U00000903", {4448}, {8}},
+ {"\U00001160\U00000904", {4448, 2308}, {3, 6}},
+ {"\U00001160\U00000308\U00000904", {4448, 2308}, {5, 8}},
+ {"\U00001160\U00000d4e", {4448, 3406}, {3, 6}},
+ {"\U00001160\U00000308\U00000d4e", {4448, 3406}, {5, 8}},
+ {"\U00001160\U00000915", {4448, 2325}, {3, 6}},
+ {"\U00001160\U00000308\U00000915", {4448, 2325}, {5, 8}},
+ {"\U00001160\U0000231a", {4448, 8986}, {3, 6}},
+ {"\U00001160\U00000308\U0000231a", {4448, 8986}, {5, 8}},
+ {"\U00001160\U00000300", {4448}, {5}},
+ {"\U00001160\U00000308\U00000300", {4448}, {7}},
+ {"\U00001160\U00000900", {4448}, {6}},
+ {"\U00001160\U00000308\U00000900", {4448}, {8}},
+ {"\U00001160\U0000094d", {4448}, {6}},
+ {"\U00001160\U00000308\U0000094d", {4448}, {8}},
+ {"\U00001160\U0000200d", {4448}, {6}},
+ {"\U00001160\U00000308\U0000200d", {4448}, {8}},
+ {"\U00001160\U00000378", {4448, 888}, {3, 5}},
+ {"\U00001160\U00000308\U00000378", {4448, 888}, {5, 7}},
+ {"\U000011a8\U00000020", {4520, 32}, {3, 4}},
+ {"\U000011a8\U00000308\U00000020", {4520, 32}, {5, 6}},
+ {"\U000011a8\U0000000d", {4520, 13}, {3, 4}},
+ {"\U000011a8\U00000308\U0000000d", {4520, 13}, {5, 6}},
+ {"\U000011a8\U0000000a", {4520, 10}, {3, 4}},
+ {"\U000011a8\U00000308\U0000000a", {4520, 10}, {5, 6}},
+ {"\U000011a8\U00000001", {4520, 1}, {3, 4}},
+ {"\U000011a8\U00000308\U00000001", {4520, 1}, {5, 6}},
+ {"\U000011a8\U0000200c", {4520}, {6}},
+ {"\U000011a8\U00000308\U0000200c", {4520}, {8}},
+ {"\U000011a8\U0001f1e6", {4520, 127462}, {3, 7}},
+ {"\U000011a8\U00000308\U0001f1e6", {4520, 127462}, {5, 9}},
+ {"\U000011a8\U00000600", {4520, 1536}, {3, 5}},
+ {"\U000011a8\U00000308\U00000600", {4520, 1536}, {5, 7}},
+ {"\U000011a8\U00000a03", {4520}, {6}},
+ {"\U000011a8\U00000308\U00000a03", {4520}, {8}},
+ {"\U000011a8\U00001100", {4520, 4352}, {3, 6}},
+ {"\U000011a8\U00000308\U00001100", {4520, 4352}, {5, 8}},
+ {"\U000011a8\U00001160", {4520, 4448}, {3, 6}},
+ {"\U000011a8\U00000308\U00001160", {4520, 4448}, {5, 8}},
+ {"\U000011a8\U000011a8", {4520}, {6}},
+ {"\U000011a8\U00000308\U000011a8", {4520, 4520}, {5, 8}},
+ {"\U000011a8\U0000ac00", {4520, 44032}, {3, 6}},
+ {"\U000011a8\U00000308\U0000ac00", {4520, 44032}, {5, 8}},
+ {"\U000011a8\U0000ac01", {4520, 44033}, {3, 6}},
+ {"\U000011a8\U00000308\U0000ac01", {4520, 44033}, {5, 8}},
+ {"\U000011a8\U00000903", {4520}, {6}},
+ {"\U000011a8\U00000308\U00000903", {4520}, {8}},
+ {"\U000011a8\U00000904", {4520, 2308}, {3, 6}},
+ {"\U000011a8\U00000308\U00000904", {4520, 2308}, {5, 8}},
+ {"\U000011a8\U00000d4e", {4520, 3406}, {3, 6}},
+ {"\U000011a8\U00000308\U00000d4e", {4520, 3406}, {5, 8}},
+ {"\U000011a8\U00000915", {4520, 2325}, {3, 6}},
+ {"\U000011a8\U00000308\U00000915", {4520, 2325}, {5, 8}},
+ {"\U000011a8\U0000231a", {4520, 8986}, {3, 6}},
+ {"\U000011a8\U00000308\U0000231a", {4520, 8986}, {5, 8}},
+ {"\U000011a8\U00000300", {4520}, {5}},
+ {"\U000011a8\U00000308\U00000300", {4520}, {7}},
+ {"\U000011a8\U00000900", {4520}, {6}},
+ {"\U000011a8\U00000308\U00000900", {4520}, {8}},
+ {"\U000011a8\U0000094d", {4520}, {6}},
+ {"\U000011a8\U00000308\U0000094d", {4520}, {8}},
+ {"\U000011a8\U0000200d", {4520}, {6}},
+ {"\U000011a8\U00000308\U0000200d", {4520}, {8}},
+ {"\U000011a8\U00000378", {4520, 888}, {3, 5}},
+ {"\U000011a8\U00000308\U00000378", {4520, 888}, {5, 7}},
+ {"\U0000ac00\U00000020", {44032, 32}, {3, 4}},
+ {"\U0000ac00\U00000308\U00000020", {44032, 32}, {5, 6}},
+ {"\U0000ac00\U0000000d", {44032, 13}, {3, 4}},
+ {"\U0000ac00\U00000308\U0000000d", {44032, 13}, {5, 6}},
+ {"\U0000ac00\U0000000a", {44032, 10}, {3, 4}},
+ {"\U0000ac00\U00000308\U0000000a", {44032, 10}, {5, 6}},
+ {"\U0000ac00\U00000001", {44032, 1}, {3, 4}},
+ {"\U0000ac00\U00000308\U00000001", {44032, 1}, {5, 6}},
+ {"\U0000ac00\U0000200c", {44032}, {6}},
+ {"\U0000ac00\U00000308\U0000200c", {44032}, {8}},
+ {"\U0000ac00\U0001f1e6", {44032, 127462}, {3, 7}},
+ {"\U0000ac00\U00000308\U0001f1e6", {44032, 127462}, {5, 9}},
+ {"\U0000ac00\U00000600", {44032, 1536}, {3, 5}},
+ {"\U0000ac00\U00000308\U00000600", {44032, 1536}, {5, 7}},
+ {"\U0000ac00\U00000a03", {44032}, {6}},
+ {"\U0000ac00\U00000308\U00000a03", {44032}, {8}},
+ {"\U0000ac00\U00001100", {44032, 4352}, {3, 6}},
+ {"\U0000ac00\U00000308\U00001100", {44032, 4352}, {5, 8}},
+ {"\U0000ac00\U00001160", {44032}, {6}},
+ {"\U0000ac00\U00000308\U00001160", {44032, 4448}, {5, 8}},
+ {"\U0000ac00\U000011a8", {44032}, {6}},
+ {"\U0000ac00\U00000308\U000011a8", {44032, 4520}, {5, 8}},
+ {"\U0000ac00\U0000ac00", {44032, 44032}, {3, 6}},
+ {"\U0000ac00\U00000308\U0000ac00", {44032, 44032}, {5, 8}},
+ {"\U0000ac00\U0000ac01", {44032, 44033}, {3, 6}},
+ {"\U0000ac00\U00000308\U0000ac01", {44032, 44033}, {5, 8}},
+ {"\U0000ac00\U00000903", {44032}, {6}},
+ {"\U0000ac00\U00000308\U00000903", {44032}, {8}},
+ {"\U0000ac00\U00000904", {44032, 2308}, {3, 6}},
+ {"\U0000ac00\U00000308\U00000904", {44032, 2308}, {5, 8}},
+ {"\U0000ac00\U00000d4e", {44032, 3406}, {3, 6}},
+ {"\U0000ac00\U00000308\U00000d4e", {44032, 3406}, {5, 8}},
+ {"\U0000ac00\U00000915", {44032, 2325}, {3, 6}},
+ {"\U0000ac00\U00000308\U00000915", {44032, 2325}, {5, 8}},
+ {"\U0000ac00\U0000231a", {44032, 8986}, {3, 6}},
+ {"\U0000ac00\U00000308\U0000231a", {44032, 8986}, {5, 8}},
+ {"\U0000ac00\U00000300", {44032}, {5}},
+ {"\U0000ac00\U00000308\U00000300", {44032}, {7}},
+ {"\U0000ac00\U00000900", {44032}, {6}},
+ {"\U0000ac00\U00000308\U00000900", {44032}, {8}},
+ {"\U0000ac00\U0000094d", {44032}, {6}},
+ {"\U0000ac00\U00000308\U0000094d", {44032}, {8}},
+ {"\U0000ac00\U0000200d", {44032}, {6}},
+ {"\U0000ac00\U00000308\U0000200d", {44032}, {8}},
+ {"\U0000ac00\U00000378", {44032, 888}, {3, 5}},
+ {"\U0000ac00\U00000308\U00000378", {44032, 888}, {5, 7}},
+ {"\U0000ac01\U00000020", {44033, 32}, {3, 4}},
+ {"\U0000ac01\U00000308\U00000020", {44033, 32}, {5, 6}},
+ {"\U0000ac01\U0000000d", {44033, 13}, {3, 4}},
+ {"\U0000ac01\U00000308\U0000000d", {44033, 13}, {5, 6}},
+ {"\U0000ac01\U0000000a", {44033, 10}, {3, 4}},
+ {"\U0000ac01\U00000308\U0000000a", {44033, 10}, {5, 6}},
+ {"\U0000ac01\U00000001", {44033, 1}, {3, 4}},
+ {"\U0000ac01\U00000308\U00000001", {44033, 1}, {5, 6}},
+ {"\U0000ac01\U0000200c", {44033}, {6}},
+ {"\U0000ac01\U00000308\U0000200c", {44033}, {8}},
+ {"\U0000ac01\U0001f1e6", {44033, 127462}, {3, 7}},
+ {"\U0000ac01\U00000308\U0001f1e6", {44033, 127462}, {5, 9}},
+ {"\U0000ac01\U00000600", {44033, 1536}, {3, 5}},
+ {"\U0000ac01\U00000308\U00000600", {44033, 1536}, {5, 7}},
+ {"\U0000ac01\U00000a03", {44033}, {6}},
+ {"\U0000ac01\U00000308\U00000a03", {44033}, {8}},
+ {"\U0000ac01\U00001100", {44033, 4352}, {3, 6}},
+ {"\U0000ac01\U00000308\U00001100", {44033, 4352}, {5, 8}},
+ {"\U0000ac01\U00001160", {44033, 4448}, {3, 6}},
+ {"\U0000ac01\U00000308\U00001160", {44033, 4448}, {5, 8}},
+ {"\U0000ac01\U000011a8", {44033}, {6}},
+ {"\U0000ac01\U00000308\U000011a8", {44033, 4520}, {5, 8}},
+ {"\U0000ac01\U0000ac00", {44033, 44032}, {3, 6}},
+ {"\U0000ac01\U00000308\U0000ac00", {44033, 44032}, {5, 8}},
+ {"\U0000ac01\U0000ac01", {44033, 44033}, {3, 6}},
+ {"\U0000ac01\U00000308\U0000ac01", {44033, 44033}, {5, 8}},
+ {"\U0000ac01\U00000903", {44033}, {6}},
+ {"\U0000ac01\U00000308\U00000903", {44033}, {8}},
+ {"\U0000ac01\U00000904", {44033, 2308}, {3, 6}},
+ {"\U0000ac01\U00000308\U00000904", {44033, 2308}, {5, 8}},
+ {"\U0000ac01\U00000d4e", {44033, 3406}, {3, 6}},
+ {"\U0000ac01\U00000308\U00000d4e", {44033, 3406}, {5, 8}},
+ {"\U0000ac01\U00000915", {44033, 2325}, {3, 6}},
+ {"\U0000ac01\U00000308\U00000915", {44033, 2325}, {5, 8}},
+ {"\U0000ac01\U0000231a", {44033, 8986}, {3, 6}},
+ {"\U0000ac01\U00000308\U0000231a", {44033, 8986}, {5, 8}},
+ {"\U0000ac01\U00000300", {44033}, {5}},
+ {"\U0000ac01\U00000308\U00000300", {44033}, {7}},
+ {"\U0000ac01\U00000900", {44033}, {6}},
+ {"\U0000ac01\U00000308\U00000900", {44033}, {8}},
+ {"\U0000ac01\U0000094d", {44033}, {6}},
+ {"\U0000ac01\U00000308\U0000094d", {44033}, {8}},
+ {"\U0000ac01\U0000200d", {44033}, {6}},
+ {"\U0000ac01\U00000308\U0000200d", {44033}, {8}},
+ {"\U0000ac01\U00000378", {44033, 888}, {3, 5}},
+ {"\U0000ac01\U00000308\U00000378", {44033, 888}, {5, 7}},
+ {"\U00000903\U00000020", {2307, 32}, {3, 4}},
+ {"\U00000903\U00000308\U00000020", {2307, 32}, {5, 6}},
+ {"\U00000903\U0000000d", {2307, 13}, {3, 4}},
+ {"\U00000903\U00000308\U0000000d", {2307, 13}, {5, 6}},
+ {"\U00000903\U0000000a", {2307, 10}, {3, 4}},
+ {"\U00000903\U00000308\U0000000a", {2307, 10}, {5, 6}},
+ {"\U00000903\U00000001", {2307, 1}, {3, 4}},
+ {"\U00000903\U00000308\U00000001", {2307, 1}, {5, 6}},
+ {"\U00000903\U0000200c", {2307}, {6}},
+ {"\U00000903\U00000308\U0000200c", {2307}, {8}},
+ {"\U00000903\U0001f1e6", {2307, 127462}, {3, 7}},
+ {"\U00000903\U00000308\U0001f1e6", {2307, 127462}, {5, 9}},
+ {"\U00000903\U00000600", {2307, 1536}, {3, 5}},
+ {"\U00000903\U00000308\U00000600", {2307, 1536}, {5, 7}},
+ {"\U00000903\U00000a03", {2307}, {6}},
+ {"\U00000903\U00000308\U00000a03", {2307}, {8}},
+ {"\U00000903\U00001100", {2307, 4352}, {3, 6}},
+ {"\U00000903\U00000308\U00001100", {2307, 4352}, {5, 8}},
+ {"\U00000903\U00001160", {2307, 4448}, {3, 6}},
+ {"\U00000903\U00000308\U00001160", {2307, 4448}, {5, 8}},
+ {"\U00000903\U000011a8", {2307, 4520}, {3, 6}},
+ {"\U00000903\U00000308\U000011a8", {2307, 4520}, {5, 8}},
+ {"\U00000903\U0000ac00", {2307, 44032}, {3, 6}},
+ {"\U00000903\U00000308\U0000ac00", {2307, 44032}, {5, 8}},
+ {"\U00000903\U0000ac01", {2307, 44033}, {3, 6}},
+ {"\U00000903\U00000308\U0000ac01", {2307, 44033}, {5, 8}},
+ {"\U00000903\U00000903", {2307}, {6}},
+ {"\U00000903\U00000308\U00000903", {2307}, {8}},
+ {"\U00000903\U00000904", {2307, 2308}, {3, 6}},
+ {"\U00000903\U00000308\U00000904", {2307, 2308}, {5, 8}},
+ {"\U00000903\U00000d4e", {2307, 3406}, {3, 6}},
+ {"\U00000903\U00000308\U00000d4e", {2307, 3406}, {5, 8}},
+ {"\U00000903\U00000915", {2307, 2325}, {3, 6}},
+ {"\U00000903\U00000308\U00000915", {2307, 2325}, {5, 8}},
+ {"\U00000903\U0000231a", {2307, 8986}, {3, 6}},
+ {"\U00000903\U00000308\U0000231a", {2307, 8986}, {5, 8}},
+ {"\U00000903\U00000300", {2307}, {5}},
+ {"\U00000903\U00000308\U00000300", {2307}, {7}},
+ {"\U00000903\U00000900", {2307}, {6}},
+ {"\U00000903\U00000308\U00000900", {2307}, {8}},
+ {"\U00000903\U0000094d", {2307}, {6}},
+ {"\U00000903\U00000308\U0000094d", {2307}, {8}},
+ {"\U00000903\U0000200d", {2307}, {6}},
+ {"\U00000903\U00000308\U0000200d", {2307}, {8}},
+ {"\U00000903\U00000378", {2307, 888}, {3, 5}},
+ {"\U00000903\U00000308\U00000378", {2307, 888}, {5, 7}},
+ {"\U00000904\U00000020", {2308, 32}, {3, 4}},
+ {"\U00000904\U00000308\U00000020", {2308, 32}, {5, 6}},
+ {"\U00000904\U0000000d", {2308, 13}, {3, 4}},
+ {"\U00000904\U00000308\U0000000d", {2308, 13}, {5, 6}},
+ {"\U00000904\U0000000a", {2308, 10}, {3, 4}},
+ {"\U00000904\U00000308\U0000000a", {2308, 10}, {5, 6}},
+ {"\U00000904\U00000001", {2308, 1}, {3, 4}},
+ {"\U00000904\U00000308\U00000001", {2308, 1}, {5, 6}},
+ {"\U00000904\U0000200c", {2308}, {6}},
+ {"\U00000904\U00000308\U0000200c", {2308}, {8}},
+ {"\U00000904\U0001f1e6", {2308, 127462}, {3, 7}},
+ {"\U00000904\U00000308\U0001f1e6", {2308, 127462}, {5, 9}},
+ {"\U00000904\U00000600", {2308, 1536}, {3, 5}},
+ {"\U00000904\U00000308\U00000600", {2308, 1536}, {5, 7}},
+ {"\U00000904\U00000a03", {2308}, {6}},
+ {"\U00000904\U00000308\U00000a03", {2308}, {8}},
+ {"\U00000904\U00001100", {2308, 4352}, {3, 6}},
+ {"\U00000904\U00000308\U00001100", {2308, 4352}, {5, 8}},
+ {"\U00000904\U00001160", {2308, 4448}, {3, 6}},
+ {"\U00000904\U00000308\U00001160", {2308, 4448}, {5, 8}},
+ {"\U00000904\U000011a8", {2308, 4520}, {3, 6}},
+ {"\U00000904\U00000308\U000011a8", {2308, 4520}, {5, 8}},
+ {"\U00000904\U0000ac00", {2308, 44032}, {3, 6}},
+ {"\U00000904\U00000308\U0000ac00", {2308, 44032}, {5, 8}},
+ {"\U00000904\U0000ac01", {2308, 44033}, {3, 6}},
+ {"\U00000904\U00000308\U0000ac01", {2308, 44033}, {5, 8}},
+ {"\U00000904\U00000903", {2308}, {6}},
+ {"\U00000904\U00000308\U00000903", {2308}, {8}},
+ {"\U00000904\U00000904", {2308, 2308}, {3, 6}},
+ {"\U00000904\U00000308\U00000904", {2308, 2308}, {5, 8}},
+ {"\U00000904\U00000d4e", {2308, 3406}, {3, 6}},
+ {"\U00000904\U00000308\U00000d4e", {2308, 3406}, {5, 8}},
+ {"\U00000904\U00000915", {2308, 2325}, {3, 6}},
+ {"\U00000904\U00000308\U00000915", {2308, 2325}, {5, 8}},
+ {"\U00000904\U0000231a", {2308, 8986}, {3, 6}},
+ {"\U00000904\U00000308\U0000231a", {2308, 8986}, {5, 8}},
+ {"\U00000904\U00000300", {2308}, {5}},
+ {"\U00000904\U00000308\U00000300", {2308}, {7}},
+ {"\U00000904\U00000900", {2308}, {6}},
+ {"\U00000904\U00000308\U00000900", {2308}, {8}},
+ {"\U00000904\U0000094d", {2308}, {6}},
+ {"\U00000904\U00000308\U0000094d", {2308}, {8}},
+ {"\U00000904\U0000200d", {2308}, {6}},
+ {"\U00000904\U00000308\U0000200d", {2308}, {8}},
+ {"\U00000904\U00000378", {2308, 888}, {3, 5}},
+ {"\U00000904\U00000308\U00000378", {2308, 888}, {5, 7}},
+ {"\U00000d4e\U00000020", {3406}, {4}},
+ {"\U00000d4e\U00000308\U00000020", {3406, 32}, {5, 6}},
+ {"\U00000d4e\U0000000d", {3406, 13}, {3, 4}},
+ {"\U00000d4e\U00000308\U0000000d", {3406, 13}, {5, 6}},
+ {"\U00000d4e\U0000000a", {3406, 10}, {3, 4}},
+ {"\U00000d4e\U00000308\U0000000a", {3406, 10}, {5, 6}},
+ {"\U00000d4e\U00000001", {3406, 1}, {3, 4}},
+ {"\U00000d4e\U00000308\U00000001", {3406, 1}, {5, 6}},
+ {"\U00000d4e\U0000200c", {3406}, {6}},
+ {"\U00000d4e\U00000308\U0000200c", {3406}, {8}},
+ {"\U00000d4e\U0001f1e6", {3406}, {7}},
+ {"\U00000d4e\U00000308\U0001f1e6", {3406, 127462}, {5, 9}},
+ {"\U00000d4e\U00000600", {3406}, {5}},
+ {"\U00000d4e\U00000308\U00000600", {3406, 1536}, {5, 7}},
+ {"\U00000d4e\U00000a03", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00000a03", {3406}, {8}},
+ {"\U00000d4e\U00001100", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00001100", {3406, 4352}, {5, 8}},
+ {"\U00000d4e\U00001160", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00001160", {3406, 4448}, {5, 8}},
+ {"\U00000d4e\U000011a8", {3406}, {6}},
+ {"\U00000d4e\U00000308\U000011a8", {3406, 4520}, {5, 8}},
+ {"\U00000d4e\U0000ac00", {3406}, {6}},
+ {"\U00000d4e\U00000308\U0000ac00", {3406, 44032}, {5, 8}},
+ {"\U00000d4e\U0000ac01", {3406}, {6}},
+ {"\U00000d4e\U00000308\U0000ac01", {3406, 44033}, {5, 8}},
+ {"\U00000d4e\U00000903", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00000903", {3406}, {8}},
+ {"\U00000d4e\U00000904", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00000904", {3406, 2308}, {5, 8}},
+ {"\U00000d4e\U00000d4e", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00000d4e", {3406, 3406}, {5, 8}},
+ {"\U00000d4e\U00000915", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00000915", {3406, 2325}, {5, 8}},
+ {"\U00000d4e\U0000231a", {3406}, {6}},
+ {"\U00000d4e\U00000308\U0000231a", {3406, 8986}, {5, 8}},
+ {"\U00000d4e\U00000300", {3406}, {5}},
+ {"\U00000d4e\U00000308\U00000300", {3406}, {7}},
+ {"\U00000d4e\U00000900", {3406}, {6}},
+ {"\U00000d4e\U00000308\U00000900", {3406}, {8}},
+ {"\U00000d4e\U0000094d", {3406}, {6}},
+ {"\U00000d4e\U00000308\U0000094d", {3406}, {8}},
+ {"\U00000d4e\U0000200d", {3406}, {6}},
+ {"\U00000d4e\U00000308\U0000200d", {3406}, {8}},
+ {"\U00000d4e\U00000378", {3406}, {5}},
+ {"\U00000d4e\U00000308\U00000378", {3406, 888}, {5, 7}},
+ {"\U00000915\U00000020", {2325, 32}, {3, 4}},
+ {"\U00000915\U00000308\U00000020", {2325, 32}, {5, 6}},
+ {"\U00000915\U0000000d", {2325, 13}, {3, 4}},
+ {"\U00000915\U00000308\U0000000d", {2325, 13}, {5, 6}},
+ {"\U00000915\U0000000a", {2325, 10}, {3, 4}},
+ {"\U00000915\U00000308\U0000000a", {2325, 10}, {5, 6}},
+ {"\U00000915\U00000001", {2325, 1}, {3, 4}},
+ {"\U00000915\U00000308\U00000001", {2325, 1}, {5, 6}},
+ {"\U00000915\U0000200c", {2325}, {6}},
+ {"\U00000915\U00000308\U0000200c", {2325}, {8}},
+ {"\U00000915\U0001f1e6", {2325, 127462}, {3, 7}},
+ {"\U00000915\U00000308\U0001f1e6", {2325, 127462}, {5, 9}},
+ {"\U00000915\U00000600", {2325, 1536}, {3, 5}},
+ {"\U00000915\U00000308\U00000600", {2325, 1536}, {5, 7}},
+ {"\U00000915\U00000a03", {2325}, {6}},
+ {"\U00000915\U00000308\U00000a03", {2325}, {8}},
+ {"\U00000915\U00001100", {2325, 4352}, {3, 6}},
+ {"\U00000915\U00000308\U00001100", {2325, 4352}, {5, 8}},
+ {"\U00000915\U00001160", {2325, 4448}, {3, 6}},
+ {"\U00000915\U00000308\U00001160", {2325, 4448}, {5, 8}},
+ {"\U00000915\U000011a8", {2325, 4520}, {3, 6}},
+ {"\U00000915\U00000308\U000011a8", {2325, 4520}, {5, 8}},
+ {"\U00000915\U0000ac00", {2325, 44032}, {3, 6}},
+ {"\U00000915\U00000308\U0000ac00", {2325, 44032}, {5, 8}},
+ {"\U00000915\U0000ac01", {2325, 44033}, {3, 6}},
+ {"\U00000915\U00000308\U0000ac01", {2325, 44033}, {5, 8}},
+ {"\U00000915\U00000903", {2325}, {6}},
+ {"\U00000915\U00000308\U00000903", {2325}, {8}},
+ {"\U00000915\U00000904", {2325, 2308}, {3, 6}},
+ {"\U00000915\U00000308\U00000904", {2325, 2308}, {5, 8}},
+ {"\U00000915\U00000d4e", {2325, 3406}, {3, 6}},
+ {"\U00000915\U00000308\U00000d4e", {2325, 3406}, {5, 8}},
+ {"\U00000915\U00000915", {2325, 2325}, {3, 6}},
+ {"\U00000915\U00000308\U00000915", {2325, 2325}, {5, 8}},
+ {"\U00000915\U0000231a", {2325, 8986}, {3, 6}},
+ {"\U00000915\U00000308\U0000231a", {2325, 8986}, {5, 8}},
+ {"\U00000915\U00000300", {2325}, {5}},
+ {"\U00000915\U00000308\U00000300", {2325}, {7}},
+ {"\U00000915\U00000900", {2325}, {6}},
+ {"\U00000915\U00000308\U00000900", {2325}, {8}},
+ {"\U00000915\U0000094d", {2325}, {6}},
+ {"\U00000915\U00000308\U0000094d", {2325}, {8}},
+ {"\U00000915\U0000200d", {2325}, {6}},
+ {"\U00000915\U00000308\U0000200d", {2325}, {8}},
+ {"\U00000915\U00000378", {2325, 888}, {3, 5}},
+ {"\U00000915\U00000308\U00000378", {2325, 888}, {5, 7}},
+ {"\U0000231a\U00000020", {8986, 32}, {3, 4}},
+ {"\U0000231a\U00000308\U00000020", {8986, 32}, {5, 6}},
+ {"\U0000231a\U0000000d", {8986, 13}, {3, 4}},
+ {"\U0000231a\U00000308\U0000000d", {8986, 13}, {5, 6}},
+ {"\U0000231a\U0000000a", {8986, 10}, {3, 4}},
+ {"\U0000231a\U00000308\U0000000a", {8986, 10}, {5, 6}},
+ {"\U0000231a\U00000001", {8986, 1}, {3, 4}},
+ {"\U0000231a\U00000308\U00000001", {8986, 1}, {5, 6}},
+ {"\U0000231a\U0000200c", {8986}, {6}},
+ {"\U0000231a\U00000308\U0000200c", {8986}, {8}},
+ {"\U0000231a\U0001f1e6", {8986, 127462}, {3, 7}},
+ {"\U0000231a\U00000308\U0001f1e6", {8986, 127462}, {5, 9}},
+ {"\U0000231a\U00000600", {8986, 1536}, {3, 5}},
+ {"\U0000231a\U00000308\U00000600", {8986, 1536}, {5, 7}},
+ {"\U0000231a\U00000a03", {8986}, {6}},
+ {"\U0000231a\U00000308\U00000a03", {8986}, {8}},
+ {"\U0000231a\U00001100", {8986, 4352}, {3, 6}},
+ {"\U0000231a\U00000308\U00001100", {8986, 4352}, {5, 8}},
+ {"\U0000231a\U00001160", {8986, 4448}, {3, 6}},
+ {"\U0000231a\U00000308\U00001160", {8986, 4448}, {5, 8}},
+ {"\U0000231a\U000011a8", {8986, 4520}, {3, 6}},
+ {"\U0000231a\U00000308\U000011a8", {8986, 4520}, {5, 8}},
+ {"\U0000231a\U0000ac00", {8986, 44032}, {3, 6}},
+ {"\U0000231a\U00000308\U0000ac00", {8986, 44032}, {5, 8}},
+ {"\U0000231a\U0000ac01", {8986, 44033}, {3, 6}},
+ {"\U0000231a\U00000308\U0000ac01", {8986, 44033}, {5, 8}},
+ {"\U0000231a\U00000903", {8986}, {6}},
+ {"\U0000231a\U00000308\U00000903", {8986}, {8}},
+ {"\U0000231a\U00000904", {8986, 2308}, {3, 6}},
+ {"\U0000231a\U00000308\U00000904", {8986, 2308}, {5, 8}},
+ {"\U0000231a\U00000d4e", {8986, 3406}, {3, 6}},
+ {"\U0000231a\U00000308\U00000d4e", {8986, 3406}, {5, 8}},
+ {"\U0000231a\U00000915", {8986, 2325}, {3, 6}},
+ {"\U0000231a\U00000308\U00000915", {8986, 2325}, {5, 8}},
+ {"\U0000231a\U0000231a", {8986, 8986}, {3, 6}},
+ {"\U0000231a\U00000308\U0000231a", {8986, 8986}, {5, 8}},
+ {"\U0000231a\U00000300", {8986}, {5}},
+ {"\U0000231a\U00000308\U00000300", {8986}, {7}},
+ {"\U0000231a\U00000900", {8986}, {6}},
+ {"\U0000231a\U00000308\U00000900", {8986}, {8}},
+ {"\U0000231a\U0000094d", {8986}, {6}},
+ {"\U0000231a\U00000308\U0000094d", {8986}, {8}},
+ {"\U0000231a\U0000200d", {8986}, {6}},
+ {"\U0000231a\U00000308\U0000200d", {8986}, {8}},
+ {"\U0000231a\U00000378", {8986, 888}, {3, 5}},
+ {"\U0000231a\U00000308\U00000378", {8986, 888}, {5, 7}},
+ {"\U00000300\U00000020", {768, 32}, {2, 3}},
+ {"\U00000300\U00000308\U00000020", {768, 32}, {4, 5}},
+ {"\U00000300\U0000000d", {768, 13}, {2, 3}},
+ {"\U00000300\U00000308\U0000000d", {768, 13}, {4, 5}},
+ {"\U00000300\U0000000a", {768, 10}, {2, 3}},
+ {"\U00000300\U00000308\U0000000a", {768, 10}, {4, 5}},
+ {"\U00000300\U00000001", {768, 1}, {2, 3}},
+ {"\U00000300\U00000308\U00000001", {768, 1}, {4, 5}},
+ {"\U00000300\U0000200c", {768}, {5}},
+ {"\U00000300\U00000308\U0000200c", {768}, {7}},
+ {"\U00000300\U0001f1e6", {768, 127462}, {2, 6}},
+ {"\U00000300\U00000308\U0001f1e6", {768, 127462}, {4, 8}},
+ {"\U00000300\U00000600", {768, 1536}, {2, 4}},
+ {"\U00000300\U00000308\U00000600", {768, 1536}, {4, 6}},
+ {"\U00000300\U00000a03", {768}, {5}},
+ {"\U00000300\U00000308\U00000a03", {768}, {7}},
+ {"\U00000300\U00001100", {768, 4352}, {2, 5}},
+ {"\U00000300\U00000308\U00001100", {768, 4352}, {4, 7}},
+ {"\U00000300\U00001160", {768, 4448}, {2, 5}},
+ {"\U00000300\U00000308\U00001160", {768, 4448}, {4, 7}},
+ {"\U00000300\U000011a8", {768, 4520}, {2, 5}},
+ {"\U00000300\U00000308\U000011a8", {768, 4520}, {4, 7}},
+ {"\U00000300\U0000ac00", {768, 44032}, {2, 5}},
+ {"\U00000300\U00000308\U0000ac00", {768, 44032}, {4, 7}},
+ {"\U00000300\U0000ac01", {768, 44033}, {2, 5}},
+ {"\U00000300\U00000308\U0000ac01", {768, 44033}, {4, 7}},
+ {"\U00000300\U00000903", {768}, {5}},
+ {"\U00000300\U00000308\U00000903", {768}, {7}},
+ {"\U00000300\U00000904", {768, 2308}, {2, 5}},
+ {"\U00000300\U00000308\U00000904", {768, 2308}, {4, 7}},
+ {"\U00000300\U00000d4e", {768, 3406}, {2, 5}},
+ {"\U00000300\U00000308\U00000d4e", {768, 3406}, {4, 7}},
+ {"\U00000300\U00000915", {768, 2325}, {2, 5}},
+ {"\U00000300\U00000308\U00000915", {768, 2325}, {4, 7}},
+ {"\U00000300\U0000231a", {768, 8986}, {2, 5}},
+ {"\U00000300\U00000308\U0000231a", {768, 8986}, {4, 7}},
+ {"\U00000300\U00000300", {768}, {4}},
+ {"\U00000300\U00000308\U00000300", {768}, {6}},
+ {"\U00000300\U00000900", {768}, {5}},
+ {"\U00000300\U00000308\U00000900", {768}, {7}},
+ {"\U00000300\U0000094d", {768}, {5}},
+ {"\U00000300\U00000308\U0000094d", {768}, {7}},
+ {"\U00000300\U0000200d", {768}, {5}},
+ {"\U00000300\U00000308\U0000200d", {768}, {7}},
+ {"\U00000300\U00000378", {768, 888}, {2, 4}},
+ {"\U00000300\U00000308\U00000378", {768, 888}, {4, 6}},
+ {"\U00000900\U00000020", {2304, 32}, {3, 4}},
+ {"\U00000900\U00000308\U00000020", {2304, 32}, {5, 6}},
+ {"\U00000900\U0000000d", {2304, 13}, {3, 4}},
+ {"\U00000900\U00000308\U0000000d", {2304, 13}, {5, 6}},
+ {"\U00000900\U0000000a", {2304, 10}, {3, 4}},
+ {"\U00000900\U00000308\U0000000a", {2304, 10}, {5, 6}},
+ {"\U00000900\U00000001", {2304, 1}, {3, 4}},
+ {"\U00000900\U00000308\U00000001", {2304, 1}, {5, 6}},
+ {"\U00000900\U0000200c", {2304}, {6}},
+ {"\U00000900\U00000308\U0000200c", {2304}, {8}},
+ {"\U00000900\U0001f1e6", {2304, 127462}, {3, 7}},
+ {"\U00000900\U00000308\U0001f1e6", {2304, 127462}, {5, 9}},
+ {"\U00000900\U00000600", {2304, 1536}, {3, 5}},
+ {"\U00000900\U00000308\U00000600", {2304, 1536}, {5, 7}},
+ {"\U00000900\U00000a03", {2304}, {6}},
+ {"\U00000900\U00000308\U00000a03", {2304}, {8}},
+ {"\U00000900\U00001100", {2304, 4352}, {3, 6}},
+ {"\U00000900\U00000308\U00001100", {2304, 4352}, {5, 8}},
+ {"\U00000900\U00001160", {2304, 4448}, {3, 6}},
+ {"\U00000900\U00000308\U00001160", {2304, 4448}, {5, 8}},
+ {"\U00000900\U000011a8", {2304, 4520}, {3, 6}},
+ {"\U00000900\U00000308\U000011a8", {2304, 4520}, {5, 8}},
+ {"\U00000900\U0000ac00", {2304, 44032}, {3, 6}},
+ {"\U00000900\U00000308\U0000ac00", {2304, 44032}, {5, 8}},
+ {"\U00000900\U0000ac01", {2304, 44033}, {3, 6}},
+ {"\U00000900\U00000308\U0000ac01", {2304, 44033}, {5, 8}},
+ {"\U00000900\U00000903", {2304}, {6}},
+ {"\U00000900\U00000308\U00000903", {2304}, {8}},
+ {"\U00000900\U00000904", {2304, 2308}, {3, 6}},
+ {"\U00000900\U00000308\U00000904", {2304, 2308}, {5, 8}},
+ {"\U00000900\U00000d4e", {2304, 3406}, {3, 6}},
+ {"\U00000900\U00000308\U00000d4e", {2304, 3406}, {5, 8}},
+ {"\U00000900\U00000915", {2304, 2325}, {3, 6}},
+ {"\U00000900\U00000308\U00000915", {2304, 2325}, {5, 8}},
+ {"\U00000900\U0000231a", {2304, 8986}, {3, 6}},
+ {"\U00000900\U00000308\U0000231a", {2304, 8986}, {5, 8}},
+ {"\U00000900\U00000300", {2304}, {5}},
+ {"\U00000900\U00000308\U00000300", {2304}, {7}},
+ {"\U00000900\U00000900", {2304}, {6}},
+ {"\U00000900\U00000308\U00000900", {2304}, {8}},
+ {"\U00000900\U0000094d", {2304}, {6}},
+ {"\U00000900\U00000308\U0000094d", {2304}, {8}},
+ {"\U00000900\U0000200d", {2304}, {6}},
+ {"\U00000900\U00000308\U0000200d", {2304}, {8}},
+ {"\U00000900\U00000378", {2304, 888}, {3, 5}},
+ {"\U00000900\U00000308\U00000378", {2304, 888}, {5, 7}},
+ {"\U0000094d\U00000020", {2381, 32}, {3, 4}},
+ {"\U0000094d\U00000308\U00000020", {2381, 32}, {5, 6}},
+ {"\U0000094d\U0000000d", {2381, 13}, {3, 4}},
+ {"\U0000094d\U00000308\U0000000d", {2381, 13}, {5, 6}},
+ {"\U0000094d\U0000000a", {2381, 10}, {3, 4}},
+ {"\U0000094d\U00000308\U0000000a", {2381, 10}, {5, 6}},
+ {"\U0000094d\U00000001", {2381, 1}, {3, 4}},
+ {"\U0000094d\U00000308\U00000001", {2381, 1}, {5, 6}},
+ {"\U0000094d\U0000200c", {2381}, {6}},
+ {"\U0000094d\U00000308\U0000200c", {2381}, {8}},
+ {"\U0000094d\U0001f1e6", {2381, 127462}, {3, 7}},
+ {"\U0000094d\U00000308\U0001f1e6", {2381, 127462}, {5, 9}},
+ {"\U0000094d\U00000600", {2381, 1536}, {3, 5}},
+ {"\U0000094d\U00000308\U00000600", {2381, 1536}, {5, 7}},
+ {"\U0000094d\U00000a03", {2381}, {6}},
+ {"\U0000094d\U00000308\U00000a03", {2381}, {8}},
+ {"\U0000094d\U00001100", {2381, 4352}, {3, 6}},
+ {"\U0000094d\U00000308\U00001100", {2381, 4352}, {5, 8}},
+ {"\U0000094d\U00001160", {2381, 4448}, {3, 6}},
+ {"\U0000094d\U00000308\U00001160", {2381, 4448}, {5, 8}},
+ {"\U0000094d\U000011a8", {2381, 4520}, {3, 6}},
+ {"\U0000094d\U00000308\U000011a8", {2381, 4520}, {5, 8}},
+ {"\U0000094d\U0000ac00", {2381, 44032}, {3, 6}},
+ {"\U0000094d\U00000308\U0000ac00", {2381, 44032}, {5, 8}},
+ {"\U0000094d\U0000ac01", {2381, 44033}, {3, 6}},
+ {"\U0000094d\U00000308\U0000ac01", {2381, 44033}, {5, 8}},
+ {"\U0000094d\U00000903", {2381}, {6}},
+ {"\U0000094d\U00000308\U00000903", {2381}, {8}},
+ {"\U0000094d\U00000904", {2381, 2308}, {3, 6}},
+ {"\U0000094d\U00000308\U00000904", {2381, 2308}, {5, 8}},
+ {"\U0000094d\U00000d4e", {2381, 3406}, {3, 6}},
+ {"\U0000094d\U00000308\U00000d4e", {2381, 3406}, {5, 8}},
+ {"\U0000094d\U00000915", {2381, 2325}, {3, 6}},
+ {"\U0000094d\U00000308\U00000915", {2381, 2325}, {5, 8}},
+ {"\U0000094d\U0000231a", {2381, 8986}, {3, 6}},
+ {"\U0000094d\U00000308\U0000231a", {2381, 8986}, {5, 8}},
+ {"\U0000094d\U00000300", {2381}, {5}},
+ {"\U0000094d\U00000308\U00000300", {2381}, {7}},
+ {"\U0000094d\U00000900", {2381}, {6}},
+ {"\U0000094d\U00000308\U00000900", {2381}, {8}},
+ {"\U0000094d\U0000094d", {2381}, {6}},
+ {"\U0000094d\U00000308\U0000094d", {2381}, {8}},
+ {"\U0000094d\U0000200d", {2381}, {6}},
+ {"\U0000094d\U00000308\U0000200d", {2381}, {8}},
+ {"\U0000094d\U00000378", {2381, 888}, {3, 5}},
+ {"\U0000094d\U00000308\U00000378", {2381, 888}, {5, 7}},
+ {"\U0000200d\U00000020", {8205, 32}, {3, 4}},
+ {"\U0000200d\U00000308\U00000020", {8205, 32}, {5, 6}},
+ {"\U0000200d\U0000000d", {8205, 13}, {3, 4}},
+ {"\U0000200d\U00000308\U0000000d", {8205, 13}, {5, 6}},
+ {"\U0000200d\U0000000a", {8205, 10}, {3, 4}},
+ {"\U0000200d\U00000308\U0000000a", {8205, 10}, {5, 6}},
+ {"\U0000200d\U00000001", {8205, 1}, {3, 4}},
+ {"\U0000200d\U00000308\U00000001", {8205, 1}, {5, 6}},
+ {"\U0000200d\U0000200c", {8205}, {6}},
+ {"\U0000200d\U00000308\U0000200c", {8205}, {8}},
+ {"\U0000200d\U0001f1e6", {8205, 127462}, {3, 7}},
+ {"\U0000200d\U00000308\U0001f1e6", {8205, 127462}, {5, 9}},
+ {"\U0000200d\U00000600", {8205, 1536}, {3, 5}},
+ {"\U0000200d\U00000308\U00000600", {8205, 1536}, {5, 7}},
+ {"\U0000200d\U00000a03", {8205}, {6}},
+ {"\U0000200d\U00000308\U00000a03", {8205}, {8}},
+ {"\U0000200d\U00001100", {8205, 4352}, {3, 6}},
+ {"\U0000200d\U00000308\U00001100", {8205, 4352}, {5, 8}},
+ {"\U0000200d\U00001160", {8205, 4448}, {3, 6}},
+ {"\U0000200d\U00000308\U00001160", {8205, 4448}, {5, 8}},
+ {"\U0000200d\U000011a8", {8205, 4520}, {3, 6}},
+ {"\U0000200d\U00000308\U000011a8", {8205, 4520}, {5, 8}},
+ {"\U0000200d\U0000ac00", {8205, 44032}, {3, 6}},
+ {"\U0000200d\U00000308\U0000ac00", {8205, 44032}, {5, 8}},
+ {"\U0000200d\U0000ac01", {8205, 44033}, {3, 6}},
+ {"\U0000200d\U00000308\U0000ac01", {8205, 44033}, {5, 8}},
+ {"\U0000200d\U00000903", {8205}, {6}},
+ {"\U0000200d\U00000308\U00000903", {8205}, {8}},
+ {"\U0000200d\U00000904", {8205, 2308}, {3, 6}},
+ {"\U0000200d\U00000308\U00000904", {8205, 2308}, {5, 8}},
+ {"\U0000200d\U00000d4e", {8205, 3406}, {3, 6}},
+ {"\U0000200d\U00000308\U00000d4e", {8205, 3406}, {5, 8}},
+ {"\U0000200d\U00000915", {8205, 2325}, {3, 6}},
+ {"\U0000200d\U00000308\U00000915", {8205, 2325}, {5, 8}},
+ {"\U0000200d\U0000231a", {8205, 8986}, {3, 6}},
+ {"\U0000200d\U00000308\U0000231a", {8205, 8986}, {5, 8}},
+ {"\U0000200d\U00000300", {8205}, {5}},
+ {"\U0000200d\U00000308\U00000300", {8205}, {7}},
+ {"\U0000200d\U00000900", {8205}, {6}},
+ {"\U0000200d\U00000308\U00000900", {8205}, {8}},
+ {"\U0000200d\U0000094d", {8205}, {6}},
+ {"\U0000200d\U00000308\U0000094d", {8205}, {8}},
+ {"\U0000200d\U0000200d", {8205}, {6}},
+ {"\U0000200d\U00000308\U0000200d", {8205}, {8}},
+ {"\U0000200d\U00000378", {8205, 888}, {3, 5}},
+ {"\U0000200d\U00000308\U00000378", {8205, 888}, {5, 7}},
+ {"\U00000378\U00000020", {888, 32}, {2, 3}},
+ {"\U00000378\U00000308\U00000020", {888, 32}, {4, 5}},
+ {"\U00000378\U0000000d", {888, 13}, {2, 3}},
+ {"\U00000378\U00000308\U0000000d", {888, 13}, {4, 5}},
+ {"\U00000378\U0000000a", {888, 10}, {2, 3}},
+ {"\U00000378\U00000308\U0000000a", {888, 10}, {4, 5}},
+ {"\U00000378\U00000001", {888, 1}, {2, 3}},
+ {"\U00000378\U00000308\U00000001", {888, 1}, {4, 5}},
+ {"\U00000378\U0000200c", {888}, {5}},
+ {"\U00000378\U00000308\U0000200c", {888}, {7}},
+ {"\U00000378\U0001f1e6", {888, 127462}, {2, 6}},
+ {"\U00000378\U00000308\U0001f1e6", {888, 127462}, {4, 8}},
+ {"\U00000378\U00000600", {888, 1536}, {2, 4}},
+ {"\U00000378\U00000308\U00000600", {888, 1536}, {4, 6}},
+ {"\U00000378\U00000a03", {888}, {5}},
+ {"\U00000378\U00000308\U00000a03", {888}, {7}},
+ {"\U00000378\U00001100", {888, 4352}, {2, 5}},
+ {"\U00000378\U00000308\U00001100", {888, 4352}, {4, 7}},
+ {"\U00000378\U00001160", {888, 4448}, {2, 5}},
+ {"\U00000378\U00000308\U00001160", {888, 4448}, {4, 7}},
+ {"\U00000378\U000011a8", {888, 4520}, {2, 5}},
+ {"\U00000378\U00000308\U000011a8", {888, 4520}, {4, 7}},
+ {"\U00000378\U0000ac00", {888, 44032}, {2, 5}},
+ {"\U00000378\U00000308\U0000ac00", {888, 44032}, {4, 7}},
+ {"\U00000378\U0000ac01", {888, 44033}, {2, 5}},
+ {"\U00000378\U00000308\U0000ac01", {888, 44033}, {4, 7}},
+ {"\U00000378\U00000903", {888}, {5}},
+ {"\U00000378\U00000308\U00000903", {888}, {7}},
+ {"\U00000378\U00000904", {888, 2308}, {2, 5}},
+ {"\U00000378\U00000308\U00000904", {888, 2308}, {4, 7}},
+ {"\U00000378\U00000d4e", {888, 3406}, {2, 5}},
+ {"\U00000378\U00000308\U00000d4e", {888, 3406}, {4, 7}},
+ {"\U00000378\U00000915", {888, 2325}, {2, 5}},
+ {"\U00000378\U00000308\U00000915", {888, 2325}, {4, 7}},
+ {"\U00000378\U0000231a", {888, 8986}, {2, 5}},
+ {"\U00000378\U00000308\U0000231a", {888, 8986}, {4, 7}},
+ {"\U00000378\U00000300", {888}, {4}},
+ {"\U00000378\U00000308\U00000300", {888}, {6}},
+ {"\U00000378\U00000900", {888}, {5}},
+ {"\U00000378\U00000308\U00000900", {888}, {7}},
+ {"\U00000378\U0000094d", {888}, {5}},
+ {"\U00000378\U00000308\U0000094d", {888}, {7}},
+ {"\U00000378\U0000200d", {888}, {5}},
+ {"\U00000378\U00000308\U0000200d", {888}, {7}},
+ {"\U00000378\U00000378", {888, 888}, {2, 4}},
+ {"\U00000378\U00000308\U00000378", {888, 888}, {4, 6}},
+ {"\U0000000d\U0000000a\U00000061\U0000000a\U00000308", {13, 97, 10, 776}, {2, 3, 4, 6}},
+ {"\U00000061\U00000308", {97}, {3}},
+ {"\U00000020\U0000200d\U00000646", {32, 1606}, {4, 6}},
+ {"\U00000646\U0000200d\U00000020", {1606, 32}, {5, 6}},
+ {"\U00001100\U00001100", {4352}, {6}},
+ {"\U0000ac00\U000011a8\U00001100", {44032, 4352}, {6, 9}},
+ {"\U0000ac01\U000011a8\U00001100", {44033, 4352}, {6, 9}},
+ {"\U0001f1e6\U0001f1e7\U0001f1e8\U00000062", {127462, 127464, 98}, {8, 12, 13}},
+ {"\U00000061\U0001f1e6\U0001f1e7\U0001f1e8\U00000062", {97, 127462, 127464, 98}, {1, 9, 13, 14}},
+ {"\U00000061\U0001f1e6\U0001f1e7\U0000200d\U0001f1e8\U00000062", {97, 127462, 127464, 98}, {1, 12, 16, 17}},
+ {"\U00000061\U0001f1e6\U0000200d\U0001f1e7\U0001f1e8\U00000062", {97, 127462, 127463, 98}, {1, 8, 16, 17}},
+ {"\U00000061\U0001f1e6\U0001f1e7\U0001f1e8\U0001f1e9\U00000062", {97, 127462, 127464, 98}, {1, 9, 17, 18}},
+ {"\U00000061\U0000200d", {97}, {4}},
+ {"\U00000061\U00000308\U00000062", {97, 98}, {3, 4}},
+ {"\U00000061\U00000903\U00000062", {97, 98}, {4, 5}},
+ {"\U00000061\U00000600\U00000062", {97, 1536}, {1, 4}},
+ {"\U0001f476\U0001f3ff\U0001f476", {128118, 128118}, {8, 12}},
+ {"\U00000061\U0001f3ff\U0001f476", {97, 128118}, {5, 9}},
+ {"\U00000061\U0001f3ff\U0001f476\U0000200d\U0001f6d1", {97, 128118}, {5, 16}},
+ {"\U0001f476\U0001f3ff\U00000308\U0000200d\U0001f476\U0001f3ff", {128118}, {21}},
+ {"\U0001f6d1\U0000200d\U0001f6d1", {128721}, {11}},
+ {"\U00000061\U0000200d\U0001f6d1", {97, 128721}, {4, 8}},
+ {"\U00002701\U0000200d\U00002701", {9985}, {9}},
+ {"\U00000061\U0000200d\U00002701", {97, 9985}, {4, 7}},
+ {"\U00000915\U00000924", {2325, 2340}, {3, 6}},
+ {"\U00000915\U0000094d\U00000924", {2325}, {9}},
+ {"\U00000915\U0000094d\U0000094d\U00000924", {2325}, {12}},
+ {"\U00000915\U0000094d\U0000200d\U00000924", {2325}, {12}},
+ {"\U00000915\U0000093c\U0000200d\U0000094d\U00000924", {2325}, {15}},
+ {"\U00000915\U0000093c\U0000094d\U0000200d\U00000924", {2325}, {15}},
+ {"\U00000915\U0000094d\U00000924\U0000094d\U0000092f", {2325}, {15}},
+ {"\U00000915\U0000094d\U00000061", {2325, 97}, {6, 7}},
+ {"\U00000061\U0000094d\U00000924", {97, 2340}, {4, 7}},
+ {"\U0000003f\U0000094d\U00000924", {63, 2340}, {4, 7}},
+ {"\U00000915\U0000094d\U0000094d\U00000924", {2325}, {12}}}};
+
+/// The data for UTF-16.
+///
+/// Note that most of the data for the UTF-16 and UTF-32 are identical. However
+/// since the size of the code units differ the breaks can contain different
+/// values.
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+std::array<data<wchar_t>, 1093> data_utf16 = {{
+ {L"\U00000020\U00000020", {32, 32}, {1, 2}},
+ {L"\U00000020\U00000308\U00000020", {32, 32}, {2, 3}},
+ {L"\U00000020\U0000000d", {32, 13}, {1, 2}},
+ {L"\U00000020\U00000308\U0000000d", {32, 13}, {2, 3}},
+ {L"\U00000020\U0000000a", {32, 10}, {1, 2}},
+ {L"\U00000020\U00000308\U0000000a", {32, 10}, {2, 3}},
+ {L"\U00000020\U00000001", {32, 1}, {1, 2}},
+ {L"\U00000020\U00000308\U00000001", {32, 1}, {2, 3}},
+ {L"\U00000020\U0000200c", {32}, {2}},
+ {L"\U00000020\U00000308\U0000200c", {32}, {3}},
+ {L"\U00000020\U0001f1e6", {32, 127462}, {1, 3}},
+ {L"\U00000020\U00000308\U0001f1e6", {32, 127462}, {2, 4}},
+ {L"\U00000020\U00000600", {32, 1536}, {1, 2}},
+ {L"\U00000020\U00000308\U00000600", {32, 1536}, {2, 3}},
+ {L"\U00000020\U00000a03", {32}, {2}},
+ {L"\U00000020\U00000308\U00000a03", {32}, {3}},
+ {L"\U00000020\U00001100", {32, 4352}, {1, 2}},
+ {L"\U00000020\U00000308\U00001100", {32, 4352}, {2, 3}},
+ {L"\U00000020\U00001160", {32, 4448}, {1, 2}},
+ {L"\U00000020\U00000308\U00001160", {32, 4448}, {2, 3}},
+ {L"\U00000020\U000011a8", {32, 4520}, {1, 2}},
+ {L"\U00000020\U00000308\U000011a8", {32, 4520}, {2, 3}},
+ {L"\U00000020\U0000ac00", {32, 44032}, {1, 2}},
+ {L"\U00000020\U00000308\U0000ac00", {32, 44032}, {2, 3}},
+ {L"\U00000020\U0000ac01", {32, 44033}, {1, 2}},
+ {L"\U00000020\U00000308\U0000ac01", {32, 44033}, {2, 3}},
+ {L"\U00000020\U00000903", {32}, {2}},
+ {L"\U00000020\U00000308\U00000903", {32}, {3}},
+ {L"\U00000020\U00000904", {32, 2308}, {1, 2}},
+ {L"\U00000020\U00000308\U00000904", {32, 2308}, {2, 3}},
+ {L"\U00000020\U00000d4e", {32, 3406}, {1, 2}},
+ {L"\U00000020\U00000308\U00000d4e", {32, 3406}, {2, 3}},
+ {L"\U00000020\U00000915", {32, 2325}, {1, 2}},
+ {L"\U00000020\U00000308\U00000915", {32, 2325}, {2, 3}},
+ {L"\U00000020\U0000231a", {32, 8986}, {1, 2}},
+ {L"\U00000020\U00000308\U0000231a", {32, 8986}, {2, 3}},
+ {L"\U00000020\U00000300", {32}, {2}},
+ {L"\U00000020\U00000308\U00000300", {32}, {3}},
+ {L"\U00000020\U00000900", {32}, {2}},
+ {L"\U00000020\U00000308\U00000900", {32}, {3}},
+ {L"\U00000020\U0000094d", {32}, {2}},
+ {L"\U00000020\U00000308\U0000094d", {32}, {3}},
+ {L"\U00000020\U0000200d", {32}, {2}},
+ {L"\U00000020\U00000308\U0000200d", {32}, {3}},
+ {L"\U00000020\U00000378", {32, 888}, {1, 2}},
+ {L"\U00000020\U00000308\U00000378", {32, 888}, {2, 3}},
+ {L"\U0000000d\U00000020", {13, 32}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000020", {13, 776, 32}, {1, 2, 3}},
+ {L"\U0000000d\U0000000d", {13, 13}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000000d", {13, 776, 13}, {1, 2, 3}},
+ {L"\U0000000d\U0000000a", {13}, {2}},
+ {L"\U0000000d\U00000308\U0000000a", {13, 776, 10}, {1, 2, 3}},
+ {L"\U0000000d\U00000001", {13, 1}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000001", {13, 776, 1}, {1, 2, 3}},
+ {L"\U0000000d\U0000200c", {13, 8204}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000200c", {13, 776}, {1, 3}},
+ {L"\U0000000d\U0001f1e6", {13, 127462}, {1, 3}},
+ {L"\U0000000d\U00000308\U0001f1e6", {13, 776, 127462}, {1, 2, 4}},
+ {L"\U0000000d\U00000600", {13, 1536}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000600", {13, 776, 1536}, {1, 2, 3}},
+ {L"\U0000000d\U00000a03", {13, 2563}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000a03", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00001100", {13, 4352}, {1, 2}},
+ {L"\U0000000d\U00000308\U00001100", {13, 776, 4352}, {1, 2, 3}},
+ {L"\U0000000d\U00001160", {13, 4448}, {1, 2}},
+ {L"\U0000000d\U00000308\U00001160", {13, 776, 4448}, {1, 2, 3}},
+ {L"\U0000000d\U000011a8", {13, 4520}, {1, 2}},
+ {L"\U0000000d\U00000308\U000011a8", {13, 776, 4520}, {1, 2, 3}},
+ {L"\U0000000d\U0000ac00", {13, 44032}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000ac00", {13, 776, 44032}, {1, 2, 3}},
+ {L"\U0000000d\U0000ac01", {13, 44033}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000ac01", {13, 776, 44033}, {1, 2, 3}},
+ {L"\U0000000d\U00000903", {13, 2307}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000903", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00000904", {13, 2308}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000904", {13, 776, 2308}, {1, 2, 3}},
+ {L"\U0000000d\U00000d4e", {13, 3406}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000d4e", {13, 776, 3406}, {1, 2, 3}},
+ {L"\U0000000d\U00000915", {13, 2325}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000915", {13, 776, 2325}, {1, 2, 3}},
+ {L"\U0000000d\U0000231a", {13, 8986}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000231a", {13, 776, 8986}, {1, 2, 3}},
+ {L"\U0000000d\U00000300", {13, 768}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000300", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00000900", {13, 2304}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000900", {13, 776}, {1, 3}},
+ {L"\U0000000d\U0000094d", {13, 2381}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000094d", {13, 776}, {1, 3}},
+ {L"\U0000000d\U0000200d", {13, 8205}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000200d", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00000378", {13, 888}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000378", {13, 776, 888}, {1, 2, 3}},
+ {L"\U0000000a\U00000020", {10, 32}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000020", {10, 776, 32}, {1, 2, 3}},
+ {L"\U0000000a\U0000000d", {10, 13}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000000d", {10, 776, 13}, {1, 2, 3}},
+ {L"\U0000000a\U0000000a", {10, 10}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000000a", {10, 776, 10}, {1, 2, 3}},
+ {L"\U0000000a\U00000001", {10, 1}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000001", {10, 776, 1}, {1, 2, 3}},
+ {L"\U0000000a\U0000200c", {10, 8204}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000200c", {10, 776}, {1, 3}},
+ {L"\U0000000a\U0001f1e6", {10, 127462}, {1, 3}},
+ {L"\U0000000a\U00000308\U0001f1e6", {10, 776, 127462}, {1, 2, 4}},
+ {L"\U0000000a\U00000600", {10, 1536}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000600", {10, 776, 1536}, {1, 2, 3}},
+ {L"\U0000000a\U00000a03", {10, 2563}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000a03", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00001100", {10, 4352}, {1, 2}},
+ {L"\U0000000a\U00000308\U00001100", {10, 776, 4352}, {1, 2, 3}},
+ {L"\U0000000a\U00001160", {10, 4448}, {1, 2}},
+ {L"\U0000000a\U00000308\U00001160", {10, 776, 4448}, {1, 2, 3}},
+ {L"\U0000000a\U000011a8", {10, 4520}, {1, 2}},
+ {L"\U0000000a\U00000308\U000011a8", {10, 776, 4520}, {1, 2, 3}},
+ {L"\U0000000a\U0000ac00", {10, 44032}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000ac00", {10, 776, 44032}, {1, 2, 3}},
+ {L"\U0000000a\U0000ac01", {10, 44033}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000ac01", {10, 776, 44033}, {1, 2, 3}},
+ {L"\U0000000a\U00000903", {10, 2307}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000903", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00000904", {10, 2308}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000904", {10, 776, 2308}, {1, 2, 3}},
+ {L"\U0000000a\U00000d4e", {10, 3406}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000d4e", {10, 776, 3406}, {1, 2, 3}},
+ {L"\U0000000a\U00000915", {10, 2325}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000915", {10, 776, 2325}, {1, 2, 3}},
+ {L"\U0000000a\U0000231a", {10, 8986}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000231a", {10, 776, 8986}, {1, 2, 3}},
+ {L"\U0000000a\U00000300", {10, 768}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000300", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00000900", {10, 2304}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000900", {10, 776}, {1, 3}},
+ {L"\U0000000a\U0000094d", {10, 2381}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000094d", {10, 776}, {1, 3}},
+ {L"\U0000000a\U0000200d", {10, 8205}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000200d", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00000378", {10, 888}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000378", {10, 776, 888}, {1, 2, 3}},
+ {L"\U00000001\U00000020", {1, 32}, {1, 2}},
+ {L"\U00000001\U00000308\U00000020", {1, 776, 32}, {1, 2, 3}},
+ {L"\U00000001\U0000000d", {1, 13}, {1, 2}},
+ {L"\U00000001\U00000308\U0000000d", {1, 776, 13}, {1, 2, 3}},
+ {L"\U00000001\U0000000a", {1, 10}, {1, 2}},
+ {L"\U00000001\U00000308\U0000000a", {1, 776, 10}, {1, 2, 3}},
+ {L"\U00000001\U00000001", {1, 1}, {1, 2}},
+ {L"\U00000001\U00000308\U00000001", {1, 776, 1}, {1, 2, 3}},
+ {L"\U00000001\U0000200c", {1, 8204}, {1, 2}},
+ {L"\U00000001\U00000308\U0000200c", {1, 776}, {1, 3}},
+ {L"\U00000001\U0001f1e6", {1, 127462}, {1, 3}},
+ {L"\U00000001\U00000308\U0001f1e6", {1, 776, 127462}, {1, 2, 4}},
+ {L"\U00000001\U00000600", {1, 1536}, {1, 2}},
+ {L"\U00000001\U00000308\U00000600", {1, 776, 1536}, {1, 2, 3}},
+ {L"\U00000001\U00000a03", {1, 2563}, {1, 2}},
+ {L"\U00000001\U00000308\U00000a03", {1, 776}, {1, 3}},
+ {L"\U00000001\U00001100", {1, 4352}, {1, 2}},
+ {L"\U00000001\U00000308\U00001100", {1, 776, 4352}, {1, 2, 3}},
+ {L"\U00000001\U00001160", {1, 4448}, {1, 2}},
+ {L"\U00000001\U00000308\U00001160", {1, 776, 4448}, {1, 2, 3}},
+ {L"\U00000001\U000011a8", {1, 4520}, {1, 2}},
+ {L"\U00000001\U00000308\U000011a8", {1, 776, 4520}, {1, 2, 3}},
+ {L"\U00000001\U0000ac00", {1, 44032}, {1, 2}},
+ {L"\U00000001\U00000308\U0000ac00", {1, 776, 44032}, {1, 2, 3}},
+ {L"\U00000001\U0000ac01", {1, 44033}, {1, 2}},
+ {L"\U00000001\U00000308\U0000ac01", {1, 776, 44033}, {1, 2, 3}},
+ {L"\U00000001\U00000903", {1, 2307}, {1, 2}},
+ {L"\U00000001\U00000308\U00000903", {1, 776}, {1, 3}},
+ {L"\U00000001\U00000904", {1, 2308}, {1, 2}},
+ {L"\U00000001\U00000308\U00000904", {1, 776, 2308}, {1, 2, 3}},
+ {L"\U00000001\U00000d4e", {1, 3406}, {1, 2}},
+ {L"\U00000001\U00000308\U00000d4e", {1, 776, 3406}, {1, 2, 3}},
+ {L"\U00000001\U00000915", {1, 2325}, {1, 2}},
+ {L"\U00000001\U00000308\U00000915", {1, 776, 2325}, {1, 2, 3}},
+ {L"\U00000001\U0000231a", {1, 8986}, {1, 2}},
+ {L"\U00000001\U00000308\U0000231a", {1, 776, 8986}, {1, 2, 3}},
+ {L"\U00000001\U00000300", {1, 768}, {1, 2}},
+ {L"\U00000001\U00000308\U00000300", {1, 776}, {1, 3}},
+ {L"\U00000001\U00000900", {1, 2304}, {1, 2}},
+ {L"\U00000001\U00000308\U00000900", {1, 776}, {1, 3}},
+ {L"\U00000001\U0000094d", {1, 2381}, {1, 2}},
+ {L"\U00000001\U00000308\U0000094d", {1, 776}, {1, 3}},
+ {L"\U00000001\U0000200d", {1, 8205}, {1, 2}},
+ {L"\U00000001\U00000308\U0000200d", {1, 776}, {1, 3}},
+ {L"\U00000001\U00000378", {1, 888}, {1, 2}},
+ {L"\U00000001\U00000308\U00000378", {1, 776, 888}, {1, 2, 3}},
+ {L"\U0000200c\U00000020", {8204, 32}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000020", {8204, 32}, {2, 3}},
+ {L"\U0000200c\U0000000d", {8204, 13}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000000d", {8204, 13}, {2, 3}},
+ {L"\U0000200c\U0000000a", {8204, 10}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000000a", {8204, 10}, {2, 3}},
+ {L"\U0000200c\U00000001", {8204, 1}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000001", {8204, 1}, {2, 3}},
+ {L"\U0000200c\U0000200c", {8204}, {2}},
+ {L"\U0000200c\U00000308\U0000200c", {8204}, {3}},
+ {L"\U0000200c\U0001f1e6", {8204, 127462}, {1, 3}},
+ {L"\U0000200c\U00000308\U0001f1e6", {8204, 127462}, {2, 4}},
+ {L"\U0000200c\U00000600", {8204, 1536}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000600", {8204, 1536}, {2, 3}},
+ {L"\U0000200c\U00000a03", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000a03", {8204}, {3}},
+ {L"\U0000200c\U00001100", {8204, 4352}, {1, 2}},
+ {L"\U0000200c\U00000308\U00001100", {8204, 4352}, {2, 3}},
+ {L"\U0000200c\U00001160", {8204, 4448}, {1, 2}},
+ {L"\U0000200c\U00000308\U00001160", {8204, 4448}, {2, 3}},
+ {L"\U0000200c\U000011a8", {8204, 4520}, {1, 2}},
+ {L"\U0000200c\U00000308\U000011a8", {8204, 4520}, {2, 3}},
+ {L"\U0000200c\U0000ac00", {8204, 44032}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000ac00", {8204, 44032}, {2, 3}},
+ {L"\U0000200c\U0000ac01", {8204, 44033}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000ac01", {8204, 44033}, {2, 3}},
+ {L"\U0000200c\U00000903", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000903", {8204}, {3}},
+ {L"\U0000200c\U00000904", {8204, 2308}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000904", {8204, 2308}, {2, 3}},
+ {L"\U0000200c\U00000d4e", {8204, 3406}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000d4e", {8204, 3406}, {2, 3}},
+ {L"\U0000200c\U00000915", {8204, 2325}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000915", {8204, 2325}, {2, 3}},
+ {L"\U0000200c\U0000231a", {8204, 8986}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000231a", {8204, 8986}, {2, 3}},
+ {L"\U0000200c\U00000300", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000300", {8204}, {3}},
+ {L"\U0000200c\U00000900", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000900", {8204}, {3}},
+ {L"\U0000200c\U0000094d", {8204}, {2}},
+ {L"\U0000200c\U00000308\U0000094d", {8204}, {3}},
+ {L"\U0000200c\U0000200d", {8204}, {2}},
+ {L"\U0000200c\U00000308\U0000200d", {8204}, {3}},
+ {L"\U0000200c\U00000378", {8204, 888}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000378", {8204, 888}, {2, 3}},
+ {L"\U0001f1e6\U00000020", {127462, 32}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00000020", {127462, 32}, {3, 4}},
+ {L"\U0001f1e6\U0000000d", {127462, 13}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U0000000d", {127462, 13}, {3, 4}},
+ {L"\U0001f1e6\U0000000a", {127462, 10}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U0000000a", {127462, 10}, {3, 4}},
+ {L"\U0001f1e6\U00000001", {127462, 1}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00000001", {127462, 1}, {3, 4}},
+ {L"\U0001f1e6\U0000200c", {127462}, {3}},
+ {L"\U0001f1e6\U00000308\U0000200c", {127462}, {4}},
+ {L"\U0001f1e6\U0001f1e6", {127462}, {4}},
+ {L"\U0001f1e6\U00000308\U0001f1e6", {127462, 127462}, {3, 5}},
+ {L"\U0001f1e6\U00000600", {127462, 1536}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00000600", {127462, 1536}, {3, 4}},
+ {L"\U0001f1e6\U00000a03", {127462}, {3}},
+ {L"\U0001f1e6\U00000308\U00000a03", {127462}, {4}},
+ {L"\U0001f1e6\U00001100", {127462, 4352}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00001100", {127462, 4352}, {3, 4}},
+ {L"\U0001f1e6\U00001160", {127462, 4448}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00001160", {127462, 4448}, {3, 4}},
+ {L"\U0001f1e6\U000011a8", {127462, 4520}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U000011a8", {127462, 4520}, {3, 4}},
+ {L"\U0001f1e6\U0000ac00", {127462, 44032}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U0000ac00", {127462, 44032}, {3, 4}},
+ {L"\U0001f1e6\U0000ac01", {127462, 44033}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U0000ac01", {127462, 44033}, {3, 4}},
+ {L"\U0001f1e6\U00000903", {127462}, {3}},
+ {L"\U0001f1e6\U00000308\U00000903", {127462}, {4}},
+ {L"\U0001f1e6\U00000904", {127462, 2308}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00000904", {127462, 2308}, {3, 4}},
+ {L"\U0001f1e6\U00000d4e", {127462, 3406}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00000d4e", {127462, 3406}, {3, 4}},
+ {L"\U0001f1e6\U00000915", {127462, 2325}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00000915", {127462, 2325}, {3, 4}},
+ {L"\U0001f1e6\U0000231a", {127462, 8986}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U0000231a", {127462, 8986}, {3, 4}},
+ {L"\U0001f1e6\U00000300", {127462}, {3}},
+ {L"\U0001f1e6\U00000308\U00000300", {127462}, {4}},
+ {L"\U0001f1e6\U00000900", {127462}, {3}},
+ {L"\U0001f1e6\U00000308\U00000900", {127462}, {4}},
+ {L"\U0001f1e6\U0000094d", {127462}, {3}},
+ {L"\U0001f1e6\U00000308\U0000094d", {127462}, {4}},
+ {L"\U0001f1e6\U0000200d", {127462}, {3}},
+ {L"\U0001f1e6\U00000308\U0000200d", {127462}, {4}},
+ {L"\U0001f1e6\U00000378", {127462, 888}, {2, 3}},
+ {L"\U0001f1e6\U00000308\U00000378", {127462, 888}, {3, 4}},
+ {L"\U00000600\U00000020", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000020", {1536, 32}, {2, 3}},
+ {L"\U00000600\U0000000d", {1536, 13}, {1, 2}},
+ {L"\U00000600\U00000308\U0000000d", {1536, 13}, {2, 3}},
+ {L"\U00000600\U0000000a", {1536, 10}, {1, 2}},
+ {L"\U00000600\U00000308\U0000000a", {1536, 10}, {2, 3}},
+ {L"\U00000600\U00000001", {1536, 1}, {1, 2}},
+ {L"\U00000600\U00000308\U00000001", {1536, 1}, {2, 3}},
+ {L"\U00000600\U0000200c", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000200c", {1536}, {3}},
+ {L"\U00000600\U0001f1e6", {1536}, {3}},
+ {L"\U00000600\U00000308\U0001f1e6", {1536, 127462}, {2, 4}},
+ {L"\U00000600\U00000600", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000600", {1536, 1536}, {2, 3}},
+ {L"\U00000600\U00000a03", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000a03", {1536}, {3}},
+ {L"\U00000600\U00001100", {1536}, {2}},
+ {L"\U00000600\U00000308\U00001100", {1536, 4352}, {2, 3}},
+ {L"\U00000600\U00001160", {1536}, {2}},
+ {L"\U00000600\U00000308\U00001160", {1536, 4448}, {2, 3}},
+ {L"\U00000600\U000011a8", {1536}, {2}},
+ {L"\U00000600\U00000308\U000011a8", {1536, 4520}, {2, 3}},
+ {L"\U00000600\U0000ac00", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000ac00", {1536, 44032}, {2, 3}},
+ {L"\U00000600\U0000ac01", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000ac01", {1536, 44033}, {2, 3}},
+ {L"\U00000600\U00000903", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000903", {1536}, {3}},
+ {L"\U00000600\U00000904", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000904", {1536, 2308}, {2, 3}},
+ {L"\U00000600\U00000d4e", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000d4e", {1536, 3406}, {2, 3}},
+ {L"\U00000600\U00000915", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000915", {1536, 2325}, {2, 3}},
+ {L"\U00000600\U0000231a", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000231a", {1536, 8986}, {2, 3}},
+ {L"\U00000600\U00000300", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000300", {1536}, {3}},
+ {L"\U00000600\U00000900", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000900", {1536}, {3}},
+ {L"\U00000600\U0000094d", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000094d", {1536}, {3}},
+ {L"\U00000600\U0000200d", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000200d", {1536}, {3}},
+ {L"\U00000600\U00000378", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000378", {1536, 888}, {2, 3}},
+ {L"\U00000a03\U00000020", {2563, 32}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000020", {2563, 32}, {2, 3}},
+ {L"\U00000a03\U0000000d", {2563, 13}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000000d", {2563, 13}, {2, 3}},
+ {L"\U00000a03\U0000000a", {2563, 10}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000000a", {2563, 10}, {2, 3}},
+ {L"\U00000a03\U00000001", {2563, 1}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000001", {2563, 1}, {2, 3}},
+ {L"\U00000a03\U0000200c", {2563}, {2}},
+ {L"\U00000a03\U00000308\U0000200c", {2563}, {3}},
+ {L"\U00000a03\U0001f1e6", {2563, 127462}, {1, 3}},
+ {L"\U00000a03\U00000308\U0001f1e6", {2563, 127462}, {2, 4}},
+ {L"\U00000a03\U00000600", {2563, 1536}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000600", {2563, 1536}, {2, 3}},
+ {L"\U00000a03\U00000a03", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000a03", {2563}, {3}},
+ {L"\U00000a03\U00001100", {2563, 4352}, {1, 2}},
+ {L"\U00000a03\U00000308\U00001100", {2563, 4352}, {2, 3}},
+ {L"\U00000a03\U00001160", {2563, 4448}, {1, 2}},
+ {L"\U00000a03\U00000308\U00001160", {2563, 4448}, {2, 3}},
+ {L"\U00000a03\U000011a8", {2563, 4520}, {1, 2}},
+ {L"\U00000a03\U00000308\U000011a8", {2563, 4520}, {2, 3}},
+ {L"\U00000a03\U0000ac00", {2563, 44032}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000ac00", {2563, 44032}, {2, 3}},
+ {L"\U00000a03\U0000ac01", {2563, 44033}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000ac01", {2563, 44033}, {2, 3}},
+ {L"\U00000a03\U00000903", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000903", {2563}, {3}},
+ {L"\U00000a03\U00000904", {2563, 2308}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000904", {2563, 2308}, {2, 3}},
+ {L"\U00000a03\U00000d4e", {2563, 3406}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000d4e", {2563, 3406}, {2, 3}},
+ {L"\U00000a03\U00000915", {2563, 2325}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000915", {2563, 2325}, {2, 3}},
+ {L"\U00000a03\U0000231a", {2563, 8986}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000231a", {2563, 8986}, {2, 3}},
+ {L"\U00000a03\U00000300", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000300", {2563}, {3}},
+ {L"\U00000a03\U00000900", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000900", {2563}, {3}},
+ {L"\U00000a03\U0000094d", {2563}, {2}},
+ {L"\U00000a03\U00000308\U0000094d", {2563}, {3}},
+ {L"\U00000a03\U0000200d", {2563}, {2}},
+ {L"\U00000a03\U00000308\U0000200d", {2563}, {3}},
+ {L"\U00000a03\U00000378", {2563, 888}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000378", {2563, 888}, {2, 3}},
+ {L"\U00001100\U00000020", {4352, 32}, {1, 2}},
+ {L"\U00001100\U00000308\U00000020", {4352, 32}, {2, 3}},
+ {L"\U00001100\U0000000d", {4352, 13}, {1, 2}},
+ {L"\U00001100\U00000308\U0000000d", {4352, 13}, {2, 3}},
+ {L"\U00001100\U0000000a", {4352, 10}, {1, 2}},
+ {L"\U00001100\U00000308\U0000000a", {4352, 10}, {2, 3}},
+ {L"\U00001100\U00000001", {4352, 1}, {1, 2}},
+ {L"\U00001100\U00000308\U00000001", {4352, 1}, {2, 3}},
+ {L"\U00001100\U0000200c", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000200c", {4352}, {3}},
+ {L"\U00001100\U0001f1e6", {4352, 127462}, {1, 3}},
+ {L"\U00001100\U00000308\U0001f1e6", {4352, 127462}, {2, 4}},
+ {L"\U00001100\U00000600", {4352, 1536}, {1, 2}},
+ {L"\U00001100\U00000308\U00000600", {4352, 1536}, {2, 3}},
+ {L"\U00001100\U00000a03", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000a03", {4352}, {3}},
+ {L"\U00001100\U00001100", {4352}, {2}},
+ {L"\U00001100\U00000308\U00001100", {4352, 4352}, {2, 3}},
+ {L"\U00001100\U00001160", {4352}, {2}},
+ {L"\U00001100\U00000308\U00001160", {4352, 4448}, {2, 3}},
+ {L"\U00001100\U000011a8", {4352, 4520}, {1, 2}},
+ {L"\U00001100\U00000308\U000011a8", {4352, 4520}, {2, 3}},
+ {L"\U00001100\U0000ac00", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000ac00", {4352, 44032}, {2, 3}},
+ {L"\U00001100\U0000ac01", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000ac01", {4352, 44033}, {2, 3}},
+ {L"\U00001100\U00000903", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000903", {4352}, {3}},
+ {L"\U00001100\U00000904", {4352, 2308}, {1, 2}},
+ {L"\U00001100\U00000308\U00000904", {4352, 2308}, {2, 3}},
+ {L"\U00001100\U00000d4e", {4352, 3406}, {1, 2}},
+ {L"\U00001100\U00000308\U00000d4e", {4352, 3406}, {2, 3}},
+ {L"\U00001100\U00000915", {4352, 2325}, {1, 2}},
+ {L"\U00001100\U00000308\U00000915", {4352, 2325}, {2, 3}},
+ {L"\U00001100\U0000231a", {4352, 8986}, {1, 2}},
+ {L"\U00001100\U00000308\U0000231a", {4352, 8986}, {2, 3}},
+ {L"\U00001100\U00000300", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000300", {4352}, {3}},
+ {L"\U00001100\U00000900", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000900", {4352}, {3}},
+ {L"\U00001100\U0000094d", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000094d", {4352}, {3}},
+ {L"\U00001100\U0000200d", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000200d", {4352}, {3}},
+ {L"\U00001100\U00000378", {4352, 888}, {1, 2}},
+ {L"\U00001100\U00000308\U00000378", {4352, 888}, {2, 3}},
+ {L"\U00001160\U00000020", {4448, 32}, {1, 2}},
+ {L"\U00001160\U00000308\U00000020", {4448, 32}, {2, 3}},
+ {L"\U00001160\U0000000d", {4448, 13}, {1, 2}},
+ {L"\U00001160\U00000308\U0000000d", {4448, 13}, {2, 3}},
+ {L"\U00001160\U0000000a", {4448, 10}, {1, 2}},
+ {L"\U00001160\U00000308\U0000000a", {4448, 10}, {2, 3}},
+ {L"\U00001160\U00000001", {4448, 1}, {1, 2}},
+ {L"\U00001160\U00000308\U00000001", {4448, 1}, {2, 3}},
+ {L"\U00001160\U0000200c", {4448}, {2}},
+ {L"\U00001160\U00000308\U0000200c", {4448}, {3}},
+ {L"\U00001160\U0001f1e6", {4448, 127462}, {1, 3}},
+ {L"\U00001160\U00000308\U0001f1e6", {4448, 127462}, {2, 4}},
+ {L"\U00001160\U00000600", {4448, 1536}, {1, 2}},
+ {L"\U00001160\U00000308\U00000600", {4448, 1536}, {2, 3}},
+ {L"\U00001160\U00000a03", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000a03", {4448}, {3}},
+ {L"\U00001160\U00001100", {4448, 4352}, {1, 2}},
+ {L"\U00001160\U00000308\U00001100", {4448, 4352}, {2, 3}},
+ {L"\U00001160\U00001160", {4448}, {2}},
+ {L"\U00001160\U00000308\U00001160", {4448, 4448}, {2, 3}},
+ {L"\U00001160\U000011a8", {4448}, {2}},
+ {L"\U00001160\U00000308\U000011a8", {4448, 4520}, {2, 3}},
+ {L"\U00001160\U0000ac00", {4448, 44032}, {1, 2}},
+ {L"\U00001160\U00000308\U0000ac00", {4448, 44032}, {2, 3}},
+ {L"\U00001160\U0000ac01", {4448, 44033}, {1, 2}},
+ {L"\U00001160\U00000308\U0000ac01", {4448, 44033}, {2, 3}},
+ {L"\U00001160\U00000903", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000903", {4448}, {3}},
+ {L"\U00001160\U00000904", {4448, 2308}, {1, 2}},
+ {L"\U00001160\U00000308\U00000904", {4448, 2308}, {2, 3}},
+ {L"\U00001160\U00000d4e", {4448, 3406}, {1, 2}},
+ {L"\U00001160\U00000308\U00000d4e", {4448, 3406}, {2, 3}},
+ {L"\U00001160\U00000915", {4448, 2325}, {1, 2}},
+ {L"\U00001160\U00000308\U00000915", {4448, 2325}, {2, 3}},
+ {L"\U00001160\U0000231a", {4448, 8986}, {1, 2}},
+ {L"\U00001160\U00000308\U0000231a", {4448, 8986}, {2, 3}},
+ {L"\U00001160\U00000300", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000300", {4448}, {3}},
+ {L"\U00001160\U00000900", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000900", {4448}, {3}},
+ {L"\U00001160\U0000094d", {4448}, {2}},
+ {L"\U00001160\U00000308\U0000094d", {4448}, {3}},
+ {L"\U00001160\U0000200d", {4448}, {2}},
+ {L"\U00001160\U00000308\U0000200d", {4448}, {3}},
+ {L"\U00001160\U00000378", {4448, 888}, {1, 2}},
+ {L"\U00001160\U00000308\U00000378", {4448, 888}, {2, 3}},
+ {L"\U000011a8\U00000020", {4520, 32}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000020", {4520, 32}, {2, 3}},
+ {L"\U000011a8\U0000000d", {4520, 13}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000000d", {4520, 13}, {2, 3}},
+ {L"\U000011a8\U0000000a", {4520, 10}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000000a", {4520, 10}, {2, 3}},
+ {L"\U000011a8\U00000001", {4520, 1}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000001", {4520, 1}, {2, 3}},
+ {L"\U000011a8\U0000200c", {4520}, {2}},
+ {L"\U000011a8\U00000308\U0000200c", {4520}, {3}},
+ {L"\U000011a8\U0001f1e6", {4520, 127462}, {1, 3}},
+ {L"\U000011a8\U00000308\U0001f1e6", {4520, 127462}, {2, 4}},
+ {L"\U000011a8\U00000600", {4520, 1536}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000600", {4520, 1536}, {2, 3}},
+ {L"\U000011a8\U00000a03", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000a03", {4520}, {3}},
+ {L"\U000011a8\U00001100", {4520, 4352}, {1, 2}},
+ {L"\U000011a8\U00000308\U00001100", {4520, 4352}, {2, 3}},
+ {L"\U000011a8\U00001160", {4520, 4448}, {1, 2}},
+ {L"\U000011a8\U00000308\U00001160", {4520, 4448}, {2, 3}},
+ {L"\U000011a8\U000011a8", {4520}, {2}},
+ {L"\U000011a8\U00000308\U000011a8", {4520, 4520}, {2, 3}},
+ {L"\U000011a8\U0000ac00", {4520, 44032}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000ac00", {4520, 44032}, {2, 3}},
+ {L"\U000011a8\U0000ac01", {4520, 44033}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000ac01", {4520, 44033}, {2, 3}},
+ {L"\U000011a8\U00000903", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000903", {4520}, {3}},
+ {L"\U000011a8\U00000904", {4520, 2308}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000904", {4520, 2308}, {2, 3}},
+ {L"\U000011a8\U00000d4e", {4520, 3406}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000d4e", {4520, 3406}, {2, 3}},
+ {L"\U000011a8\U00000915", {4520, 2325}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000915", {4520, 2325}, {2, 3}},
+ {L"\U000011a8\U0000231a", {4520, 8986}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000231a", {4520, 8986}, {2, 3}},
+ {L"\U000011a8\U00000300", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000300", {4520}, {3}},
+ {L"\U000011a8\U00000900", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000900", {4520}, {3}},
+ {L"\U000011a8\U0000094d", {4520}, {2}},
+ {L"\U000011a8\U00000308\U0000094d", {4520}, {3}},
+ {L"\U000011a8\U0000200d", {4520}, {2}},
+ {L"\U000011a8\U00000308\U0000200d", {4520}, {3}},
+ {L"\U000011a8\U00000378", {4520, 888}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000378", {4520, 888}, {2, 3}},
+ {L"\U0000ac00\U00000020", {44032, 32}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000020", {44032, 32}, {2, 3}},
+ {L"\U0000ac00\U0000000d", {44032, 13}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000000d", {44032, 13}, {2, 3}},
+ {L"\U0000ac00\U0000000a", {44032, 10}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000000a", {44032, 10}, {2, 3}},
+ {L"\U0000ac00\U00000001", {44032, 1}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000001", {44032, 1}, {2, 3}},
+ {L"\U0000ac00\U0000200c", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U0000200c", {44032}, {3}},
+ {L"\U0000ac00\U0001f1e6", {44032, 127462}, {1, 3}},
+ {L"\U0000ac00\U00000308\U0001f1e6", {44032, 127462}, {2, 4}},
+ {L"\U0000ac00\U00000600", {44032, 1536}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000600", {44032, 1536}, {2, 3}},
+ {L"\U0000ac00\U00000a03", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000a03", {44032}, {3}},
+ {L"\U0000ac00\U00001100", {44032, 4352}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00001100", {44032, 4352}, {2, 3}},
+ {L"\U0000ac00\U00001160", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00001160", {44032, 4448}, {2, 3}},
+ {L"\U0000ac00\U000011a8", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U000011a8", {44032, 4520}, {2, 3}},
+ {L"\U0000ac00\U0000ac00", {44032, 44032}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000ac00", {44032, 44032}, {2, 3}},
+ {L"\U0000ac00\U0000ac01", {44032, 44033}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000ac01", {44032, 44033}, {2, 3}},
+ {L"\U0000ac00\U00000903", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000903", {44032}, {3}},
+ {L"\U0000ac00\U00000904", {44032, 2308}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000904", {44032, 2308}, {2, 3}},
+ {L"\U0000ac00\U00000d4e", {44032, 3406}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000d4e", {44032, 3406}, {2, 3}},
+ {L"\U0000ac00\U00000915", {44032, 2325}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000915", {44032, 2325}, {2, 3}},
+ {L"\U0000ac00\U0000231a", {44032, 8986}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000231a", {44032, 8986}, {2, 3}},
+ {L"\U0000ac00\U00000300", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000300", {44032}, {3}},
+ {L"\U0000ac00\U00000900", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000900", {44032}, {3}},
+ {L"\U0000ac00\U0000094d", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U0000094d", {44032}, {3}},
+ {L"\U0000ac00\U0000200d", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U0000200d", {44032}, {3}},
+ {L"\U0000ac00\U00000378", {44032, 888}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000378", {44032, 888}, {2, 3}},
+ {L"\U0000ac01\U00000020", {44033, 32}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000020", {44033, 32}, {2, 3}},
+ {L"\U0000ac01\U0000000d", {44033, 13}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000000d", {44033, 13}, {2, 3}},
+ {L"\U0000ac01\U0000000a", {44033, 10}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000000a", {44033, 10}, {2, 3}},
+ {L"\U0000ac01\U00000001", {44033, 1}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000001", {44033, 1}, {2, 3}},
+ {L"\U0000ac01\U0000200c", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U0000200c", {44033}, {3}},
+ {L"\U0000ac01\U0001f1e6", {44033, 127462}, {1, 3}},
+ {L"\U0000ac01\U00000308\U0001f1e6", {44033, 127462}, {2, 4}},
+ {L"\U0000ac01\U00000600", {44033, 1536}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000600", {44033, 1536}, {2, 3}},
+ {L"\U0000ac01\U00000a03", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000a03", {44033}, {3}},
+ {L"\U0000ac01\U00001100", {44033, 4352}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00001100", {44033, 4352}, {2, 3}},
+ {L"\U0000ac01\U00001160", {44033, 4448}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00001160", {44033, 4448}, {2, 3}},
+ {L"\U0000ac01\U000011a8", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U000011a8", {44033, 4520}, {2, 3}},
+ {L"\U0000ac01\U0000ac00", {44033, 44032}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000ac00", {44033, 44032}, {2, 3}},
+ {L"\U0000ac01\U0000ac01", {44033, 44033}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000ac01", {44033, 44033}, {2, 3}},
+ {L"\U0000ac01\U00000903", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000903", {44033}, {3}},
+ {L"\U0000ac01\U00000904", {44033, 2308}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000904", {44033, 2308}, {2, 3}},
+ {L"\U0000ac01\U00000d4e", {44033, 3406}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000d4e", {44033, 3406}, {2, 3}},
+ {L"\U0000ac01\U00000915", {44033, 2325}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000915", {44033, 2325}, {2, 3}},
+ {L"\U0000ac01\U0000231a", {44033, 8986}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000231a", {44033, 8986}, {2, 3}},
+ {L"\U0000ac01\U00000300", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000300", {44033}, {3}},
+ {L"\U0000ac01\U00000900", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000900", {44033}, {3}},
+ {L"\U0000ac01\U0000094d", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U0000094d", {44033}, {3}},
+ {L"\U0000ac01\U0000200d", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U0000200d", {44033}, {3}},
+ {L"\U0000ac01\U00000378", {44033, 888}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000378", {44033, 888}, {2, 3}},
+ {L"\U00000903\U00000020", {2307, 32}, {1, 2}},
+ {L"\U00000903\U00000308\U00000020", {2307, 32}, {2, 3}},
+ {L"\U00000903\U0000000d", {2307, 13}, {1, 2}},
+ {L"\U00000903\U00000308\U0000000d", {2307, 13}, {2, 3}},
+ {L"\U00000903\U0000000a", {2307, 10}, {1, 2}},
+ {L"\U00000903\U00000308\U0000000a", {2307, 10}, {2, 3}},
+ {L"\U00000903\U00000001", {2307, 1}, {1, 2}},
+ {L"\U00000903\U00000308\U00000001", {2307, 1}, {2, 3}},
+ {L"\U00000903\U0000200c", {2307}, {2}},
+ {L"\U00000903\U00000308\U0000200c", {2307}, {3}},
+ {L"\U00000903\U0001f1e6", {2307, 127462}, {1, 3}},
+ {L"\U00000903\U00000308\U0001f1e6", {2307, 127462}, {2, 4}},
+ {L"\U00000903\U00000600", {2307, 1536}, {1, 2}},
+ {L"\U00000903\U00000308\U00000600", {2307, 1536}, {2, 3}},
+ {L"\U00000903\U00000a03", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000a03", {2307}, {3}},
+ {L"\U00000903\U00001100", {2307, 4352}, {1, 2}},
+ {L"\U00000903\U00000308\U00001100", {2307, 4352}, {2, 3}},
+ {L"\U00000903\U00001160", {2307, 4448}, {1, 2}},
+ {L"\U00000903\U00000308\U00001160", {2307, 4448}, {2, 3}},
+ {L"\U00000903\U000011a8", {2307, 4520}, {1, 2}},
+ {L"\U00000903\U00000308\U000011a8", {2307, 4520}, {2, 3}},
+ {L"\U00000903\U0000ac00", {2307, 44032}, {1, 2}},
+ {L"\U00000903\U00000308\U0000ac00", {2307, 44032}, {2, 3}},
+ {L"\U00000903\U0000ac01", {2307, 44033}, {1, 2}},
+ {L"\U00000903\U00000308\U0000ac01", {2307, 44033}, {2, 3}},
+ {L"\U00000903\U00000903", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000903", {2307}, {3}},
+ {L"\U00000903\U00000904", {2307, 2308}, {1, 2}},
+ {L"\U00000903\U00000308\U00000904", {2307, 2308}, {2, 3}},
+ {L"\U00000903\U00000d4e", {2307, 3406}, {1, 2}},
+ {L"\U00000903\U00000308\U00000d4e", {2307, 3406}, {2, 3}},
+ {L"\U00000903\U00000915", {2307, 2325}, {1, 2}},
+ {L"\U00000903\U00000308\U00000915", {2307, 2325}, {2, 3}},
+ {L"\U00000903\U0000231a", {2307, 8986}, {1, 2}},
+ {L"\U00000903\U00000308\U0000231a", {2307, 8986}, {2, 3}},
+ {L"\U00000903\U00000300", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000300", {2307}, {3}},
+ {L"\U00000903\U00000900", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000900", {2307}, {3}},
+ {L"\U00000903\U0000094d", {2307}, {2}},
+ {L"\U00000903\U00000308\U0000094d", {2307}, {3}},
+ {L"\U00000903\U0000200d", {2307}, {2}},
+ {L"\U00000903\U00000308\U0000200d", {2307}, {3}},
+ {L"\U00000903\U00000378", {2307, 888}, {1, 2}},
+ {L"\U00000903\U00000308\U00000378", {2307, 888}, {2, 3}},
+ {L"\U00000904\U00000020", {2308, 32}, {1, 2}},
+ {L"\U00000904\U00000308\U00000020", {2308, 32}, {2, 3}},
+ {L"\U00000904\U0000000d", {2308, 13}, {1, 2}},
+ {L"\U00000904\U00000308\U0000000d", {2308, 13}, {2, 3}},
+ {L"\U00000904\U0000000a", {2308, 10}, {1, 2}},
+ {L"\U00000904\U00000308\U0000000a", {2308, 10}, {2, 3}},
+ {L"\U00000904\U00000001", {2308, 1}, {1, 2}},
+ {L"\U00000904\U00000308\U00000001", {2308, 1}, {2, 3}},
+ {L"\U00000904\U0000200c", {2308}, {2}},
+ {L"\U00000904\U00000308\U0000200c", {2308}, {3}},
+ {L"\U00000904\U0001f1e6", {2308, 127462}, {1, 3}},
+ {L"\U00000904\U00000308\U0001f1e6", {2308, 127462}, {2, 4}},
+ {L"\U00000904\U00000600", {2308, 1536}, {1, 2}},
+ {L"\U00000904\U00000308\U00000600", {2308, 1536}, {2, 3}},
+ {L"\U00000904\U00000a03", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000a03", {2308}, {3}},
+ {L"\U00000904\U00001100", {2308, 4352}, {1, 2}},
+ {L"\U00000904\U00000308\U00001100", {2308, 4352}, {2, 3}},
+ {L"\U00000904\U00001160", {2308, 4448}, {1, 2}},
+ {L"\U00000904\U00000308\U00001160", {2308, 4448}, {2, 3}},
+ {L"\U00000904\U000011a8", {2308, 4520}, {1, 2}},
+ {L"\U00000904\U00000308\U000011a8", {2308, 4520}, {2, 3}},
+ {L"\U00000904\U0000ac00", {2308, 44032}, {1, 2}},
+ {L"\U00000904\U00000308\U0000ac00", {2308, 44032}, {2, 3}},
+ {L"\U00000904\U0000ac01", {2308, 44033}, {1, 2}},
+ {L"\U00000904\U00000308\U0000ac01", {2308, 44033}, {2, 3}},
+ {L"\U00000904\U00000903", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000903", {2308}, {3}},
+ {L"\U00000904\U00000904", {2308, 2308}, {1, 2}},
+ {L"\U00000904\U00000308\U00000904", {2308, 2308}, {2, 3}},
+ {L"\U00000904\U00000d4e", {2308, 3406}, {1, 2}},
+ {L"\U00000904\U00000308\U00000d4e", {2308, 3406}, {2, 3}},
+ {L"\U00000904\U00000915", {2308, 2325}, {1, 2}},
+ {L"\U00000904\U00000308\U00000915", {2308, 2325}, {2, 3}},
+ {L"\U00000904\U0000231a", {2308, 8986}, {1, 2}},
+ {L"\U00000904\U00000308\U0000231a", {2308, 8986}, {2, 3}},
+ {L"\U00000904\U00000300", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000300", {2308}, {3}},
+ {L"\U00000904\U00000900", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000900", {2308}, {3}},
+ {L"\U00000904\U0000094d", {2308}, {2}},
+ {L"\U00000904\U00000308\U0000094d", {2308}, {3}},
+ {L"\U00000904\U0000200d", {2308}, {2}},
+ {L"\U00000904\U00000308\U0000200d", {2308}, {3}},
+ {L"\U00000904\U00000378", {2308, 888}, {1, 2}},
+ {L"\U00000904\U00000308\U00000378", {2308, 888}, {2, 3}},
+ {L"\U00000d4e\U00000020", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000020", {3406, 32}, {2, 3}},
+ {L"\U00000d4e\U0000000d", {3406, 13}, {1, 2}},
+ {L"\U00000d4e\U00000308\U0000000d", {3406, 13}, {2, 3}},
+ {L"\U00000d4e\U0000000a", {3406, 10}, {1, 2}},
+ {L"\U00000d4e\U00000308\U0000000a", {3406, 10}, {2, 3}},
+ {L"\U00000d4e\U00000001", {3406, 1}, {1, 2}},
+ {L"\U00000d4e\U00000308\U00000001", {3406, 1}, {2, 3}},
+ {L"\U00000d4e\U0000200c", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000200c", {3406}, {3}},
+ {L"\U00000d4e\U0001f1e6", {3406}, {3}},
+ {L"\U00000d4e\U00000308\U0001f1e6", {3406, 127462}, {2, 4}},
+ {L"\U00000d4e\U00000600", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000600", {3406, 1536}, {2, 3}},
+ {L"\U00000d4e\U00000a03", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000a03", {3406}, {3}},
+ {L"\U00000d4e\U00001100", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00001100", {3406, 4352}, {2, 3}},
+ {L"\U00000d4e\U00001160", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00001160", {3406, 4448}, {2, 3}},
+ {L"\U00000d4e\U000011a8", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U000011a8", {3406, 4520}, {2, 3}},
+ {L"\U00000d4e\U0000ac00", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000ac00", {3406, 44032}, {2, 3}},
+ {L"\U00000d4e\U0000ac01", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000ac01", {3406, 44033}, {2, 3}},
+ {L"\U00000d4e\U00000903", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000903", {3406}, {3}},
+ {L"\U00000d4e\U00000904", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000904", {3406, 2308}, {2, 3}},
+ {L"\U00000d4e\U00000d4e", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000d4e", {3406, 3406}, {2, 3}},
+ {L"\U00000d4e\U00000915", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000915", {3406, 2325}, {2, 3}},
+ {L"\U00000d4e\U0000231a", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000231a", {3406, 8986}, {2, 3}},
+ {L"\U00000d4e\U00000300", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000300", {3406}, {3}},
+ {L"\U00000d4e\U00000900", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000900", {3406}, {3}},
+ {L"\U00000d4e\U0000094d", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000094d", {3406}, {3}},
+ {L"\U00000d4e\U0000200d", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000200d", {3406}, {3}},
+ {L"\U00000d4e\U00000378", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000378", {3406, 888}, {2, 3}},
+ {L"\U00000915\U00000020", {2325, 32}, {1, 2}},
+ {L"\U00000915\U00000308\U00000020", {2325, 32}, {2, 3}},
+ {L"\U00000915\U0000000d", {2325, 13}, {1, 2}},
+ {L"\U00000915\U00000308\U0000000d", {2325, 13}, {2, 3}},
+ {L"\U00000915\U0000000a", {2325, 10}, {1, 2}},
+ {L"\U00000915\U00000308\U0000000a", {2325, 10}, {2, 3}},
+ {L"\U00000915\U00000001", {2325, 1}, {1, 2}},
+ {L"\U00000915\U00000308\U00000001", {2325, 1}, {2, 3}},
+ {L"\U00000915\U0000200c", {2325}, {2}},
+ {L"\U00000915\U00000308\U0000200c", {2325}, {3}},
+ {L"\U00000915\U0001f1e6", {2325, 127462}, {1, 3}},
+ {L"\U00000915\U00000308\U0001f1e6", {2325, 127462}, {2, 4}},
+ {L"\U00000915\U00000600", {2325, 1536}, {1, 2}},
+ {L"\U00000915\U00000308\U00000600", {2325, 1536}, {2, 3}},
+ {L"\U00000915\U00000a03", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000a03", {2325}, {3}},
+ {L"\U00000915\U00001100", {2325, 4352}, {1, 2}},
+ {L"\U00000915\U00000308\U00001100", {2325, 4352}, {2, 3}},
+ {L"\U00000915\U00001160", {2325, 4448}, {1, 2}},
+ {L"\U00000915\U00000308\U00001160", {2325, 4448}, {2, 3}},
+ {L"\U00000915\U000011a8", {2325, 4520}, {1, 2}},
+ {L"\U00000915\U00000308\U000011a8", {2325, 4520}, {2, 3}},
+ {L"\U00000915\U0000ac00", {2325, 44032}, {1, 2}},
+ {L"\U00000915\U00000308\U0000ac00", {2325, 44032}, {2, 3}},
+ {L"\U00000915\U0000ac01", {2325, 44033}, {1, 2}},
+ {L"\U00000915\U00000308\U0000ac01", {2325, 44033}, {2, 3}},
+ {L"\U00000915\U00000903", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000903", {2325}, {3}},
+ {L"\U00000915\U00000904", {2325, 2308}, {1, 2}},
+ {L"\U00000915\U00000308\U00000904", {2325, 2308}, {2, 3}},
+ {L"\U00000915\U00000d4e", {2325, 3406}, {1, 2}},
+ {L"\U00000915\U00000308\U00000d4e", {2325, 3406}, {2, 3}},
+ {L"\U00000915\U00000915", {2325, 2325}, {1, 2}},
+ {L"\U00000915\U00000308\U00000915", {2325, 2325}, {2, 3}},
+ {L"\U00000915\U0000231a", {2325, 8986}, {1, 2}},
+ {L"\U00000915\U00000308\U0000231a", {2325, 8986}, {2, 3}},
+ {L"\U00000915\U00000300", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000300", {2325}, {3}},
+ {L"\U00000915\U00000900", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000900", {2325}, {3}},
+ {L"\U00000915\U0000094d", {2325}, {2}},
+ {L"\U00000915\U00000308\U0000094d", {2325}, {3}},
+ {L"\U00000915\U0000200d", {2325}, {2}},
+ {L"\U00000915\U00000308\U0000200d", {2325}, {3}},
+ {L"\U00000915\U00000378", {2325, 888}, {1, 2}},
+ {L"\U00000915\U00000308\U00000378", {2325, 888}, {2, 3}},
+ {L"\U0000231a\U00000020", {8986, 32}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000020", {8986, 32}, {2, 3}},
+ {L"\U0000231a\U0000000d", {8986, 13}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000000d", {8986, 13}, {2, 3}},
+ {L"\U0000231a\U0000000a", {8986, 10}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000000a", {8986, 10}, {2, 3}},
+ {L"\U0000231a\U00000001", {8986, 1}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000001", {8986, 1}, {2, 3}},
+ {L"\U0000231a\U0000200c", {8986}, {2}},
+ {L"\U0000231a\U00000308\U0000200c", {8986}, {3}},
+ {L"\U0000231a\U0001f1e6", {8986, 127462}, {1, 3}},
+ {L"\U0000231a\U00000308\U0001f1e6", {8986, 127462}, {2, 4}},
+ {L"\U0000231a\U00000600", {8986, 1536}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000600", {8986, 1536}, {2, 3}},
+ {L"\U0000231a\U00000a03", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000a03", {8986}, {3}},
+ {L"\U0000231a\U00001100", {8986, 4352}, {1, 2}},
+ {L"\U0000231a\U00000308\U00001100", {8986, 4352}, {2, 3}},
+ {L"\U0000231a\U00001160", {8986, 4448}, {1, 2}},
+ {L"\U0000231a\U00000308\U00001160", {8986, 4448}, {2, 3}},
+ {L"\U0000231a\U000011a8", {8986, 4520}, {1, 2}},
+ {L"\U0000231a\U00000308\U000011a8", {8986, 4520}, {2, 3}},
+ {L"\U0000231a\U0000ac00", {8986, 44032}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000ac00", {8986, 44032}, {2, 3}},
+ {L"\U0000231a\U0000ac01", {8986, 44033}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000ac01", {8986, 44033}, {2, 3}},
+ {L"\U0000231a\U00000903", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000903", {8986}, {3}},
+ {L"\U0000231a\U00000904", {8986, 2308}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000904", {8986, 2308}, {2, 3}},
+ {L"\U0000231a\U00000d4e", {8986, 3406}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000d4e", {8986, 3406}, {2, 3}},
+ {L"\U0000231a\U00000915", {8986, 2325}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000915", {8986, 2325}, {2, 3}},
+ {L"\U0000231a\U0000231a", {8986, 8986}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000231a", {8986, 8986}, {2, 3}},
+ {L"\U0000231a\U00000300", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000300", {8986}, {3}},
+ {L"\U0000231a\U00000900", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000900", {8986}, {3}},
+ {L"\U0000231a\U0000094d", {8986}, {2}},
+ {L"\U0000231a\U00000308\U0000094d", {8986}, {3}},
+ {L"\U0000231a\U0000200d", {8986}, {2}},
+ {L"\U0000231a\U00000308\U0000200d", {8986}, {3}},
+ {L"\U0000231a\U00000378", {8986, 888}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000378", {8986, 888}, {2, 3}},
+ {L"\U00000300\U00000020", {768, 32}, {1, 2}},
+ {L"\U00000300\U00000308\U00000020", {768, 32}, {2, 3}},
+ {L"\U00000300\U0000000d", {768, 13}, {1, 2}},
+ {L"\U00000300\U00000308\U0000000d", {768, 13}, {2, 3}},
+ {L"\U00000300\U0000000a", {768, 10}, {1, 2}},
+ {L"\U00000300\U00000308\U0000000a", {768, 10}, {2, 3}},
+ {L"\U00000300\U00000001", {768, 1}, {1, 2}},
+ {L"\U00000300\U00000308\U00000001", {768, 1}, {2, 3}},
+ {L"\U00000300\U0000200c", {768}, {2}},
+ {L"\U00000300\U00000308\U0000200c", {768}, {3}},
+ {L"\U00000300\U0001f1e6", {768, 127462}, {1, 3}},
+ {L"\U00000300\U00000308\U0001f1e6", {768, 127462}, {2, 4}},
+ {L"\U00000300\U00000600", {768, 1536}, {1, 2}},
+ {L"\U00000300\U00000308\U00000600", {768, 1536}, {2, 3}},
+ {L"\U00000300\U00000a03", {768}, {2}},
+ {L"\U00000300\U00000308\U00000a03", {768}, {3}},
+ {L"\U00000300\U00001100", {768, 4352}, {1, 2}},
+ {L"\U00000300\U00000308\U00001100", {768, 4352}, {2, 3}},
+ {L"\U00000300\U00001160", {768, 4448}, {1, 2}},
+ {L"\U00000300\U00000308\U00001160", {768, 4448}, {2, 3}},
+ {L"\U00000300\U000011a8", {768, 4520}, {1, 2}},
+ {L"\U00000300\U00000308\U000011a8", {768, 4520}, {2, 3}},
+ {L"\U00000300\U0000ac00", {768, 44032}, {1, 2}},
+ {L"\U00000300\U00000308\U0000ac00", {768, 44032}, {2, 3}},
+ {L"\U00000300\U0000ac01", {768, 44033}, {1, 2}},
+ {L"\U00000300\U00000308\U0000ac01", {768, 44033}, {2, 3}},
+ {L"\U00000300\U00000903", {768}, {2}},
+ {L"\U00000300\U00000308\U00000903", {768}, {3}},
+ {L"\U00000300\U00000904", {768, 2308}, {1, 2}},
+ {L"\U00000300\U00000308\U00000904", {768, 2308}, {2, 3}},
+ {L"\U00000300\U00000d4e", {768, 3406}, {1, 2}},
+ {L"\U00000300\U00000308\U00000d4e", {768, 3406}, {2, 3}},
+ {L"\U00000300\U00000915", {768, 2325}, {1, 2}},
+ {L"\U00000300\U00000308\U00000915", {768, 2325}, {2, 3}},
+ {L"\U00000300\U0000231a", {768, 8986}, {1, 2}},
+ {L"\U00000300\U00000308\U0000231a", {768, 8986}, {2, 3}},
+ {L"\U00000300\U00000300", {768}, {2}},
+ {L"\U00000300\U00000308\U00000300", {768}, {3}},
+ {L"\U00000300\U00000900", {768}, {2}},
+ {L"\U00000300\U00000308\U00000900", {768}, {3}},
+ {L"\U00000300\U0000094d", {768}, {2}},
+ {L"\U00000300\U00000308\U0000094d", {768}, {3}},
+ {L"\U00000300\U0000200d", {768}, {2}},
+ {L"\U00000300\U00000308\U0000200d", {768}, {3}},
+ {L"\U00000300\U00000378", {768, 888}, {1, 2}},
+ {L"\U00000300\U00000308\U00000378", {768, 888}, {2, 3}},
+ {L"\U00000900\U00000020", {2304, 32}, {1, 2}},
+ {L"\U00000900\U00000308\U00000020", {2304, 32}, {2, 3}},
+ {L"\U00000900\U0000000d", {2304, 13}, {1, 2}},
+ {L"\U00000900\U00000308\U0000000d", {2304, 13}, {2, 3}},
+ {L"\U00000900\U0000000a", {2304, 10}, {1, 2}},
+ {L"\U00000900\U00000308\U0000000a", {2304, 10}, {2, 3}},
+ {L"\U00000900\U00000001", {2304, 1}, {1, 2}},
+ {L"\U00000900\U00000308\U00000001", {2304, 1}, {2, 3}},
+ {L"\U00000900\U0000200c", {2304}, {2}},
+ {L"\U00000900\U00000308\U0000200c", {2304}, {3}},
+ {L"\U00000900\U0001f1e6", {2304, 127462}, {1, 3}},
+ {L"\U00000900\U00000308\U0001f1e6", {2304, 127462}, {2, 4}},
+ {L"\U00000900\U00000600", {2304, 1536}, {1, 2}},
+ {L"\U00000900\U00000308\U00000600", {2304, 1536}, {2, 3}},
+ {L"\U00000900\U00000a03", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000a03", {2304}, {3}},
+ {L"\U00000900\U00001100", {2304, 4352}, {1, 2}},
+ {L"\U00000900\U00000308\U00001100", {2304, 4352}, {2, 3}},
+ {L"\U00000900\U00001160", {2304, 4448}, {1, 2}},
+ {L"\U00000900\U00000308\U00001160", {2304, 4448}, {2, 3}},
+ {L"\U00000900\U000011a8", {2304, 4520}, {1, 2}},
+ {L"\U00000900\U00000308\U000011a8", {2304, 4520}, {2, 3}},
+ {L"\U00000900\U0000ac00", {2304, 44032}, {1, 2}},
+ {L"\U00000900\U00000308\U0000ac00", {2304, 44032}, {2, 3}},
+ {L"\U00000900\U0000ac01", {2304, 44033}, {1, 2}},
+ {L"\U00000900\U00000308\U0000ac01", {2304, 44033}, {2, 3}},
+ {L"\U00000900\U00000903", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000903", {2304}, {3}},
+ {L"\U00000900\U00000904", {2304, 2308}, {1, 2}},
+ {L"\U00000900\U00000308\U00000904", {2304, 2308}, {2, 3}},
+ {L"\U00000900\U00000d4e", {2304, 3406}, {1, 2}},
+ {L"\U00000900\U00000308\U00000d4e", {2304, 3406}, {2, 3}},
+ {L"\U00000900\U00000915", {2304, 2325}, {1, 2}},
+ {L"\U00000900\U00000308\U00000915", {2304, 2325}, {2, 3}},
+ {L"\U00000900\U0000231a", {2304, 8986}, {1, 2}},
+ {L"\U00000900\U00000308\U0000231a", {2304, 8986}, {2, 3}},
+ {L"\U00000900\U00000300", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000300", {2304}, {3}},
+ {L"\U00000900\U00000900", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000900", {2304}, {3}},
+ {L"\U00000900\U0000094d", {2304}, {2}},
+ {L"\U00000900\U00000308\U0000094d", {2304}, {3}},
+ {L"\U00000900\U0000200d", {2304}, {2}},
+ {L"\U00000900\U00000308\U0000200d", {2304}, {3}},
+ {L"\U00000900\U00000378", {2304, 888}, {1, 2}},
+ {L"\U00000900\U00000308\U00000378", {2304, 888}, {2, 3}},
+ {L"\U0000094d\U00000020", {2381, 32}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000020", {2381, 32}, {2, 3}},
+ {L"\U0000094d\U0000000d", {2381, 13}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000000d", {2381, 13}, {2, 3}},
+ {L"\U0000094d\U0000000a", {2381, 10}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000000a", {2381, 10}, {2, 3}},
+ {L"\U0000094d\U00000001", {2381, 1}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000001", {2381, 1}, {2, 3}},
+ {L"\U0000094d\U0000200c", {2381}, {2}},
+ {L"\U0000094d\U00000308\U0000200c", {2381}, {3}},
+ {L"\U0000094d\U0001f1e6", {2381, 127462}, {1, 3}},
+ {L"\U0000094d\U00000308\U0001f1e6", {2381, 127462}, {2, 4}},
+ {L"\U0000094d\U00000600", {2381, 1536}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000600", {2381, 1536}, {2, 3}},
+ {L"\U0000094d\U00000a03", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000a03", {2381}, {3}},
+ {L"\U0000094d\U00001100", {2381, 4352}, {1, 2}},
+ {L"\U0000094d\U00000308\U00001100", {2381, 4352}, {2, 3}},
+ {L"\U0000094d\U00001160", {2381, 4448}, {1, 2}},
+ {L"\U0000094d\U00000308\U00001160", {2381, 4448}, {2, 3}},
+ {L"\U0000094d\U000011a8", {2381, 4520}, {1, 2}},
+ {L"\U0000094d\U00000308\U000011a8", {2381, 4520}, {2, 3}},
+ {L"\U0000094d\U0000ac00", {2381, 44032}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000ac00", {2381, 44032}, {2, 3}},
+ {L"\U0000094d\U0000ac01", {2381, 44033}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000ac01", {2381, 44033}, {2, 3}},
+ {L"\U0000094d\U00000903", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000903", {2381}, {3}},
+ {L"\U0000094d\U00000904", {2381, 2308}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000904", {2381, 2308}, {2, 3}},
+ {L"\U0000094d\U00000d4e", {2381, 3406}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000d4e", {2381, 3406}, {2, 3}},
+ {L"\U0000094d\U00000915", {2381, 2325}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000915", {2381, 2325}, {2, 3}},
+ {L"\U0000094d\U0000231a", {2381, 8986}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000231a", {2381, 8986}, {2, 3}},
+ {L"\U0000094d\U00000300", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000300", {2381}, {3}},
+ {L"\U0000094d\U00000900", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000900", {2381}, {3}},
+ {L"\U0000094d\U0000094d", {2381}, {2}},
+ {L"\U0000094d\U00000308\U0000094d", {2381}, {3}},
+ {L"\U0000094d\U0000200d", {2381}, {2}},
+ {L"\U0000094d\U00000308\U0000200d", {2381}, {3}},
+ {L"\U0000094d\U00000378", {2381, 888}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000378", {2381, 888}, {2, 3}},
+ {L"\U0000200d\U00000020", {8205, 32}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000020", {8205, 32}, {2, 3}},
+ {L"\U0000200d\U0000000d", {8205, 13}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000000d", {8205, 13}, {2, 3}},
+ {L"\U0000200d\U0000000a", {8205, 10}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000000a", {8205, 10}, {2, 3}},
+ {L"\U0000200d\U00000001", {8205, 1}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000001", {8205, 1}, {2, 3}},
+ {L"\U0000200d\U0000200c", {8205}, {2}},
+ {L"\U0000200d\U00000308\U0000200c", {8205}, {3}},
+ {L"\U0000200d\U0001f1e6", {8205, 127462}, {1, 3}},
+ {L"\U0000200d\U00000308\U0001f1e6", {8205, 127462}, {2, 4}},
+ {L"\U0000200d\U00000600", {8205, 1536}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000600", {8205, 1536}, {2, 3}},
+ {L"\U0000200d\U00000a03", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000a03", {8205}, {3}},
+ {L"\U0000200d\U00001100", {8205, 4352}, {1, 2}},
+ {L"\U0000200d\U00000308\U00001100", {8205, 4352}, {2, 3}},
+ {L"\U0000200d\U00001160", {8205, 4448}, {1, 2}},
+ {L"\U0000200d\U00000308\U00001160", {8205, 4448}, {2, 3}},
+ {L"\U0000200d\U000011a8", {8205, 4520}, {1, 2}},
+ {L"\U0000200d\U00000308\U000011a8", {8205, 4520}, {2, 3}},
+ {L"\U0000200d\U0000ac00", {8205, 44032}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000ac00", {8205, 44032}, {2, 3}},
+ {L"\U0000200d\U0000ac01", {8205, 44033}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000ac01", {8205, 44033}, {2, 3}},
+ {L"\U0000200d\U00000903", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000903", {8205}, {3}},
+ {L"\U0000200d\U00000904", {8205, 2308}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000904", {8205, 2308}, {2, 3}},
+ {L"\U0000200d\U00000d4e", {8205, 3406}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000d4e", {8205, 3406}, {2, 3}},
+ {L"\U0000200d\U00000915", {8205, 2325}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000915", {8205, 2325}, {2, 3}},
+ {L"\U0000200d\U0000231a", {8205, 8986}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000231a", {8205, 8986}, {2, 3}},
+ {L"\U0000200d\U00000300", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000300", {8205}, {3}},
+ {L"\U0000200d\U00000900", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000900", {8205}, {3}},
+ {L"\U0000200d\U0000094d", {8205}, {2}},
+ {L"\U0000200d\U00000308\U0000094d", {8205}, {3}},
+ {L"\U0000200d\U0000200d", {8205}, {2}},
+ {L"\U0000200d\U00000308\U0000200d", {8205}, {3}},
+ {L"\U0000200d\U00000378", {8205, 888}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000378", {8205, 888}, {2, 3}},
+ {L"\U00000378\U00000020", {888, 32}, {1, 2}},
+ {L"\U00000378\U00000308\U00000020", {888, 32}, {2, 3}},
+ {L"\U00000378\U0000000d", {888, 13}, {1, 2}},
+ {L"\U00000378\U00000308\U0000000d", {888, 13}, {2, 3}},
+ {L"\U00000378\U0000000a", {888, 10}, {1, 2}},
+ {L"\U00000378\U00000308\U0000000a", {888, 10}, {2, 3}},
+ {L"\U00000378\U00000001", {888, 1}, {1, 2}},
+ {L"\U00000378\U00000308\U00000001", {888, 1}, {2, 3}},
+ {L"\U00000378\U0000200c", {888}, {2}},
+ {L"\U00000378\U00000308\U0000200c", {888}, {3}},
+ {L"\U00000378\U0001f1e6", {888, 127462}, {1, 3}},
+ {L"\U00000378\U00000308\U0001f1e6", {888, 127462}, {2, 4}},
+ {L"\U00000378\U00000600", {888, 1536}, {1, 2}},
+ {L"\U00000378\U00000308\U00000600", {888, 1536}, {2, 3}},
+ {L"\U00000378\U00000a03", {888}, {2}},
+ {L"\U00000378\U00000308\U00000a03", {888}, {3}},
+ {L"\U00000378\U00001100", {888, 4352}, {1, 2}},
+ {L"\U00000378\U00000308\U00001100", {888, 4352}, {2, 3}},
+ {L"\U00000378\U00001160", {888, 4448}, {1, 2}},
+ {L"\U00000378\U00000308\U00001160", {888, 4448}, {2, 3}},
+ {L"\U00000378\U000011a8", {888, 4520}, {1, 2}},
+ {L"\U00000378\U00000308\U000011a8", {888, 4520}, {2, 3}},
+ {L"\U00000378\U0000ac00", {888, 44032}, {1, 2}},
+ {L"\U00000378\U00000308\U0000ac00", {888, 44032}, {2, 3}},
+ {L"\U00000378\U0000ac01", {888, 44033}, {1, 2}},
+ {L"\U00000378\U00000308\U0000ac01", {888, 44033}, {2, 3}},
+ {L"\U00000378\U00000903", {888}, {2}},
+ {L"\U00000378\U00000308\U00000903", {888}, {3}},
+ {L"\U00000378\U00000904", {888, 2308}, {1, 2}},
+ {L"\U00000378\U00000308\U00000904", {888, 2308}, {2, 3}},
+ {L"\U00000378\U00000d4e", {888, 3406}, {1, 2}},
+ {L"\U00000378\U00000308\U00000d4e", {888, 3406}, {2, 3}},
+ {L"\U00000378\U00000915", {888, 2325}, {1, 2}},
+ {L"\U00000378\U00000308\U00000915", {888, 2325}, {2, 3}},
+ {L"\U00000378\U0000231a", {888, 8986}, {1, 2}},
+ {L"\U00000378\U00000308\U0000231a", {888, 8986}, {2, 3}},
+ {L"\U00000378\U00000300", {888}, {2}},
+ {L"\U00000378\U00000308\U00000300", {888}, {3}},
+ {L"\U00000378\U00000900", {888}, {2}},
+ {L"\U00000378\U00000308\U00000900", {888}, {3}},
+ {L"\U00000378\U0000094d", {888}, {2}},
+ {L"\U00000378\U00000308\U0000094d", {888}, {3}},
+ {L"\U00000378\U0000200d", {888}, {2}},
+ {L"\U00000378\U00000308\U0000200d", {888}, {3}},
+ {L"\U00000378\U00000378", {888, 888}, {1, 2}},
+ {L"\U00000378\U00000308\U00000378", {888, 888}, {2, 3}},
+ {L"\U0000000d\U0000000a\U00000061\U0000000a\U00000308", {13, 97, 10, 776}, {2, 3, 4, 5}},
+ {L"\U00000061\U00000308", {97}, {2}},
+ {L"\U00000020\U0000200d\U00000646", {32, 1606}, {2, 3}},
+ {L"\U00000646\U0000200d\U00000020", {1606, 32}, {2, 3}},
+ {L"\U00001100\U00001100", {4352}, {2}},
+ {L"\U0000ac00\U000011a8\U00001100", {44032, 4352}, {2, 3}},
+ {L"\U0000ac01\U000011a8\U00001100", {44033, 4352}, {2, 3}},
+ {L"\U0001f1e6\U0001f1e7\U0001f1e8\U00000062", {127462, 127464, 98}, {4, 6, 7}},
+ {L"\U00000061\U0001f1e6\U0001f1e7\U0001f1e8\U00000062", {97, 127462, 127464, 98}, {1, 5, 7, 8}},
+ {L"\U00000061\U0001f1e6\U0001f1e7\U0000200d\U0001f1e8\U00000062", {97, 127462, 127464, 98}, {1, 6, 8, 9}},
+ {L"\U00000061\U0001f1e6\U0000200d\U0001f1e7\U0001f1e8\U00000062", {97, 127462, 127463, 98}, {1, 4, 8, 9}},
+ {L"\U00000061\U0001f1e6\U0001f1e7\U0001f1e8\U0001f1e9\U00000062", {97, 127462, 127464, 98}, {1, 5, 9, 10}},
+ {L"\U00000061\U0000200d", {97}, {2}},
+ {L"\U00000061\U00000308\U00000062", {97, 98}, {2, 3}},
+ {L"\U00000061\U00000903\U00000062", {97, 98}, {2, 3}},
+ {L"\U00000061\U00000600\U00000062", {97, 1536}, {1, 3}},
+ {L"\U0001f476\U0001f3ff\U0001f476", {128118, 128118}, {4, 6}},
+ {L"\U00000061\U0001f3ff\U0001f476", {97, 128118}, {3, 5}},
+ {L"\U00000061\U0001f3ff\U0001f476\U0000200d\U0001f6d1", {97, 128118}, {3, 8}},
+ {L"\U0001f476\U0001f3ff\U00000308\U0000200d\U0001f476\U0001f3ff", {128118}, {10}},
+ {L"\U0001f6d1\U0000200d\U0001f6d1", {128721}, {5}},
+ {L"\U00000061\U0000200d\U0001f6d1", {97, 128721}, {2, 4}},
+ {L"\U00002701\U0000200d\U00002701", {9985}, {3}},
+ {L"\U00000061\U0000200d\U00002701", {97, 9985}, {2, 3}},
+ {L"\U00000915\U00000924", {2325, 2340}, {1, 2}},
+ {L"\U00000915\U0000094d\U00000924", {2325}, {3}},
+ {L"\U00000915\U0000094d\U0000094d\U00000924", {2325}, {4}},
+ {L"\U00000915\U0000094d\U0000200d\U00000924", {2325}, {4}},
+ {L"\U00000915\U0000093c\U0000200d\U0000094d\U00000924", {2325}, {5}},
+ {L"\U00000915\U0000093c\U0000094d\U0000200d\U00000924", {2325}, {5}},
+ {L"\U00000915\U0000094d\U00000924\U0000094d\U0000092f", {2325}, {5}},
+ {L"\U00000915\U0000094d\U00000061", {2325, 97}, {2, 3}},
+ {L"\U00000061\U0000094d\U00000924", {97, 2340}, {2, 3}},
+ {L"\U0000003f\U0000094d\U00000924", {63, 2340}, {2, 3}},
+ {L"\U00000915\U0000094d\U0000094d\U00000924", {2325}, {4}}}};
+
+/// The data for UTF-8.
+///
+/// Note that most of the data for the UTF-16 and UTF-32 are identical. However
+/// since the size of the code units differ the breaks can contain different
+/// values.
+std::array<data<wchar_t>, 1093> data_utf32 = {{
+ {L"\U00000020\U00000020", {32, 32}, {1, 2}},
+ {L"\U00000020\U00000308\U00000020", {32, 32}, {2, 3}},
+ {L"\U00000020\U0000000d", {32, 13}, {1, 2}},
+ {L"\U00000020\U00000308\U0000000d", {32, 13}, {2, 3}},
+ {L"\U00000020\U0000000a", {32, 10}, {1, 2}},
+ {L"\U00000020\U00000308\U0000000a", {32, 10}, {2, 3}},
+ {L"\U00000020\U00000001", {32, 1}, {1, 2}},
+ {L"\U00000020\U00000308\U00000001", {32, 1}, {2, 3}},
+ {L"\U00000020\U0000200c", {32}, {2}},
+ {L"\U00000020\U00000308\U0000200c", {32}, {3}},
+ {L"\U00000020\U0001f1e6", {32, 127462}, {1, 2}},
+ {L"\U00000020\U00000308\U0001f1e6", {32, 127462}, {2, 3}},
+ {L"\U00000020\U00000600", {32, 1536}, {1, 2}},
+ {L"\U00000020\U00000308\U00000600", {32, 1536}, {2, 3}},
+ {L"\U00000020\U00000a03", {32}, {2}},
+ {L"\U00000020\U00000308\U00000a03", {32}, {3}},
+ {L"\U00000020\U00001100", {32, 4352}, {1, 2}},
+ {L"\U00000020\U00000308\U00001100", {32, 4352}, {2, 3}},
+ {L"\U00000020\U00001160", {32, 4448}, {1, 2}},
+ {L"\U00000020\U00000308\U00001160", {32, 4448}, {2, 3}},
+ {L"\U00000020\U000011a8", {32, 4520}, {1, 2}},
+ {L"\U00000020\U00000308\U000011a8", {32, 4520}, {2, 3}},
+ {L"\U00000020\U0000ac00", {32, 44032}, {1, 2}},
+ {L"\U00000020\U00000308\U0000ac00", {32, 44032}, {2, 3}},
+ {L"\U00000020\U0000ac01", {32, 44033}, {1, 2}},
+ {L"\U00000020\U00000308\U0000ac01", {32, 44033}, {2, 3}},
+ {L"\U00000020\U00000903", {32}, {2}},
+ {L"\U00000020\U00000308\U00000903", {32}, {3}},
+ {L"\U00000020\U00000904", {32, 2308}, {1, 2}},
+ {L"\U00000020\U00000308\U00000904", {32, 2308}, {2, 3}},
+ {L"\U00000020\U00000d4e", {32, 3406}, {1, 2}},
+ {L"\U00000020\U00000308\U00000d4e", {32, 3406}, {2, 3}},
+ {L"\U00000020\U00000915", {32, 2325}, {1, 2}},
+ {L"\U00000020\U00000308\U00000915", {32, 2325}, {2, 3}},
+ {L"\U00000020\U0000231a", {32, 8986}, {1, 2}},
+ {L"\U00000020\U00000308\U0000231a", {32, 8986}, {2, 3}},
+ {L"\U00000020\U00000300", {32}, {2}},
+ {L"\U00000020\U00000308\U00000300", {32}, {3}},
+ {L"\U00000020\U00000900", {32}, {2}},
+ {L"\U00000020\U00000308\U00000900", {32}, {3}},
+ {L"\U00000020\U0000094d", {32}, {2}},
+ {L"\U00000020\U00000308\U0000094d", {32}, {3}},
+ {L"\U00000020\U0000200d", {32}, {2}},
+ {L"\U00000020\U00000308\U0000200d", {32}, {3}},
+ {L"\U00000020\U00000378", {32, 888}, {1, 2}},
+ {L"\U00000020\U00000308\U00000378", {32, 888}, {2, 3}},
+ {L"\U0000000d\U00000020", {13, 32}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000020", {13, 776, 32}, {1, 2, 3}},
+ {L"\U0000000d\U0000000d", {13, 13}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000000d", {13, 776, 13}, {1, 2, 3}},
+ {L"\U0000000d\U0000000a", {13}, {2}},
+ {L"\U0000000d\U00000308\U0000000a", {13, 776, 10}, {1, 2, 3}},
+ {L"\U0000000d\U00000001", {13, 1}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000001", {13, 776, 1}, {1, 2, 3}},
+ {L"\U0000000d\U0000200c", {13, 8204}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000200c", {13, 776}, {1, 3}},
+ {L"\U0000000d\U0001f1e6", {13, 127462}, {1, 2}},
+ {L"\U0000000d\U00000308\U0001f1e6", {13, 776, 127462}, {1, 2, 3}},
+ {L"\U0000000d\U00000600", {13, 1536}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000600", {13, 776, 1536}, {1, 2, 3}},
+ {L"\U0000000d\U00000a03", {13, 2563}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000a03", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00001100", {13, 4352}, {1, 2}},
+ {L"\U0000000d\U00000308\U00001100", {13, 776, 4352}, {1, 2, 3}},
+ {L"\U0000000d\U00001160", {13, 4448}, {1, 2}},
+ {L"\U0000000d\U00000308\U00001160", {13, 776, 4448}, {1, 2, 3}},
+ {L"\U0000000d\U000011a8", {13, 4520}, {1, 2}},
+ {L"\U0000000d\U00000308\U000011a8", {13, 776, 4520}, {1, 2, 3}},
+ {L"\U0000000d\U0000ac00", {13, 44032}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000ac00", {13, 776, 44032}, {1, 2, 3}},
+ {L"\U0000000d\U0000ac01", {13, 44033}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000ac01", {13, 776, 44033}, {1, 2, 3}},
+ {L"\U0000000d\U00000903", {13, 2307}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000903", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00000904", {13, 2308}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000904", {13, 776, 2308}, {1, 2, 3}},
+ {L"\U0000000d\U00000d4e", {13, 3406}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000d4e", {13, 776, 3406}, {1, 2, 3}},
+ {L"\U0000000d\U00000915", {13, 2325}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000915", {13, 776, 2325}, {1, 2, 3}},
+ {L"\U0000000d\U0000231a", {13, 8986}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000231a", {13, 776, 8986}, {1, 2, 3}},
+ {L"\U0000000d\U00000300", {13, 768}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000300", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00000900", {13, 2304}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000900", {13, 776}, {1, 3}},
+ {L"\U0000000d\U0000094d", {13, 2381}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000094d", {13, 776}, {1, 3}},
+ {L"\U0000000d\U0000200d", {13, 8205}, {1, 2}},
+ {L"\U0000000d\U00000308\U0000200d", {13, 776}, {1, 3}},
+ {L"\U0000000d\U00000378", {13, 888}, {1, 2}},
+ {L"\U0000000d\U00000308\U00000378", {13, 776, 888}, {1, 2, 3}},
+ {L"\U0000000a\U00000020", {10, 32}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000020", {10, 776, 32}, {1, 2, 3}},
+ {L"\U0000000a\U0000000d", {10, 13}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000000d", {10, 776, 13}, {1, 2, 3}},
+ {L"\U0000000a\U0000000a", {10, 10}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000000a", {10, 776, 10}, {1, 2, 3}},
+ {L"\U0000000a\U00000001", {10, 1}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000001", {10, 776, 1}, {1, 2, 3}},
+ {L"\U0000000a\U0000200c", {10, 8204}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000200c", {10, 776}, {1, 3}},
+ {L"\U0000000a\U0001f1e6", {10, 127462}, {1, 2}},
+ {L"\U0000000a\U00000308\U0001f1e6", {10, 776, 127462}, {1, 2, 3}},
+ {L"\U0000000a\U00000600", {10, 1536}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000600", {10, 776, 1536}, {1, 2, 3}},
+ {L"\U0000000a\U00000a03", {10, 2563}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000a03", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00001100", {10, 4352}, {1, 2}},
+ {L"\U0000000a\U00000308\U00001100", {10, 776, 4352}, {1, 2, 3}},
+ {L"\U0000000a\U00001160", {10, 4448}, {1, 2}},
+ {L"\U0000000a\U00000308\U00001160", {10, 776, 4448}, {1, 2, 3}},
+ {L"\U0000000a\U000011a8", {10, 4520}, {1, 2}},
+ {L"\U0000000a\U00000308\U000011a8", {10, 776, 4520}, {1, 2, 3}},
+ {L"\U0000000a\U0000ac00", {10, 44032}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000ac00", {10, 776, 44032}, {1, 2, 3}},
+ {L"\U0000000a\U0000ac01", {10, 44033}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000ac01", {10, 776, 44033}, {1, 2, 3}},
+ {L"\U0000000a\U00000903", {10, 2307}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000903", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00000904", {10, 2308}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000904", {10, 776, 2308}, {1, 2, 3}},
+ {L"\U0000000a\U00000d4e", {10, 3406}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000d4e", {10, 776, 3406}, {1, 2, 3}},
+ {L"\U0000000a\U00000915", {10, 2325}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000915", {10, 776, 2325}, {1, 2, 3}},
+ {L"\U0000000a\U0000231a", {10, 8986}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000231a", {10, 776, 8986}, {1, 2, 3}},
+ {L"\U0000000a\U00000300", {10, 768}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000300", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00000900", {10, 2304}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000900", {10, 776}, {1, 3}},
+ {L"\U0000000a\U0000094d", {10, 2381}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000094d", {10, 776}, {1, 3}},
+ {L"\U0000000a\U0000200d", {10, 8205}, {1, 2}},
+ {L"\U0000000a\U00000308\U0000200d", {10, 776}, {1, 3}},
+ {L"\U0000000a\U00000378", {10, 888}, {1, 2}},
+ {L"\U0000000a\U00000308\U00000378", {10, 776, 888}, {1, 2, 3}},
+ {L"\U00000001\U00000020", {1, 32}, {1, 2}},
+ {L"\U00000001\U00000308\U00000020", {1, 776, 32}, {1, 2, 3}},
+ {L"\U00000001\U0000000d", {1, 13}, {1, 2}},
+ {L"\U00000001\U00000308\U0000000d", {1, 776, 13}, {1, 2, 3}},
+ {L"\U00000001\U0000000a", {1, 10}, {1, 2}},
+ {L"\U00000001\U00000308\U0000000a", {1, 776, 10}, {1, 2, 3}},
+ {L"\U00000001\U00000001", {1, 1}, {1, 2}},
+ {L"\U00000001\U00000308\U00000001", {1, 776, 1}, {1, 2, 3}},
+ {L"\U00000001\U0000200c", {1, 8204}, {1, 2}},
+ {L"\U00000001\U00000308\U0000200c", {1, 776}, {1, 3}},
+ {L"\U00000001\U0001f1e6", {1, 127462}, {1, 2}},
+ {L"\U00000001\U00000308\U0001f1e6", {1, 776, 127462}, {1, 2, 3}},
+ {L"\U00000001\U00000600", {1, 1536}, {1, 2}},
+ {L"\U00000001\U00000308\U00000600", {1, 776, 1536}, {1, 2, 3}},
+ {L"\U00000001\U00000a03", {1, 2563}, {1, 2}},
+ {L"\U00000001\U00000308\U00000a03", {1, 776}, {1, 3}},
+ {L"\U00000001\U00001100", {1, 4352}, {1, 2}},
+ {L"\U00000001\U00000308\U00001100", {1, 776, 4352}, {1, 2, 3}},
+ {L"\U00000001\U00001160", {1, 4448}, {1, 2}},
+ {L"\U00000001\U00000308\U00001160", {1, 776, 4448}, {1, 2, 3}},
+ {L"\U00000001\U000011a8", {1, 4520}, {1, 2}},
+ {L"\U00000001\U00000308\U000011a8", {1, 776, 4520}, {1, 2, 3}},
+ {L"\U00000001\U0000ac00", {1, 44032}, {1, 2}},
+ {L"\U00000001\U00000308\U0000ac00", {1, 776, 44032}, {1, 2, 3}},
+ {L"\U00000001\U0000ac01", {1, 44033}, {1, 2}},
+ {L"\U00000001\U00000308\U0000ac01", {1, 776, 44033}, {1, 2, 3}},
+ {L"\U00000001\U00000903", {1, 2307}, {1, 2}},
+ {L"\U00000001\U00000308\U00000903", {1, 776}, {1, 3}},
+ {L"\U00000001\U00000904", {1, 2308}, {1, 2}},
+ {L"\U00000001\U00000308\U00000904", {1, 776, 2308}, {1, 2, 3}},
+ {L"\U00000001\U00000d4e", {1, 3406}, {1, 2}},
+ {L"\U00000001\U00000308\U00000d4e", {1, 776, 3406}, {1, 2, 3}},
+ {L"\U00000001\U00000915", {1, 2325}, {1, 2}},
+ {L"\U00000001\U00000308\U00000915", {1, 776, 2325}, {1, 2, 3}},
+ {L"\U00000001\U0000231a", {1, 8986}, {1, 2}},
+ {L"\U00000001\U00000308\U0000231a", {1, 776, 8986}, {1, 2, 3}},
+ {L"\U00000001\U00000300", {1, 768}, {1, 2}},
+ {L"\U00000001\U00000308\U00000300", {1, 776}, {1, 3}},
+ {L"\U00000001\U00000900", {1, 2304}, {1, 2}},
+ {L"\U00000001\U00000308\U00000900", {1, 776}, {1, 3}},
+ {L"\U00000001\U0000094d", {1, 2381}, {1, 2}},
+ {L"\U00000001\U00000308\U0000094d", {1, 776}, {1, 3}},
+ {L"\U00000001\U0000200d", {1, 8205}, {1, 2}},
+ {L"\U00000001\U00000308\U0000200d", {1, 776}, {1, 3}},
+ {L"\U00000001\U00000378", {1, 888}, {1, 2}},
+ {L"\U00000001\U00000308\U00000378", {1, 776, 888}, {1, 2, 3}},
+ {L"\U0000200c\U00000020", {8204, 32}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000020", {8204, 32}, {2, 3}},
+ {L"\U0000200c\U0000000d", {8204, 13}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000000d", {8204, 13}, {2, 3}},
+ {L"\U0000200c\U0000000a", {8204, 10}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000000a", {8204, 10}, {2, 3}},
+ {L"\U0000200c\U00000001", {8204, 1}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000001", {8204, 1}, {2, 3}},
+ {L"\U0000200c\U0000200c", {8204}, {2}},
+ {L"\U0000200c\U00000308\U0000200c", {8204}, {3}},
+ {L"\U0000200c\U0001f1e6", {8204, 127462}, {1, 2}},
+ {L"\U0000200c\U00000308\U0001f1e6", {8204, 127462}, {2, 3}},
+ {L"\U0000200c\U00000600", {8204, 1536}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000600", {8204, 1536}, {2, 3}},
+ {L"\U0000200c\U00000a03", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000a03", {8204}, {3}},
+ {L"\U0000200c\U00001100", {8204, 4352}, {1, 2}},
+ {L"\U0000200c\U00000308\U00001100", {8204, 4352}, {2, 3}},
+ {L"\U0000200c\U00001160", {8204, 4448}, {1, 2}},
+ {L"\U0000200c\U00000308\U00001160", {8204, 4448}, {2, 3}},
+ {L"\U0000200c\U000011a8", {8204, 4520}, {1, 2}},
+ {L"\U0000200c\U00000308\U000011a8", {8204, 4520}, {2, 3}},
+ {L"\U0000200c\U0000ac00", {8204, 44032}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000ac00", {8204, 44032}, {2, 3}},
+ {L"\U0000200c\U0000ac01", {8204, 44033}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000ac01", {8204, 44033}, {2, 3}},
+ {L"\U0000200c\U00000903", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000903", {8204}, {3}},
+ {L"\U0000200c\U00000904", {8204, 2308}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000904", {8204, 2308}, {2, 3}},
+ {L"\U0000200c\U00000d4e", {8204, 3406}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000d4e", {8204, 3406}, {2, 3}},
+ {L"\U0000200c\U00000915", {8204, 2325}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000915", {8204, 2325}, {2, 3}},
+ {L"\U0000200c\U0000231a", {8204, 8986}, {1, 2}},
+ {L"\U0000200c\U00000308\U0000231a", {8204, 8986}, {2, 3}},
+ {L"\U0000200c\U00000300", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000300", {8204}, {3}},
+ {L"\U0000200c\U00000900", {8204}, {2}},
+ {L"\U0000200c\U00000308\U00000900", {8204}, {3}},
+ {L"\U0000200c\U0000094d", {8204}, {2}},
+ {L"\U0000200c\U00000308\U0000094d", {8204}, {3}},
+ {L"\U0000200c\U0000200d", {8204}, {2}},
+ {L"\U0000200c\U00000308\U0000200d", {8204}, {3}},
+ {L"\U0000200c\U00000378", {8204, 888}, {1, 2}},
+ {L"\U0000200c\U00000308\U00000378", {8204, 888}, {2, 3}},
+ {L"\U0001f1e6\U00000020", {127462, 32}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00000020", {127462, 32}, {2, 3}},
+ {L"\U0001f1e6\U0000000d", {127462, 13}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U0000000d", {127462, 13}, {2, 3}},
+ {L"\U0001f1e6\U0000000a", {127462, 10}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U0000000a", {127462, 10}, {2, 3}},
+ {L"\U0001f1e6\U00000001", {127462, 1}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00000001", {127462, 1}, {2, 3}},
+ {L"\U0001f1e6\U0000200c", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U0000200c", {127462}, {3}},
+ {L"\U0001f1e6\U0001f1e6", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U0001f1e6", {127462, 127462}, {2, 3}},
+ {L"\U0001f1e6\U00000600", {127462, 1536}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00000600", {127462, 1536}, {2, 3}},
+ {L"\U0001f1e6\U00000a03", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U00000a03", {127462}, {3}},
+ {L"\U0001f1e6\U00001100", {127462, 4352}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00001100", {127462, 4352}, {2, 3}},
+ {L"\U0001f1e6\U00001160", {127462, 4448}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00001160", {127462, 4448}, {2, 3}},
+ {L"\U0001f1e6\U000011a8", {127462, 4520}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U000011a8", {127462, 4520}, {2, 3}},
+ {L"\U0001f1e6\U0000ac00", {127462, 44032}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U0000ac00", {127462, 44032}, {2, 3}},
+ {L"\U0001f1e6\U0000ac01", {127462, 44033}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U0000ac01", {127462, 44033}, {2, 3}},
+ {L"\U0001f1e6\U00000903", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U00000903", {127462}, {3}},
+ {L"\U0001f1e6\U00000904", {127462, 2308}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00000904", {127462, 2308}, {2, 3}},
+ {L"\U0001f1e6\U00000d4e", {127462, 3406}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00000d4e", {127462, 3406}, {2, 3}},
+ {L"\U0001f1e6\U00000915", {127462, 2325}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00000915", {127462, 2325}, {2, 3}},
+ {L"\U0001f1e6\U0000231a", {127462, 8986}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U0000231a", {127462, 8986}, {2, 3}},
+ {L"\U0001f1e6\U00000300", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U00000300", {127462}, {3}},
+ {L"\U0001f1e6\U00000900", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U00000900", {127462}, {3}},
+ {L"\U0001f1e6\U0000094d", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U0000094d", {127462}, {3}},
+ {L"\U0001f1e6\U0000200d", {127462}, {2}},
+ {L"\U0001f1e6\U00000308\U0000200d", {127462}, {3}},
+ {L"\U0001f1e6\U00000378", {127462, 888}, {1, 2}},
+ {L"\U0001f1e6\U00000308\U00000378", {127462, 888}, {2, 3}},
+ {L"\U00000600\U00000020", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000020", {1536, 32}, {2, 3}},
+ {L"\U00000600\U0000000d", {1536, 13}, {1, 2}},
+ {L"\U00000600\U00000308\U0000000d", {1536, 13}, {2, 3}},
+ {L"\U00000600\U0000000a", {1536, 10}, {1, 2}},
+ {L"\U00000600\U00000308\U0000000a", {1536, 10}, {2, 3}},
+ {L"\U00000600\U00000001", {1536, 1}, {1, 2}},
+ {L"\U00000600\U00000308\U00000001", {1536, 1}, {2, 3}},
+ {L"\U00000600\U0000200c", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000200c", {1536}, {3}},
+ {L"\U00000600\U0001f1e6", {1536}, {2}},
+ {L"\U00000600\U00000308\U0001f1e6", {1536, 127462}, {2, 3}},
+ {L"\U00000600\U00000600", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000600", {1536, 1536}, {2, 3}},
+ {L"\U00000600\U00000a03", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000a03", {1536}, {3}},
+ {L"\U00000600\U00001100", {1536}, {2}},
+ {L"\U00000600\U00000308\U00001100", {1536, 4352}, {2, 3}},
+ {L"\U00000600\U00001160", {1536}, {2}},
+ {L"\U00000600\U00000308\U00001160", {1536, 4448}, {2, 3}},
+ {L"\U00000600\U000011a8", {1536}, {2}},
+ {L"\U00000600\U00000308\U000011a8", {1536, 4520}, {2, 3}},
+ {L"\U00000600\U0000ac00", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000ac00", {1536, 44032}, {2, 3}},
+ {L"\U00000600\U0000ac01", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000ac01", {1536, 44033}, {2, 3}},
+ {L"\U00000600\U00000903", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000903", {1536}, {3}},
+ {L"\U00000600\U00000904", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000904", {1536, 2308}, {2, 3}},
+ {L"\U00000600\U00000d4e", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000d4e", {1536, 3406}, {2, 3}},
+ {L"\U00000600\U00000915", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000915", {1536, 2325}, {2, 3}},
+ {L"\U00000600\U0000231a", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000231a", {1536, 8986}, {2, 3}},
+ {L"\U00000600\U00000300", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000300", {1536}, {3}},
+ {L"\U00000600\U00000900", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000900", {1536}, {3}},
+ {L"\U00000600\U0000094d", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000094d", {1536}, {3}},
+ {L"\U00000600\U0000200d", {1536}, {2}},
+ {L"\U00000600\U00000308\U0000200d", {1536}, {3}},
+ {L"\U00000600\U00000378", {1536}, {2}},
+ {L"\U00000600\U00000308\U00000378", {1536, 888}, {2, 3}},
+ {L"\U00000a03\U00000020", {2563, 32}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000020", {2563, 32}, {2, 3}},
+ {L"\U00000a03\U0000000d", {2563, 13}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000000d", {2563, 13}, {2, 3}},
+ {L"\U00000a03\U0000000a", {2563, 10}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000000a", {2563, 10}, {2, 3}},
+ {L"\U00000a03\U00000001", {2563, 1}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000001", {2563, 1}, {2, 3}},
+ {L"\U00000a03\U0000200c", {2563}, {2}},
+ {L"\U00000a03\U00000308\U0000200c", {2563}, {3}},
+ {L"\U00000a03\U0001f1e6", {2563, 127462}, {1, 2}},
+ {L"\U00000a03\U00000308\U0001f1e6", {2563, 127462}, {2, 3}},
+ {L"\U00000a03\U00000600", {2563, 1536}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000600", {2563, 1536}, {2, 3}},
+ {L"\U00000a03\U00000a03", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000a03", {2563}, {3}},
+ {L"\U00000a03\U00001100", {2563, 4352}, {1, 2}},
+ {L"\U00000a03\U00000308\U00001100", {2563, 4352}, {2, 3}},
+ {L"\U00000a03\U00001160", {2563, 4448}, {1, 2}},
+ {L"\U00000a03\U00000308\U00001160", {2563, 4448}, {2, 3}},
+ {L"\U00000a03\U000011a8", {2563, 4520}, {1, 2}},
+ {L"\U00000a03\U00000308\U000011a8", {2563, 4520}, {2, 3}},
+ {L"\U00000a03\U0000ac00", {2563, 44032}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000ac00", {2563, 44032}, {2, 3}},
+ {L"\U00000a03\U0000ac01", {2563, 44033}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000ac01", {2563, 44033}, {2, 3}},
+ {L"\U00000a03\U00000903", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000903", {2563}, {3}},
+ {L"\U00000a03\U00000904", {2563, 2308}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000904", {2563, 2308}, {2, 3}},
+ {L"\U00000a03\U00000d4e", {2563, 3406}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000d4e", {2563, 3406}, {2, 3}},
+ {L"\U00000a03\U00000915", {2563, 2325}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000915", {2563, 2325}, {2, 3}},
+ {L"\U00000a03\U0000231a", {2563, 8986}, {1, 2}},
+ {L"\U00000a03\U00000308\U0000231a", {2563, 8986}, {2, 3}},
+ {L"\U00000a03\U00000300", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000300", {2563}, {3}},
+ {L"\U00000a03\U00000900", {2563}, {2}},
+ {L"\U00000a03\U00000308\U00000900", {2563}, {3}},
+ {L"\U00000a03\U0000094d", {2563}, {2}},
+ {L"\U00000a03\U00000308\U0000094d", {2563}, {3}},
+ {L"\U00000a03\U0000200d", {2563}, {2}},
+ {L"\U00000a03\U00000308\U0000200d", {2563}, {3}},
+ {L"\U00000a03\U00000378", {2563, 888}, {1, 2}},
+ {L"\U00000a03\U00000308\U00000378", {2563, 888}, {2, 3}},
+ {L"\U00001100\U00000020", {4352, 32}, {1, 2}},
+ {L"\U00001100\U00000308\U00000020", {4352, 32}, {2, 3}},
+ {L"\U00001100\U0000000d", {4352, 13}, {1, 2}},
+ {L"\U00001100\U00000308\U0000000d", {4352, 13}, {2, 3}},
+ {L"\U00001100\U0000000a", {4352, 10}, {1, 2}},
+ {L"\U00001100\U00000308\U0000000a", {4352, 10}, {2, 3}},
+ {L"\U00001100\U00000001", {4352, 1}, {1, 2}},
+ {L"\U00001100\U00000308\U00000001", {4352, 1}, {2, 3}},
+ {L"\U00001100\U0000200c", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000200c", {4352}, {3}},
+ {L"\U00001100\U0001f1e6", {4352, 127462}, {1, 2}},
+ {L"\U00001100\U00000308\U0001f1e6", {4352, 127462}, {2, 3}},
+ {L"\U00001100\U00000600", {4352, 1536}, {1, 2}},
+ {L"\U00001100\U00000308\U00000600", {4352, 1536}, {2, 3}},
+ {L"\U00001100\U00000a03", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000a03", {4352}, {3}},
+ {L"\U00001100\U00001100", {4352}, {2}},
+ {L"\U00001100\U00000308\U00001100", {4352, 4352}, {2, 3}},
+ {L"\U00001100\U00001160", {4352}, {2}},
+ {L"\U00001100\U00000308\U00001160", {4352, 4448}, {2, 3}},
+ {L"\U00001100\U000011a8", {4352, 4520}, {1, 2}},
+ {L"\U00001100\U00000308\U000011a8", {4352, 4520}, {2, 3}},
+ {L"\U00001100\U0000ac00", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000ac00", {4352, 44032}, {2, 3}},
+ {L"\U00001100\U0000ac01", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000ac01", {4352, 44033}, {2, 3}},
+ {L"\U00001100\U00000903", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000903", {4352}, {3}},
+ {L"\U00001100\U00000904", {4352, 2308}, {1, 2}},
+ {L"\U00001100\U00000308\U00000904", {4352, 2308}, {2, 3}},
+ {L"\U00001100\U00000d4e", {4352, 3406}, {1, 2}},
+ {L"\U00001100\U00000308\U00000d4e", {4352, 3406}, {2, 3}},
+ {L"\U00001100\U00000915", {4352, 2325}, {1, 2}},
+ {L"\U00001100\U00000308\U00000915", {4352, 2325}, {2, 3}},
+ {L"\U00001100\U0000231a", {4352, 8986}, {1, 2}},
+ {L"\U00001100\U00000308\U0000231a", {4352, 8986}, {2, 3}},
+ {L"\U00001100\U00000300", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000300", {4352}, {3}},
+ {L"\U00001100\U00000900", {4352}, {2}},
+ {L"\U00001100\U00000308\U00000900", {4352}, {3}},
+ {L"\U00001100\U0000094d", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000094d", {4352}, {3}},
+ {L"\U00001100\U0000200d", {4352}, {2}},
+ {L"\U00001100\U00000308\U0000200d", {4352}, {3}},
+ {L"\U00001100\U00000378", {4352, 888}, {1, 2}},
+ {L"\U00001100\U00000308\U00000378", {4352, 888}, {2, 3}},
+ {L"\U00001160\U00000020", {4448, 32}, {1, 2}},
+ {L"\U00001160\U00000308\U00000020", {4448, 32}, {2, 3}},
+ {L"\U00001160\U0000000d", {4448, 13}, {1, 2}},
+ {L"\U00001160\U00000308\U0000000d", {4448, 13}, {2, 3}},
+ {L"\U00001160\U0000000a", {4448, 10}, {1, 2}},
+ {L"\U00001160\U00000308\U0000000a", {4448, 10}, {2, 3}},
+ {L"\U00001160\U00000001", {4448, 1}, {1, 2}},
+ {L"\U00001160\U00000308\U00000001", {4448, 1}, {2, 3}},
+ {L"\U00001160\U0000200c", {4448}, {2}},
+ {L"\U00001160\U00000308\U0000200c", {4448}, {3}},
+ {L"\U00001160\U0001f1e6", {4448, 127462}, {1, 2}},
+ {L"\U00001160\U00000308\U0001f1e6", {4448, 127462}, {2, 3}},
+ {L"\U00001160\U00000600", {4448, 1536}, {1, 2}},
+ {L"\U00001160\U00000308\U00000600", {4448, 1536}, {2, 3}},
+ {L"\U00001160\U00000a03", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000a03", {4448}, {3}},
+ {L"\U00001160\U00001100", {4448, 4352}, {1, 2}},
+ {L"\U00001160\U00000308\U00001100", {4448, 4352}, {2, 3}},
+ {L"\U00001160\U00001160", {4448}, {2}},
+ {L"\U00001160\U00000308\U00001160", {4448, 4448}, {2, 3}},
+ {L"\U00001160\U000011a8", {4448}, {2}},
+ {L"\U00001160\U00000308\U000011a8", {4448, 4520}, {2, 3}},
+ {L"\U00001160\U0000ac00", {4448, 44032}, {1, 2}},
+ {L"\U00001160\U00000308\U0000ac00", {4448, 44032}, {2, 3}},
+ {L"\U00001160\U0000ac01", {4448, 44033}, {1, 2}},
+ {L"\U00001160\U00000308\U0000ac01", {4448, 44033}, {2, 3}},
+ {L"\U00001160\U00000903", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000903", {4448}, {3}},
+ {L"\U00001160\U00000904", {4448, 2308}, {1, 2}},
+ {L"\U00001160\U00000308\U00000904", {4448, 2308}, {2, 3}},
+ {L"\U00001160\U00000d4e", {4448, 3406}, {1, 2}},
+ {L"\U00001160\U00000308\U00000d4e", {4448, 3406}, {2, 3}},
+ {L"\U00001160\U00000915", {4448, 2325}, {1, 2}},
+ {L"\U00001160\U00000308\U00000915", {4448, 2325}, {2, 3}},
+ {L"\U00001160\U0000231a", {4448, 8986}, {1, 2}},
+ {L"\U00001160\U00000308\U0000231a", {4448, 8986}, {2, 3}},
+ {L"\U00001160\U00000300", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000300", {4448}, {3}},
+ {L"\U00001160\U00000900", {4448}, {2}},
+ {L"\U00001160\U00000308\U00000900", {4448}, {3}},
+ {L"\U00001160\U0000094d", {4448}, {2}},
+ {L"\U00001160\U00000308\U0000094d", {4448}, {3}},
+ {L"\U00001160\U0000200d", {4448}, {2}},
+ {L"\U00001160\U00000308\U0000200d", {4448}, {3}},
+ {L"\U00001160\U00000378", {4448, 888}, {1, 2}},
+ {L"\U00001160\U00000308\U00000378", {4448, 888}, {2, 3}},
+ {L"\U000011a8\U00000020", {4520, 32}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000020", {4520, 32}, {2, 3}},
+ {L"\U000011a8\U0000000d", {4520, 13}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000000d", {4520, 13}, {2, 3}},
+ {L"\U000011a8\U0000000a", {4520, 10}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000000a", {4520, 10}, {2, 3}},
+ {L"\U000011a8\U00000001", {4520, 1}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000001", {4520, 1}, {2, 3}},
+ {L"\U000011a8\U0000200c", {4520}, {2}},
+ {L"\U000011a8\U00000308\U0000200c", {4520}, {3}},
+ {L"\U000011a8\U0001f1e6", {4520, 127462}, {1, 2}},
+ {L"\U000011a8\U00000308\U0001f1e6", {4520, 127462}, {2, 3}},
+ {L"\U000011a8\U00000600", {4520, 1536}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000600", {4520, 1536}, {2, 3}},
+ {L"\U000011a8\U00000a03", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000a03", {4520}, {3}},
+ {L"\U000011a8\U00001100", {4520, 4352}, {1, 2}},
+ {L"\U000011a8\U00000308\U00001100", {4520, 4352}, {2, 3}},
+ {L"\U000011a8\U00001160", {4520, 4448}, {1, 2}},
+ {L"\U000011a8\U00000308\U00001160", {4520, 4448}, {2, 3}},
+ {L"\U000011a8\U000011a8", {4520}, {2}},
+ {L"\U000011a8\U00000308\U000011a8", {4520, 4520}, {2, 3}},
+ {L"\U000011a8\U0000ac00", {4520, 44032}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000ac00", {4520, 44032}, {2, 3}},
+ {L"\U000011a8\U0000ac01", {4520, 44033}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000ac01", {4520, 44033}, {2, 3}},
+ {L"\U000011a8\U00000903", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000903", {4520}, {3}},
+ {L"\U000011a8\U00000904", {4520, 2308}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000904", {4520, 2308}, {2, 3}},
+ {L"\U000011a8\U00000d4e", {4520, 3406}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000d4e", {4520, 3406}, {2, 3}},
+ {L"\U000011a8\U00000915", {4520, 2325}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000915", {4520, 2325}, {2, 3}},
+ {L"\U000011a8\U0000231a", {4520, 8986}, {1, 2}},
+ {L"\U000011a8\U00000308\U0000231a", {4520, 8986}, {2, 3}},
+ {L"\U000011a8\U00000300", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000300", {4520}, {3}},
+ {L"\U000011a8\U00000900", {4520}, {2}},
+ {L"\U000011a8\U00000308\U00000900", {4520}, {3}},
+ {L"\U000011a8\U0000094d", {4520}, {2}},
+ {L"\U000011a8\U00000308\U0000094d", {4520}, {3}},
+ {L"\U000011a8\U0000200d", {4520}, {2}},
+ {L"\U000011a8\U00000308\U0000200d", {4520}, {3}},
+ {L"\U000011a8\U00000378", {4520, 888}, {1, 2}},
+ {L"\U000011a8\U00000308\U00000378", {4520, 888}, {2, 3}},
+ {L"\U0000ac00\U00000020", {44032, 32}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000020", {44032, 32}, {2, 3}},
+ {L"\U0000ac00\U0000000d", {44032, 13}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000000d", {44032, 13}, {2, 3}},
+ {L"\U0000ac00\U0000000a", {44032, 10}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000000a", {44032, 10}, {2, 3}},
+ {L"\U0000ac00\U00000001", {44032, 1}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000001", {44032, 1}, {2, 3}},
+ {L"\U0000ac00\U0000200c", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U0000200c", {44032}, {3}},
+ {L"\U0000ac00\U0001f1e6", {44032, 127462}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0001f1e6", {44032, 127462}, {2, 3}},
+ {L"\U0000ac00\U00000600", {44032, 1536}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000600", {44032, 1536}, {2, 3}},
+ {L"\U0000ac00\U00000a03", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000a03", {44032}, {3}},
+ {L"\U0000ac00\U00001100", {44032, 4352}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00001100", {44032, 4352}, {2, 3}},
+ {L"\U0000ac00\U00001160", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00001160", {44032, 4448}, {2, 3}},
+ {L"\U0000ac00\U000011a8", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U000011a8", {44032, 4520}, {2, 3}},
+ {L"\U0000ac00\U0000ac00", {44032, 44032}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000ac00", {44032, 44032}, {2, 3}},
+ {L"\U0000ac00\U0000ac01", {44032, 44033}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000ac01", {44032, 44033}, {2, 3}},
+ {L"\U0000ac00\U00000903", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000903", {44032}, {3}},
+ {L"\U0000ac00\U00000904", {44032, 2308}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000904", {44032, 2308}, {2, 3}},
+ {L"\U0000ac00\U00000d4e", {44032, 3406}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000d4e", {44032, 3406}, {2, 3}},
+ {L"\U0000ac00\U00000915", {44032, 2325}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000915", {44032, 2325}, {2, 3}},
+ {L"\U0000ac00\U0000231a", {44032, 8986}, {1, 2}},
+ {L"\U0000ac00\U00000308\U0000231a", {44032, 8986}, {2, 3}},
+ {L"\U0000ac00\U00000300", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000300", {44032}, {3}},
+ {L"\U0000ac00\U00000900", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U00000900", {44032}, {3}},
+ {L"\U0000ac00\U0000094d", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U0000094d", {44032}, {3}},
+ {L"\U0000ac00\U0000200d", {44032}, {2}},
+ {L"\U0000ac00\U00000308\U0000200d", {44032}, {3}},
+ {L"\U0000ac00\U00000378", {44032, 888}, {1, 2}},
+ {L"\U0000ac00\U00000308\U00000378", {44032, 888}, {2, 3}},
+ {L"\U0000ac01\U00000020", {44033, 32}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000020", {44033, 32}, {2, 3}},
+ {L"\U0000ac01\U0000000d", {44033, 13}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000000d", {44033, 13}, {2, 3}},
+ {L"\U0000ac01\U0000000a", {44033, 10}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000000a", {44033, 10}, {2, 3}},
+ {L"\U0000ac01\U00000001", {44033, 1}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000001", {44033, 1}, {2, 3}},
+ {L"\U0000ac01\U0000200c", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U0000200c", {44033}, {3}},
+ {L"\U0000ac01\U0001f1e6", {44033, 127462}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0001f1e6", {44033, 127462}, {2, 3}},
+ {L"\U0000ac01\U00000600", {44033, 1536}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000600", {44033, 1536}, {2, 3}},
+ {L"\U0000ac01\U00000a03", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000a03", {44033}, {3}},
+ {L"\U0000ac01\U00001100", {44033, 4352}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00001100", {44033, 4352}, {2, 3}},
+ {L"\U0000ac01\U00001160", {44033, 4448}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00001160", {44033, 4448}, {2, 3}},
+ {L"\U0000ac01\U000011a8", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U000011a8", {44033, 4520}, {2, 3}},
+ {L"\U0000ac01\U0000ac00", {44033, 44032}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000ac00", {44033, 44032}, {2, 3}},
+ {L"\U0000ac01\U0000ac01", {44033, 44033}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000ac01", {44033, 44033}, {2, 3}},
+ {L"\U0000ac01\U00000903", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000903", {44033}, {3}},
+ {L"\U0000ac01\U00000904", {44033, 2308}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000904", {44033, 2308}, {2, 3}},
+ {L"\U0000ac01\U00000d4e", {44033, 3406}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000d4e", {44033, 3406}, {2, 3}},
+ {L"\U0000ac01\U00000915", {44033, 2325}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000915", {44033, 2325}, {2, 3}},
+ {L"\U0000ac01\U0000231a", {44033, 8986}, {1, 2}},
+ {L"\U0000ac01\U00000308\U0000231a", {44033, 8986}, {2, 3}},
+ {L"\U0000ac01\U00000300", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000300", {44033}, {3}},
+ {L"\U0000ac01\U00000900", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U00000900", {44033}, {3}},
+ {L"\U0000ac01\U0000094d", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U0000094d", {44033}, {3}},
+ {L"\U0000ac01\U0000200d", {44033}, {2}},
+ {L"\U0000ac01\U00000308\U0000200d", {44033}, {3}},
+ {L"\U0000ac01\U00000378", {44033, 888}, {1, 2}},
+ {L"\U0000ac01\U00000308\U00000378", {44033, 888}, {2, 3}},
+ {L"\U00000903\U00000020", {2307, 32}, {1, 2}},
+ {L"\U00000903\U00000308\U00000020", {2307, 32}, {2, 3}},
+ {L"\U00000903\U0000000d", {2307, 13}, {1, 2}},
+ {L"\U00000903\U00000308\U0000000d", {2307, 13}, {2, 3}},
+ {L"\U00000903\U0000000a", {2307, 10}, {1, 2}},
+ {L"\U00000903\U00000308\U0000000a", {2307, 10}, {2, 3}},
+ {L"\U00000903\U00000001", {2307, 1}, {1, 2}},
+ {L"\U00000903\U00000308\U00000001", {2307, 1}, {2, 3}},
+ {L"\U00000903\U0000200c", {2307}, {2}},
+ {L"\U00000903\U00000308\U0000200c", {2307}, {3}},
+ {L"\U00000903\U0001f1e6", {2307, 127462}, {1, 2}},
+ {L"\U00000903\U00000308\U0001f1e6", {2307, 127462}, {2, 3}},
+ {L"\U00000903\U00000600", {2307, 1536}, {1, 2}},
+ {L"\U00000903\U00000308\U00000600", {2307, 1536}, {2, 3}},
+ {L"\U00000903\U00000a03", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000a03", {2307}, {3}},
+ {L"\U00000903\U00001100", {2307, 4352}, {1, 2}},
+ {L"\U00000903\U00000308\U00001100", {2307, 4352}, {2, 3}},
+ {L"\U00000903\U00001160", {2307, 4448}, {1, 2}},
+ {L"\U00000903\U00000308\U00001160", {2307, 4448}, {2, 3}},
+ {L"\U00000903\U000011a8", {2307, 4520}, {1, 2}},
+ {L"\U00000903\U00000308\U000011a8", {2307, 4520}, {2, 3}},
+ {L"\U00000903\U0000ac00", {2307, 44032}, {1, 2}},
+ {L"\U00000903\U00000308\U0000ac00", {2307, 44032}, {2, 3}},
+ {L"\U00000903\U0000ac01", {2307, 44033}, {1, 2}},
+ {L"\U00000903\U00000308\U0000ac01", {2307, 44033}, {2, 3}},
+ {L"\U00000903\U00000903", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000903", {2307}, {3}},
+ {L"\U00000903\U00000904", {2307, 2308}, {1, 2}},
+ {L"\U00000903\U00000308\U00000904", {2307, 2308}, {2, 3}},
+ {L"\U00000903\U00000d4e", {2307, 3406}, {1, 2}},
+ {L"\U00000903\U00000308\U00000d4e", {2307, 3406}, {2, 3}},
+ {L"\U00000903\U00000915", {2307, 2325}, {1, 2}},
+ {L"\U00000903\U00000308\U00000915", {2307, 2325}, {2, 3}},
+ {L"\U00000903\U0000231a", {2307, 8986}, {1, 2}},
+ {L"\U00000903\U00000308\U0000231a", {2307, 8986}, {2, 3}},
+ {L"\U00000903\U00000300", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000300", {2307}, {3}},
+ {L"\U00000903\U00000900", {2307}, {2}},
+ {L"\U00000903\U00000308\U00000900", {2307}, {3}},
+ {L"\U00000903\U0000094d", {2307}, {2}},
+ {L"\U00000903\U00000308\U0000094d", {2307}, {3}},
+ {L"\U00000903\U0000200d", {2307}, {2}},
+ {L"\U00000903\U00000308\U0000200d", {2307}, {3}},
+ {L"\U00000903\U00000378", {2307, 888}, {1, 2}},
+ {L"\U00000903\U00000308\U00000378", {2307, 888}, {2, 3}},
+ {L"\U00000904\U00000020", {2308, 32}, {1, 2}},
+ {L"\U00000904\U00000308\U00000020", {2308, 32}, {2, 3}},
+ {L"\U00000904\U0000000d", {2308, 13}, {1, 2}},
+ {L"\U00000904\U00000308\U0000000d", {2308, 13}, {2, 3}},
+ {L"\U00000904\U0000000a", {2308, 10}, {1, 2}},
+ {L"\U00000904\U00000308\U0000000a", {2308, 10}, {2, 3}},
+ {L"\U00000904\U00000001", {2308, 1}, {1, 2}},
+ {L"\U00000904\U00000308\U00000001", {2308, 1}, {2, 3}},
+ {L"\U00000904\U0000200c", {2308}, {2}},
+ {L"\U00000904\U00000308\U0000200c", {2308}, {3}},
+ {L"\U00000904\U0001f1e6", {2308, 127462}, {1, 2}},
+ {L"\U00000904\U00000308\U0001f1e6", {2308, 127462}, {2, 3}},
+ {L"\U00000904\U00000600", {2308, 1536}, {1, 2}},
+ {L"\U00000904\U00000308\U00000600", {2308, 1536}, {2, 3}},
+ {L"\U00000904\U00000a03", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000a03", {2308}, {3}},
+ {L"\U00000904\U00001100", {2308, 4352}, {1, 2}},
+ {L"\U00000904\U00000308\U00001100", {2308, 4352}, {2, 3}},
+ {L"\U00000904\U00001160", {2308, 4448}, {1, 2}},
+ {L"\U00000904\U00000308\U00001160", {2308, 4448}, {2, 3}},
+ {L"\U00000904\U000011a8", {2308, 4520}, {1, 2}},
+ {L"\U00000904\U00000308\U000011a8", {2308, 4520}, {2, 3}},
+ {L"\U00000904\U0000ac00", {2308, 44032}, {1, 2}},
+ {L"\U00000904\U00000308\U0000ac00", {2308, 44032}, {2, 3}},
+ {L"\U00000904\U0000ac01", {2308, 44033}, {1, 2}},
+ {L"\U00000904\U00000308\U0000ac01", {2308, 44033}, {2, 3}},
+ {L"\U00000904\U00000903", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000903", {2308}, {3}},
+ {L"\U00000904\U00000904", {2308, 2308}, {1, 2}},
+ {L"\U00000904\U00000308\U00000904", {2308, 2308}, {2, 3}},
+ {L"\U00000904\U00000d4e", {2308, 3406}, {1, 2}},
+ {L"\U00000904\U00000308\U00000d4e", {2308, 3406}, {2, 3}},
+ {L"\U00000904\U00000915", {2308, 2325}, {1, 2}},
+ {L"\U00000904\U00000308\U00000915", {2308, 2325}, {2, 3}},
+ {L"\U00000904\U0000231a", {2308, 8986}, {1, 2}},
+ {L"\U00000904\U00000308\U0000231a", {2308, 8986}, {2, 3}},
+ {L"\U00000904\U00000300", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000300", {2308}, {3}},
+ {L"\U00000904\U00000900", {2308}, {2}},
+ {L"\U00000904\U00000308\U00000900", {2308}, {3}},
+ {L"\U00000904\U0000094d", {2308}, {2}},
+ {L"\U00000904\U00000308\U0000094d", {2308}, {3}},
+ {L"\U00000904\U0000200d", {2308}, {2}},
+ {L"\U00000904\U00000308\U0000200d", {2308}, {3}},
+ {L"\U00000904\U00000378", {2308, 888}, {1, 2}},
+ {L"\U00000904\U00000308\U00000378", {2308, 888}, {2, 3}},
+ {L"\U00000d4e\U00000020", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000020", {3406, 32}, {2, 3}},
+ {L"\U00000d4e\U0000000d", {3406, 13}, {1, 2}},
+ {L"\U00000d4e\U00000308\U0000000d", {3406, 13}, {2, 3}},
+ {L"\U00000d4e\U0000000a", {3406, 10}, {1, 2}},
+ {L"\U00000d4e\U00000308\U0000000a", {3406, 10}, {2, 3}},
+ {L"\U00000d4e\U00000001", {3406, 1}, {1, 2}},
+ {L"\U00000d4e\U00000308\U00000001", {3406, 1}, {2, 3}},
+ {L"\U00000d4e\U0000200c", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000200c", {3406}, {3}},
+ {L"\U00000d4e\U0001f1e6", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0001f1e6", {3406, 127462}, {2, 3}},
+ {L"\U00000d4e\U00000600", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000600", {3406, 1536}, {2, 3}},
+ {L"\U00000d4e\U00000a03", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000a03", {3406}, {3}},
+ {L"\U00000d4e\U00001100", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00001100", {3406, 4352}, {2, 3}},
+ {L"\U00000d4e\U00001160", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00001160", {3406, 4448}, {2, 3}},
+ {L"\U00000d4e\U000011a8", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U000011a8", {3406, 4520}, {2, 3}},
+ {L"\U00000d4e\U0000ac00", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000ac00", {3406, 44032}, {2, 3}},
+ {L"\U00000d4e\U0000ac01", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000ac01", {3406, 44033}, {2, 3}},
+ {L"\U00000d4e\U00000903", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000903", {3406}, {3}},
+ {L"\U00000d4e\U00000904", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000904", {3406, 2308}, {2, 3}},
+ {L"\U00000d4e\U00000d4e", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000d4e", {3406, 3406}, {2, 3}},
+ {L"\U00000d4e\U00000915", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000915", {3406, 2325}, {2, 3}},
+ {L"\U00000d4e\U0000231a", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000231a", {3406, 8986}, {2, 3}},
+ {L"\U00000d4e\U00000300", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000300", {3406}, {3}},
+ {L"\U00000d4e\U00000900", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000900", {3406}, {3}},
+ {L"\U00000d4e\U0000094d", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000094d", {3406}, {3}},
+ {L"\U00000d4e\U0000200d", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U0000200d", {3406}, {3}},
+ {L"\U00000d4e\U00000378", {3406}, {2}},
+ {L"\U00000d4e\U00000308\U00000378", {3406, 888}, {2, 3}},
+ {L"\U00000915\U00000020", {2325, 32}, {1, 2}},
+ {L"\U00000915\U00000308\U00000020", {2325, 32}, {2, 3}},
+ {L"\U00000915\U0000000d", {2325, 13}, {1, 2}},
+ {L"\U00000915\U00000308\U0000000d", {2325, 13}, {2, 3}},
+ {L"\U00000915\U0000000a", {2325, 10}, {1, 2}},
+ {L"\U00000915\U00000308\U0000000a", {2325, 10}, {2, 3}},
+ {L"\U00000915\U00000001", {2325, 1}, {1, 2}},
+ {L"\U00000915\U00000308\U00000001", {2325, 1}, {2, 3}},
+ {L"\U00000915\U0000200c", {2325}, {2}},
+ {L"\U00000915\U00000308\U0000200c", {2325}, {3}},
+ {L"\U00000915\U0001f1e6", {2325, 127462}, {1, 2}},
+ {L"\U00000915\U00000308\U0001f1e6", {2325, 127462}, {2, 3}},
+ {L"\U00000915\U00000600", {2325, 1536}, {1, 2}},
+ {L"\U00000915\U00000308\U00000600", {2325, 1536}, {2, 3}},
+ {L"\U00000915\U00000a03", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000a03", {2325}, {3}},
+ {L"\U00000915\U00001100", {2325, 4352}, {1, 2}},
+ {L"\U00000915\U00000308\U00001100", {2325, 4352}, {2, 3}},
+ {L"\U00000915\U00001160", {2325, 4448}, {1, 2}},
+ {L"\U00000915\U00000308\U00001160", {2325, 4448}, {2, 3}},
+ {L"\U00000915\U000011a8", {2325, 4520}, {1, 2}},
+ {L"\U00000915\U00000308\U000011a8", {2325, 4520}, {2, 3}},
+ {L"\U00000915\U0000ac00", {2325, 44032}, {1, 2}},
+ {L"\U00000915\U00000308\U0000ac00", {2325, 44032}, {2, 3}},
+ {L"\U00000915\U0000ac01", {2325, 44033}, {1, 2}},
+ {L"\U00000915\U00000308\U0000ac01", {2325, 44033}, {2, 3}},
+ {L"\U00000915\U00000903", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000903", {2325}, {3}},
+ {L"\U00000915\U00000904", {2325, 2308}, {1, 2}},
+ {L"\U00000915\U00000308\U00000904", {2325, 2308}, {2, 3}},
+ {L"\U00000915\U00000d4e", {2325, 3406}, {1, 2}},
+ {L"\U00000915\U00000308\U00000d4e", {2325, 3406}, {2, 3}},
+ {L"\U00000915\U00000915", {2325, 2325}, {1, 2}},
+ {L"\U00000915\U00000308\U00000915", {2325, 2325}, {2, 3}},
+ {L"\U00000915\U0000231a", {2325, 8986}, {1, 2}},
+ {L"\U00000915\U00000308\U0000231a", {2325, 8986}, {2, 3}},
+ {L"\U00000915\U00000300", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000300", {2325}, {3}},
+ {L"\U00000915\U00000900", {2325}, {2}},
+ {L"\U00000915\U00000308\U00000900", {2325}, {3}},
+ {L"\U00000915\U0000094d", {2325}, {2}},
+ {L"\U00000915\U00000308\U0000094d", {2325}, {3}},
+ {L"\U00000915\U0000200d", {2325}, {2}},
+ {L"\U00000915\U00000308\U0000200d", {2325}, {3}},
+ {L"\U00000915\U00000378", {2325, 888}, {1, 2}},
+ {L"\U00000915\U00000308\U00000378", {2325, 888}, {2, 3}},
+ {L"\U0000231a\U00000020", {8986, 32}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000020", {8986, 32}, {2, 3}},
+ {L"\U0000231a\U0000000d", {8986, 13}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000000d", {8986, 13}, {2, 3}},
+ {L"\U0000231a\U0000000a", {8986, 10}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000000a", {8986, 10}, {2, 3}},
+ {L"\U0000231a\U00000001", {8986, 1}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000001", {8986, 1}, {2, 3}},
+ {L"\U0000231a\U0000200c", {8986}, {2}},
+ {L"\U0000231a\U00000308\U0000200c", {8986}, {3}},
+ {L"\U0000231a\U0001f1e6", {8986, 127462}, {1, 2}},
+ {L"\U0000231a\U00000308\U0001f1e6", {8986, 127462}, {2, 3}},
+ {L"\U0000231a\U00000600", {8986, 1536}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000600", {8986, 1536}, {2, 3}},
+ {L"\U0000231a\U00000a03", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000a03", {8986}, {3}},
+ {L"\U0000231a\U00001100", {8986, 4352}, {1, 2}},
+ {L"\U0000231a\U00000308\U00001100", {8986, 4352}, {2, 3}},
+ {L"\U0000231a\U00001160", {8986, 4448}, {1, 2}},
+ {L"\U0000231a\U00000308\U00001160", {8986, 4448}, {2, 3}},
+ {L"\U0000231a\U000011a8", {8986, 4520}, {1, 2}},
+ {L"\U0000231a\U00000308\U000011a8", {8986, 4520}, {2, 3}},
+ {L"\U0000231a\U0000ac00", {8986, 44032}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000ac00", {8986, 44032}, {2, 3}},
+ {L"\U0000231a\U0000ac01", {8986, 44033}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000ac01", {8986, 44033}, {2, 3}},
+ {L"\U0000231a\U00000903", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000903", {8986}, {3}},
+ {L"\U0000231a\U00000904", {8986, 2308}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000904", {8986, 2308}, {2, 3}},
+ {L"\U0000231a\U00000d4e", {8986, 3406}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000d4e", {8986, 3406}, {2, 3}},
+ {L"\U0000231a\U00000915", {8986, 2325}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000915", {8986, 2325}, {2, 3}},
+ {L"\U0000231a\U0000231a", {8986, 8986}, {1, 2}},
+ {L"\U0000231a\U00000308\U0000231a", {8986, 8986}, {2, 3}},
+ {L"\U0000231a\U00000300", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000300", {8986}, {3}},
+ {L"\U0000231a\U00000900", {8986}, {2}},
+ {L"\U0000231a\U00000308\U00000900", {8986}, {3}},
+ {L"\U0000231a\U0000094d", {8986}, {2}},
+ {L"\U0000231a\U00000308\U0000094d", {8986}, {3}},
+ {L"\U0000231a\U0000200d", {8986}, {2}},
+ {L"\U0000231a\U00000308\U0000200d", {8986}, {3}},
+ {L"\U0000231a\U00000378", {8986, 888}, {1, 2}},
+ {L"\U0000231a\U00000308\U00000378", {8986, 888}, {2, 3}},
+ {L"\U00000300\U00000020", {768, 32}, {1, 2}},
+ {L"\U00000300\U00000308\U00000020", {768, 32}, {2, 3}},
+ {L"\U00000300\U0000000d", {768, 13}, {1, 2}},
+ {L"\U00000300\U00000308\U0000000d", {768, 13}, {2, 3}},
+ {L"\U00000300\U0000000a", {768, 10}, {1, 2}},
+ {L"\U00000300\U00000308\U0000000a", {768, 10}, {2, 3}},
+ {L"\U00000300\U00000001", {768, 1}, {1, 2}},
+ {L"\U00000300\U00000308\U00000001", {768, 1}, {2, 3}},
+ {L"\U00000300\U0000200c", {768}, {2}},
+ {L"\U00000300\U00000308\U0000200c", {768}, {3}},
+ {L"\U00000300\U0001f1e6", {768, 127462}, {1, 2}},
+ {L"\U00000300\U00000308\U0001f1e6", {768, 127462}, {2, 3}},
+ {L"\U00000300\U00000600", {768, 1536}, {1, 2}},
+ {L"\U00000300\U00000308\U00000600", {768, 1536}, {2, 3}},
+ {L"\U00000300\U00000a03", {768}, {2}},
+ {L"\U00000300\U00000308\U00000a03", {768}, {3}},
+ {L"\U00000300\U00001100", {768, 4352}, {1, 2}},
+ {L"\U00000300\U00000308\U00001100", {768, 4352}, {2, 3}},
+ {L"\U00000300\U00001160", {768, 4448}, {1, 2}},
+ {L"\U00000300\U00000308\U00001160", {768, 4448}, {2, 3}},
+ {L"\U00000300\U000011a8", {768, 4520}, {1, 2}},
+ {L"\U00000300\U00000308\U000011a8", {768, 4520}, {2, 3}},
+ {L"\U00000300\U0000ac00", {768, 44032}, {1, 2}},
+ {L"\U00000300\U00000308\U0000ac00", {768, 44032}, {2, 3}},
+ {L"\U00000300\U0000ac01", {768, 44033}, {1, 2}},
+ {L"\U00000300\U00000308\U0000ac01", {768, 44033}, {2, 3}},
+ {L"\U00000300\U00000903", {768}, {2}},
+ {L"\U00000300\U00000308\U00000903", {768}, {3}},
+ {L"\U00000300\U00000904", {768, 2308}, {1, 2}},
+ {L"\U00000300\U00000308\U00000904", {768, 2308}, {2, 3}},
+ {L"\U00000300\U00000d4e", {768, 3406}, {1, 2}},
+ {L"\U00000300\U00000308\U00000d4e", {768, 3406}, {2, 3}},
+ {L"\U00000300\U00000915", {768, 2325}, {1, 2}},
+ {L"\U00000300\U00000308\U00000915", {768, 2325}, {2, 3}},
+ {L"\U00000300\U0000231a", {768, 8986}, {1, 2}},
+ {L"\U00000300\U00000308\U0000231a", {768, 8986}, {2, 3}},
+ {L"\U00000300\U00000300", {768}, {2}},
+ {L"\U00000300\U00000308\U00000300", {768}, {3}},
+ {L"\U00000300\U00000900", {768}, {2}},
+ {L"\U00000300\U00000308\U00000900", {768}, {3}},
+ {L"\U00000300\U0000094d", {768}, {2}},
+ {L"\U00000300\U00000308\U0000094d", {768}, {3}},
+ {L"\U00000300\U0000200d", {768}, {2}},
+ {L"\U00000300\U00000308\U0000200d", {768}, {3}},
+ {L"\U00000300\U00000378", {768, 888}, {1, 2}},
+ {L"\U00000300\U00000308\U00000378", {768, 888}, {2, 3}},
+ {L"\U00000900\U00000020", {2304, 32}, {1, 2}},
+ {L"\U00000900\U00000308\U00000020", {2304, 32}, {2, 3}},
+ {L"\U00000900\U0000000d", {2304, 13}, {1, 2}},
+ {L"\U00000900\U00000308\U0000000d", {2304, 13}, {2, 3}},
+ {L"\U00000900\U0000000a", {2304, 10}, {1, 2}},
+ {L"\U00000900\U00000308\U0000000a", {2304, 10}, {2, 3}},
+ {L"\U00000900\U00000001", {2304, 1}, {1, 2}},
+ {L"\U00000900\U00000308\U00000001", {2304, 1}, {2, 3}},
+ {L"\U00000900\U0000200c", {2304}, {2}},
+ {L"\U00000900\U00000308\U0000200c", {2304}, {3}},
+ {L"\U00000900\U0001f1e6", {2304, 127462}, {1, 2}},
+ {L"\U00000900\U00000308\U0001f1e6", {2304, 127462}, {2, 3}},
+ {L"\U00000900\U00000600", {2304, 1536}, {1, 2}},
+ {L"\U00000900\U00000308\U00000600", {2304, 1536}, {2, 3}},
+ {L"\U00000900\U00000a03", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000a03", {2304}, {3}},
+ {L"\U00000900\U00001100", {2304, 4352}, {1, 2}},
+ {L"\U00000900\U00000308\U00001100", {2304, 4352}, {2, 3}},
+ {L"\U00000900\U00001160", {2304, 4448}, {1, 2}},
+ {L"\U00000900\U00000308\U00001160", {2304, 4448}, {2, 3}},
+ {L"\U00000900\U000011a8", {2304, 4520}, {1, 2}},
+ {L"\U00000900\U00000308\U000011a8", {2304, 4520}, {2, 3}},
+ {L"\U00000900\U0000ac00", {2304, 44032}, {1, 2}},
+ {L"\U00000900\U00000308\U0000ac00", {2304, 44032}, {2, 3}},
+ {L"\U00000900\U0000ac01", {2304, 44033}, {1, 2}},
+ {L"\U00000900\U00000308\U0000ac01", {2304, 44033}, {2, 3}},
+ {L"\U00000900\U00000903", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000903", {2304}, {3}},
+ {L"\U00000900\U00000904", {2304, 2308}, {1, 2}},
+ {L"\U00000900\U00000308\U00000904", {2304, 2308}, {2, 3}},
+ {L"\U00000900\U00000d4e", {2304, 3406}, {1, 2}},
+ {L"\U00000900\U00000308\U00000d4e", {2304, 3406}, {2, 3}},
+ {L"\U00000900\U00000915", {2304, 2325}, {1, 2}},
+ {L"\U00000900\U00000308\U00000915", {2304, 2325}, {2, 3}},
+ {L"\U00000900\U0000231a", {2304, 8986}, {1, 2}},
+ {L"\U00000900\U00000308\U0000231a", {2304, 8986}, {2, 3}},
+ {L"\U00000900\U00000300", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000300", {2304}, {3}},
+ {L"\U00000900\U00000900", {2304}, {2}},
+ {L"\U00000900\U00000308\U00000900", {2304}, {3}},
+ {L"\U00000900\U0000094d", {2304}, {2}},
+ {L"\U00000900\U00000308\U0000094d", {2304}, {3}},
+ {L"\U00000900\U0000200d", {2304}, {2}},
+ {L"\U00000900\U00000308\U0000200d", {2304}, {3}},
+ {L"\U00000900\U00000378", {2304, 888}, {1, 2}},
+ {L"\U00000900\U00000308\U00000378", {2304, 888}, {2, 3}},
+ {L"\U0000094d\U00000020", {2381, 32}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000020", {2381, 32}, {2, 3}},
+ {L"\U0000094d\U0000000d", {2381, 13}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000000d", {2381, 13}, {2, 3}},
+ {L"\U0000094d\U0000000a", {2381, 10}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000000a", {2381, 10}, {2, 3}},
+ {L"\U0000094d\U00000001", {2381, 1}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000001", {2381, 1}, {2, 3}},
+ {L"\U0000094d\U0000200c", {2381}, {2}},
+ {L"\U0000094d\U00000308\U0000200c", {2381}, {3}},
+ {L"\U0000094d\U0001f1e6", {2381, 127462}, {1, 2}},
+ {L"\U0000094d\U00000308\U0001f1e6", {2381, 127462}, {2, 3}},
+ {L"\U0000094d\U00000600", {2381, 1536}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000600", {2381, 1536}, {2, 3}},
+ {L"\U0000094d\U00000a03", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000a03", {2381}, {3}},
+ {L"\U0000094d\U00001100", {2381, 4352}, {1, 2}},
+ {L"\U0000094d\U00000308\U00001100", {2381, 4352}, {2, 3}},
+ {L"\U0000094d\U00001160", {2381, 4448}, {1, 2}},
+ {L"\U0000094d\U00000308\U00001160", {2381, 4448}, {2, 3}},
+ {L"\U0000094d\U000011a8", {2381, 4520}, {1, 2}},
+ {L"\U0000094d\U00000308\U000011a8", {2381, 4520}, {2, 3}},
+ {L"\U0000094d\U0000ac00", {2381, 44032}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000ac00", {2381, 44032}, {2, 3}},
+ {L"\U0000094d\U0000ac01", {2381, 44033}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000ac01", {2381, 44033}, {2, 3}},
+ {L"\U0000094d\U00000903", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000903", {2381}, {3}},
+ {L"\U0000094d\U00000904", {2381, 2308}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000904", {2381, 2308}, {2, 3}},
+ {L"\U0000094d\U00000d4e", {2381, 3406}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000d4e", {2381, 3406}, {2, 3}},
+ {L"\U0000094d\U00000915", {2381, 2325}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000915", {2381, 2325}, {2, 3}},
+ {L"\U0000094d\U0000231a", {2381, 8986}, {1, 2}},
+ {L"\U0000094d\U00000308\U0000231a", {2381, 8986}, {2, 3}},
+ {L"\U0000094d\U00000300", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000300", {2381}, {3}},
+ {L"\U0000094d\U00000900", {2381}, {2}},
+ {L"\U0000094d\U00000308\U00000900", {2381}, {3}},
+ {L"\U0000094d\U0000094d", {2381}, {2}},
+ {L"\U0000094d\U00000308\U0000094d", {2381}, {3}},
+ {L"\U0000094d\U0000200d", {2381}, {2}},
+ {L"\U0000094d\U00000308\U0000200d", {2381}, {3}},
+ {L"\U0000094d\U00000378", {2381, 888}, {1, 2}},
+ {L"\U0000094d\U00000308\U00000378", {2381, 888}, {2, 3}},
+ {L"\U0000200d\U00000020", {8205, 32}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000020", {8205, 32}, {2, 3}},
+ {L"\U0000200d\U0000000d", {8205, 13}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000000d", {8205, 13}, {2, 3}},
+ {L"\U0000200d\U0000000a", {8205, 10}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000000a", {8205, 10}, {2, 3}},
+ {L"\U0000200d\U00000001", {8205, 1}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000001", {8205, 1}, {2, 3}},
+ {L"\U0000200d\U0000200c", {8205}, {2}},
+ {L"\U0000200d\U00000308\U0000200c", {8205}, {3}},
+ {L"\U0000200d\U0001f1e6", {8205, 127462}, {1, 2}},
+ {L"\U0000200d\U00000308\U0001f1e6", {8205, 127462}, {2, 3}},
+ {L"\U0000200d\U00000600", {8205, 1536}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000600", {8205, 1536}, {2, 3}},
+ {L"\U0000200d\U00000a03", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000a03", {8205}, {3}},
+ {L"\U0000200d\U00001100", {8205, 4352}, {1, 2}},
+ {L"\U0000200d\U00000308\U00001100", {8205, 4352}, {2, 3}},
+ {L"\U0000200d\U00001160", {8205, 4448}, {1, 2}},
+ {L"\U0000200d\U00000308\U00001160", {8205, 4448}, {2, 3}},
+ {L"\U0000200d\U000011a8", {8205, 4520}, {1, 2}},
+ {L"\U0000200d\U00000308\U000011a8", {8205, 4520}, {2, 3}},
+ {L"\U0000200d\U0000ac00", {8205, 44032}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000ac00", {8205, 44032}, {2, 3}},
+ {L"\U0000200d\U0000ac01", {8205, 44033}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000ac01", {8205, 44033}, {2, 3}},
+ {L"\U0000200d\U00000903", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000903", {8205}, {3}},
+ {L"\U0000200d\U00000904", {8205, 2308}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000904", {8205, 2308}, {2, 3}},
+ {L"\U0000200d\U00000d4e", {8205, 3406}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000d4e", {8205, 3406}, {2, 3}},
+ {L"\U0000200d\U00000915", {8205, 2325}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000915", {8205, 2325}, {2, 3}},
+ {L"\U0000200d\U0000231a", {8205, 8986}, {1, 2}},
+ {L"\U0000200d\U00000308\U0000231a", {8205, 8986}, {2, 3}},
+ {L"\U0000200d\U00000300", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000300", {8205}, {3}},
+ {L"\U0000200d\U00000900", {8205}, {2}},
+ {L"\U0000200d\U00000308\U00000900", {8205}, {3}},
+ {L"\U0000200d\U0000094d", {8205}, {2}},
+ {L"\U0000200d\U00000308\U0000094d", {8205}, {3}},
+ {L"\U0000200d\U0000200d", {8205}, {2}},
+ {L"\U0000200d\U00000308\U0000200d", {8205}, {3}},
+ {L"\U0000200d\U00000378", {8205, 888}, {1, 2}},
+ {L"\U0000200d\U00000308\U00000378", {8205, 888}, {2, 3}},
+ {L"\U00000378\U00000020", {888, 32}, {1, 2}},
+ {L"\U00000378\U00000308\U00000020", {888, 32}, {2, 3}},
+ {L"\U00000378\U0000000d", {888, 13}, {1, 2}},
+ {L"\U00000378\U00000308\U0000000d", {888, 13}, {2, 3}},
+ {L"\U00000378\U0000000a", {888, 10}, {1, 2}},
+ {L"\U00000378\U00000308\U0000000a", {888, 10}, {2, 3}},
+ {L"\U00000378\U00000001", {888, 1}, {1, 2}},
+ {L"\U00000378\U00000308\U00000001", {888, 1}, {2, 3}},
+ {L"\U00000378\U0000200c", {888}, {2}},
+ {L"\U00000378\U00000308\U0000200c", {888}, {3}},
+ {L"\U00000378\U0001f1e6", {888, 127462}, {1, 2}},
+ {L"\U00000378\U00000308\U0001f1e6", {888, 127462}, {2, 3}},
+ {L"\U00000378\U00000600", {888, 1536}, {1, 2}},
+ {L"\U00000378\U00000308\U00000600", {888, 1536}, {2, 3}},
+ {L"\U00000378\U00000a03", {888}, {2}},
+ {L"\U00000378\U00000308\U00000a03", {888}, {3}},
+ {L"\U00000378\U00001100", {888, 4352}, {1, 2}},
+ {L"\U00000378\U00000308\U00001100", {888, 4352}, {2, 3}},
+ {L"\U00000378\U00001160", {888, 4448}, {1, 2}},
+ {L"\U00000378\U00000308\U00001160", {888, 4448}, {2, 3}},
+ {L"\U00000378\U000011a8", {888, 4520}, {1, 2}},
+ {L"\U00000378\U00000308\U000011a8", {888, 4520}, {2, 3}},
+ {L"\U00000378\U0000ac00", {888, 44032}, {1, 2}},
+ {L"\U00000378\U00000308\U0000ac00", {888, 44032}, {2, 3}},
+ {L"\U00000378\U0000ac01", {888, 44033}, {1, 2}},
+ {L"\U00000378\U00000308\U0000ac01", {888, 44033}, {2, 3}},
+ {L"\U00000378\U00000903", {888}, {2}},
+ {L"\U00000378\U00000308\U00000903", {888}, {3}},
+ {L"\U00000378\U00000904", {888, 2308}, {1, 2}},
+ {L"\U00000378\U00000308\U00000904", {888, 2308}, {2, 3}},
+ {L"\U00000378\U00000d4e", {888, 3406}, {1, 2}},
+ {L"\U00000378\U00000308\U00000d4e", {888, 3406}, {2, 3}},
+ {L"\U00000378\U00000915", {888, 2325}, {1, 2}},
+ {L"\U00000378\U00000308\U00000915", {888, 2325}, {2, 3}},
+ {L"\U00000378\U0000231a", {888, 8986}, {1, 2}},
+ {L"\U00000378\U00000308\U0000231a", {888, 8986}, {2, 3}},
+ {L"\U00000378\U00000300", {888}, {2}},
+ {L"\U00000378\U00000308\U00000300", {888}, {3}},
+ {L"\U00000378\U00000900", {888}, {2}},
+ {L"\U00000378\U00000308\U00000900", {888}, {3}},
+ {L"\U00000378\U0000094d", {888}, {2}},
+ {L"\U00000378\U00000308\U0000094d", {888}, {3}},
+ {L"\U00000378\U0000200d", {888}, {2}},
+ {L"\U00000378\U00000308\U0000200d", {888}, {3}},
+ {L"\U00000378\U00000378", {888, 888}, {1, 2}},
+ {L"\U00000378\U00000308\U00000378", {888, 888}, {2, 3}},
+ {L"\U0000000d\U0000000a\U00000061\U0000000a\U00000308", {13, 97, 10, 776}, {2, 3, 4, 5}},
+ {L"\U00000061\U00000308", {97}, {2}},
+ {L"\U00000020\U0000200d\U00000646", {32, 1606}, {2, 3}},
+ {L"\U00000646\U0000200d\U00000020", {1606, 32}, {2, 3}},
+ {L"\U00001100\U00001100", {4352}, {2}},
+ {L"\U0000ac00\U000011a8\U00001100", {44032, 4352}, {2, 3}},
+ {L"\U0000ac01\U000011a8\U00001100", {44033, 4352}, {2, 3}},
+ {L"\U0001f1e6\U0001f1e7\U0001f1e8\U00000062", {127462, 127464, 98}, {2, 3, 4}},
+ {L"\U00000061\U0001f1e6\U0001f1e7\U0001f1e8\U00000062", {97, 127462, 127464, 98}, {1, 3, 4, 5}},
+ {L"\U00000061\U0001f1e6\U0001f1e7\U0000200d\U0001f1e8\U00000062", {97, 127462, 127464, 98}, {1, 4, 5, 6}},
+ {L"\U00000061\U0001f1e6\U0000200d\U0001f1e7\U0001f1e8\U00000062", {97, 127462, 127463, 98}, {1, 3, 5, 6}},
+ {L"\U00000061\U0001f1e6\U0001f1e7\U0001f1e8\U0001f1e9\U00000062", {97, 127462, 127464, 98}, {1, 3, 5, 6}},
+ {L"\U00000061\U0000200d", {97}, {2}},
+ {L"\U00000061\U00000308\U00000062", {97, 98}, {2, 3}},
+ {L"\U00000061\U00000903\U00000062", {97, 98}, {2, 3}},
+ {L"\U00000061\U00000600\U00000062", {97, 1536}, {1, 3}},
+ {L"\U0001f476\U0001f3ff\U0001f476", {128118, 128118}, {2, 3}},
+ {L"\U00000061\U0001f3ff\U0001f476", {97, 128118}, {2, 3}},
+ {L"\U00000061\U0001f3ff\U0001f476\U0000200d\U0001f6d1", {97, 128118}, {2, 5}},
+ {L"\U0001f476\U0001f3ff\U00000308\U0000200d\U0001f476\U0001f3ff", {128118}, {6}},
+ {L"\U0001f6d1\U0000200d\U0001f6d1", {128721}, {3}},
+ {L"\U00000061\U0000200d\U0001f6d1", {97, 128721}, {2, 3}},
+ {L"\U00002701\U0000200d\U00002701", {9985}, {3}},
+ {L"\U00000061\U0000200d\U00002701", {97, 9985}, {2, 3}},
+ {L"\U00000915\U00000924", {2325, 2340}, {1, 2}},
+ {L"\U00000915\U0000094d\U00000924", {2325}, {3}},
+ {L"\U00000915\U0000094d\U0000094d\U00000924", {2325}, {4}},
+ {L"\U00000915\U0000094d\U0000200d\U00000924", {2325}, {4}},
+ {L"\U00000915\U0000093c\U0000200d\U0000094d\U00000924", {2325}, {5}},
+ {L"\U00000915\U0000093c\U0000094d\U0000200d\U00000924", {2325}, {5}},
+ {L"\U00000915\U0000094d\U00000924\U0000094d\U0000092f", {2325}, {5}},
+ {L"\U00000915\U0000094d\U00000061", {2325, 97}, {2, 3}},
+ {L"\U00000061\U0000094d\U00000924", {97, 2340}, {2, 3}},
+ {L"\U0000003f\U0000094d\U00000924", {63, 2340}, {2, 3}},
+ {L"\U00000915\U0000094d\U0000094d\U00000924", {2325}, {4}}}};
+#endif // TEST_HAS_NO_WIDE_CHARACTERS
+
+#endif // LIBCXX_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_EXTENDED_GRAPHEME_CLUSTER_H
diff --git a/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.pass.cpp b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.pass.cpp
new file mode 100644
index 0000000000000..90f7cb2c6ee09
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/extended_grapheme_cluster.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-unicode
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// <format>
+
+// Tests the implementation of the extended grapheme cluster boundaries per
+// https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
+//
+// The tests are based on the test data provided by Unicode
+// https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
+
+#include <cassert>
+#include <format>
+#include <functional>
+#include <numeric>
+
+#include "extended_grapheme_cluster.h"
+
+// Validates whether the number of code points in our "database" matches with
+// the number in the Unicode. The assumption is when the number of items per
+// property matches the code points themselves also match.
+namespace {
+namespace cluster = std::__extended_grapheme_custer_property_boundary;
+constexpr int count_entries(cluster::__property property) {
+ return std::transform_reduce(
+ std::begin(cluster::__entries), std::end(cluster::__entries), 0, std::plus{}, [property](auto entry) {
+ if (static_cast<cluster::__property>(entry & 0xf) != property)
+ return 0;
+
+ return 1 + static_cast<int>((entry >> 4) & 0x7f);
+ });
+}
+
+static_assert(count_entries(cluster::__property::__Prepend) == 28);
+static_assert(count_entries(cluster::__property::__CR) == 1);
+static_assert(count_entries(cluster::__property::__LF) == 1);
+static_assert(count_entries(cluster::__property::__Control) == 3893);
+static_assert(count_entries(cluster::__property::__Extend) == 2198);
+static_assert(count_entries(cluster::__property::__Regional_Indicator) == 26);
+static_assert(count_entries(cluster::__property::__SpacingMark) == 378);
+static_assert(count_entries(cluster::__property::__L) == 125);
+static_assert(count_entries(cluster::__property::__V) == 100);
+static_assert(count_entries(cluster::__property::__T) == 137);
+static_assert(count_entries(cluster::__property::__LV) == 399);
+static_assert(count_entries(cluster::__property::__LVT) == 10773);
+static_assert(count_entries(cluster::__property::__ZWJ) == 1);
+static_assert(count_entries(cluster::__property::__Extended_Pictographic) == 3537);
+
+namespace inCB = std::__indic_conjunct_break;
+constexpr int count_entries(inCB::__property property) {
+ return std::transform_reduce(
+ std::begin(inCB::__entries), std::end(inCB::__entries), 0, std::plus{}, [property](auto entry) {
+ if (static_cast<inCB::__property>(entry & 0b11) != property)
+ return 0;
+
+ return 1 + static_cast<int>((entry >> 2) & 0b1'1111'1111);
+ });
+}
+
+static_assert(count_entries(inCB::__property::__Linker) == 6);
+static_assert(count_entries(inCB::__property::__Consonant) == 240);
+static_assert(count_entries(inCB::__property::__Extend) == 2192);
+
+} // namespace
+
+template <class Data>
+constexpr void test(const Data& data) {
+ for (const auto& d : data) {
+ assert(d.code_points.size() == d.breaks.size());
+
+ std::__unicode::__extended_grapheme_cluster_view view{d.input.begin(), d.input.end()};
+ for (std::size_t i = 0; i < d.breaks.size(); ++i) {
+ auto r = view.__consume();
+ assert(r.__code_point_ == d.code_points[i]);
+ assert(r.__last_ == d.input.begin() + d.breaks[i]);
+ }
+ }
+}
+
+constexpr bool test() {
+ test(data_utf8);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ if constexpr (sizeof(wchar_t) == 2)
+ test(data_utf16);
+ else
+ test(data_utf32);
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ // static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/test_exception.h b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/test_exception.h
new file mode 100644
index 0000000000000..3b879421c9f2a
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/format.string/format.string.std/test_exception.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_TEST_EXCEPTION_H
+#define _LIBCPP_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_TEST_EXCEPTION_H
+
+#include <format>
+#include <string_view>
+
+namespace detail {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+template <class Parser, class CharT>
+void test_exception(std::string_view what, const CharT* fmt) {
+ try {
+ std::basic_format_parse_context<CharT> parse_ctx(fmt);
+ (void)Parser{}.parse(parse_ctx);
+ assert(false);
+ } catch (std::format_error& e) {
+ LIBCPP_ASSERT(e.what() == what);
+ return;
+ }
+
+ assert(false);
+}
+#endif
+} // namespace detail
+
+/**
+ * Wrapper for the exception tests.
+ *
+ * When using the real function directly during in a constexpr test and add
+ * the `std::is_constant_evaluated()` test there the compilation fails. This
+ * happens since assert calls the non-constexpr function '__assert_fail'.
+ * Solve this issue with an layer of indirection.
+ */
+template <class Parser, class CharT>
+constexpr void test_exception(std::string_view what, const CharT* fmt) {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ if (!std::is_constant_evaluated())
+ detail::test_exception<Parser>(what, fmt);
+#else
+ (void)what;
+ (void)fmt;
+#endif
+}
+
+#endif // _LIBCPP_TEST_STD_UTILITIES_FORMAT_FORMAT_STRING_FORMAT_STRING_STD_TEST_EXCEPTION_H
diff --git a/libcxx/test/libcxx-03/utilities/format/no_specializations.verify.cpp b/libcxx/test/libcxx-03/utilities/format/no_specializations.verify.cpp
new file mode 100644
index 0000000000000..e1acbaf16f5b4
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/format/no_specializations.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Check that user-specializations are diagnosed
+// See [format.arg]/2
+
+#include <format>
+
+#if !__has_warning("-Winvalid-specialization")
+// expected-no-diagnostics
+#else
+struct S {};
+
+template <>
+class std::basic_format_arg<S>; // expected-error {{cannot be specialized}}
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/bind_back.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/bind_back.pass.cpp
new file mode 100644
index 0000000000000..de7d78fc0f024
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/bind_back.pass.cpp
@@ -0,0 +1,416 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// functional
+
+// template <class F, class... Args>
+// constexpr unspecified __bind_back(F&&, Args&&...);
+
+// This isn't part of the standard, however we use it internally and there is a
+// chance that it will be added to the standard, so we implement those tests
+// as-if it were part of the spec.
+
+#include <functional>
+#include <cassert>
+#include <tuple>
+#include <utility>
+
+#include "callable_types.h"
+#include "test_macros.h"
+
+struct CopyMoveInfo {
+ enum { none, copy, move } copy_kind;
+
+ constexpr CopyMoveInfo() : copy_kind(none) {}
+ constexpr CopyMoveInfo(CopyMoveInfo const&) : copy_kind(copy) {}
+ constexpr CopyMoveInfo(CopyMoveInfo&&) : copy_kind(move) {}
+};
+
+template <class ...Args>
+struct is_bind_backable {
+ template <class ...LocalArgs>
+ static auto test(int)
+ -> decltype((void)std::__bind_back(std::declval<LocalArgs>()...), std::true_type());
+
+ template <class...>
+ static std::false_type test(...);
+
+ static constexpr bool value = decltype(test<Args...>(0))::value;
+};
+
+struct NotCopyMove {
+ NotCopyMove() = delete;
+ NotCopyMove(const NotCopyMove&) = delete;
+ NotCopyMove(NotCopyMove&&) = delete;
+ template <class ...Args>
+ void operator()(Args&& ...) const { }
+};
+
+struct NonConstCopyConstructible {
+ explicit NonConstCopyConstructible() {}
+ NonConstCopyConstructible(NonConstCopyConstructible&) {}
+};
+
+struct MoveConstructible {
+ explicit MoveConstructible() {}
+ MoveConstructible(MoveConstructible&&) {}
+};
+
+struct MakeTuple {
+ template <class ...Args>
+ constexpr auto operator()(Args&& ...args) const {
+ return std::make_tuple(std::forward<Args>(args)...);
+ }
+};
+
+template <int X>
+struct Elem {
+ template <int Y>
+ constexpr bool operator==(Elem<Y> const&) const
+ { return X == Y; }
+};
+
+constexpr bool test() {
+ // Bind arguments, call without arguments
+ {
+ {
+ auto f = std::__bind_back(MakeTuple{});
+ assert(f() == std::make_tuple());
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{});
+ assert(f() == std::make_tuple(Elem<1>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{});
+ assert(f() == std::make_tuple(Elem<1>{}, Elem<2>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{}, Elem<3>{});
+ assert(f() == std::make_tuple(Elem<1>{}, Elem<2>{}, Elem<3>{}));
+ }
+ }
+
+ // Bind no arguments, call with arguments
+ {
+ {
+ auto f = std::__bind_back(MakeTuple{});
+ assert(f(Elem<1>{}) == std::make_tuple(Elem<1>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{});
+ assert(f(Elem<1>{}, Elem<2>{}) == std::make_tuple(Elem<1>{}, Elem<2>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{});
+ assert(f(Elem<1>{}, Elem<2>{}, Elem<3>{}) == std::make_tuple(Elem<1>{}, Elem<2>{}, Elem<3>{}));
+ }
+ }
+
+ // Bind arguments, call with arguments
+ {
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{});
+ assert(f(Elem<10>{}) == std::make_tuple(Elem<10>{}, Elem<1>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{});
+ assert(f(Elem<10>{}) == std::make_tuple(Elem<10>{}, Elem<1>{}, Elem<2>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{}, Elem<3>{});
+ assert(f(Elem<10>{}) == std::make_tuple(Elem<10>{}, Elem<1>{}, Elem<2>{}, Elem<3>{}));
+ }
+
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{});
+ assert(f(Elem<10>{}, Elem<11>{}) == std::make_tuple(Elem<10>{}, Elem<11>{}, Elem<1>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{});
+ assert(f(Elem<10>{}, Elem<11>{}) == std::make_tuple(Elem<10>{}, Elem<11>{}, Elem<1>{}, Elem<2>{}));
+ }
+ {
+ auto f = std::__bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{}, Elem<3>{});
+ assert(f(Elem<10>{}, Elem<11>{}) == std::make_tuple(Elem<10>{}, Elem<11>{}, Elem<1>{}, Elem<2>{}, Elem<3>{}));
+ }
+ }
+
+ // Basic tests with fundamental types
+ {
+ int n = 2;
+ int m = 1;
+ auto add = [](int x, int y) { return x + y; };
+ auto addN = [](int a, int b, int c, int d, int e, int f) {
+ return a + b + c + d + e + f;
+ };
+
+ auto a = std::__bind_back(add, m, n);
+ assert(a() == 3);
+
+ auto b = std::__bind_back(addN, m, n, m, m, m, m);
+ assert(b() == 7);
+
+ auto c = std::__bind_back(addN, n, m);
+ assert(c(1, 1, 1, 1) == 7);
+
+ auto f = std::__bind_back(add, n);
+ assert(f(3) == 5);
+
+ auto g = std::__bind_back(add, n, 1);
+ assert(g() == 3);
+
+ auto h = std::__bind_back(addN, 1, 1, 1);
+ assert(h(2, 2, 2) == 9);
+ }
+
+ // Make sure we don't treat std::reference_wrapper specially.
+ {
+ auto sub = [](std::reference_wrapper<int> a, std::reference_wrapper<int> b) {
+ return a.get() - b.get();
+ };
+ int i = 1, j = 2;
+ auto f = std::__bind_back(sub, std::ref(i));
+ assert(f(std::ref(j)) == 2 - 1);
+ }
+
+ // Make sure we can call a function that's a pointer to a member function.
+ {
+ struct MemberFunction {
+ constexpr bool foo(int, int) { return true; }
+ };
+ MemberFunction value;
+ auto fn = std::__bind_back(&MemberFunction::foo, 0, 0);
+ assert(fn(value));
+ }
+
+ // Make sure that we copy the bound arguments into the unspecified-type.
+ {
+ auto add = [](int x, int y) { return x + y; };
+ int n = 2;
+ auto i = std::__bind_back(add, n, 1);
+ n = 100;
+ assert(i() == 3);
+ }
+
+ // Make sure we pass the bound arguments to the function object
+ // with the right value category.
+ {
+ {
+ auto wasCopied = [](CopyMoveInfo info) {
+ return info.copy_kind == CopyMoveInfo::copy;
+ };
+ CopyMoveInfo info;
+ auto copied = std::__bind_back(wasCopied, info);
+ assert(copied());
+ }
+
+ {
+ auto wasMoved = [](CopyMoveInfo info) {
+ return info.copy_kind == CopyMoveInfo::move;
+ };
+ CopyMoveInfo info;
+ auto moved = std::__bind_back(wasMoved, info);
+ assert(std::move(moved)());
+ }
+ }
+
+ // Make sure we call the correctly cv-ref qualified operator() based on the
+ // value category of the __bind_back unspecified-type.
+ {
+ struct F {
+ constexpr int operator()() & { return 1; }
+ constexpr int operator()() const& { return 2; }
+ constexpr int operator()() && { return 3; }
+ constexpr int operator()() const&& { return 4; }
+ };
+ auto x = std::__bind_back(F{});
+ using X = decltype(x);
+ assert(static_cast<X&>(x)() == 1);
+ assert(static_cast<X const&>(x)() == 2);
+ assert(static_cast<X&&>(x)() == 3);
+ assert(static_cast<X const&&>(x)() == 4);
+ }
+
+ // Make sure the __bind_back unspecified-type is NOT invocable when the call would select a
+ // differently-qualified operator().
+ //
+ // For example, if the call to `operator()() &` is ill-formed, the call to the unspecified-type
+ // should be ill-formed and not fall back to the `operator()() const&` overload.
+ {
+ // Make sure we delete the & overload when the underlying call isn't valid
+ {
+ struct F {
+ void operator()() & = delete;
+ void operator()() const&;
+ void operator()() &&;
+ void operator()() const&&;
+ };
+ using X = decltype(std::__bind_back(F{}));
+ static_assert(!std::is_invocable_v<X&>);
+ static_assert( std::is_invocable_v<X const&>);
+ static_assert( std::is_invocable_v<X>);
+ static_assert( std::is_invocable_v<X const>);
+ }
+
+ // There's no way to make sure we delete the const& overload when the underlying call isn't valid,
+ // so we can't check this one.
+
+ // Make sure we delete the && overload when the underlying call isn't valid
+ {
+ struct F {
+ void operator()() &;
+ void operator()() const&;
+ void operator()() && = delete;
+ void operator()() const&&;
+ };
+ using X = decltype(std::__bind_back(F{}));
+ static_assert( std::is_invocable_v<X&>);
+ static_assert( std::is_invocable_v<X const&>);
+ static_assert(!std::is_invocable_v<X>);
+ static_assert( std::is_invocable_v<X const>);
+ }
+
+ // Make sure we delete the const&& overload when the underlying call isn't valid
+ {
+ struct F {
+ void operator()() &;
+ void operator()() const&;
+ void operator()() &&;
+ void operator()() const&& = delete;
+ };
+ using X = decltype(std::__bind_back(F{}));
+ static_assert( std::is_invocable_v<X&>);
+ static_assert( std::is_invocable_v<X const&>);
+ static_assert( std::is_invocable_v<X>);
+ static_assert(!std::is_invocable_v<X const>);
+ }
+ }
+
+ // Some examples by Tim Song
+ {
+ {
+ struct T { };
+ struct F {
+ void operator()(T&&) const &;
+ void operator()(T&&) && = delete;
+ };
+ using X = decltype(std::__bind_back(F{}));
+ static_assert(!std::is_invocable_v<X, T>);
+ }
+
+ {
+ struct T { };
+ struct F {
+ void operator()(T const&) const;
+ void operator()(T&&) const = delete;
+ };
+ using X = decltype(std::__bind_back(F{}, T{}));
+ static_assert(!std::is_invocable_v<X>);
+ }
+ }
+
+ // Test properties of the constructor of the unspecified-type returned by __bind_back.
+ {
+ {
+ MoveOnlyCallable<bool> value(true);
+ auto ret = std::__bind_back(std::move(value), 1);
+ assert(ret());
+ assert(ret(1, 2, 3));
+
+ auto ret1 = std::move(ret);
+ assert(!ret());
+ assert(ret1());
+ assert(ret1(1, 2, 3));
+
+ using RetT = decltype(ret);
+ static_assert( std::is_move_constructible<RetT>::value);
+ static_assert(!std::is_copy_constructible<RetT>::value);
+ static_assert(!std::is_move_assignable<RetT>::value);
+ static_assert(!std::is_copy_assignable<RetT>::value);
+ }
+ {
+ CopyCallable<bool> value(true);
+ auto ret = std::__bind_back(value, 1);
+ assert(ret());
+ assert(ret(1, 2, 3));
+
+ auto ret1 = std::move(ret);
+ assert(ret1());
+ assert(ret1(1, 2, 3));
+
+ auto ret2 = std::__bind_back(std::move(value), 1);
+ assert(!ret());
+ assert(ret2());
+ assert(ret2(1, 2, 3));
+
+ using RetT = decltype(ret);
+ static_assert( std::is_move_constructible<RetT>::value);
+ static_assert( std::is_copy_constructible<RetT>::value);
+ static_assert(!std::is_move_assignable<RetT>::value);
+ static_assert(!std::is_copy_assignable<RetT>::value);
+ }
+ {
+ CopyAssignableWrapper value(true);
+ using RetT = decltype(std::__bind_back(value, 1));
+
+ static_assert(std::is_move_constructible<RetT>::value);
+ static_assert(std::is_copy_constructible<RetT>::value);
+ static_assert(std::is_move_assignable<RetT>::value);
+ static_assert(std::is_copy_assignable<RetT>::value);
+ }
+ {
+ MoveAssignableWrapper value(true);
+ using RetT = decltype(std::__bind_back(std::move(value), 1));
+
+ static_assert( std::is_move_constructible<RetT>::value);
+ static_assert(!std::is_copy_constructible<RetT>::value);
+ static_assert( std::is_move_assignable<RetT>::value);
+ static_assert(!std::is_copy_assignable<RetT>::value);
+ }
+ }
+
+ // Make sure __bind_back is SFINAE friendly
+ {
+ static_assert(!std::is_constructible_v<NotCopyMove, NotCopyMove&>);
+ static_assert(!std::is_move_constructible_v<NotCopyMove>);
+ static_assert(!is_bind_backable<NotCopyMove>::value);
+ static_assert(!is_bind_backable<NotCopyMove&>::value);
+
+ auto takeAnything = [](auto&& ...) { };
+ static_assert(!std::is_constructible_v<MoveConstructible, MoveConstructible&>);
+ static_assert( std::is_move_constructible_v<MoveConstructible>);
+ static_assert( is_bind_backable<decltype(takeAnything), MoveConstructible>::value);
+ static_assert(!is_bind_backable<decltype(takeAnything), MoveConstructible&>::value);
+
+ static_assert( std::is_constructible_v<NonConstCopyConstructible, NonConstCopyConstructible&>);
+ static_assert(!std::is_move_constructible_v<NonConstCopyConstructible>);
+ static_assert(!is_bind_backable<decltype(takeAnything), NonConstCopyConstructible&>::value);
+ static_assert(!is_bind_backable<decltype(takeAnything), NonConstCopyConstructible>::value);
+ }
+
+ // Make sure bind_back's unspecified type's operator() is SFINAE-friendly
+ {
+ using T = decltype(std::__bind_back(std::declval<int(*)(int, int)>(), 1));
+ static_assert(!std::is_invocable<T>::value);
+ static_assert( std::is_invocable<T, int>::value);
+ static_assert(!std::is_invocable<T, void*>::value);
+ static_assert(!std::is_invocable<T, int, int>::value);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/compose.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/compose.pass.cpp
new file mode 100644
index 0000000000000..7e597081cfaad
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.bind.partial/compose.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
+
+// template <class F1, class F2>
+// constexpr unspecified __compose(F1&&, F2&&);
+
+#include <__functional/compose.h>
+#include <cassert>
+#include <tuple>
+#include <utility>
+
+template <int X>
+struct Elem {
+ template <int Y>
+ constexpr bool operator==(Elem<Y> const&) const
+ { return X == Y; }
+};
+
+struct F {
+ template <class ...Args>
+ constexpr auto operator()(Args&& ...args) const {
+ return std::make_tuple(Elem<888>{}, std::forward<Args>(args)...);
+ }
+};
+
+struct G {
+ template <class ...Args>
+ constexpr auto operator()(Args&& ...args) const {
+ return std::make_tuple(Elem<999>{}, std::forward<Args>(args)...);
+ }
+};
+
+constexpr bool test() {
+ F const f;
+ G const g;
+
+ {
+ auto c = std::__compose(f, g);
+ assert(c() == f(g()));
+ }
+ {
+ auto c = std::__compose(f, g);
+ assert(c(Elem<0>{}) == f(g(Elem<0>{})));
+ }
+ {
+ auto c = std::__compose(f, g);
+ assert(c(Elem<0>{}, Elem<1>{}) == f(g(Elem<0>{}, Elem<1>{})));
+ }
+ {
+ auto c = std::__compose(f, g);
+ assert(c(Elem<0>{}, Elem<1>{}, Elem<2>{}) == f(g(Elem<0>{}, Elem<1>{}, Elem<2>{})));
+ }
+
+ // Make sure we can call a function that's a pointer to a member function.
+ {
+ struct MemberFunction1 {
+ constexpr Elem<0> foo() { return {}; }
+ };
+ struct MemberFunction2 {
+ constexpr MemberFunction1 bar() { return {}; }
+ };
+ auto c = std::__compose(&MemberFunction1::foo, &MemberFunction2::bar);
+ assert(c(MemberFunction2{}) == Elem<0>{});
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.blocks.arc.pass.mm b/libcxx/test/libcxx-03/utilities/function.objects/func.blocks.arc.pass.mm
new file mode 100644
index 0000000000000..c9ace62000be3
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.blocks.arc.pass.mm
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// std::function support for "blocks" when ARC is enabled
+
+// UNSUPPORTED: c++03
+
+// This test requires the Blocks runtime, which is (only?) available on Darwin
+// out-of-the-box.
+// REQUIRES: has-fblocks && has-fobjc-arc && darwin
+
+// ADDITIONAL_COMPILE_FLAGS: -fblocks -fobjc-arc
+
+#include <functional>
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+struct Foo {
+ Foo() = default;
+ Foo(std::size_t (^bl)()) : f(bl) {}
+
+ std::function<int()> f;
+};
+
+Foo Factory(std::size_t (^bl)()) {
+ Foo result(bl);
+ return result;
+}
+
+Foo Factory2() {
+ auto hello = std::string("Hello world");
+ return Factory(^() {
+ return hello.size();
+ });
+}
+
+Foo AssignmentFactory(std::size_t (^bl)()) {
+ Foo result;
+ result.f = bl;
+ return result;
+}
+
+Foo AssignmentFactory2() {
+ auto hello = std::string("Hello world");
+ return AssignmentFactory(^() {
+ return hello.size();
+ });
+}
+
+int main(int, char **) {
+ // Case 1, works
+ {
+ auto hello = std::string("Hello world");
+ auto f = AssignmentFactory(^() {
+ return hello.size();
+ });
+ assert(f.f() == 11);
+ }
+
+ // Case 2, works
+ {
+ auto f = AssignmentFactory2();
+ assert(f.f() == 11);
+ }
+
+ // Case 3, works
+ {
+ auto hello = std::string("Hello world");
+ auto f = Factory(^() {
+ return hello.size();
+ });
+ assert(f.f() == 11);
+ }
+
+ // Case 4, used to crash under ARC
+ {
+ auto f = Factory2();
+ assert(f.f() == 11);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.blocks.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.blocks.pass.cpp
new file mode 100644
index 0000000000000..a917e9fe1f81e
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.blocks.pass.cpp
@@ -0,0 +1,147 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// std::function support for the "blocks" extension
+
+// UNSUPPORTED: c++03
+
+// This test requires the Blocks runtime, which is (only?) available
+// on Darwin out-of-the-box.
+// REQUIRES: has-fblocks && darwin
+
+// ADDITIONAL_COMPILE_FLAGS: -fblocks
+
+#include <cassert>
+#include <cstdlib>
+#include <functional>
+#include <typeinfo>
+
+#include <Block.h>
+
+#include "test_macros.h"
+#include "count_new.h"
+
+
+struct A {
+ static int count;
+ int id_;
+ explicit A(int id) { ++count; id_ = id; }
+ A(const A &a) { id_ = a.id_; ++count; }
+ ~A() { id_ = -1; --count; }
+ int operator()() const { return -1; }
+ int operator()(int i) const { return i; }
+ int operator()(int, int) const { return -2; }
+ int operator()(int, int, int) const { return -3; }
+ int id() const { return id_; }
+};
+
+int A::count = 0;
+
+int g(int) { return 0; }
+
+int main(int, char**)
+{
+ // swap
+ {
+ std::function<int(int)> f1 = g;
+ std::function<int(int)> f2 = ^(int x) { return x + 1; };
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
+ RTTI_ASSERT(*f2.target<int(^)(int)>() != 0);
+ swap(f1, f2);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ RTTI_ASSERT(*f1.target<int(^)(int)>() != 0);
+ RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
+ }
+
+ // operator bool
+ {
+ std::function<int(int)> f;
+ assert(!f);
+ f = ^(int x) { return x+1; };
+ assert(f);
+ }
+
+ // operator()
+ {
+ std::function<int ()> r1(^{ return 4; });
+ assert(r1() == 4);
+ }
+ {
+ __block bool called = false;
+ std::function<void ()> r1(^{ called = true; });
+ r1();
+ assert(called);
+ }
+ {
+ __block int param = 0;
+ std::function<void (int)> r1(^(int x){ param = x; });
+ r1(4);
+ assert(param == 4);
+ }
+ {
+ std::function<int (int)> r1(^(int x){ return x + 4; });
+ assert(r1(3) == 7);
+ }
+ {
+ __block int param1 = 0;
+ __block int param2 = 0;
+ std::function<void (int, int)> r1(^(int x, int y){ param1 = x; param2 = y; });
+ r1(3, 4);
+ assert(param1 == 3);
+ assert(param2 == 4);
+ }
+ {
+ std::function<int (int, int)> r1(^(int x, int y){ return x + y; });
+ assert(r1(3, 4) == 7);
+ }
+
+ // swap
+ {
+ std::function<int(int)> f1 = A(999);
+ std::function<int(int)> f2 = ^(int x) { return x + 1; };
+ assert(A::count == 1);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ RTTI_ASSERT(f1.target<A>()->id() == 999);
+ RTTI_ASSERT((*f2.target<int(^)(int)>())(13) == 14);
+ f1.swap(f2);
+ assert(A::count == 1);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ RTTI_ASSERT((*f1.target<int(^)(int)>())(13) == 14);
+ RTTI_ASSERT(f2.target<A>()->id() == 999);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(A::count == 0);
+
+ // operator== and operator!=
+ {
+ std::function<int(int)> f;
+ assert(f == nullptr);
+ assert(nullptr == f);
+ f = ^(int x) { return x + 1; };
+ assert(f != nullptr);
+ assert(nullptr != f);
+ }
+
+ // target
+ {
+ int (^block)(int) = Block_copy(^(int x) { return x + 1; });
+ std::function<int(int)> f = block;
+ RTTI_ASSERT(*f.target<int(^)(int)>() == block);
+ RTTI_ASSERT(f.target<int(*)(int)>() == 0);
+ Block_release(block);
+ }
+
+ // target_type
+ {
+ std::function<int(int)> f = ^(int x) { return x + 1; };
+ RTTI_ASSERT(f.target_type() == typeid(int(^)(int)));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.compile.pass.cpp
new file mode 100644
index 0000000000000..b0128ae6ff053
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.compile.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, c++20, c++23
+
+// <functional>
+
+// Type of `std::not_fn<NTTP>()` is always empty.
+
+#include <functional>
+#include <type_traits>
+
+struct NonEmptyFunctionObject {
+ bool val = true;
+ bool operator()() const;
+};
+
+bool func();
+
+struct SomeClass {
+ bool member_object;
+ bool member_function();
+};
+
+using ResultWithEmptyFuncObject = decltype(std::not_fn<std::false_type{}>());
+static_assert(std::is_empty_v<ResultWithEmptyFuncObject>);
+
+using ResultWithNotEmptyFuncObject = decltype(std::not_fn<NonEmptyFunctionObject{}>());
+static_assert(std::is_empty_v<ResultWithNotEmptyFuncObject>);
+
+using ResultWithFunctionPointer = decltype(std::not_fn<&func>());
+static_assert(std::is_empty_v<ResultWithFunctionPointer>);
+
+using ResultWithMemberObjectPointer = decltype(std::not_fn<&SomeClass::member_object>());
+static_assert(std::is_empty_v<ResultWithMemberObjectPointer>);
+
+using ResultWithMemberFunctionPointer = decltype(std::not_fn<&SomeClass::member_function>());
+static_assert(std::is_empty_v<ResultWithMemberFunctionPointer>);
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.nodiscard.verify.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..acef2d3d24a29
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.not.fn/not_fn.nttp.nodiscard.verify.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, c++11, c++14, c++17, c++20, c++23
+
+// <functional>
+
+// Test the libc++ extension that std::not_fn<NTTP> is marked as [[nodiscard]].
+
+#include <functional>
+#include <type_traits>
+
+void test() {
+ using F = std::true_type;
+ std::not_fn<F{}>(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ auto negated = std::not_fn<F{}>();
+ negated(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
new file mode 100644
index 0000000000000..48460d1488fd7
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
@@ -0,0 +1,405 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// INVOKE (f, t1, t2, ..., tN)
+
+//------------------------------------------------------------------------------
+// TESTING INVOKE(f, t1, t2, ..., tN)
+// - Bullet 1 -- (t1.*f)(t2, ..., tN)
+// - Bullet 2 -- (t1.get().*f)(t2, ..., tN) // t1 is a reference_wrapper
+// - Bullet 3 -- ((*t1).*f)(t2, ..., tN)
+//
+// Overview:
+// Bullets 1, 2 and 3 handle the case where 'f' is a pointer to member function.
+// Bullet 1 only handles the cases where t1 is an object of type T or a
+// type derived from 'T'. Bullet 2 handles the case where 't1' is a reference
+// wrapper and bullet 3 handles all other cases.
+//
+// Concerns:
+// 1) cv-qualified member function signatures are accepted.
+// 2) reference qualified member function signatures are accepted.
+// 3) member functions with varargs at the end are accepted.
+// 4) The arguments are perfect forwarded to the member function call.
+// 5) Classes that are publicly derived from 'T' are accepted as the call object
+// 6) All types that dereference to T or a type derived from T can be used
+// as the call object.
+// 7) Pointers to T or a type derived from T can be used as the call object.
+// 8) Reference return types are properly deduced.
+// 9) reference_wrappers are properly handled and unwrapped.
+//
+//
+// Plan:
+// 1) Create a class that contains a set, 'S', of non-static functions.
+// 'S' should include functions that cover every single combination
+// of qualifiers and varargs for arities of 0, 1 and 2 (C-1,2,3).
+// The argument types used in the functions should be non-copyable (C-4).
+// The functions should return 'MethodID::setUncheckedCall()'.
+//
+// 2) Create a set of supported call object, 'Objs', of different types
+// and behaviors. (C-5,6,7)
+//
+// 3) Attempt to call each function, 'f', in 'S' with each call object, 'c',
+// in 'Objs'. After every attempted call to 'f' check that 'f' was
+// actually called using 'MethodID::checkCalled(<return-value>)'
+//
+// 3b) If 'f' is reference qualified call 'f' with the properly qualified
+// call object. Otherwise call 'f' with lvalue call objects.
+//
+// 3a) If 'f' is const, volatile, or cv qualified then call it with call
+// objects that are equally or less cv-qualified.
+
+#include <functional>
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+#include "invoke_helpers.h"
+
+//==============================================================================
+// MemFun03 - C++03 compatible set of test member functions.
+struct MemFun03 {
+ typedef void*& R;
+#define F(...) \
+ R f(__VA_ARGS__) { return MethodID<R(MemFun03::*)(__VA_ARGS__)>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const { return MethodID<R(MemFun03::*)(__VA_ARGS__) const>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) volatile>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) const volatile>::setUncheckedCall(); }
+#
+ F()
+ F(...)
+ F(ArgType&)
+ F(ArgType&, ...)
+ F(ArgType&, ArgType&)
+ F(ArgType&, ArgType&, ...)
+ F(ArgType&, ArgType&, ArgType&)
+ F(ArgType&, ArgType&, ArgType&, ...)
+#undef F
+public:
+ MemFun03() {}
+private:
+ MemFun03(MemFun03 const&);
+ MemFun03& operator=(MemFun03 const&);
+};
+
+
+#if TEST_STD_VER >= 11
+
+//==============================================================================
+// MemFun11 - C++11 reference qualified test member functions.
+struct MemFun11 {
+ typedef void*& R;
+ typedef MemFun11 C;
+#define F(...) \
+ R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); }
+#
+ F()
+ F(...)
+ F(ArgType&&)
+ F(ArgType&&, ...)
+ F(ArgType&&, ArgType&&)
+ F(ArgType&&, ArgType&&, ...)
+ F(ArgType&&, ArgType&&, ArgType&&)
+ F(ArgType&&, ArgType&&, ArgType&&, ...)
+#undef F
+public:
+ MemFun11() {}
+private:
+ MemFun11(MemFun11 const&);
+ MemFun11& operator=(MemFun11 const&);
+};
+
+#endif // TEST_STD_VER >= 11
+
+
+
+//==============================================================================
+// TestCase - A test case for a single member function.
+// ClassType - The type of the class being tested.
+// CallSig - The function signature of the method being tested.
+// Arity - the arity of 'CallSig'
+// CV - the cv qualifiers of 'CallSig' represented as a type tag.
+// RValue - The method is RValue qualified.
+// ArgRValue - Call the method with RValue arguments.
+template <class ClassType, class CallSig, int Arity, class CV,
+ bool RValue = false, bool ArgRValue = false>
+struct TestCaseImp {
+public:
+
+ static void run() { TestCaseImp().doTest(); }
+
+private:
+ //==========================================================================
+ // TEST DISPATCH
+ void doTest() {
+ // (Plan-2) Create test call objects.
+ typedef ClassType T;
+ typedef DerivedFromType<T> D;
+ T obj;
+ T* obj_ptr = &obj;
+ D der;
+ D* der_ptr = &der;
+ DerefToType<T> dref;
+ DerefPropType<T> dref2;
+ std::reference_wrapper<T> rref(obj);
+ std::reference_wrapper<D> drref(der);
+
+ // (Plan-3) Dispatch based on the CV tags.
+ CV tag;
+ Bool<!RValue> NotRValue;
+ runTestDispatch(tag, obj);
+ runTestDispatch(tag, der);
+ runTestDispatch(tag, dref2);
+ runTestDispatchIf(NotRValue, tag, dref);
+ runTestDispatchIf(NotRValue, tag, obj_ptr);
+ runTestDispatchIf(NotRValue, tag, der_ptr);
+#if TEST_STD_VER >= 11
+ runTestDispatchIf(NotRValue, tag, rref);
+ runTestDispatchIf(NotRValue, tag, drref);
+#endif
+ }
+
+ template <class QT, class Tp>
+ void runTestDispatchIf(Bool<true>, QT q, Tp& v) {
+ runTestDispatch(q, v);
+ }
+
+ template <class QT, class Tp>
+ void runTestDispatchIf(Bool<false>, QT, Tp&) {
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_None, Tp& v) {
+ runTest(v);
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_Const, Tp& v) {
+ runTest(v);
+ runTest(makeConst(v));
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_Volatile, Tp& v) {
+ runTest(v);
+ runTest(makeVolatile(v));
+
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_CV, Tp& v) {
+ runTest(v);
+ runTest(makeConst(v));
+ runTest(makeVolatile(v));
+ runTest(makeCV(v));
+ }
+
+ template <class T>
+ void runTest(const std::reference_wrapper<T>& obj) {
+ typedef Caster<Q_None, RValue> SCast;
+ typedef Caster<Q_None, ArgRValue> ACast;
+ typedef CallSig (ClassType::*MemPtr);
+ // Delegate test to logic in invoke_helpers.h
+ BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
+ b.runTest( (MemPtr)&ClassType::f, obj);
+ }
+
+ template <class T>
+ void runTest(T* obj) {
+ typedef Caster<Q_None, RValue> SCast;
+ typedef Caster<Q_None, ArgRValue> ACast;
+ typedef CallSig (ClassType::*MemPtr);
+ // Delegate test to logic in invoke_helpers.h
+ BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
+ b.runTest( (MemPtr)&ClassType::f, obj);
+ }
+
+ template <class Obj>
+ void runTest(Obj& obj) {
+ typedef Caster<Q_None, RValue> SCast;
+ typedef Caster<Q_None, ArgRValue> ACast;
+ typedef CallSig (ClassType::*MemPtr);
+ // Delegate test to logic in invoke_helpers.h
+ BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
+ b.runTest( (MemPtr)&ClassType::f, obj);
+ }
+};
+
+template <class Sig, int Arity, class CV>
+struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
+
+#if TEST_STD_VER >= 11
+template <class Sig, int Arity, class CV, bool RValue = false>
+struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
+
+template <class Type>
+struct ReferenceWrapper {
+ using type = Type;
+ Type* ptr;
+
+ static void fun(Type&) noexcept;
+ static void fun(Type&&) = delete;
+
+ template <class Type2,
+ class = typename std::enable_if<!std::__is_same_uncvref<Type2, ReferenceWrapper>::value>::type>
+ constexpr ReferenceWrapper(Type2&& t) noexcept : ptr(&t) {}
+
+ constexpr Type& get() const noexcept { return *ptr; }
+ constexpr operator Type&() const noexcept { return *ptr; }
+
+ template <class... _ArgTypes>
+ constexpr std::__invoke_result_t<Type&, _ArgTypes...> operator()(_ArgTypes&&... __args) const {
+ return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
+ }
+};
+
+template <class Tp>
+struct DerivedFromRefWrap : public ReferenceWrapper<Tp> {
+ constexpr DerivedFromRefWrap(Tp& tp) : ReferenceWrapper<Tp>(tp) {}
+};
+
+TEST_CONSTEXPR_CXX14 bool test_derived_from_ref_wrap() {
+ int x = 42;
+ ReferenceWrapper<int> r(x);
+ DerivedFromRefWrap<int> d(x);
+ auto get_fn = &ReferenceWrapper<int>::get;
+ auto& ret = std::__invoke(get_fn, r);
+ assert(&ret == &x);
+ auto& ret2 = std::__invoke(get_fn, d);
+ assert(&ret2 == &x);
+
+ return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test_reference_wrapper_reference_wrapper() {
+ int x = 42;
+ auto get_fn = &std::reference_wrapper<int>::get;
+ std::reference_wrapper<int> r(x);
+ std::reference_wrapper<std::reference_wrapper<int>> r2(r);
+ auto& ret3 = std::__invoke(get_fn, r2);
+ assert(&ret3 == &x);
+
+ return true;
+}
+#endif
+
+int main(int, char**) {
+ typedef void*& R;
+ typedef ArgType A;
+ TestCase<R(), 0, Q_None>::run();
+ TestCase<R() const, 0, Q_Const>::run();
+ TestCase<R() volatile, 0, Q_Volatile>::run();
+ TestCase<R() const volatile, 0, Q_CV>::run();
+ TestCase<R(...), 0, Q_None>::run();
+ TestCase<R(...) const, 0, Q_Const>::run();
+ TestCase<R(...) volatile, 0, Q_Volatile>::run();
+ TestCase<R(...) const volatile, 0, Q_CV>::run();
+ TestCase<R(A&), 1, Q_None>::run();
+ TestCase<R(A&) const, 1, Q_Const>::run();
+ TestCase<R(A&) volatile, 1, Q_Volatile>::run();
+ TestCase<R(A&) const volatile, 1, Q_CV>::run();
+ TestCase<R(A&, ...), 1, Q_None>::run();
+ TestCase<R(A&, ...) const, 1, Q_Const>::run();
+ TestCase<R(A&, ...) volatile, 1, Q_Volatile>::run();
+ TestCase<R(A&, ...) const volatile, 1, Q_CV>::run();
+ TestCase<R(A&, A&), 2, Q_None>::run();
+ TestCase<R(A&, A&) const, 2, Q_Const>::run();
+ TestCase<R(A&, A&) volatile, 2, Q_Volatile>::run();
+ TestCase<R(A&, A&) const volatile, 2, Q_CV>::run();
+ TestCase<R(A&, A&, ...), 2, Q_None>::run();
+ TestCase<R(A&, A&, ...) const, 2, Q_Const>::run();
+ TestCase<R(A&, A&, ...) volatile, 2, Q_Volatile>::run();
+ TestCase<R(A&, A&, ...) const volatile, 2, Q_CV>::run();
+ TestCase<R(A&, A&, A&), 3, Q_None>::run();
+ TestCase<R(A&, A&, A&) const, 3, Q_Const>::run();
+ TestCase<R(A&, A&, A&) volatile, 3, Q_Volatile>::run();
+ TestCase<R(A&, A&, A&) const volatile, 3, Q_CV>::run();
+ TestCase<R(A&, A&, A&, ...), 3, Q_None>::run();
+ TestCase<R(A&, A&, A&, ...) const, 3, Q_Const>::run();
+ TestCase<R(A&, A&, A&, ...) volatile, 3, Q_Volatile>::run();
+ TestCase<R(A&, A&, A&, ...) const volatile, 3, Q_CV>::run();
+
+#if TEST_STD_VER >= 11
+ TestCase11<R() &, 0, Q_None>::run();
+ TestCase11<R() const &, 0, Q_Const>::run();
+ TestCase11<R() volatile &, 0, Q_Volatile>::run();
+ TestCase11<R() const volatile &, 0, Q_CV>::run();
+ TestCase11<R(...) &, 0, Q_None>::run();
+ TestCase11<R(...) const &, 0, Q_Const>::run();
+ TestCase11<R(...) volatile &, 0, Q_Volatile>::run();
+ TestCase11<R(...) const volatile &, 0, Q_CV>::run();
+ TestCase11<R(A&&) &, 1, Q_None>::run();
+ TestCase11<R(A&&) const &, 1, Q_Const>::run();
+ TestCase11<R(A&&) volatile &, 1, Q_Volatile>::run();
+ TestCase11<R(A&&) const volatile &, 1, Q_CV>::run();
+ TestCase11<R(A&&, ...) &, 1, Q_None>::run();
+ TestCase11<R(A&&, ...) const &, 1, Q_Const>::run();
+ TestCase11<R(A&&, ...) volatile &, 1, Q_Volatile>::run();
+ TestCase11<R(A&&, ...) const volatile &, 1, Q_CV>::run();
+ TestCase11<R(A&&, A&&) &, 2, Q_None>::run();
+ TestCase11<R(A&&, A&&) const &, 2, Q_Const>::run();
+ TestCase11<R(A&&, A&&) volatile &, 2, Q_Volatile>::run();
+ TestCase11<R(A&&, A&&) const volatile &, 2, Q_CV>::run();
+ TestCase11<R(A&&, A&&, ...) &, 2, Q_None>::run();
+ TestCase11<R(A&&, A&&, ...) const &, 2, Q_Const>::run();
+ TestCase11<R(A&&, A&&, ...) volatile &, 2, Q_Volatile>::run();
+ TestCase11<R(A&&, A&&, ...) const volatile &, 2, Q_CV>::run();
+ TestCase11<R() &&, 0, Q_None, /* RValue */ true>::run();
+ TestCase11<R() const &&, 0, Q_Const, /* RValue */ true>::run();
+ TestCase11<R() volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R() const volatile &&, 0, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(...) &&, 0, Q_None, /* RValue */ true>::run();
+ TestCase11<R(...) const &&, 0, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(...) volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(...) const volatile &&, 0, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&) &&, 1, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&) const &&, 1, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) &&, 1, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) const &&, 1, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) &&, 2, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) const &&, 2, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) &&, 2, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) const &&, 2, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) &&, 3, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) const &&, 3, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) &&, 3, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) const &&, 3, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
+
+ test_derived_from_ref_wrap();
+ test_reference_wrapper_reference_wrapper();
+#if TEST_STD_VER > 11
+ static_assert(test_derived_from_ref_wrap(), "");
+#endif
+#if TEST_STD_VER > 17
+ static_assert(test_reference_wrapper_reference_wrapper(), "");
+#endif
+#endif // TEST_STD_VER >= 11
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp
new file mode 100644
index 0000000000000..0df59290824bb
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp
@@ -0,0 +1,210 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME(EricWF): Make this test pass in C++03 with Clang once the transition
+// has gotten far enough that __invoke works.
+// XFAIL: c++03
+
+// <functional>
+
+// INVOKE (f, t1, t2, ..., tN)
+
+//------------------------------------------------------------------------------
+// TESTING INVOKE(f, t1, t2, ..., tN)
+// - Bullet 4 -- t1.*f
+// - Bullet 5 -- t1.get().*f // t1 is a reference wrapper.
+// - Bullet 6 -- (*t1).*f
+//
+// Overview:
+// Bullets 4, 5 and 6 handle the case where 'f' is a pointer to member object.
+// Bullet 4 only handles the cases where t1 is an object of type T or a
+// type derived from 'T'. Bullet 5 handles cases where 't1' is a reference_wrapper
+// and bullet 6 handles all other cases.
+//
+// Concerns:
+// 1) The return type is always an lvalue reference.
+// 2) The return type is not less cv-qualified that the object that contains it.
+// 3) The return type is not less cv-qualified than object type.
+// 4) The call object is perfectly forwarded.
+// 5) Classes that are publicly derived from 'T' are accepted as the call object
+// 6) All types that dereference to T or a type derived from T can be used
+// as the call object.
+// 7) Pointers to T or a type derived from T can be used as the call object.
+// 8) reference_wrapper's are properly unwrapped before invoking the function.
+
+#include <functional>
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+#include "invoke_helpers.h"
+
+template <class Tp>
+struct TestMemberObject {
+ TestMemberObject() : object() {}
+ Tp object;
+private:
+ TestMemberObject(TestMemberObject const&);
+ TestMemberObject& operator=(TestMemberObject const&);
+};
+
+template <class ObjectType>
+struct TestCase {
+ public:
+
+ static void run() { TestCase().doTest(); }
+
+private:
+ typedef TestMemberObject<ObjectType> TestType;
+
+ //==========================================================================
+ // TEST DISPATCH
+ void doTest() {
+ typedef DerivedFromType<TestType> Derived;
+ TestType obj;
+ TestType* obj_ptr = &obj;
+ Derived der;
+ Derived* der_ptr = &der;
+ DerefToType<TestType> dref;
+ DerefPropType<TestType> dref2;
+ std::reference_wrapper<TestType> rref(obj);
+ std::reference_wrapper<Derived> drref(der);
+
+ {
+ typedef ObjectType (TestType::*MemPtr);
+ typedef ObjectType E;
+ MemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
+#if TEST_STD_VER >= 11
+ runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
+ runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
+#endif
+ runTestNoPropDispatch<E>(M, dref, &dref.object.object);
+ }
+ {
+ typedef ObjectType const (TestType::*CMemPtr);
+ typedef ObjectType const E;
+ CMemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
+#if TEST_STD_VER >= 11
+ runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
+ runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
+#endif
+ runTestNoPropDispatch<E>(M, dref, &dref.object.object);
+ }
+ {
+ typedef ObjectType volatile (TestType::*VMemPtr);
+ typedef ObjectType volatile E;
+ VMemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
+#if TEST_STD_VER >= 11
+ runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
+ runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
+#endif
+ runTestNoPropDispatch<E>(M, dref, &dref.object.object);
+ }
+ {
+ typedef ObjectType const volatile (TestType::*CVMemPtr);
+ typedef ObjectType const volatile E;
+ CVMemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object);
+#if TEST_STD_VER >= 11
+ runTestPropCVDispatch<E>(M, rref, &(rref.get().object));
+ runTestPropCVDispatch<E>(M, drref, &(drref.get().object));
+#endif
+ runTestNoPropDispatch<E>(M, dref, &dref.object.object);
+ }
+ }
+
+ template <class Expect, class Fn, class T>
+ void runTestDispatch(Fn M, T& obj, ObjectType* expect) {
+ runTest<Expect &> (M, C_<T&>(obj), expect);
+ runTest<Expect const&> (M, C_<T const&>(obj), expect);
+ runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect);
+ runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect);
+#if TEST_STD_VER >= 11
+ runTest<Expect&&> (M, C_<T&&>(obj), expect);
+ runTest<Expect const&&> (M, C_<T const&&>(obj), expect);
+ runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect);
+ runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect);
+#endif
+ }
+
+ template <class Expect, class Fn, class T>
+ void runTestPropCVDispatch(Fn M, T& obj, ObjectType* expect) {
+ runTest<Expect &> (M, obj, expect);
+ runTest<Expect const&> (M, makeConst(obj), expect);
+ runTest<Expect volatile&> (M, makeVolatile(obj), expect);
+ runTest<Expect const volatile&>(M, makeCV(obj), expect);
+ }
+
+ template <class Expect, class Fn, class T>
+ void runTestNoPropDispatch(Fn M, T& obj, ObjectType* expect) {
+ runTest<Expect&>(M, C_<T &>(obj), expect);
+ runTest<Expect&>(M, C_<T const&>(obj), expect);
+ runTest<Expect&>(M, C_<T volatile&>(obj), expect);
+ runTest<Expect&>(M, C_<T const volatile&>(obj), expect);
+#if TEST_STD_VER >= 11
+ runTest<Expect&>(M, C_<T&&>(obj), expect);
+ runTest<Expect&>(M, C_<T const&&>(obj), expect);
+ runTest<Expect&>(M, C_<T volatile&&>(obj), expect);
+ runTest<Expect&>(M, C_<T const volatile&&>(obj), expect);
+#endif
+ }
+
+ template <class Expect, class Fn, class T>
+ void runTest(Fn M, const T& obj, ObjectType* expect) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(M, obj)), Expect
+ >::value), "");
+ Expect e = std::__invoke(M, obj);
+ assert(&e == expect);
+ }
+
+ template <class Expect, class Fn, class T>
+#if TEST_STD_VER >= 11
+ void runTest(Fn M, T&& obj, ObjectType* expect) {
+#else
+ void runTest(Fn M, T& obj, ObjectType* expect ) {
+#endif
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(M, std::forward<T>(obj))), Expect
+ >::value), "");
+ Expect e = std::__invoke(M, std::forward<T>(obj));
+ assert(&e == expect);
+ }
+ }
+};
+
+int main(int, char**) {
+ TestCase<ArgType>::run();
+ TestCase<ArgType const>::run();
+ TestCase<ArgType volatile>::run();
+ TestCase<ArgType const volatile>::run();
+ TestCase<ArgType*>::run();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp
new file mode 100644
index 0000000000000..fb789fa0a86cc
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/bullet_7.pass.cpp
@@ -0,0 +1,328 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// INVOKE (f, t1, t2, ..., tN)
+
+//------------------------------------------------------------------------------
+// TESTING INVOKE(f, t1, t2, ..., tN)
+// - Bullet 7 -- f(t2, ..., tN)
+//
+// Overview:
+// Bullet 7 handles the cases where the first argument is not a member
+// function.
+//
+// Concerns:
+// 1) Different types of callable objects are supported. Including
+// 1a) Free Function pointers and references.
+// 1b) Classes which provide a call operator
+// 1c) lambdas
+// 2) The callable objects are perfect forwarded.
+// 3) The arguments are perfect forwarded.
+// 4) Signatures which include varargs are supported.
+// 5) In C++03 3 extra arguments should be allowed.
+//
+// Plan:
+// 1) Define a set of free functions, 'SF', and class types with call
+// operators, 'SC', that address concerns 4 and 5. The free functions should
+// return 'FunctionID::setUncheckedCall()' and the call operators should
+// return 'MethodID::setUncheckedCall()'.
+//
+// 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f'
+// using the correct number of arguments and cv-ref qualifiers. Check that
+// 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free
+// function and 'MethodID::checkCall()' otherwise.
+
+
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "invoke_helpers.h"
+
+
+//==============================================================================
+// freeFunction03 - A C++03 free function.
+void*& freeFunction03() {
+ return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall();
+}
+
+void*& freeFunction03(...) {
+ return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0>
+void*& freeFunction03(A0&) {
+ return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall();
+}
+
+
+template <class A0>
+void*& freeFunction03(A0&, ...) {
+ return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0, class A1>
+void*& freeFunction03(A0&, A1&) {
+ return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall();
+}
+
+
+template <class A0, class A1>
+void*& freeFunction03(A0&, A1&, ...) {
+ return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0, class A1, class A2>
+void*& freeFunction03(A0&, A1&, A2&) {
+ return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0, class A1, class A2>
+void*& freeFunction03(A0&, A1&, A2&, ...) {
+ return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall();
+}
+
+//==============================================================================
+// Functor03 - C++03 compatible functor object
+struct Functor03 {
+ typedef void*& R;
+ typedef Functor03 C;
+#define F(Args, ...) \
+ __VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \
+ __VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \
+ __VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \
+ __VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); }
+#
+ F(())
+ F((A0&), template <class A0>)
+ F((A0&, A1&), template <class A0, class A1>)
+ F((A0&, A1&, A2&), template <class A0, class A1, class A2>)
+#undef F
+public:
+ Functor03() {}
+private:
+ Functor03(Functor03 const&);
+ Functor03& operator=(Functor03 const&);
+};
+
+
+#if TEST_STD_VER >= 11
+
+//==============================================================================
+// freeFunction11 - A C++11 free function.
+template <class ...Args>
+void*& freeFunction11(Args&&...) {
+ return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall();
+}
+
+template <class ...Args>
+void*& freeFunction11(Args&&...,...) {
+ return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall();
+}
+
+//==============================================================================
+// Functor11 - C++11 reference qualified test member functions.
+struct Functor11 {
+ typedef void*& R;
+ typedef Functor11 C;
+
+#define F(CV) \
+ template <class ...Args> \
+ R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); }
+#
+ F(&)
+ F(const &)
+ F(volatile &)
+ F(const volatile &)
+ F(&&)
+ F(const &&)
+ F(volatile &&)
+ F(const volatile &&)
+#undef F
+public:
+ Functor11() {}
+private:
+ Functor11(Functor11 const&);
+ Functor11& operator=(Functor11 const&);
+};
+
+#endif // TEST_STD_VER >= 11
+
+
+//==============================================================================
+// TestCaseFunctorImp - A test case for an operator() class method.
+// ClassType - The type of the call object.
+// CallSig - The function signature of the call operator being tested.
+// Arity - the arity of 'CallSig'
+// ObjCaster - Transformation function applied to call object.
+// ArgCaster - Transformation function applied to the extra arguments.
+template <class ClassType, class CallSig, int Arity,
+ class ObjCaster, class ArgCaster = LValueCaster>
+struct TestCaseFunctorImp {
+public:
+ static void run() {
+ typedef MethodID<CallSig ClassType::*> MID;
+ BasicTest<MID, Arity, ObjCaster, ArgCaster> t;
+ typedef ClassType T;
+ typedef DerivedFromType<T> D;
+ T obj;
+ D der;
+ t.runTest(obj);
+ t.runTest(der);
+ }
+};
+
+//==============================================================================
+// TestCaseFreeFunction - A test case for a free function.
+// CallSig - The function signature of the free function being tested.
+// FnPtr - The function being tested.
+// Arity - the arity of 'CallSig'
+// ArgCaster - Transformation function to be applied to the extra arguments.
+template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster>
+struct TestCaseFreeFunction {
+public:
+ static void run() {
+ typedef FunctionPtrID<CallSig, FnPtr> FID;
+ BasicTest<FID, Arity, LValueCaster, ArgCaster> t;
+
+ DerefToType<CallSig*> deref_to(FnPtr);
+ DerefToType<CallSig&> deref_to_ref(*FnPtr);
+
+ t.runTest(FnPtr);
+ t.runTest(*FnPtr);
+ t.runTest(deref_to);
+ t.runTest(deref_to_ref);
+ }
+};
+
+//==============================================================================
+// runTest Helpers
+//==============================================================================
+#if TEST_STD_VER >= 11
+template <class Sig, int Arity, class ArgCaster>
+void runFunctionTestCase11() {
+ TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>();
+}
+#endif
+
+template <class Sig, int Arity, class ArgCaster>
+void runFunctionTestCase() {
+ TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>();
+#if TEST_STD_VER >= 11
+ runFunctionTestCase11<Sig, Arity, ArgCaster>();
+#endif
+}
+
+template <class Sig, int Arity, class ObjCaster, class ArgCaster>
+void runFunctorTestCase() {
+ TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run();
+}
+
+template <class Sig, int Arity, class ObjCaster>
+void runFunctorTestCase() {
+ TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run();
+}
+
+#if TEST_STD_VER >= 11
+// runTestCase - Run a test case for C++11 class functor types
+template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster>
+void runFunctorTestCase11() {
+ TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run();
+}
+#endif
+
+// runTestCase - Run a test case for both function and functor types.
+template <class Sig, int Arity, class ArgCaster>
+void runTestCase() {
+ runFunctionTestCase<Sig, Arity, ArgCaster>();
+ runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>();
+};
+
+int main(int, char**) {
+ typedef void*& R;
+ typedef ArgType A;
+ typedef A const CA;
+
+ runTestCase< R(), 0, LValueCaster >();
+ runTestCase< R(A&), 1, LValueCaster >();
+ runTestCase< R(A&, A&), 2, LValueCaster >();
+ runTestCase< R(A&, A&, A&), 3, LValueCaster >();
+ runTestCase< R(CA&), 1, ConstCaster >();
+ runTestCase< R(CA&, CA&), 2, ConstCaster >();
+ runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >();
+
+ runFunctionTestCase<R(...), 0, LValueCaster >();
+ runFunctionTestCase<R(A&, ...), 1, LValueCaster >();
+ runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >();
+ runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >();
+
+#if TEST_STD_VER >= 11
+ runFunctionTestCase11<R(A&&), 1, MoveCaster >();
+ runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >();
+#endif
+
+ runFunctorTestCase<R(), 0, LValueCaster >();
+ runFunctorTestCase<R() const, 0, ConstCaster >();
+ runFunctorTestCase<R() volatile, 0, VolatileCaster >();
+ runFunctorTestCase<R() const volatile, 0, CVCaster >();
+ runFunctorTestCase<R(A&), 1, LValueCaster >();
+ runFunctorTestCase<R(A&) const, 1, ConstCaster >();
+ runFunctorTestCase<R(A&) volatile, 1, VolatileCaster >();
+ runFunctorTestCase<R(A&) const volatile, 1, CVCaster >();
+ runFunctorTestCase<R(A&, A&), 2, LValueCaster >();
+ runFunctorTestCase<R(A&, A&) const, 2, ConstCaster >();
+ runFunctorTestCase<R(A&, A&) volatile, 2, VolatileCaster >();
+ runFunctorTestCase<R(A&, A&) const volatile, 2, CVCaster >();
+ runFunctorTestCase<R(A&, A&, A&), 3, LValueCaster >();
+ runFunctorTestCase<R(A&, A&, A&) const, 3, ConstCaster >();
+ runFunctorTestCase<R(A&, A&, A&) volatile, 3, VolatileCaster >();
+ runFunctorTestCase<R(A&, A&, A&) const volatile, 3, CVCaster >();
+ {
+ typedef ConstCaster CC;
+ runFunctorTestCase<R(CA&), 1, LValueCaster, CC>();
+ runFunctorTestCase<R(CA&) const, 1, ConstCaster, CC>();
+ runFunctorTestCase<R(CA&) volatile, 1, VolatileCaster, CC>();
+ runFunctorTestCase<R(CA&) const volatile, 1, CVCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&), 2, LValueCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&) const, 2, ConstCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&) volatile, 2, VolatileCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&) const volatile, 2, CVCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&), 3, LValueCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&) const, 3, ConstCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&) volatile, 3, VolatileCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>();
+ }
+
+#if TEST_STD_VER >= 11
+ runFunctorTestCase11<R() &, 0, LValueCaster >();
+ runFunctorTestCase11<R() const &, 0, ConstCaster >();
+ runFunctorTestCase11<R() volatile &, 0, VolatileCaster >();
+ runFunctorTestCase11<R() const volatile &, 0, CVCaster >();
+ runFunctorTestCase11<R() &&, 0, MoveCaster >();
+ runFunctorTestCase11<R() const &&, 0, MoveConstCaster >();
+ runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >();
+ runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >();
+ {
+ typedef MoveCaster MC;
+ runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>();
+ runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>();
+ runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>();
+ runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>();
+ runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>();
+ runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>();
+ runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>();
+ runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>();
+ }
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.cpp
new file mode 100644
index 0000000000000..e534553a87f04
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// [func.require]
+
+#include <type_traits>
+#include <functional>
+
+#include "test_macros.h"
+
+template <typename T, int N>
+struct Array
+{
+ typedef T type[N];
+};
+
+struct Type
+{
+ Array<char, 1>::type& f1();
+ Array<char, 2>::type& f2() const;
+#if TEST_STD_VER >= 11
+ Array<char, 1>::type& g1() &;
+ Array<char, 2>::type& g2() const &;
+ Array<char, 3>::type& g3() &&;
+ Array<char, 4>::type& g4() const &&;
+#endif
+};
+
+int main(int, char**)
+{
+ static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, "");
+ static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, "");
+#if TEST_STD_VER >= 11
+ static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, "");
+ static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, "");
+ static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, "");
+ static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h
new file mode 100644
index 0000000000000..f6f418b51c489
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.require/invoke_helpers.h
@@ -0,0 +1,375 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 INVOKE_HELPERS_H
+#define INVOKE_HELPERS_H
+
+#include <type_traits>
+#include <cassert>
+#include <functional>
+
+#include "test_macros.h"
+
+template <int I>
+struct Int : public std::integral_constant<int, I> {};
+
+template <bool P>
+struct Bool : public std::integral_constant<bool, P> {};
+
+struct Q_None {
+ template <class T>
+ struct apply { typedef T type; };
+};
+
+struct Q_Const {
+ template <class T>
+ struct apply { typedef T const type; };
+};
+
+struct Q_Volatile {
+ template <class T>
+ struct apply { typedef T volatile type; };
+};
+
+struct Q_CV {
+ template <class T>
+ struct apply { typedef T const volatile type; };
+};
+
+// Caster - A functor object that performs cv-qualifier and value category
+// conversions.
+// QualTag - A metafunction type that applies cv-qualifiers to its argument.
+// RValue - True if the resulting object should be an RValue reference.
+// False otherwise.
+template <class QualTag, bool RValue = false>
+struct Caster {
+ template <class T>
+ struct apply {
+ typedef typename std::remove_reference<T>::type RawType;
+ typedef typename QualTag::template apply<RawType>::type CVType;
+#if TEST_STD_VER >= 11
+ typedef typename std::conditional<RValue,
+ CVType&&, CVType&
+ >::type type;
+#else
+ typedef CVType& type;
+#endif
+ };
+
+ template <class T>
+ typename apply<T>::type
+ operator()(T& obj) const {
+ typedef typename apply<T>::type OutType;
+ return static_cast<OutType>(obj);
+ }
+};
+
+typedef Caster<Q_None> LValueCaster;
+typedef Caster<Q_Const> ConstCaster;
+typedef Caster<Q_Volatile> VolatileCaster;
+typedef Caster<Q_CV> CVCaster;
+typedef Caster<Q_None, true> MoveCaster;
+typedef Caster<Q_Const, true> MoveConstCaster;
+typedef Caster<Q_Volatile, true> MoveVolatileCaster;
+typedef Caster<Q_CV, true> MoveCVCaster;
+
+
+template <class Tp>
+Tp const& makeConst(Tp& ref) { return ref; }
+
+template <class Tp>
+Tp const* makeConst(Tp* ptr) { return ptr; }
+
+template <class Tp>
+std::reference_wrapper<const Tp> makeConst(std::reference_wrapper<Tp>& ref) {
+ return std::reference_wrapper<const Tp>(ref.get());
+}
+
+template <class Tp>
+Tp volatile& makeVolatile(Tp& ref) { return ref; }
+
+template <class Tp>
+Tp volatile* makeVolatile(Tp* ptr) { return ptr; }
+
+template <class Tp>
+std::reference_wrapper<volatile Tp> makeVolatile(std::reference_wrapper<Tp>& ref) {
+ return std::reference_wrapper<volatile Tp>(ref.get());
+}
+
+template <class Tp>
+Tp const volatile& makeCV(Tp& ref) { return ref; }
+
+template <class Tp>
+Tp const volatile* makeCV(Tp* ptr) { return ptr; }
+
+template <class Tp>
+std::reference_wrapper<const volatile Tp> makeCV(std::reference_wrapper<Tp>& ref) {
+ return std::reference_wrapper<const volatile Tp>(ref.get());
+}
+
+// A shorter name for 'static_cast'
+template <class QualType, class Tp>
+QualType C_(Tp& v) { return static_cast<QualType>(v); };
+
+//==============================================================================
+// ArgType - A non-copyable type intended to be used as a dummy argument type
+// to test functions.
+struct ArgType {
+ int value;
+ explicit ArgType(int val = 0) : value(val) {}
+private:
+ ArgType(ArgType const&);
+ ArgType& operator=(ArgType const&);
+};
+
+//==============================================================================
+// DerivedFromBase - A type that derives from its template argument 'Base'
+template <class Base>
+struct DerivedFromType : public Base {
+ DerivedFromType() : Base() {}
+ template <class Tp>
+ explicit DerivedFromType(Tp const& t) : Base(t) {}
+};
+
+//==============================================================================
+// DerefToType - A type that dereferences to its template argument 'To'.
+// The cv-ref qualifiers of the 'DerefToType' object do not propagate
+// to the resulting 'To' object.
+template <class To>
+struct DerefToType {
+ To object;
+
+ DerefToType() {}
+
+ template <class Up>
+ explicit DerefToType(Up const& val) : object(val) {}
+
+ To& operator*() const volatile { return const_cast<To&>(object); }
+};
+
+//==============================================================================
+// DerefPropToType - A type that dereferences to its template argument 'To'.
+// The cv-ref qualifiers of the 'DerefPropToType' object propagate
+// to the resulting 'To' object.
+template <class To>
+struct DerefPropType {
+ To object;
+
+ DerefPropType() {}
+
+ template <class Up>
+ explicit DerefPropType(Up const& val) : object(val) {}
+
+#if TEST_STD_VER < 11
+ To& operator*() { return object; }
+ To const& operator*() const { return object; }
+ To volatile& operator*() volatile { return object; }
+ To const volatile& operator*() const volatile { return object; }
+#else
+ To& operator*() & { return object; }
+ To const& operator*() const & { return object; }
+ To volatile& operator*() volatile & { return object; }
+ To const volatile& operator*() const volatile & { return object; }
+ To&& operator*() && { return static_cast<To &&>(object); }
+ To const&& operator*() const && { return static_cast<To const&&>(object); }
+ To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); }
+ To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); }
+#endif
+};
+
+//==============================================================================
+// MethodID - A type that uniquely identifies a member function for a class.
+// This type is used to communicate between the member functions being tested
+// and the tests invoking them.
+// - Test methods should call 'setUncheckedCall()' whenever they are invoked.
+// - Tests consume the unchecked call using checkCall(<return-value>)` to assert
+// that the method has been called and that the return value of `__invoke`
+// matches what the method actually returned.
+template <class T>
+struct MethodID {
+ typedef void* IDType;
+
+ static int dummy; // A dummy memory location.
+ static void* id; // The "ID" is the value of this pointer.
+ static bool unchecked_call; // Has a call happened that has not been checked.
+
+ static void*& setUncheckedCall() {
+ assert(unchecked_call == false);
+ unchecked_call = true;
+ return id;
+ }
+
+ static bool checkCalled(void*& return_value) {
+ bool old = unchecked_call;
+ unchecked_call = false;
+ return old && id == return_value && &id == &return_value;
+ }
+};
+
+template <class T> int MethodID<T>::dummy = 0;
+template <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy;
+template <class T> bool MethodID<T>::unchecked_call = false;
+
+
+//==============================================================================
+// FunctionPtrID - Like MethodID but for free function pointers.
+template <class T, T*>
+struct FunctionPtrID {
+ static int dummy; // A dummy memory location.
+ static void* id; // The "ID" is the value of this pointer.
+ static bool unchecked_call; // Has a call happened that has not been checked.
+
+ static void*& setUncheckedCall() {
+ assert(unchecked_call == false);
+ unchecked_call = true;
+ return id;
+ }
+
+ static bool checkCalled(void*& return_value) {
+ bool old = unchecked_call;
+ unchecked_call = false;
+ return old && id == return_value && &id == &return_value;
+ }
+};
+
+template <class T, T* Ptr> int FunctionPtrID<T, Ptr>::dummy = 0;
+template <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy;
+template <class T, T* Ptr> bool FunctionPtrID<T, Ptr>::unchecked_call = false;
+
+//==============================================================================
+// BasicTest - The basic test structure for everything except
+// member object pointers.
+// ID - The "Function Identifier" type used either MethodID or FunctionPtrID.
+// Arity - The Arity of the call signature.
+// ObjectCaster - The object transformation functor type.
+// ArgCaster - The extra argument transformation functor type.
+template <class ID, int Arity, class ObjectCaster = LValueCaster,
+ class ArgCaster = LValueCaster>
+struct BasicTest {
+ template <class ObjectT>
+ void runTest(ObjectT& object) {
+ Int<Arity> A;
+ runTestImp(A, object);
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTest(MethodPtr ptr, ObjectT& object) {
+ Int<Arity> A;
+ runTestImp(A, ptr, object);
+ }
+
+private:
+ typedef void*& CallRet;
+ ObjectCaster object_cast;
+ ArgCaster arg_cast;
+ ArgType a0, a1, a2;
+
+ //==========================================================================
+ // BULLET 1, 2 AND 3 TEST METHODS
+ //==========================================================================
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object));
+ assert(ID::checkCalled(ret));
+ }
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0));
+ assert(ID::checkCalled(ret));
+ }
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
+ assert(ID::checkCalled(ret));
+ }
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
+ assert(ID::checkCalled(ret));
+ }
+ }
+
+ //==========================================================================
+ // BULLET 7 TEST METHODS
+ //==========================================================================
+ template <class ObjectT>
+ void runTestImp(Int<0>, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object));
+ assert(ID::checkCalled(ret));
+ }
+ }
+
+ template <class ObjectT>
+ void runTestImp(Int<1>, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object), arg_cast(a0)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0));
+ assert(ID::checkCalled(ret));
+ }
+ }
+
+ template <class ObjectT>
+ void runTestImp(Int<2>, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1));
+ assert(ID::checkCalled(ret));
+ }
+ }
+
+ template <class ObjectT>
+ void runTestImp(Int<3>, ObjectT& object) {
+ {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
+ assert(ID::checkCalled(ret));
+ }
+ }
+};
+
+#endif // INVOKE_HELPERS_H
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/move_reentrant.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/move_reentrant.pass.cpp
new file mode 100644
index 0000000000000..acf224e6b7d44
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/move_reentrant.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
+
+// <functional>
+
+// class function<R(ArgTypes...)>
+
+// function& operator=(function &&);
+
+#include <functional>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct A
+{
+ static std::function<void()> global;
+ static bool cancel;
+
+ A() = default;
+ A(const A&) = default;
+ A& operator=(const A&) = default;
+ ~A() {
+ DoNotOptimize(cancel);
+ if (cancel)
+ global = std::function<void()>(nullptr);
+ }
+ void operator()() {}
+};
+
+std::function<void()> A::global;
+bool A::cancel = false;
+
+int main(int, char**)
+{
+ A::global = A();
+ RTTI_ASSERT(A::global.target<A>());
+
+ // Check that we don't recurse in A::~A().
+ A::cancel = true;
+ A::global = std::function<void()>(nullptr);
+ RTTI_ASSERT(!A::global.target<A>());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign_reentrant.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign_reentrant.pass.cpp
new file mode 100644
index 0000000000000..83c342b1a5e66
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign_reentrant.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
+
+// <functional>
+
+// class function<R(ArgTypes...)>
+
+// function& operator=(nullptr_t);
+
+#include <functional>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct A
+{
+ static std::function<void()> global;
+ static bool cancel;
+
+ A() = default;
+ A(const A&) = default;
+ A& operator=(const A&) = default;
+ ~A() {
+ DoNotOptimize(cancel);
+ if (cancel)
+ global = nullptr;
+ }
+ void operator()() {}
+};
+
+std::function<void()> A::global;
+bool A::cancel = false;
+
+int main(int, char**)
+{
+ A::global = A();
+ RTTI_ASSERT(A::global.target<A>());
+
+ // Check that we don't recurse in A::~A().
+ A::cancel = true;
+ A::global = nullptr;
+ RTTI_ASSERT(!A::global.target<A>());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/refwrap/binary.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/binary.pass.cpp
new file mode 100644
index 0000000000000..f14359f54a4fb
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/binary.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: c++03 || c++11 || c++14
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+// <functional>
+
+// reference_wrapper
+
+// check for deriving from binary_function
+
+#include <functional>
+#include <type_traits>
+
+#include "test_macros.h"
+
+class functor1
+ : public std::unary_function<int, char>
+{
+};
+
+class functor2
+ : public std::binary_function<char, int, double>
+{
+};
+
+class functor3
+ : public std::unary_function<int, int>,
+ public std::binary_function<char, int, double>
+{
+public:
+ typedef float result_type;
+};
+
+class functor4
+ : public std::unary_function<int, int>,
+ public std::binary_function<char, int, double>
+{
+public:
+};
+
+struct C
+{
+ typedef int argument_type;
+ typedef int result_type;
+};
+
+int main(int, char**)
+{
+ static_assert((!std::is_base_of<std::binary_function<int, char, int>,
+ std::reference_wrapper<functor1> >::value), "");
+ static_assert((std::is_base_of<std::binary_function<char, int, double>,
+ std::reference_wrapper<functor2> >::value), "");
+ static_assert((std::is_base_of<std::binary_function<char, int, double>,
+ std::reference_wrapper<functor3> >::value), "");
+ static_assert((std::is_base_of<std::binary_function<char, int, double>,
+ std::reference_wrapper<functor4> >::value), "");
+ static_assert((!std::is_base_of<std::binary_function<int, int, int>,
+ std::reference_wrapper<C> >::value), "");
+ static_assert((!std::is_base_of<std::binary_function<int, int, float>,
+ std::reference_wrapper<float ()> >::value), "");
+ static_assert((!std::is_base_of<std::binary_function<int, int, float>,
+ std::reference_wrapper<float (int)> >::value), "");
+ static_assert((std::is_base_of<std::binary_function<int, int, float>,
+ std::reference_wrapper<float (int, int)> >::value), "");
+ static_assert((!std::is_base_of<std::binary_function<int, int, float>,
+ std::reference_wrapper<float(*)()> >::value), "");
+ static_assert((!std::is_base_of<std::binary_function<int, int, float>,
+ std::reference_wrapper<float(*)(int)> >::value), "");
+ static_assert((std::is_base_of<std::binary_function<int, int, float>,
+ std::reference_wrapper<float(*)(int, int)> >::value), "");
+ static_assert((!std::is_base_of<std::binary_function<C*, int, float>,
+ std::reference_wrapper<float(C::*)()> >::value), "");
+ static_assert((std::is_base_of<std::binary_function<C*, int, float>,
+ std::reference_wrapper<float(C::*)(int)> >::value), "");
+ static_assert((std::is_base_of<std::binary_function<const volatile C*, int, float>,
+ std::reference_wrapper<float(C::*)(int) const volatile> >::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp
new file mode 100644
index 0000000000000..1ce88feeadf28
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/desugars_to.compile.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
+
+// This test requires variable templates
+// UNSUPPORTED: gcc && c++11
+
+// <functional>
+
+// reference_wrapper
+
+// Ensure that std::reference_wrapper does not inhibit optimizations based on the
+// std::__desugars_to internal helper.
+
+#include <functional>
+#include <__type_traits/desugars_to.h>
+
+struct Operation {};
+struct Tag {};
+
+namespace std {
+template <>
+bool const __desugars_to_v<Tag, Operation> = true;
+}
+
+static_assert(std::__desugars_to_v<Tag, Operation>, "something is wrong with the test");
+
+// make sure we pass through reference_wrapper
+static_assert(std::__desugars_to_v<Tag, std::reference_wrapper<Operation> >, "");
+static_assert(std::__desugars_to_v<Tag, std::reference_wrapper<Operation const> >, "");
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.binary.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.binary.compile.pass.cpp
new file mode 100644
index 0000000000000..023ed8ddbfa37
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.binary.compile.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: msvc
+
+// ensure that binary_function always has the same ABI
+
+#include <functional>
+
+struct S1 : std::less<int>, std::greater<int> {};
+
+static_assert(sizeof(S1) == 2, "");
+
+struct S2 : std::less<int> { char c; };
+
+static_assert(sizeof(S2) == 1, "");
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.unary.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.unary.compile.pass.cpp
new file mode 100644
index 0000000000000..58b8dc5dc5377
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/layout.unary.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
+// UNSUPPORTED: msvc
+
+// ensure that unary_function always has the same ABI
+
+#include <functional>
+
+struct S1 : std::negate<int>, std::bit_not<int> {};
+
+static_assert(sizeof(S1) == 2, "");
+
+struct S2 : std::negate<int> { char c; };
+
+static_assert(sizeof(S2) == 1, "");
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/refwrap/unary.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/unary.pass.cpp
new file mode 100644
index 0000000000000..4d7ab16ec366f
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/refwrap/unary.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: c++03 || c++11 || c++14
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+// <functional>
+
+// reference_wrapper
+
+// check for deriving from unary_function
+
+#include <functional>
+#include <type_traits>
+
+#include "test_macros.h"
+
+class functor1
+ : public std::unary_function<int, char>
+{
+};
+
+class functor2
+ : public std::binary_function<char, int, double>
+{
+};
+
+class functor3
+ : public std::unary_function<int, int>,
+ public std::binary_function<char, int, double>
+{
+public:
+ typedef float result_type;
+};
+
+class functor4
+ : public std::unary_function<int, int>,
+ public std::binary_function<char, int, double>
+{
+public:
+};
+
+struct C
+{
+ typedef int argument_type;
+ typedef int result_type;
+};
+
+int main(int, char**)
+{
+ static_assert((std::is_base_of<std::unary_function<int, char>,
+ std::reference_wrapper<functor1> >::value), "");
+ static_assert((!std::is_base_of<std::unary_function<char, int>,
+ std::reference_wrapper<functor2> >::value), "");
+ static_assert((std::is_base_of<std::unary_function<int, int>,
+ std::reference_wrapper<functor3> >::value), "");
+ static_assert((std::is_base_of<std::unary_function<int, int>,
+ std::reference_wrapper<functor4> >::value), "");
+ static_assert((!std::is_base_of<std::unary_function<int, int>,
+ std::reference_wrapper<C> >::value), "");
+ static_assert((!std::is_base_of<std::unary_function<int, float>,
+ std::reference_wrapper<float(*)()> >::value), "");
+ static_assert((std::is_base_of<std::unary_function<int, float>,
+ std::reference_wrapper<float (int)> >::value), "");
+ static_assert((!std::is_base_of<std::unary_function<int, float>,
+ std::reference_wrapper<float (int, int)> >::value), "");
+ static_assert((std::is_base_of<std::unary_function<int, float>,
+ std::reference_wrapper<float(*)(int)> >::value), "");
+ static_assert((!std::is_base_of<std::unary_function<int, float>,
+ std::reference_wrapper<float(*)(int, int)> >::value), "");
+ static_assert((std::is_base_of<std::unary_function<C*, float>,
+ std::reference_wrapper<float(C::*)()> >::value), "");
+ static_assert((std::is_base_of<std::unary_function<const volatile C*, float>,
+ std::reference_wrapper<float(C::*)() const volatile> >::value), "");
+ static_assert((!std::is_base_of<std::unary_function<C*, float>,
+ std::reference_wrapper<float(C::*)(int)> >::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/function.objects/unord.hash/murmur2_or_cityhash_ubsan_unsigned_overflow_ignored.pass.cpp b/libcxx/test/libcxx-03/utilities/function.objects/unord.hash/murmur2_or_cityhash_ubsan_unsigned_overflow_ignored.pass.cpp
new file mode 100644
index 0000000000000..11f0724f990c8
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/function.objects/unord.hash/murmur2_or_cityhash_ubsan_unsigned_overflow_ignored.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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that UBSAN doesn't generate unsigned integer overflow diagnostics
+// from within the hashing internals.
+
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "test_macros.h"
+
+typedef std::__murmur2_or_cityhash<std::uint32_t> Hash32;
+typedef std::__murmur2_or_cityhash<std::uint64_t> Hash64;
+
+void test(const void* key, int len) {
+ for (int i=1; i <= len; ++i) {
+ Hash32 h1;
+ Hash64 h2;
+ DoNotOptimize(h1(key, i));
+ DoNotOptimize(h2(key, i));
+ }
+}
+
+int main(int, char**) {
+ const std::string TestCases[] = {
+ "abcdaoeuaoeclaoeoaeuaoeuaousaotehu]+}sthoasuthaoesutahoesutaohesutaoeusaoetuhasoetuhaoseutaoseuthaoesutaohes",
+ "00000000000000000000000000000000000000000000000000000000000000000000000",
+ "1237546895+54+4554985416849484213464984765465464654564565645645646546456546546"
+ };
+ const std::size_t NumCases = sizeof(TestCases)/sizeof(TestCases[0]);
+ for (std::size_t i=0; i < NumCases; ++i)
+ test(TestCases[i].data(), TestCases[i].length());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/intseq/for_each_index_sequence.pass.cpp b/libcxx/test/libcxx-03/utilities/intseq/for_each_index_sequence.pass.cpp
new file mode 100644
index 0000000000000..99345274da29e
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/intseq/for_each_index_sequence.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <utility>
+
+// inline constexpr auto __for_each_index_sequence = []<size_t... _Index>(index_sequence<_Index...>, auto __func)
+
+#include <utility>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+ int count = 0;
+ std::__for_each_index_sequence(std::make_index_sequence<8>(), [&]<std::size_t _Index> { count += _Index; });
+ assert(count == 28);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp b/libcxx/test/libcxx-03/utilities/is_pointer_in_range.pass.cpp
new file mode 100644
index 0000000000000..b0a27c79287d4
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/is_pointer_in_range.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__utility/is_pointer_in_range.h>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T, class U>
+TEST_CONSTEXPR_CXX14 void test_cv_quals() {
+ T i = 0;
+ U j = 0;
+ assert(!std::__is_pointer_in_range(&i, &i, &i));
+ assert(std::__is_pointer_in_range(&i, &i + 1, &i));
+ assert(!std::__is_pointer_in_range(&i, &i + 1, &j));
+
+#if TEST_STD_VER >= 20
+ {
+ T* arr1 = new int[4]{1, 2, 3, 4};
+ U* arr2 = new int[4]{5, 6, 7, 8};
+
+ assert(!std::__is_pointer_in_range(arr1, arr1 + 4, arr2));
+ assert(std::__is_pointer_in_range(arr1, arr1 + 4, arr1 + 3));
+ assert(!std::__is_pointer_in_range(arr1, arr1, arr1 + 3));
+
+ delete[] arr1;
+ delete[] arr2;
+ }
+#endif
+}
+
+TEST_CONSTEXPR_CXX14 bool test() {
+ test_cv_quals<int, int>();
+ test_cv_quals<const int, int>();
+ test_cv_quals<int, const int>();
+ test_cv_quals<const int, const int>();
+ test_cv_quals<volatile int, int>();
+ test_cv_quals<int, volatile int>();
+ test_cv_quals<volatile int, volatile int>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 14
+ static_assert(test(), "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp b/libcxx/test/libcxx-03/utilities/is_valid_range.pass.cpp
new file mode 100644
index 0000000000000..cb800aee5674b
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/is_valid_range.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__utility/is_valid_range.h>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T, class TQualified>
+TEST_CONSTEXPR_CXX14 void check_type() {
+ {
+ // We need to ensure that the addresses of i and j are ordered as &i < &j for
+ // the test below to work portably, so we define them in a struct.
+ struct {
+ T i = 0;
+ T j = 0;
+ } storage;
+ assert(std::__is_valid_range(static_cast<TQualified*>(&storage.i), static_cast<TQualified*>(&storage.i)));
+ assert(std::__is_valid_range(static_cast<TQualified*>(&storage.i), static_cast<TQualified*>(&storage.i + 1)));
+
+ assert(!std::__is_valid_range(static_cast<TQualified*>(&storage.j), static_cast<TQualified*>(&storage.i)));
+ assert(!std::__is_valid_range(static_cast<TQualified*>(&storage.i + 1), static_cast<TQualified*>(&storage.i)));
+
+ // We detect this as being a valid range even though it is not really valid.
+ assert(std::__is_valid_range(static_cast<TQualified*>(&storage.i), static_cast<TQualified*>(&storage.j)));
+ }
+
+ {
+ T arr[3] = {1, 2, 3};
+ assert(std::__is_valid_range(static_cast<TQualified*>(&arr[0]), static_cast<TQualified*>(&arr[0])));
+ assert(std::__is_valid_range(static_cast<TQualified*>(&arr[0]), static_cast<TQualified*>(&arr[1])));
+ assert(std::__is_valid_range(static_cast<TQualified*>(&arr[0]), static_cast<TQualified*>(&arr[2])));
+
+ assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[1]), static_cast<TQualified*>(&arr[0])));
+ assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[2]), static_cast<TQualified*>(&arr[0])));
+ }
+
+#if TEST_STD_VER >= 20
+ {
+ T* arr = new int[4]{1, 2, 3, 4};
+ assert(std::__is_valid_range(static_cast<TQualified*>(arr), static_cast<TQualified*>(arr + 4)));
+ delete[] arr;
+ }
+#endif
+}
+
+TEST_CONSTEXPR_CXX14 bool test() {
+ check_type<int, int>();
+ check_type<int, int const>();
+ check_type<int, int volatile>();
+ check_type<int, int const volatile>();
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 14
+ static_assert(test(), "");
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp
new file mode 100644
index 0000000000000..60ef98ae905d0
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address.pass.cpp
@@ -0,0 +1,159 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class T> constexpr T* __to_address(T* p) noexcept;
+// template <class Ptr> constexpr auto __to_address(const Ptr& p) noexcept;
+
+#include <memory>
+#include <cassert>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Irrelevant;
+
+struct P1 {
+ using element_type = Irrelevant;
+ TEST_CONSTEXPR explicit P1(int *p) : p_(p) { }
+ TEST_CONSTEXPR int *operator->() const { return p_; }
+ int *p_;
+};
+
+struct P2 {
+ using element_type = Irrelevant;
+ TEST_CONSTEXPR explicit P2(int *p) : p_(p) { }
+ TEST_CONSTEXPR P1 operator->() const { return p_; }
+ P1 p_;
+};
+
+struct P3 {
+ TEST_CONSTEXPR explicit P3(int *p) : p_(p) { }
+ int *p_;
+};
+
+template<>
+struct std::pointer_traits<P3> {
+ static TEST_CONSTEXPR int *to_address(const P3& p) { return p.p_; }
+};
+
+struct P4 {
+ TEST_CONSTEXPR explicit P4(int *p) : p_(p) { }
+ int *operator->() const; // should never be called
+ int *p_;
+};
+
+template<>
+struct std::pointer_traits<P4> {
+ static TEST_CONSTEXPR int *to_address(const P4& p) { return p.p_; }
+};
+
+struct P5 {
+ using element_type = Irrelevant;
+ int const* const& operator->() const;
+};
+
+struct P6 {};
+
+template<>
+struct std::pointer_traits<P6> {
+ static int const* const& to_address(const P6&);
+};
+
+// Taken from a build breakage caused in Clang
+namespace P7 {
+ template<typename T> struct CanProxy;
+ template<typename T>
+ struct CanQual {
+ CanProxy<T> operator->() const { return CanProxy<T>(); }
+ };
+ template<typename T>
+ struct CanProxy {
+ const CanProxy<T> *operator->() const { return nullptr; }
+ };
+} // namespace P7
+
+namespace P8 {
+ template<class T>
+ struct FancyPtrA {
+ using element_type = Irrelevant;
+ T *p_;
+ TEST_CONSTEXPR FancyPtrA(T *p) : p_(p) {}
+ T& operator*() const;
+ TEST_CONSTEXPR T *operator->() const { return p_; }
+ };
+ template<class T>
+ struct FancyPtrB {
+ T *p_;
+ TEST_CONSTEXPR FancyPtrB(T *p) : p_(p) {}
+ T& operator*() const;
+ };
+} // namespace P8
+
+template<class T>
+struct std::pointer_traits<P8::FancyPtrB<T> > {
+ static TEST_CONSTEXPR T *to_address(const P8::FancyPtrB<T>& p) { return p.p_; }
+};
+
+struct Incomplete;
+template<class T> struct Holder { T t; };
+
+
+TEST_CONSTEXPR_CXX14 bool test() {
+ int i = 0;
+ ASSERT_NOEXCEPT(std::__to_address(&i));
+ assert(std::__to_address(&i) == &i);
+ P1 p1(&i);
+ ASSERT_NOEXCEPT(std::__to_address(p1));
+ assert(std::__to_address(p1) == &i);
+ P2 p2(&i);
+ ASSERT_NOEXCEPT(std::__to_address(p2));
+ assert(std::__to_address(p2) == &i);
+ P3 p3(&i);
+ ASSERT_NOEXCEPT(std::__to_address(p3));
+ assert(std::__to_address(p3) == &i);
+ P4 p4(&i);
+ ASSERT_NOEXCEPT(std::__to_address(p4));
+ assert(std::__to_address(p4) == &i);
+
+ ASSERT_SAME_TYPE(decltype(std::__to_address(std::declval<int const*>())), int const*);
+ ASSERT_SAME_TYPE(decltype(std::__to_address(std::declval<P5>())), int const*);
+ ASSERT_SAME_TYPE(decltype(std::__to_address(std::declval<P6>())), int const*);
+
+ P7::CanQual<int>* p7 = nullptr;
+ assert(std::__to_address(p7) == nullptr);
+ ASSERT_SAME_TYPE(decltype(std::__to_address(p7)), P7::CanQual<int>*);
+
+ Holder<Incomplete> *p8_nil = nullptr; // for C++03 compatibility
+ P8::FancyPtrA<Holder<Incomplete> > p8a = p8_nil;
+ assert(std::__to_address(p8a) == p8_nil);
+ ASSERT_SAME_TYPE(decltype(std::__to_address(p8a)), decltype(p8_nil));
+
+ P8::FancyPtrB<Holder<Incomplete> > p8b = p8_nil;
+ assert(std::__to_address(p8b) == p8_nil);
+ ASSERT_SAME_TYPE(decltype(std::__to_address(p8b)), decltype(p8_nil));
+
+ int p9[2] = {};
+ assert(std::__to_address(p9) == p9);
+ ASSERT_SAME_TYPE(decltype(std::__to_address(p9)), int*);
+
+ const int p10[2] = {};
+ assert(std::__to_address(p10) == p10);
+ ASSERT_SAME_TYPE(decltype(std::__to_address(p10)), const int*);
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 14
+ static_assert(test(), "");
+#endif
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_funcptr.verify.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_funcptr.verify.cpp
new file mode 100644
index 0000000000000..02b1676055e7b
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_funcptr.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class T> constexpr T* __to_address(T* p) noexcept;
+// Mandates: T is not a function type.
+
+#include <memory>
+
+int (*pf)();
+
+void test() {
+ (void)std::__to_address(pf); // expected-error@*:* {{is a function type}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_function.verify.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_function.verify.cpp
new file mode 100644
index 0000000000000..b8825a181d37a
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_on_function.verify.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class T> constexpr T* __to_address(T* p) noexcept;
+// Mandates: T is not a function type.
+
+#include <memory>
+
+int f();
+
+void test() {
+ (void)std::__to_address(f); // expected-error@*:* {{is a function type}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp
new file mode 100644
index 0000000000000..5eed12d19c072
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class T> constexpr T* __to_address(T* p) noexcept;
+// template <class Ptr> constexpr auto __to_address(const Ptr& p) noexcept;
+
+#include <memory>
+
+#include <array>
+#include <cassert>
+#include <span>
+#include <string>
+#include <string_view>
+#include <valarray>
+#include <vector>
+#include "test_macros.h"
+
+template<class C>
+void test_container_iterators(C c)
+{
+ const C& cc = c;
+ assert(std::__to_address(c.begin()) == c.data());
+ assert(std::__to_address(c.end()) == c.data() + c.size());
+ assert(std::__to_address(cc.begin()) == cc.data());
+ assert(std::__to_address(cc.end()) == cc.data() + cc.size());
+}
+
+void test_valarray_iterators()
+{
+ std::valarray<int> v(100);
+ int *p = std::__to_address(std::begin(v));
+ int *q = std::__to_address(std::end(v));
+ assert(q - p == 100);
+}
+
+int main(int, char**) {
+ test_container_iterators(std::array<int, 3>());
+ test_container_iterators(std::vector<int>(3));
+ test_container_iterators(std::string("abc"));
+#if TEST_STD_VER >= 17
+ test_container_iterators(std::string_view("abc"));
+#endif
+#if TEST_STD_VER >= 20
+ test_container_iterators(std::span<const char>("abc"));
+#endif
+ test_valarray_iterators();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.const_eval.verify.cpp b/libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.const_eval.verify.cpp
new file mode 100644
index 0000000000000..d63018da7408a
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.const_eval.verify.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<size_t N, class T>
+// [[nodiscard]] constexpr T* assume_aligned(T* ptr);
+
+#include <memory>
+#include <cstddef>
+
+template <size_t Size>
+constexpr bool test() {
+ char data[1];
+
+ [[maybe_unused]] auto data1 = std::assume_aligned<Size>(data);
+
+ return true;
+}
+
+static_assert(test<2>());
+// expected-error at -1 {{static assertion expression is not an integral constant expression}}
+// expected-note@* {{alignment of the base pointee object (1 byte) is less than the asserted 2 bytes}}
+
+static_assert(test<4>());
+// expected-error at -1 {{static assertion expression is not an integral constant expression}}
+// expected-note@* {{alignment of the base pointee object (1 byte) is less than the asserted 4 bytes}}
+
+static_assert(test<8>());
+// expected-error at -1 {{static assertion expression is not an integral constant expression}}
+// expected-note@* {{alignment of the base pointee object (1 byte) is less than the asserted 8 bytes}}
+
+static_assert(test<16>());
+// expected-error at -1 {{static assertion expression is not an integral constant expression}}
+// expected-note@* {{alignment of the base pointee object (1 byte) is less than the asserted 16 bytes}}
+
+static_assert(test<32>());
+// expected-error at -1 {{static assertion expression is not an integral constant expression}}
+// expected-note@* {{alignment of the base pointee object (1 byte) is less than the asserted 32 bytes}}
+
+static_assert(test<64>());
+// expected-error at -1 {{static assertion expression is not an integral constant expression}}
+// expected-note@* {{alignment of the base pointee object (1 byte) is less than the asserted 64 bytes}}
diff --git a/libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp b/libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
new file mode 100644
index 0000000000000..b206fe31ea196
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <memory>
+
+// template<size_t N, class T>
+// [[nodiscard]] constexpr T* assume_aligned(T* ptr);
+
+// This test checks that we static_assert inside std::assume_aligned<N>(p)
+// when N is not a power of two. However, Clang will already emit an error
+// in its own __builtin_assume_aligned, so we ignore that additional error
+// for the purpose of this test. We also ignore the additional warning about
+// remainder by 0 being undefined.
+// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error -Xclang -verify-ignore-unexpected=warning
+
+#include <memory>
+
+void f() {
+ int *p = nullptr;
+ (void)std::assume_aligned<0>(p); // expected-error@*:* {{std::assume_aligned<N>(p) requires N to be a power of two}}
+ (void)std::assume_aligned<3>(p); // expected-error@*:* {{std::assume_aligned<N>(p) requires N to be a power of two}}
+ (void)std::assume_aligned<5>(p); // expected-error@*:* {{std::assume_aligned<N>(p) requires N to be a power of two}}
+ (void)std::assume_aligned<33>(p); // expected-error@*:* {{std::assume_aligned<N>(p) requires N to be a power of two}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/util.smartptr/race_condition.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/race_condition.pass.cpp
new file mode 100644
index 0000000000000..cbecd2d1dc7ab
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/race_condition.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: no-threads
+//
+// <memory>
+//
+// class shared_ptr
+//
+// This test attempts to create a race condition surrounding use_count()
+// with the hope that TSAN will diagnose it.
+
+#include <memory>
+#include <atomic>
+#include <thread>
+#include <cassert>
+
+#include "make_test_thread.h"
+#include "test_macros.h"
+
+typedef std::shared_ptr<int> Ptr;
+typedef std::weak_ptr<int> WeakPtr;
+
+std::atomic_bool Start;
+std::atomic_bool KeepRunning;
+
+struct TestRunner {
+ TestRunner(Ptr xx) : x(xx) {}
+ void operator()() {
+ while (Start == false) {}
+ while (KeepRunning) {
+ // loop to prevent always checking the atomic.
+ for (int i=0; i < 100000; ++i) {
+ Ptr x2 = x; // increment shared count
+ WeakPtr x3 = x; // increment weak count
+ Ptr x4 = x3.lock(); // increment shared count via lock
+ WeakPtr x5 = x3; // increment weak count
+ }
+ }
+ }
+ Ptr x;
+};
+
+void run_test(Ptr p) {
+ Start = false;
+ KeepRunning = true;
+ assert(p.use_count() == 2);
+ TestRunner r(p);
+ assert(p.use_count() == 3);
+ std::thread t1 = support::make_test_thread(r); // Start the test thread.
+ assert(p.use_count() == 4);
+ Start = true;
+ // Run until we witness 25 use count changes via both
+ // shared and weak pointer methods.
+ WeakPtr w = p;
+ int shared_changes_count = 0;
+ int weak_changes_count = 0;
+ while (shared_changes_count < 25 && weak_changes_count < 25) {
+ // check use_count on the shared_ptr
+ int last = p.use_count();
+ int new_val = p.use_count();
+ assert(last >= 4);
+ assert(new_val >= 4);
+ if (last != new_val) ++shared_changes_count;
+ // Check use_count on the weak_ptr
+ last = w.use_count();
+ new_val = w.use_count();
+ assert(last >= 4);
+ assert(new_val >= 4);
+ if (last != new_val) ++weak_changes_count;
+ }
+ // kill the test thread.
+ KeepRunning = false;
+ t1.join();
+ assert(p.use_count() == 3);
+}
+
+int main(int, char**) {
+ {
+ // Test with out-of-place shared_count.
+ Ptr p(new int(42));
+ run_test(p);
+ assert(p.use_count() == 1);
+ }
+ {
+ // Test with in-place shared_count.
+ int val = 42;
+ Ptr p = std::make_shared<int>(val);
+ run_test(p);
+ assert(p.use_count() == 1);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.verify.cpp b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.verify.cpp
new file mode 100644
index 0000000000000..26ecfe66e3e4d
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.verify.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
+
+#include <memory>
+#include <cstddef>
+#include <type_traits>
+
+template <int> struct Tag {};
+
+template <int ID>
+using SPtr = std::shared_ptr<void(Tag<ID>)>;
+
+template <int ID>
+using FnType = void(Tag<ID>);
+
+template <int ID>
+void TestFn(Tag<ID>) {}
+
+template <int ID>
+FnType<ID>* getFn() {
+ return &TestFn<ID>;
+}
+
+struct Deleter {
+ template <class Tp>
+ void operator()(Tp) const {
+ using RawT = typename std::remove_pointer<Tp>::type;
+ static_assert(std::is_function<RawT>::value ||
+ std::is_same<typename std::remove_cv<RawT>::type,
+ std::nullptr_t>::value,
+ "");
+ }
+};
+
+int main(int, char**) {
+ {
+ SPtr<0> s; // OK
+ SPtr<1> s1(nullptr); // OK
+ SPtr<2> s2(getFn<2>(), Deleter{}); // OK
+ SPtr<3> s3(nullptr, Deleter{}); // OK
+ }
+
+ // expected-error-re@*:* {{static assertion failed{{.*}}default_delete cannot be instantiated for function types}}
+ std::default_delete<FnType<5>> deleter{}; // expected-note {{requested here}}
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/libcxx.control_block_layout.pass.cpp b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/libcxx.control_block_layout.pass.cpp
new file mode 100644
index 0000000000000..0b48bc92f02af
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/libcxx.control_block_layout.pass.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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-abi-no-compressed-pair-padding
+
+// This test makes sure that the control block implementation used for non-array
+// types in std::make_shared and std::allocate_shared is ABI compatible with the
+// original implementation.
+//
+// This test is relevant because the implementation of that control block is
+// different starting in C++20, a change that was required to implement P0674.
+
+#include <cassert>
+#include <cstddef>
+#include <memory>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include <string>
+#include <vector>
+
+#include "test_macros.h"
+
+struct value_init_tag {};
+
+template <class T, int _Idx, bool CanBeEmptyBase = std::is_empty<T>::value && !std::__libcpp_is_final<T>::value>
+struct compressed_pair_elem {
+ explicit compressed_pair_elem(value_init_tag) : value_() {}
+
+ template <class U>
+ explicit compressed_pair_elem(U&& u) : value_(std::forward<U>(u)) {}
+
+ T& get() { return value_; }
+
+private:
+ T value_;
+};
+
+template <class T, int _Idx>
+struct compressed_pair_elem<T, _Idx, true> : private T {
+ explicit compressed_pair_elem(value_init_tag) : T() {}
+
+ template <class U>
+ explicit compressed_pair_elem(U&& u) : T(std::forward<U>(u)) {}
+
+ T& get() { return *this; }
+};
+
+template <class T1, class T2>
+class compressed_pair : private compressed_pair_elem<T1, 0>, private compressed_pair_elem<T2, 1> {
+public:
+ using Base1 = compressed_pair_elem<T1, 0>;
+ using Base2 = compressed_pair_elem<T2, 1>;
+
+ template <class U1, class U2>
+ explicit compressed_pair(U1&& t1, U2&& t2) : Base1(std::forward<U1>(t1)), Base2(std::forward<U2>(t2)) {}
+
+ T1& first() { return static_cast<Base1&>(*this).get(); }
+ T2& second() { return static_cast<Base2&>(*this).get(); }
+};
+
+// This is the pre-C++20 implementation of the control block used by non-array
+// std::allocate_shared and std::make_shared. We keep it here so that we can
+// make sure our implementation is backwards compatible with it forever.
+//
+// Of course, the class and its methods were renamed, but the size and layout
+// of the class should remain the same as the original implementation.
+template <class T, class Alloc>
+struct OldEmplaceControlBlock : std::__shared_weak_count {
+ explicit OldEmplaceControlBlock(Alloc a) : data_(std::move(a), value_init_tag()) {}
+ T* get_elem() noexcept { return std::addressof(data_.second()); }
+ Alloc* get_alloc() noexcept { return std::addressof(data_.first()); }
+
+private:
+ virtual void __on_zero_shared() noexcept {
+ // Not implemented
+ }
+
+ virtual void __on_zero_shared_weak() noexcept {
+ // Not implemented
+ }
+
+ compressed_pair<Alloc, T> data_;
+};
+
+template <class T, template <class> class Alloc>
+void test() {
+ using Old = OldEmplaceControlBlock<T, Alloc<T>>;
+ using New = std::__shared_ptr_emplace<T, Alloc<T>>;
+
+ static_assert(sizeof(New) == sizeof(Old), "");
+ static_assert(alignof(New) == alignof(Old), "");
+
+ // Also make sure each member is at the same offset
+ Alloc<T> a;
+ Old old(a);
+ New new_(a);
+
+ // 1. Check the stored object
+ {
+ char const* old_elem = reinterpret_cast<char const*>(old.get_elem());
+ char const* new_elem = reinterpret_cast<char const*>(new_.__get_elem());
+ std::ptrdiff_t old_offset = old_elem - reinterpret_cast<char const*>(&old);
+ std::ptrdiff_t new_offset = new_elem - reinterpret_cast<char const*>(&new_);
+ assert(new_offset == old_offset && "offset of stored element changed");
+ }
+
+ // 2. Check the allocator
+ {
+ char const* old_alloc = reinterpret_cast<char const*>(old.get_alloc());
+ char const* new_alloc = reinterpret_cast<char const*>(new_.__get_alloc());
+ std::ptrdiff_t old_offset = old_alloc - reinterpret_cast<char const*>(&old);
+ std::ptrdiff_t new_offset = new_alloc - reinterpret_cast<char const*>(&new_);
+ assert(new_offset == old_offset && "offset of allocator changed");
+ }
+
+ // Make sure both types have the same triviality (that has ABI impact since
+ // it determined how objects are passed). Both should be non-trivial.
+ static_assert(std::is_trivially_copyable<New>::value == std::is_trivially_copyable<Old>::value, "");
+ static_assert(
+ std::is_trivially_default_constructible<New>::value == std::is_trivially_default_constructible<Old>::value, "");
+}
+
+// Object types to store in the control block
+struct TrivialEmptyType {};
+
+struct alignas(32) OveralignedEmptyType {};
+
+struct TrivialNonEmptyType {
+ char c[11];
+};
+
+struct FinalEmptyType final {};
+
+struct NonTrivialType {
+ char c[22];
+ NonTrivialType() : c{'x'} {}
+};
+
+struct VirtualFunctionType {
+ virtual ~VirtualFunctionType() {}
+};
+
+// Allocator types
+template <class T>
+struct TrivialEmptyAlloc {
+ using value_type = T;
+ TrivialEmptyAlloc() = default;
+ template <class U>
+ TrivialEmptyAlloc(TrivialEmptyAlloc<U>) {}
+ T* allocate(std::size_t) { return nullptr; }
+ void deallocate(T*, std::size_t) {}
+};
+
+template <class T>
+struct TrivialNonEmptyAlloc {
+ char storage[77];
+ using value_type = T;
+ TrivialNonEmptyAlloc() = default;
+ template <class U>
+ TrivialNonEmptyAlloc(TrivialNonEmptyAlloc<U>) {}
+ T* allocate(std::size_t) { return nullptr; }
+ void deallocate(T*, std::size_t) {}
+};
+
+template <class T>
+struct FinalEmptyAlloc final {
+ using value_type = T;
+ FinalEmptyAlloc() = default;
+ template <class U>
+ FinalEmptyAlloc(FinalEmptyAlloc<U>) {}
+ T* allocate(std::size_t) { return nullptr; }
+ void deallocate(T*, std::size_t) {}
+};
+
+template <class T>
+struct NonTrivialAlloc {
+ char storage[88];
+ using value_type = T;
+ NonTrivialAlloc() {}
+ template <class U>
+ NonTrivialAlloc(NonTrivialAlloc<U>) {}
+ T* allocate(std::size_t) { return nullptr; }
+ void deallocate(T*, std::size_t) {}
+};
+
+int main(int, char**) {
+ test<TrivialEmptyType, TrivialEmptyAlloc>();
+ test<TrivialEmptyType, TrivialNonEmptyAlloc>();
+ test<TrivialEmptyType, FinalEmptyAlloc>();
+ test<TrivialEmptyType, NonTrivialAlloc>();
+
+#if !defined(TEST_HAS_NO_ALIGNED_ALLOCATION)
+ test<OveralignedEmptyType, TrivialEmptyAlloc>();
+ test<OveralignedEmptyType, TrivialNonEmptyAlloc>();
+ test<OveralignedEmptyType, FinalEmptyAlloc>();
+ test<OveralignedEmptyType, NonTrivialAlloc>();
+#endif
+
+ test<TrivialNonEmptyType, TrivialEmptyAlloc>();
+ test<TrivialNonEmptyType, TrivialNonEmptyAlloc>();
+ test<TrivialNonEmptyType, FinalEmptyAlloc>();
+ test<TrivialNonEmptyType, NonTrivialAlloc>();
+
+ test<FinalEmptyType, TrivialEmptyAlloc>();
+ // FinalEmptyType combined with TrivialNonEmptyAlloc, FinalEmptyAlloc or NonTrivialAlloc is known to have an ABI break
+ // between LLVM 19 and LLVM 20. It's been deemed not severe enough to cause actual breakage.
+
+ test<NonTrivialType, TrivialEmptyAlloc>();
+ test<NonTrivialType, TrivialNonEmptyAlloc>();
+ test<NonTrivialType, FinalEmptyAlloc>();
+ test<NonTrivialType, NonTrivialAlloc>();
+
+ test<VirtualFunctionType, TrivialEmptyAlloc>();
+ test<VirtualFunctionType, TrivialNonEmptyAlloc>();
+ test<VirtualFunctionType, FinalEmptyAlloc>();
+ test<VirtualFunctionType, NonTrivialAlloc>();
+
+ // Test a few real world types just to make sure we didn't mess up badly somehow
+ test<std::string, std::allocator>();
+ test<int, std::allocator>();
+ test<std::vector<int>, std::allocator>();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.zero_size.compile.fail.cpp b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.zero_size.compile.fail.cpp
new file mode 100644
index 0000000000000..3c678d0e4d67d
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.zero_size.compile.fail.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
+
+// Make sure that std::allocate_shared<T[0]>(...) fails at compile-time.
+// While Clang and GCC appear to support T[0] as a language extension, that support is
+// unreliable (for example T[0] doesn't match a T[N] partial specialization on Clang as
+// of writing this). So instead, we make sure that this doesn't work at all with our
+// implementation.
+
+#include <memory>
+
+void f() {
+ auto p = std::allocate_shared<int[0]>(std::allocator<int[0]>());
+ (void)p;
+}
diff --git a/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.zero_size.compile.fail.cpp b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.zero_size.compile.fail.cpp
new file mode 100644
index 0000000000000..35964a52f6de2
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.zero_size.compile.fail.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
+
+// Make sure that std::make_shared<T[0]>(...) fails at compile-time.
+// While Clang and GCC appear to support T[0] as a language extension, that support is
+// unreliable (for example T[0] doesn't match a T[N] partial specialization on Clang as
+// of writing this). So instead, we make sure that this doesn't work at all with our
+// implementation.
+
+#include <memory>
+
+void f() {
+ auto p = std::make_shared<int[0]>();
+ (void)p;
+}
diff --git a/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp
new file mode 100644
index 0000000000000..0991de69b5baf
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/meta/is_referenceable.compile.pass.cpp
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// __is_referenceable_v<Tp>
+//
+// [defns.referenceable] defines "a referenceable type" as:
+// An object type, a function type that does not have cv-qualifiers
+// or a ref-qualifier, or a reference type.
+//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct Foo {};
+
+static_assert((!std::__is_referenceable_v<void>), "");
+static_assert((std::__is_referenceable_v<int>), "");
+static_assert((std::__is_referenceable_v<int[3]>), "");
+static_assert((std::__is_referenceable_v<int[]>), "");
+static_assert((std::__is_referenceable_v<int&>), "");
+static_assert((std::__is_referenceable_v<const int&>), "");
+static_assert((std::__is_referenceable_v<int*>), "");
+static_assert((std::__is_referenceable_v<const int*>), "");
+static_assert((std::__is_referenceable_v<Foo>), "");
+static_assert((std::__is_referenceable_v<const Foo>), "");
+static_assert((std::__is_referenceable_v<Foo&>), "");
+static_assert((std::__is_referenceable_v<const Foo&>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<Foo&&>), "");
+static_assert((std::__is_referenceable_v<const Foo&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<int __attribute__((__vector_size__(8)))>), "");
+static_assert((std::__is_referenceable_v<const int __attribute__((__vector_size__(8)))>), "");
+static_assert((std::__is_referenceable_v<float __attribute__((__vector_size__(16)))>), "");
+static_assert((std::__is_referenceable_v<const float __attribute__((__vector_size__(16)))>), "");
+
+// Functions without cv-qualifiers are referenceable
+static_assert((std::__is_referenceable_v<void()>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void() const>), "");
+static_assert((!std::__is_referenceable_v<void() &>), "");
+static_assert((!std::__is_referenceable_v<void() const&>), "");
+static_assert((!std::__is_referenceable_v<void() &&>), "");
+static_assert((!std::__is_referenceable_v<void() const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void(int)>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void(int) const>), "");
+static_assert((!std::__is_referenceable_v<void(int) &>), "");
+static_assert((!std::__is_referenceable_v<void(int) const&>), "");
+static_assert((!std::__is_referenceable_v<void(int) &&>), "");
+static_assert((!std::__is_referenceable_v<void(int) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void(int, float)>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void(int, float) const>), "");
+static_assert((!std::__is_referenceable_v<void(int, float) &>), "");
+static_assert((!std::__is_referenceable_v<void(int, float) const&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float) &&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void(int, float, Foo&)>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&) const>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&) &>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&) const&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&) &&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void(...)>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void(...) const>), "");
+static_assert((!std::__is_referenceable_v<void(...) &>), "");
+static_assert((!std::__is_referenceable_v<void(...) const&>), "");
+static_assert((!std::__is_referenceable_v<void(...) &&>), "");
+static_assert((!std::__is_referenceable_v<void(...) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void(int, ...)>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void(int, ...) const>), "");
+static_assert((!std::__is_referenceable_v<void(int, ...) &>), "");
+static_assert((!std::__is_referenceable_v<void(int, ...) const&>), "");
+static_assert((!std::__is_referenceable_v<void(int, ...) &&>), "");
+static_assert((!std::__is_referenceable_v<void(int, ...) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void(int, float, ...)>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void(int, float, ...) const>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, ...) &>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, ...) const&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, ...) &&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, ...) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void(int, float, Foo&, ...)>), "");
+#if TEST_STD_VER >= 11
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) const>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) &>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) const&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) &&>), "");
+static_assert((!std::__is_referenceable_v<void(int, float, Foo&, ...) const&&>), "");
+#endif
+
+// member functions with or without cv-qualifiers are referenceable
+static_assert((std::__is_referenceable_v<void (Foo::*)()>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)() const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)() &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)() const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)() &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)() const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void (Foo::*)(int)>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int) const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)(int) &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int) const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int) &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float)>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&)>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void (Foo::*)(...)>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(...) const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)(...) &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(...) const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(...) &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(...) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...)>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, ...) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...)>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, ...) const&&>), "");
+#endif
+
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...)>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) const>), "");
+#if TEST_STD_VER >= 11
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) &>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) const&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) &&>), "");
+static_assert((std::__is_referenceable_v<void (Foo::*)(int, float, Foo&, ...) const&&>), "");
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/meta/meta_base.pass.cpp b/libcxx/test/libcxx-03/utilities/meta/meta_base.pass.cpp
new file mode 100644
index 0000000000000..66c25b1d75638
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/meta/meta_base.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include "test_macros.h"
+
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__type_traits/conjunction.h>
+#include <__type_traits/disjunction.h>
+#include <__type_traits/is_valid_expansion.h>
+#include <__type_traits/negation.h>
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+struct Bomb;
+template <int N, class T = Bomb >
+struct BOOM {
+ using Explode = typename T::BOOMBOOM;
+};
+
+using True = std::true_type;
+using False = std::false_type;
+
+void test_if() {
+ ASSERT_SAME_TYPE(std::_If<true, int, long>, int);
+ ASSERT_SAME_TYPE(std::_If<false, int, long>, long);
+}
+
+void test_and() {
+ static_assert(std::_And<True>::value, "");
+ static_assert(!std::_And<False>::value, "");
+ static_assert(std::_And<True, True>::value, "");
+ static_assert(!std::_And<False, BOOM<1> >::value, "");
+ static_assert(!std::_And<True, True, True, False, BOOM<2> >::value, "");
+}
+
+void test_or() {
+ static_assert(std::_Or<True>::value, "");
+ static_assert(!std::_Or<False>::value, "");
+ static_assert(std::_Or<False, True>::value, "");
+ static_assert(std::_Or<True, std::_Not<BOOM<3> > >::value, "");
+ static_assert(!std::_Or<False, False>::value, "");
+ static_assert(std::_Or<True, BOOM<1> >::value, "");
+ static_assert(std::_Or<False, False, False, False, True, BOOM<2> >::value, "");
+}
+
+void test_combined() {
+ static_assert(std::_And<True, std::_Or<False, True, BOOM<4> > >::value, "");
+ static_assert(std::_And<True, std::_Or<False, True, BOOM<4> > >::value, "");
+ static_assert(std::_Not<std::_And<True, False, BOOM<5> > >::value, "");
+}
+
+struct MemberTest {
+ static int foo;
+ using type = long;
+
+ void func(int);
+};
+struct Empty {};
+struct MemberTest2 {
+ using foo = int;
+};
+template <class T>
+using HasFooData = decltype(T::foo);
+template <class T>
+using HasFooType = typename T::foo;
+
+template <class T, class U>
+using FuncCallable = decltype(std::declval<T>().func(std::declval<U>()));
+template <class T>
+using BadCheck = typename T::DOES_NOT_EXIST;
+
+void test_is_valid_trait() {
+ static_assert(std::_IsValidExpansion<HasFooData, MemberTest>::value, "");
+ static_assert(!std::_IsValidExpansion<HasFooType, MemberTest>::value, "");
+ static_assert(!std::_IsValidExpansion<HasFooData, MemberTest2>::value, "");
+ static_assert(std::_IsValidExpansion<HasFooType, MemberTest2>::value, "");
+ static_assert(std::_IsValidExpansion<FuncCallable, MemberTest, int>::value, "");
+ static_assert(!std::_IsValidExpansion<FuncCallable, MemberTest, void*>::value, "");
+}
+
+int main(int, char**) {
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_is_same.sh.cpp b/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_is_same.sh.cpp
new file mode 100644
index 0000000000000..cfd8adb52d854
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_is_same.sh.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a dummy feature that prevents this test from running by default.
+// REQUIRES: template-cost-testing
+
+// The table below compares the compile time and object size for each of the
+// variants listed in the RUN script.
+//
+// Impl Compile Time Object Size
+// -------------------------------------------
+// std::_IsSame: 689.634 ms 356 K
+// std::is_same: 8,129.180 ms 560 K
+//
+// RUN: %{cxx} %{flags} %{compile_flags} -c %s -o %S/orig.o -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17
+// RUN: %{cxx} %{flags} %{compile_flags} -c %s -o %S/new.o -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17 -DTEST_NEW
+
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "template_cost_testing.h"
+
+template <int N> struct Arg { enum { value = 1 }; };
+
+#ifdef TEST_NEW
+#define IS_SAME std::_IsSame
+#else
+#define IS_SAME std::is_same
+#endif
+
+#define TEST_CASE_NOP() IS_SAME < Arg< __COUNTER__ >, Arg < __COUNTER__ > >::value,
+#define TEST_CASE_TYPE() IS_SAME < Arg< __COUNTER__ >, Arg < __COUNTER__ > >,
+
+int sink(...);
+
+int x = sink(
+ REPEAT_10000(TEST_CASE_NOP)
+ REPEAT_10000(TEST_CASE_NOP) 42
+);
+
+void Foo( REPEAT_1000(TEST_CASE_TYPE) int) { }
+
+static_assert(__COUNTER__ > 10000, "");
+
+void escape() {
+
+sink(&x);
+sink(&Foo);
+}
diff --git a/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_metafunctions.sh.cpp b/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_metafunctions.sh.cpp
new file mode 100644
index 0000000000000..4815ce37b0883
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_metafunctions.sh.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 is a dummy feature that prevents this test from running by default.
+// REQUIRES: template-cost-testing
+
+// The table below compares the compile time and object size for each of the
+// variants listed in the RUN script.
+//
+// Impl Compile Time Object Size
+// -------------------------------------------
+// _And: 3,498.639 ms 158 M
+// __lazy_and: 10,138.982 ms 334 M
+// __and_: 14,181.851 ms 648 M
+//
+
+// RUN: %{cxx} %{flags} %{compile_flags} -c %s -o %S/new.o -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17
+// RUN: %{cxx} %{flags} %{compile_flags} -c %s -o %S/lazy.o -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17 -DTEST_LAZY_AND
+// RUN: %{cxx} %{flags} %{compile_flags} -c %s -o %S/std.o -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17 -DTEST_STD_AND
+
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "template_cost_testing.h"
+using std::true_type;
+using std::false_type;
+
+#define FALSE_T() std::false_type,
+#define TRUE_T() std::true_type,
+
+#ifdef TEST_LAZY_AND
+#define TEST_AND std::__lazy_and
+#define TEST_OR std::__lazy_or
+#elif defined(TEST_STD_AND)
+#define TEST_AND std::__and_
+#define TEST_OR std::__or_
+#else
+#define TEST_AND std::_And
+#define TEST_OR std::_Or
+#endif
+
+void sink(...);
+
+void Foo1(TEST_AND < REPEAT_1000(TRUE_T) true_type > t1) { sink(&t1); }
+void Foo2(TEST_AND < REPEAT_1000(TRUE_T) REPEAT_1000(TRUE_T) true_type > t2) { sink(&t2); }
+void Foo3(TEST_AND < REPEAT_1000(TRUE_T) true_type, false_type > t3) { sink(&t3); }
+void Foo4(TEST_AND < REPEAT_1000(TRUE_T) REPEAT_1000(TRUE_T) true_type, false_type > t4) { sink(&t4); }
+void Foo5(TEST_AND < false_type, REPEAT_1000(TRUE_T) true_type > t5) { sink(&t5); }
+void Foo6(TEST_AND < false_type, REPEAT_1000(TRUE_T) REPEAT_1000(TRUE_T) true_type > t6) { sink(&t6); }
+
+void escape() {
+
+sink(&Foo1);
+sink(&Foo2);
+sink(&Foo3);
+sink(&Foo4);
+sink(&Foo5);
+sink(&Foo6);
+}
diff --git a/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_variant_overloads_impl.sh.cpp b/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_variant_overloads_impl.sh.cpp
new file mode 100644
index 0000000000000..b0512325d4c2c
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/meta/stress_tests/stress_test_variant_overloads_impl.sh.cpp
@@ -0,0 +1,119 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 is a dummy feature that prevents this test from running by default.
+// REQUIRES: template-cost-testing
+
+// Test the cost of the mechanism used to create an overload set used by variant
+// to determine which alternative to construct.
+
+// The table below compares the compile time and object size for each of the
+// variants listed in the RUN script.
+//
+// Impl Compile Time Object Size
+// -----------------------------------------------------
+// flat: 959 ms 792 KiB
+// recursive: 23,444 ms 23,000 KiB
+// -----------------------------------------------------
+// variant_old: 16,894 ms 17,000 KiB
+// variant_new: 1,105 ms 828 KiB
+
+
+// RUN: %{cxx} %{flags} %{compile_flags} -std=c++17 -c %s \
+// RUN: -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -g \
+// RUN: -DTEST_NS=flat_impl -o %S/flat.o
+// RUN: %{cxx} %{flags} %{compile_flags} -std=c++17 -c %s \
+// RUN: -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -g \
+// RUN: -DTEST_NS=rec_impl -o %S/rec.o
+// RUN: %{cxx} %{flags} %{compile_flags} -std=c++17 -c %s \
+// RUN: -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -g \
+// RUN: -DTEST_NS=variant_impl -o %S/variant.o
+
+#include <type_traits>
+#include <tuple>
+#include <cassert>
+#include <variant>
+
+#include "test_macros.h"
+#include "template_cost_testing.h"
+
+template <std::size_t Idx>
+struct TestType {};
+
+template <class T>
+struct ID {
+ using type = T;
+};
+
+namespace flat_impl {
+
+struct OverloadBase { void operator()() const; };
+
+template <class Tp, std::size_t Idx>
+struct Overload {
+ auto operator()(Tp, Tp) const -> ID<Tp>;
+};
+
+template <class ...Bases>
+struct AllOverloads : OverloadBase, Bases... {};
+
+template <class IdxSeq>
+struct MakeOverloads;
+
+template <std::size_t ..._Idx>
+struct MakeOverloads<std::__tuple_indices<_Idx...> > {
+ template <class ...Types>
+ using Apply = AllOverloads<Overload<Types, _Idx>...>;
+};
+
+template <class ...Types>
+using Overloads = typename MakeOverloads<
+ std::__make_indices_imp<sizeof...(Types), 0> >::template Apply<Types...>;
+
+} // namespace flat_impl
+
+
+namespace rec_impl {
+
+template <class... Types> struct Overload;
+
+template <>
+struct Overload<> { void operator()() const; };
+
+template <class Tp, class... Types>
+struct Overload<Tp, Types...> : Overload<Types...> {
+ using Overload<Types...>::operator();
+ auto operator()(Tp, Tp) const -> ID<Tp>;
+};
+
+template <class... Types>
+using Overloads = Overload<Types...>;
+
+} // namespace rec_impl
+
+namespace variant_impl {
+ template <class ...Types>
+ using Overloads = std::__variant_detail::_MakeOverloads<Types...>;
+ } // namespace variant_impl
+
+#ifndef TEST_NS
+#error TEST_NS must be defined
+#endif
+
+#define TEST_TYPE() TestType< __COUNTER__ >,
+using T1 = TEST_NS::Overloads<REPEAT_1000(TEST_TYPE) TestType<1>, TestType<1>, int>;
+static_assert(__COUNTER__ >= 1000, "");
+
+void fn1(T1 x) { DoNotOptimize(&x); }
+void fn2(typename std::invoke_result_t<T1, int, int>::type x) { DoNotOptimize(&x); }
+
+int main(int, char**) {
+ DoNotOptimize(&fn1);
+ DoNotOptimize(&fn2);
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp b/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp
new file mode 100644
index 0000000000000..8693bb17089dc
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/no_destroy.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <__utility/no_destroy.h>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER > 17
+// Test constexpr-constructibility.
+constinit std::__no_destroy<int> nd_int_const(std::__uninitialized_tag{});
+#endif
+
+struct DestroyLast {
+ ~DestroyLast() { assert(*ptr == 5); }
+
+ int* ptr;
+} last;
+
+static std::__no_destroy<int> nd_int(5);
+
+int main(int, char**) {
+ last.ptr = &nd_int.__get();
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/block.objc.pass.mm b/libcxx/test/libcxx-03/utilities/optional/block.objc.pass.mm
new file mode 100644
index 0000000000000..e8ff3a4af5758
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/block.objc.pass.mm
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// REQUIRES: has-fblocks
+// ADDITIONAL_COMPILE_FLAGS: -fblocks
+
+// <optional>
+
+// This test makes sure that we can create a `std::optional` containing
+// an Objective-C++ block.
+
+#include <optional>
+#include <cassert>
+
+int main(int, char**)
+{
+ using Block = void (^)(void);
+ std::optional<Block> block;
+ assert(!block);
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp
new file mode 100644
index 0000000000000..9df3abb450a72
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/copy.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
+
+// <optional>
+
+// optional<T>& operator=(const optional<T>& rhs);
+
+#include <optional>
+#include <string>
+#include <type_traits>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X {};
+
+struct Y
+{
+ Y() = default;
+ Y& operator=(const Y&) { return *this; }
+};
+
+struct Z1
+{
+ Z1() = default;
+ Z1(Z1&&) = default;
+ Z1(const Z1&) = default;
+ Z1& operator=(Z1&&) = default;
+ Z1& operator=(const Z1&) = delete;
+};
+
+struct Z2
+{
+ Z2() = default;
+ Z2(Z2&&) = default;
+ Z2(const Z2&) = delete;
+ Z2& operator=(Z2&&) = default;
+ Z2& operator=(const Z2&) = default;
+};
+
+template <class T>
+constexpr bool
+test()
+{
+ optional<T> opt;
+ optional<T> opt2;
+ opt = opt2;
+ return true;
+}
+
+int main(int, char**)
+{
+ {
+ using T = int;
+ static_assert((std::is_trivially_copy_assignable<optional<T>>::value), "");
+ static_assert(test<T>(), "");
+ }
+ {
+ using T = X;
+ static_assert((std::is_trivially_copy_assignable<optional<T>>::value), "");
+ static_assert(test<T>(), "");
+ }
+ static_assert(!(std::is_trivially_copy_assignable<optional<Y>>::value), "");
+ static_assert(!(std::is_trivially_copy_assignable<optional<std::string>>::value), "");
+
+ static_assert(!(std::is_copy_assignable<optional<Z1>>::value), "");
+ static_assert(!(std::is_copy_assignable<optional<Z2>>::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/move.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
new file mode 100644
index 0000000000000..f0d7e68f54308
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.assign/move.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
+
+// <optional>
+
+// optional<T>& operator=(optional<T>&& rhs);
+
+#include <optional>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X {};
+
+struct Y
+{
+ Y() = default;
+ Y& operator=(Y&&) { return *this; }
+};
+
+struct Z1
+{
+ Z1() = default;
+ Z1(Z1&&) = default;
+ Z1& operator=(Z1&&) = delete;
+};
+
+struct Z2
+{
+ Z2() = default;
+ Z2(Z2&&) = delete;
+ Z2& operator=(Z2&&) = default;
+};
+
+template <class T>
+constexpr bool
+test()
+{
+ optional<T> opt;
+ optional<T> opt2;
+ opt = std::move(opt2);
+ return true;
+}
+
+int main(int, char**)
+{
+ {
+ using T = int;
+ static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
+ static_assert(test<T>(), "");
+ }
+ {
+ using T = X;
+ static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
+ static_assert(test<T>(), "");
+ }
+ static_assert(!(std::is_trivially_move_assignable<optional<Y>>::value), "");
+ static_assert(!(std::is_trivially_move_assignable<optional<std::string>>::value), "");
+
+ static_assert(!(std::is_move_assignable<optional<Z1>>::value), "");
+ static_assert(!(std::is_move_assignable<optional<Z2>>::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
new file mode 100644
index 0000000000000..38f611bbdfc5b
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <optional>
+
+// optional(const optional<T>& rhs);
+
+#include <optional>
+#include <string>
+#include <type_traits>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X {};
+
+struct Y
+{
+ Y() = default;
+ Y(const Y&) {}
+};
+
+struct Z
+{
+ Z() = default;
+ Z(Z&&) = delete;
+ Z(const Z&) = delete;
+ Z& operator=(Z&&) = delete;
+ Z& operator=(const Z&) = delete;
+};
+
+int main(int, char**)
+{
+ {
+ using T = int;
+ static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
+ constexpr optional<T> opt;
+ constexpr optional<T> opt2 = opt;
+ (void)opt2;
+ }
+ {
+ using T = X;
+ static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
+ constexpr optional<T> opt;
+ constexpr optional<T> opt2 = opt;
+ (void)opt2;
+ }
+ static_assert(!(std::is_trivially_copy_constructible<optional<Y>>::value), "");
+ static_assert(!(std::is_trivially_copy_constructible<optional<std::string>>::value), "");
+
+ static_assert(!(std::is_copy_constructible<optional<Z>>::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
new file mode 100644
index 0000000000000..76b7b9f3307b2
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <optional>
+
+// optional(optional<T>&& rhs);
+
+#include <optional>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+using std::optional;
+
+struct X {};
+
+struct Y
+{
+ Y() = default;
+ Y(Y&&) {}
+};
+
+struct Z
+{
+ Z() = default;
+ Z(Z&&) = delete;
+ Z(const Z&) = delete;
+ Z& operator=(Z&&) = delete;
+ Z& operator=(const Z&) = delete;
+};
+
+int main(int, char**)
+{
+ {
+ using T = int;
+ static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
+ constexpr optional<T> opt;
+ constexpr optional<T> opt2 = std::move(opt);
+ (void)opt2;
+ }
+ {
+ using T = X;
+ static_assert((std::is_trivially_copy_constructible<optional<T>>::value), "");
+ constexpr optional<T> opt;
+ constexpr optional<T> opt2 = std::move(opt);
+ (void)opt2;
+ }
+ static_assert(!(std::is_trivially_move_constructible<optional<Y>>::value), "");
+ static_assert(!(std::is_trivially_move_constructible<optional<std::string>>::value), "");
+
+ static_assert(!(std::is_move_constructible<optional<Z>>::value), "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.dereference.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.dereference.pass.cpp
new file mode 100644
index 0000000000000..31938b3f8fbaa
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.dereference.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
+//
+//===----------------------------------------------------------------------===//
+
+// <optional>
+
+// constexpr T& optional<T>::operator*() &;
+// constexpr T&& optional<T>::operator*() &&;
+// constexpr const T& optional<T>::operator*() const &;
+// constexpr T&& optional<T>::operator*() const &&;
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <optional>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ // &
+ {
+ std::optional<int> opt;
+ TEST_LIBCPP_ASSERT_FAILURE(*opt, "optional operator* called on a disengaged value");
+ }
+
+ // &&
+ {
+ std::optional<int> opt;
+ TEST_LIBCPP_ASSERT_FAILURE(*std::move(opt), "optional operator* called on a disengaged value");
+ }
+
+ // const &
+ {
+ const std::optional<int> opt;
+ TEST_LIBCPP_ASSERT_FAILURE(*opt, "optional operator* called on a disengaged value");
+ }
+
+ // const &&
+ {
+ const std::optional<int> opt;
+ TEST_LIBCPP_ASSERT_FAILURE(*std::move(opt), "optional operator* called on a disengaged value");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.pass.cpp
new file mode 100644
index 0000000000000..52009628327db
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.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
+//
+//===----------------------------------------------------------------------===//
+
+// <optional>
+
+// constexpr T* optional<T>::operator->();
+// constexpr const T* optional<T>::operator->() const;
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <optional>
+
+#include "check_assertion.h"
+
+struct X {
+ int test() const { return 3; }
+};
+
+int main(int, char**) {
+ {
+ std::optional<X> opt;
+ TEST_LIBCPP_ASSERT_FAILURE(opt->test(), "optional operator-> called on a disengaged value");
+ }
+
+ {
+ const std::optional<X> opt;
+ TEST_LIBCPP_ASSERT_FAILURE(opt->test(), "optional operator-> called on a disengaged value");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/optional_size.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional_size.pass.cpp
new file mode 100644
index 0000000000000..b928ed7432791
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/optional_size.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <optional>
+
+// template <class T> class optional;
+
+#include <optional>
+
+template <class T>
+struct type_with_bool {
+ T value;
+ bool has_value;
+};
+
+int main(int, char**) {
+ // Test that std::optional achieves the expected size. See https://llvm.org/PR61095.
+ static_assert(sizeof(std::optional<char>) == sizeof(type_with_bool<char>));
+ static_assert(sizeof(std::optional<int>) == sizeof(type_with_bool<int>));
+ static_assert(sizeof(std::optional<long>) == sizeof(type_with_bool<long>));
+ static_assert(sizeof(std::optional<std::size_t>) == sizeof(type_with_bool<std::size_t>));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/optional/optional.object/triviality.abi.pass.cpp b/libcxx/test/libcxx-03/utilities/optional/optional.object/triviality.abi.pass.cpp
new file mode 100644
index 0000000000000..7d868781ccafb
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/optional/optional.object/triviality.abi.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <optional>
+
+// This test asserts the triviality of special member functions of optional<T>
+// whenever T has these special member functions trivial. The goal of this test
+// is to make sure that we do not change the triviality of those, since that
+// constitutes an ABI break (small enough optionals would be passed by registers).
+//
+// constexpr optional(const optional& rhs);
+// constexpr optional(optional&& rhs) noexcept(see below);
+// constexpr optional<T>& operator=(const optional& rhs);
+// constexpr optional<T>& operator=(optional&& rhs) noexcept(see below);
+
+#include <optional>
+#include <type_traits>
+#include <cassert>
+
+#include "archetypes.h"
+
+#include "test_macros.h"
+
+template <class T>
+struct SpecialMemberTest {
+ using O = std::optional<T>;
+
+ static_assert(std::is_trivially_destructible_v<O> ==
+ std::is_trivially_destructible_v<T>,
+ "optional<T> is trivially destructible if and only if T is.");
+
+ static_assert(std::is_trivially_copy_constructible_v<O> ==
+ std::is_trivially_copy_constructible_v<T>,
+ "optional<T> is trivially copy constructible if and only if T is.");
+
+ static_assert(std::is_trivially_move_constructible_v<O> ==
+ std::is_trivially_move_constructible_v<T> ||
+ (!std::is_move_constructible_v<T> && std::is_trivially_copy_constructible_v<T>),
+ "optional<T> is trivially move constructible if T is trivially move constructible, "
+ "or if T is trivially copy constructible and is not move constructible.");
+
+ static_assert(std::is_trivially_copy_assignable_v<O> ==
+ (std::is_trivially_destructible_v<T> &&
+ std::is_trivially_copy_constructible_v<T> &&
+ std::is_trivially_copy_assignable_v<T>),
+ "optional<T> is trivially copy assignable if and only if T is trivially destructible, "
+ "trivially copy constructible, and trivially copy assignable.");
+
+ static_assert(std::is_trivially_move_assignable_v<O> ==
+ (std::is_trivially_destructible_v<T> &&
+ ((std::is_trivially_move_constructible_v<T> && std::is_trivially_move_assignable_v<T>) ||
+ ((!std::is_move_constructible_v<T> || !std::is_move_assignable_v<T>) &&
+ std::is_trivially_copy_constructible_v<T> && std::is_trivially_copy_assignable_v<T>))),
+ "optional<T> is trivially move assignable if T is trivially destructible, and either "
+ "(1) trivially move constructible and trivially move assignable, or "
+ "(2) not move constructible or not move assignable, and "
+ "trivially copy constructible and trivially copy assignable.");
+};
+
+template <class ...Args> static void sink(Args&&...) {}
+
+template <class ...TestTypes>
+struct DoTestsMetafunction {
+ DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
+};
+
+struct TrivialMoveNonTrivialCopy {
+ TrivialMoveNonTrivialCopy() = default;
+ TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
+ TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
+ TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
+ TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
+};
+
+struct TrivialCopyNonTrivialMove {
+ TrivialCopyNonTrivialMove() = default;
+ TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
+ TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
+ TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
+ TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
+};
+
+int main(int, char**)
+{
+ sink(
+ ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
+ ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
+ NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
+ NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
+ DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
+ );
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/smartptr/unique.ptr/null.pass.cpp b/libcxx/test/libcxx-03/utilities/smartptr/unique.ptr/null.pass.cpp
new file mode 100644
index 0000000000000..51e5ec732aa27
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/smartptr/unique.ptr/null.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <memory>
+
+// unique_ptr
+
+// FIXME(EricWF): This test contains tests for constructing a unique_ptr from NULL.
+// The behavior demonstrated in this test is not meant to be standard; It simply
+// tests the current status quo in libc++.
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+template <class VT>
+TEST_CONSTEXPR_CXX23 void test_pointer_ctor() {
+ {
+ std::unique_ptr<VT> p(0);
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<VT, Deleter<VT> > p(0);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 0);
+ }
+}
+
+template <class VT>
+TEST_CONSTEXPR_CXX23 void test_pointer_deleter_ctor() {
+ {
+ std::default_delete<VT> d;
+ std::unique_ptr<VT> p(0, d);
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<VT, Deleter<VT> > p(0, Deleter<VT>(5));
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 5);
+ }
+ {
+ NCDeleter<VT> d(5);
+ std::unique_ptr<VT, NCDeleter<VT>&> p(0, d);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 5);
+ }
+ {
+ NCConstDeleter<VT> d(5);
+ std::unique_ptr<VT, NCConstDeleter<VT> const&> p(0, d);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 5);
+ }
+}
+
+TEST_CONSTEXPR_CXX23 bool test() {
+ {
+ // test_pointer_ctor<int>();
+ test_pointer_deleter_ctor<int>();
+ }
+ {
+ test_pointer_ctor<int[]>();
+ test_pointer_deleter_ctor<int[]>();
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 23
+ static_assert(test());
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/template.bitset/assert.pass.cpp b/libcxx/test/libcxx-03/utilities/template.bitset/assert.pass.cpp
new file mode 100644
index 0000000000000..4019bdf1318eb
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/template.bitset/assert.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <bitset>
+
+// Test hardening assertions for std::bitset.
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: libcpp-hardening-mode=none
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <bitset>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ { // Empty bitset
+ std::bitset<0> c;
+ const auto& const_c = c;
+ TEST_LIBCPP_ASSERT_FAILURE(c[0], "bitset::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c[0], "bitset::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(c[42], "bitset::operator[] index out of bounds");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c[42], "bitset::operator[] index out of bounds");
+ }
+
+ { // Non-empty bitset
+ std::bitset<4> c(42);
+ const auto& const_c = c;
+ (void)c[3]; // Check that there's no assertion on valid access.
+ TEST_LIBCPP_ASSERT_FAILURE(c[4], "bitset::operator[] index out of bounds");
+ (void)const_c[3]; // Check that there's no assertion on valid access.
+ TEST_LIBCPP_ASSERT_FAILURE(const_c[4], "bitset::operator[] index out of bounds");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/template.bitset/includes.pass.cpp b/libcxx/test/libcxx-03/utilities/template.bitset/includes.pass.cpp
new file mode 100644
index 0000000000000..ae8464ac946a9
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/template.bitset/includes.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// test that <bitset> includes <string>, <stdexcept> and <iosfwd>
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+#include <bitset>
+
+#include "test_macros.h"
+
+#ifndef _LIBCPP_STRING
+#error <string> has not been included
+#endif
+
+#ifndef _LIBCPP_STDEXCEPT
+#error <stdexcept> has not been included
+#endif
+
+#ifndef _LIBCPP_IOSFWD
+#error <iosfwd> has not been included
+#endif
+
+int main(int, char**)
+{
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/tuple/__tuple_like.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/tuple/__tuple_like.compile.pass.cpp
new file mode 100644
index 0000000000000..afce2988e33ab
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/tuple/__tuple_like.compile.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <tuple>
+
+// 22.4.3 Concept `tuple-like` [tuple.like]
+//
+// template<class T>
+// concept tuple-like; // exposition only
+
+#include <__tuple/tuple_like.h>
+#include <array>
+#include <complex>
+#include <cstddef>
+#include <ranges>
+#include <tuple>
+
+#include "test_iterators.h"
+
+// Non-tuple-like type
+
+static_assert(!std::__tuple_like<int>);
+
+// Tuple-like: array
+
+static_assert(std::__tuple_like<std::array<int, 0>>);
+static_assert(std::__tuple_like<std::array<int, 1>>);
+static_assert(std::__tuple_like<std::array<int, 2>>);
+static_assert(std::__tuple_like<std::array<int, 2728>>);
+
+// Tuple-like: complex
+
+#if _LIBCPP_STD_VER >= 26
+static_assert(std::__tuple_like<std::complex<float>>);
+static_assert(std::__tuple_like<std::complex<double>>);
+static_assert(std::__tuple_like<std::complex<long double>>);
+#endif
+
+// Tuple-like: pair
+
+static_assert(std::__tuple_like<std::pair<int, float>>);
+
+// Tuple-like: tuple
+
+static_assert(std::__tuple_like<std::tuple<int>>);
+static_assert(std::__tuple_like<std::tuple<int, float>>);
+static_assert(std::__tuple_like<std::tuple<int, float, double>>);
+
+// Support for <ranges>
+
+using FI = forward_iterator<int*>;
+static_assert(std::__tuple_like<std::ranges::subrange<FI, FI, std::ranges::subrange_kind::sized>>);
+static_assert(std::__tuple_like<std::ranges::subrange<FI, FI, std::ranges::subrange_kind::unsized>>);
+static_assert(std::__tuple_like<std::ranges::subrange<int*, int*, std::ranges::subrange_kind::sized>>);
+static_assert(std::__tuple_like<std::ranges::subrange<int*, std::nullptr_t, std::ranges::subrange_kind::unsized>>);
+
+template <typename Iter>
+void test_subrange_sized() {
+ static_assert(std::__tuple_like<std::ranges::subrange<Iter, Iter, std::ranges::subrange_kind::sized>>);
+}
+
+template <typename Iter>
+void test_subrange_unsized() {
+ static_assert(std::__tuple_like<std::ranges::subrange<Iter, Iter, std::ranges::subrange_kind::unsized>>);
+}
+
+void test() {
+ test_subrange_sized<forward_iterator<int*>>();
+ test_subrange_sized<bidirectional_iterator<int*>>();
+ test_subrange_sized<random_access_iterator<int*>>();
+ test_subrange_sized<contiguous_iterator<int*>>();
+ test_subrange_sized<int*>();
+
+ test_subrange_sized<forward_iterator<int const*>>();
+ test_subrange_sized<bidirectional_iterator<int const*>>();
+ test_subrange_sized<random_access_iterator<int const*>>();
+ test_subrange_sized<contiguous_iterator<int const*>>();
+ test_subrange_sized<int const*>();
+
+ test_subrange_unsized<forward_iterator<int*>>();
+ test_subrange_unsized<bidirectional_iterator<int*>>();
+ static_assert(std::__tuple_like<std::ranges::subrange<int*, std::nullptr_t, std::ranges::subrange_kind::unsized>>);
+
+ test_subrange_unsized<forward_iterator<int const*>>();
+ test_subrange_unsized<bidirectional_iterator<int const*>>();
+ static_assert(
+ std::__tuple_like<std::ranges::subrange<const int*, std::nullptr_t, std::ranges::subrange_kind::unsized>>);
+}
diff --git a/libcxx/test/libcxx-03/utilities/tuple/no_specializations.verify.cpp b/libcxx/test/libcxx-03/utilities/tuple/no_specializations.verify.cpp
new file mode 100644
index 0000000000000..783bd814a51e1
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/tuple/no_specializations.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++11
+
+// Check that user-specializations are diagnosed
+// See [tuple.tuple.general]/1
+
+#include <tuple>
+
+#if !__has_warning("-Winvalid-specialization")
+// expected-no-diagnostics
+#else
+struct S {};
+
+template <>
+class std::tuple<S>; // expected-error {{cannot be specialized}}
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/empty_member.pass.cpp b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/empty_member.pass.cpp
new file mode 100644
index 0000000000000..ee47e628abc6b
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/empty_member.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
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// UNSUPPORTED: c++03
+
+// This is not a portable test
+
+#include <tuple>
+
+#include "test_macros.h"
+
+struct A {};
+
+struct B {};
+
+int main(int, char**)
+{
+ {
+ typedef std::tuple<int, A> T;
+ static_assert((sizeof(T) == sizeof(int)), "");
+ }
+ {
+ typedef std::tuple<A, int> T;
+ static_assert((sizeof(T) == sizeof(int)), "");
+ }
+ {
+ typedef std::tuple<A, int, B> T;
+ static_assert((sizeof(T) == sizeof(int)), "");
+ }
+ {
+ typedef std::tuple<A, B, int> T;
+ static_assert((sizeof(T) == sizeof(int)), "");
+ }
+ {
+ typedef std::tuple<int, A, B> T;
+ static_assert((sizeof(T) == sizeof(int)), "");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/array.extension.pass.cpp b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/array.extension.pass.cpp
new file mode 100644
index 0000000000000..c7847e3d4a782
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/array.extension.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// EXTENSION
+// template <class U, size_t N>
+// tuple& operator=(const array<U, N>& u);
+//
+// template <class U, size_t N>
+// tuple& operator=(array<U, N>&& u);
+
+// UNSUPPORTED: c++03
+
+#include <array>
+#include <cassert>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+
+template <class T>
+struct NothrowAssignableFrom {
+ NothrowAssignableFrom& operator=(T) noexcept { return *this; }
+};
+
+template <class T>
+struct PotentiallyThrowingAssignableFrom {
+ PotentiallyThrowingAssignableFrom& operator=(T) { return *this; }
+};
+
+int main(int, char**) {
+ // Tests for the array const& overload
+ {
+ std::array<long, 3> array = {1l, 2l, 3l};
+ std::tuple<int, int, int> tuple;
+ tuple = array;
+ assert(std::get<0>(tuple) == 1);
+ assert(std::get<1>(tuple) == 2);
+ assert(std::get<2>(tuple) == 3);
+ }
+ {
+ typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
+ typedef std::array<int, 1> Array;
+ static_assert(std::is_nothrow_assignable<Tuple&, Array const&>::value, "");
+ }
+ {
+ typedef std::tuple<PotentiallyThrowingAssignableFrom<int>> Tuple;
+ typedef std::array<int, 1> Array;
+ static_assert(std::is_assignable<Tuple&, Array const&>::value, "");
+ static_assert(!std::is_nothrow_assignable<Tuple&, Array const&>::value, "");
+ }
+
+ // Tests for the array&& overload
+ {
+ std::array<long, 3> array = {1l, 2l, 3l};
+ std::tuple<int, int, int> tuple;
+ tuple = std::move(array);
+ assert(std::get<0>(tuple) == 1);
+ assert(std::get<1>(tuple) == 2);
+ assert(std::get<2>(tuple) == 3);
+ }
+ {
+ typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
+ typedef std::array<int, 1> Array;
+ static_assert(std::is_nothrow_assignable<Tuple&, Array&&>::value, "");
+ }
+ {
+ typedef std::tuple<PotentiallyThrowingAssignableFrom<int>> Tuple;
+ typedef std::array<int, 1> Array;
+ static_assert(std::is_assignable<Tuple&, Array&&>::value, "");
+ static_assert(!std::is_nothrow_assignable<Tuple&, Array&&>::value, "");
+ }
+
+ // Test lvalue-refs and const rvalue-ref
+ {
+ typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
+ typedef std::array<int, 1> Array;
+ static_assert(std::is_nothrow_assignable<Tuple&, Array&>::value, "");
+ static_assert(std::is_nothrow_assignable<Tuple&, const Array&&>::value, "");
+ }
+
+ {
+ typedef std::tuple<NothrowAssignableFrom<int>> Tuple;
+ static_assert(!std::is_assignable<Tuple&, std::array<long, 2>&>::value, "");
+ static_assert(!std::is_assignable<Tuple&, std::array<long, 2>&&>::value, "");
+ static_assert(!std::is_assignable<Tuple&, const std::array<long, 2>&>::value, "");
+ static_assert(!std::is_assignable<Tuple&, const std::array<long, 2>&&>::value, "");
+
+ static_assert(!std::is_assignable<Tuple&, std::array<long, 4>&>::value, "");
+ static_assert(!std::is_assignable<Tuple&, std::array<long, 4>&&>::value, "");
+ static_assert(!std::is_assignable<Tuple&, const std::array<long, 4>&>::value, "");
+ static_assert(!std::is_assignable<Tuple&, const std::array<long, 4>&&>::value, "");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
new file mode 100644
index 0000000000000..b5a234ef20ffb
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <tuple-like Tuple>
+// tuple & operator=(Tuple &&);
+
+// This test checks that we do not evaluate __make_tuple_types
+// on the array when it doesn't match the size of the tuple.
+
+#include <array>
+#include <tuple>
+
+#include "test_macros.h"
+
+// Use 1256 to try and blow the template instantiation depth for all compilers.
+typedef std::array<char, 1256> array_t;
+typedef std::tuple<array_t> tuple_t;
+
+int main(int, char**)
+{
+ array_t arr;
+ tuple_t tup;
+ tup = arr;
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.cpp
new file mode 100644
index 0000000000000..a1a80483c4487
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/tuple/tuple.tuple/tuple.cnstr/PR20855_tuple_ref_binding_diagnostics.verify.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
+
+// <tuple>
+
+// See https://llvm.org/PR20855
+
+#include <tuple>
+#include <string>
+
+#include "test_macros.h"
+
+template <class Tp>
+struct ConvertsTo {
+ using RawTp = typename std::remove_cv< typename std::remove_reference<Tp>::type>::type;
+
+ operator Tp() const {
+ return static_cast<Tp>(value);
+ }
+
+ mutable RawTp value;
+};
+
+struct Base {};
+struct Derived : Base {};
+
+template <class T> struct CannotDeduce {
+ using type = T;
+};
+
+template <class ...Args>
+void F(typename CannotDeduce<std::tuple<Args...>>::type const&) {}
+
+void f() {
+ // Test that we emit our diagnostic from the library.
+ // expected-error at tuple:* 8 {{Attempted construction of reference element binds to a temporary whose lifetime has ended}}
+
+ // Good news everybody! Clang now diagnoses this for us!
+ // expected-error at tuple:* 0+ {{reference member '__value_' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+
+ {
+ F<int, const std::string&>(std::make_tuple(1, "abc")); // expected-note 1 {{requested here}}
+ }
+ {
+ std::tuple<int, const std::string&> t(1, "a"); // expected-note 1 {{requested here}}
+ }
+ {
+ F<int, const std::string&>(std::tuple<int, const std::string&>(1, "abc")); // expected-note 1 {{requested here}}
+ }
+ {
+ ConvertsTo<int&> ct;
+ std::tuple<const long&, int> t(ct, 42); // expected-note {{requested here}}
+ }
+ {
+ ConvertsTo<int> ct;
+ std::tuple<int const&, void*> t(ct, nullptr); // expected-note {{requested here}}
+ }
+ {
+ ConvertsTo<Derived> ct;
+ std::tuple<Base const&, int> t(ct, 42); // expected-note {{requested here}}
+ }
+ {
+ std::allocator<int> alloc;
+ std::tuple<std::string &&> t2("hello"); // expected-note {{requested here}}
+ std::tuple<std::string &&> t3(std::allocator_arg, alloc, "hello"); // expected-note {{requested here}}
+ }
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/__is_inplace_index.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/__is_inplace_index.pass.cpp
new file mode 100644
index 0000000000000..e26f5159603f1
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/__is_inplace_index.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// template <class _Tp> using __is_inplace_index
+
+#include <utility>
+
+#include "test_macros.h"
+
+struct S {};
+
+int main(int, char**) {
+ using I = std::in_place_index_t<0>;
+ static_assert( std::__is_inplace_index<I>::value, "");
+ static_assert( std::__is_inplace_index<const I>::value, "");
+ static_assert( std::__is_inplace_index<const volatile I>::value, "");
+ static_assert( std::__is_inplace_index<I&>::value, "");
+ static_assert( std::__is_inplace_index<const I&>::value, "");
+ static_assert( std::__is_inplace_index<const volatile I&>::value, "");
+ static_assert( std::__is_inplace_index<I&&>::value, "");
+ static_assert( std::__is_inplace_index<const I&&>::value, "");
+ static_assert( std::__is_inplace_index<const volatile I&&>::value, "");
+ static_assert(!std::__is_inplace_index<std::in_place_type_t<int>>::value, "");
+ static_assert(!std::__is_inplace_index<std::in_place_t>::value, "");
+ static_assert(!std::__is_inplace_index<void>::value, "");
+ static_assert(!std::__is_inplace_index<int>::value, "");
+ static_assert(!std::__is_inplace_index<S>::value, "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/__is_inplace_type.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/__is_inplace_type.pass.cpp
new file mode 100644
index 0000000000000..1179067d7d4ca
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/__is_inplace_type.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// template <class _Tp> using __is_inplace_type
+
+#include <utility>
+
+#include "test_macros.h"
+
+struct S {};
+
+int main(int, char**) {
+ using T = std::in_place_type_t<int>;
+ static_assert( std::__is_inplace_type<T>::value, "");
+ static_assert( std::__is_inplace_type<const T>::value, "");
+ static_assert( std::__is_inplace_type<const volatile T>::value, "");
+ static_assert( std::__is_inplace_type<T&>::value, "");
+ static_assert( std::__is_inplace_type<const T&>::value, "");
+ static_assert( std::__is_inplace_type<const volatile T&>::value, "");
+ static_assert( std::__is_inplace_type<T&&>::value, "");
+ static_assert( std::__is_inplace_type<const T&&>::value, "");
+ static_assert( std::__is_inplace_type<const volatile T&&>::value, "");
+ static_assert(!std::__is_inplace_type<std::in_place_index_t<0>>::value, "");
+ static_assert(!std::__is_inplace_type<std::in_place_t>::value, "");
+ static_assert(!std::__is_inplace_type<void>::value, "");
+ static_assert(!std::__is_inplace_type<int>::value, "");
+ static_assert(!std::__is_inplace_type<S>::value, "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v1.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v1.pass.cpp
new file mode 100644
index 0000000000000..649ff18a863f6
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v1.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Test that the CityHash implementation returns the results we expect.
+//
+// Note that this implementation is technically incorrect, however changing it is
+// an ABI break. This test ensures that we don't unintentionally break the ABI v1
+// by "fixing" the hash implementation.
+// REQUIRES: libcpp-abi-version=1
+
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <utility>
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define CHOOSE_BY_ENDIANESS(little, big) (little)
+#else
+# define CHOOSE_BY_ENDIANESS(little, big) (big)
+#endif
+
+std::string CityHash[] = {
+ {/* "abcdefgh" */ "\x61\x62\x63\x64\x65\x66\x67\x68"},
+ {/* "abcDefgh" */ "\x61\x62\x63\x44\x65\x66\x67\x68"},
+ {/* "CityHash" */ "\x43\x69\x74\x79\x48\x61\x73\x68"},
+ {/* "CitYHash" */ "\x43\x69\x74\x59\x48\x61\x73\x68"},
+};
+
+int main(int, char**) {
+ const std::pair<std::string, std::uint64_t> TestCases[] = {
+ {CityHash[0], CHOOSE_BY_ENDIANESS(0x87c69099911bab7eULL, 0x297621d7fa436a3ULL)},
+ {CityHash[1], CHOOSE_BY_ENDIANESS(0x87c69099911bab7eULL, 0xb17be531dde56e57ULL)},
+ {CityHash[2], CHOOSE_BY_ENDIANESS(0x85322632e188694aULL, 0xe14f578b688e266dULL)},
+ {CityHash[3], CHOOSE_BY_ENDIANESS(0x85322632e188694aULL, 0xca5a764a0450eac6ULL)},
+ };
+
+ std::__murmur2_or_cityhash<std::uint64_t> h64;
+ for (const auto& test_case : TestCases) {
+ assert(h64(test_case.first.data(), test_case.first.size()) == test_case.second);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v2.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v2.pass.cpp
new file mode 100644
index 0000000000000..25c0b9f177dce
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/__murmur2_or_cityhash.abi-v2.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
+
+// Test that the CityHash implementation is correct.
+//
+// In ABI v1, our CityHash implementation is incorrect and fixing it would
+// be an ABI break.
+// REQUIRES: libcpp-abi-version=2
+
+#include <cassert>
+#include <string>
+#include <utility>
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define CHOOSE_BY_ENDIANESS(little, big) (little)
+#else
+# define CHOOSE_BY_ENDIANESS(little, big) (big)
+#endif
+
+std::string CityHash[] = {
+ {/* "abcdefgh" */ "\x61\x62\x63\x64\x65\x66\x67\x68"},
+ {/* "abcDefgh" */ "\x61\x62\x63\x44\x65\x66\x67\x68"},
+ {/* "CityHash" */ "\x43\x69\x74\x79\x48\x61\x73\x68"},
+ {/* "CitYHash" */ "\x43\x69\x74\x59\x48\x61\x73\x68"},
+};
+
+int main(int, char**) {
+ const std::pair<std::string, std::uint64_t> TestCases[] = {
+ {CityHash[0], CHOOSE_BY_ENDIANESS(0x4382a8d0fe8edb17ULL, 0xca84e809bef16fbcULL)},
+ {CityHash[1], CHOOSE_BY_ENDIANESS(0xecefb080a6854061ULL, 0xd7feb824250272dcULL)},
+ {CityHash[2], CHOOSE_BY_ENDIANESS(0x169ea3aebf908d6dULL, 0xea8cef3ca6f6e368ULL)},
+ {CityHash[3], CHOOSE_BY_ENDIANESS(0xe18298a2760f09faULL, 0xf33a7700bb7a94a8ULL)},
+ };
+
+ std::__murmur2_or_cityhash<std::uint64_t> h64;
+ for (const auto& test_case : TestCases) {
+ assert(h64(test_case.first.data(), test_case.first.size()) == test_case.second);
+ }
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/forward/lifetimebound.verify.cpp b/libcxx/test/libcxx-03/utilities/utility/forward/lifetimebound.verify.cpp
new file mode 100644
index 0000000000000..4381c3af756b6
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/forward/lifetimebound.verify.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: -Wno-pessimizing-move -Wno-unused-variable
+
+#include <utility>
+
+#include "test_macros.h"
+
+struct S {
+ const int& func() [[clang::lifetimebound]];
+};
+
+void func() {
+ auto&& v1 = std::move(int{}); // expected-warning {{temporary bound to local reference 'v1' will be destroyed at the end of the full-expression}}
+ auto&& v2 = std::forward<int&&>(int{}); // expected-warning {{temporary bound to local reference 'v2' will be destroyed at the end of the full-expression}}
+ auto&& v3 = std::forward<const int&>(S{}.func()); // expected-warning {{temporary bound to local reference 'v3' will be destroyed at the end of the full-expression}}
+ auto&& v4 = std::move_if_noexcept<const int&>(S{}.func()); // expected-warning {{temporary bound to local reference 'v4' will be destroyed at the end of the full-expression}}
+#if TEST_STD_VER >= 23
+ auto&& v5 = std::forward_like<int&&>(int{}); // expected-warning {{temporary bound to local reference 'v5' will be destroyed at the end of the full-expression}}
+#endif
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate_vocabulary.attributes.verify.cpp b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate_vocabulary.attributes.verify.cpp
new file mode 100644
index 0000000000000..d5cd62ec28b2a
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/allocate_vocabulary.attributes.verify.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, c++11, c++14, c++17
+
+// check that clang warns on non-power-of-two alignment
+
+#include <memory_resource>
+
+void func() {
+ std::pmr::polymorphic_allocator<> allocator;
+ (void)allocator.allocate_bytes(0, 3); // expected-warning {{requested alignment is not a power of 2}}
+
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/assert.deallocate.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/assert.deallocate.pass.cpp
new file mode 100644
index 0000000000000..5a9813a232b85
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/assert.deallocate.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: has-unix-headers, libcpp-hardening-mode=debug
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// T* polymorphic_allocator<T>::deallocate(T*, size_t size)
+
+int AssertCount = 0;
+
+#include <memory_resource>
+#include <type_traits>
+#include <cassert>
+
+#include "check_assertion.h"
+#include "test_std_memory_resource.h"
+
+int main(int, char**) {
+ using Alloc = std::pmr::polymorphic_allocator<int>;
+ using Traits = std::allocator_traits<Alloc>;
+ NullResource R;
+ Alloc a(&R);
+ const std::size_t maxSize = Traits::max_size(a);
+
+ a.deallocate(nullptr, maxSize); // no assertion
+ TEST_LIBCPP_ASSERT_FAILURE(
+ a.deallocate(nullptr, maxSize + 1),
+ "deallocate() called for a size which exceeds max_size(), leading to a memory leak "
+ "(the argument will overflow and result in too few objects being deleted)");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
new file mode 100644
index 0000000000000..55a51c9fc26e8
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_piecewise_pair.pass.cpp
@@ -0,0 +1,170 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// TODO: Change to XFAIL once https://github.com/llvm/llvm-project/issues/40340 is fixed
+// UNSUPPORTED: availability-pmr-missing
+
+// test_memory_resource requires RTTI for dynamic_cast
+// UNSUPPORTED: no-rtti
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// template <class U1, class U2, class ...Args1, class ...Args2>
+// void polymorphic_allocator<T>::construct(pair<T1, T2>*, piecewise_construct_t
+// tuple<Args1...> x, tuple<Args2...>)
+
+// The standard specifies a transformation to uses-allocator construction as
+// follows:
+// - If uses_allocator_v<T1,memory_resource*> is false and
+// is_constructible_v<T,Args1...> is true, then xprime is x.
+// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
+// is_constructible_v<T1,allocator_arg_t,memory_resource*,Args1...> is true,
+// then xprime is
+// tuple_cat(make_tuple(allocator_arg, this->resource()), std::move(x)).
+// - Otherwise, if uses_allocator_v<T1,memory_resource*> is true and
+// is_constructible_v<T1,Args1...,memory_resource*> is true, then xprime is
+// tuple_cat(std::move(x), make_tuple(this->resource())).
+// - Otherwise the program is ill formed.
+//
+// The use of "xprime = tuple_cat(..., std::move(x), ...)" causes all of the
+// objects in 'x' to be copied into 'xprime'. If 'x' contains any types which
+// are stored by value this causes an unnecessary copy to occur. To prevent this
+// libc++ changes this call into
+// "xprime = forward_as_tuple(..., std::get<Idx>(std::move(x))..., ...)".
+// 'xprime' contains references to the values in 'x' instead of copying them.
+
+// This test checks the number of copies incurred to the elements in
+// 'tuple<Args1...>' and 'tuple<Args2...>'.
+
+#include <memory_resource>
+#include <type_traits>
+#include <utility>
+#include <tuple>
+#include <cassert>
+#include <cstdlib>
+#include "test_std_memory_resource.h"
+
+template <class T>
+struct TestHarness {
+ TestResource R;
+ std::pmr::memory_resource* M = &R;
+ std::pmr::polymorphic_allocator<T> A = M;
+ bool constructed = false;
+ T* ptr;
+
+ TestHarness() : ptr(A.allocate(1)) {}
+
+ template <class... Args>
+ void construct(Args&&... args) {
+ A.construct(ptr, std::forward<Args>(args)...);
+ constructed = true;
+ }
+
+ ~TestHarness() {
+ if (constructed)
+ A.destroy(ptr);
+ A.deallocate(ptr, 1);
+ }
+};
+
+struct CountCopies {
+ int count;
+ CountCopies() : count(0) {}
+ CountCopies(CountCopies const& o) : count(o.count + 1) {}
+};
+
+struct CountCopiesAllocV1 {
+ typedef std::pmr::polymorphic_allocator<char> allocator_type;
+ std::pmr::memory_resource* alloc;
+ int count;
+ CountCopiesAllocV1() : alloc(nullptr), count(0) {}
+ CountCopiesAllocV1(std::allocator_arg_t, allocator_type const& a, CountCopiesAllocV1 const& o)
+ : alloc(a.resource()), count(o.count + 1) {}
+
+ CountCopiesAllocV1(CountCopiesAllocV1 const& o) : count(o.count + 1) {}
+};
+
+struct CountCopiesAllocV2 {
+ typedef std::pmr::polymorphic_allocator<char> allocator_type;
+ std::pmr::memory_resource* alloc;
+ int count;
+ CountCopiesAllocV2() : alloc(nullptr), count(0) {}
+ CountCopiesAllocV2(CountCopiesAllocV2 const& o, allocator_type const& a) : alloc(a.resource()), count(o.count + 1) {}
+
+ CountCopiesAllocV2(CountCopiesAllocV2 const& o) : count(o.count + 1) {}
+};
+
+int main(int, char**) {
+ {
+ using T = CountCopies;
+ using U = CountCopiesAllocV1;
+ using P = std::pair<T, U>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, t1, t2);
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.second.count == 2);
+ assert(p.second.alloc == h.M);
+ }
+ {
+ using T = CountCopiesAllocV1;
+ using U = CountCopiesAllocV2;
+ using P = std::pair<T, U>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.first.alloc == h.M);
+ assert(p.second.count == 2);
+ assert(p.second.alloc == h.M);
+ }
+ {
+ using T = CountCopiesAllocV2;
+ using U = CountCopiesAllocV1;
+ using P = std::pair<T, U>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, std::move(t1), std::move(t2));
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.first.alloc == h.M);
+ assert(p.second.count == 2);
+ assert(p.second.alloc == h.M);
+ }
+ {
+ using T = CountCopiesAllocV2;
+ using U = CountCopies;
+ using P = std::pair<T, U>;
+
+ std::tuple<T> t1;
+ std::tuple<U> t2;
+
+ TestHarness<P> h;
+ h.construct(std::piecewise_construct, t1, t2);
+ P const& p = *h.ptr;
+ assert(p.first.count == 2);
+ assert(p.first.alloc == h.M);
+ assert(p.second.count == 2);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp
new file mode 100644
index 0000000000000..a01cdce053905
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_from_underaligned_buffer.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// TODO: Change to XFAIL once https://github.com/llvm/llvm-project/issues/40340 is fixed
+// UNSUPPORTED: availability-pmr-missing
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <cassert>
+#include <memory_resource>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+int main(int, char**) {
+ globalMemCounter.reset();
+ {
+ alignas(4) char buffer[17];
+ auto mono1 = std::pmr::monotonic_buffer_resource(buffer, 16, std::pmr::new_delete_resource());
+ std::pmr::memory_resource& r1 = mono1;
+
+ void* ret = r1.allocate(1, 1);
+ assert(ret == buffer + 15);
+ mono1.release();
+
+ ret = r1.allocate(1, 2);
+ assert(ret == buffer + 14);
+ mono1.release();
+
+ ret = r1.allocate(1, 4);
+ assert(ret == buffer + 12);
+ mono1.release();
+
+ // Test a size that is just big enough to fit in the buffer,
+ // but can't fit if it's aligned.
+ {
+ auto mono2 = std::pmr::monotonic_buffer_resource(buffer + 1, 16, std::pmr::new_delete_resource());
+ std::pmr::memory_resource& r2 = mono2;
+ ret = r2.allocate(16, 1);
+ assert(ret == buffer + 1);
+ mono2.release();
+
+ assert(globalMemCounter.checkNewCalledEq(0));
+ ret = r2.allocate(16, 2);
+ ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkNewCalledEq(1));
+ ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkLastNewSizeGe(16));
+ mono2.release();
+ ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.checkDeleteCalledEq(1));
+ }
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
new file mode 100644
index 0000000000000..29e9d0345c14f
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.monotonic.buffer/mem.res.monotonic.buffer.mem/allocate_in_geometric_progression.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// TODO: Change to XFAIL once https://github.com/llvm/llvm-project/issues/40340 is fixed
+// UNSUPPORTED: availability-pmr-missing
+
+// <memory_resource>
+
+// class monotonic_buffer_resource
+
+#include <memory_resource>
+#include <cassert>
+
+#include "count_new.h"
+
+int main(int, char**) {
+ globalMemCounter.reset();
+ std::pmr::monotonic_buffer_resource mono;
+
+ for (int i = 0; i < 100; ++i) {
+ (void)mono.allocate(1);
+ assert(globalMemCounter.last_new_size < 1000000000);
+ mono.release();
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp
new file mode 100644
index 0000000000000..3226efcec1b23
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/mem.res/mem.res.pool/unsynchronized_buffer.pass.cpp
@@ -0,0 +1,211 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// TODO: Change to XFAIL once https://github.com/llvm/llvm-project/issues/40340 is fixed
+// UNSUPPORTED: availability-pmr-missing
+
+// <memory_resource>
+
+// struct pool_options
+// class unsynchronized_pool_resource
+// class synchronized_pool_resource
+
+#include <memory_resource>
+#include <cassert>
+#include <cstdint> // SIZE_MAX, UINT32_MAX
+
+static void assert_options(const std::pmr::pool_options& actual, const std::pmr::pool_options& expected) {
+ assert(actual.max_blocks_per_chunk == expected.max_blocks_per_chunk);
+ assert(actual.largest_required_pool_block == expected.largest_required_pool_block);
+}
+
+void test_pool_options(std::pmr::pool_options initial, std::pmr::pool_options expected) {
+ std::pmr::unsynchronized_pool_resource mr(initial, std::pmr::null_memory_resource());
+ assert_options(mr.options(), expected);
+
+ std::pmr::synchronized_pool_resource mr2(initial, std::pmr::null_memory_resource());
+ assert_options(mr2.options(), expected);
+}
+
+int main(int, char**) {
+ test_pool_options({0, 0}, {1048576, 1048576});
+ test_pool_options({0, 1}, {1048576, 8});
+ test_pool_options({0, 2}, {1048576, 8});
+ test_pool_options({0, 4}, {1048576, 8});
+ test_pool_options({0, 8}, {1048576, 8});
+ test_pool_options({0, 16}, {1048576, 16});
+ test_pool_options({0, 32}, {1048576, 32});
+ test_pool_options({0, 1024}, {1048576, 1024});
+ test_pool_options({0, 1048576}, {1048576, 1048576});
+ test_pool_options({0, 2097152}, {1048576, 2097152});
+ test_pool_options({0, 1073741824}, {1048576, 1073741824});
+ test_pool_options({0, 2147483648}, {1048576, 1073741824});
+ test_pool_options({1, 0}, {16, 1048576});
+ test_pool_options({1, 1}, {16, 8});
+ test_pool_options({1, 2}, {16, 8});
+ test_pool_options({1, 4}, {16, 8});
+ test_pool_options({1, 8}, {16, 8});
+ test_pool_options({1, 16}, {16, 16});
+ test_pool_options({1, 32}, {16, 32});
+ test_pool_options({1, 1024}, {16, 1024});
+ test_pool_options({1, 1048576}, {16, 1048576});
+ test_pool_options({1, 2097152}, {16, 2097152});
+ test_pool_options({1, 1073741824}, {16, 1073741824});
+ test_pool_options({1, 2147483648}, {16, 1073741824});
+ test_pool_options({2, 0}, {16, 1048576});
+ test_pool_options({2, 1}, {16, 8});
+ test_pool_options({2, 2}, {16, 8});
+ test_pool_options({2, 4}, {16, 8});
+ test_pool_options({2, 8}, {16, 8});
+ test_pool_options({2, 16}, {16, 16});
+ test_pool_options({2, 32}, {16, 32});
+ test_pool_options({2, 1024}, {16, 1024});
+ test_pool_options({2, 1048576}, {16, 1048576});
+ test_pool_options({2, 2097152}, {16, 2097152});
+ test_pool_options({2, 1073741824}, {16, 1073741824});
+ test_pool_options({2, 2147483648}, {16, 1073741824});
+ test_pool_options({4, 0}, {16, 1048576});
+ test_pool_options({4, 1}, {16, 8});
+ test_pool_options({4, 2}, {16, 8});
+ test_pool_options({4, 4}, {16, 8});
+ test_pool_options({4, 8}, {16, 8});
+ test_pool_options({4, 16}, {16, 16});
+ test_pool_options({4, 32}, {16, 32});
+ test_pool_options({4, 1024}, {16, 1024});
+ test_pool_options({4, 1048576}, {16, 1048576});
+ test_pool_options({4, 2097152}, {16, 2097152});
+ test_pool_options({4, 1073741824}, {16, 1073741824});
+ test_pool_options({4, 2147483648}, {16, 1073741824});
+ test_pool_options({8, 0}, {16, 1048576});
+ test_pool_options({8, 1}, {16, 8});
+ test_pool_options({8, 2}, {16, 8});
+ test_pool_options({8, 4}, {16, 8});
+ test_pool_options({8, 8}, {16, 8});
+ test_pool_options({8, 16}, {16, 16});
+ test_pool_options({8, 32}, {16, 32});
+ test_pool_options({8, 1024}, {16, 1024});
+ test_pool_options({8, 1048576}, {16, 1048576});
+ test_pool_options({8, 2097152}, {16, 2097152});
+ test_pool_options({8, 1073741824}, {16, 1073741824});
+ test_pool_options({8, 2147483648}, {16, 1073741824});
+ test_pool_options({16, 0}, {16, 1048576});
+ test_pool_options({16, 1}, {16, 8});
+ test_pool_options({16, 2}, {16, 8});
+ test_pool_options({16, 4}, {16, 8});
+ test_pool_options({16, 8}, {16, 8});
+ test_pool_options({16, 16}, {16, 16});
+ test_pool_options({16, 32}, {16, 32});
+ test_pool_options({16, 1024}, {16, 1024});
+ test_pool_options({16, 1048576}, {16, 1048576});
+ test_pool_options({16, 2097152}, {16, 2097152});
+ test_pool_options({16, 1073741824}, {16, 1073741824});
+ test_pool_options({16, 2147483648}, {16, 1073741824});
+ test_pool_options({32, 0}, {32, 1048576});
+ test_pool_options({32, 1}, {32, 8});
+ test_pool_options({32, 2}, {32, 8});
+ test_pool_options({32, 4}, {32, 8});
+ test_pool_options({32, 8}, {32, 8});
+ test_pool_options({32, 16}, {32, 16});
+ test_pool_options({32, 32}, {32, 32});
+ test_pool_options({32, 1024}, {32, 1024});
+ test_pool_options({32, 1048576}, {32, 1048576});
+ test_pool_options({32, 2097152}, {32, 2097152});
+ test_pool_options({32, 1073741824}, {32, 1073741824});
+ test_pool_options({32, 2147483648}, {32, 1073741824});
+ test_pool_options({1024, 0}, {1024, 1048576});
+ test_pool_options({1024, 1}, {1024, 8});
+ test_pool_options({1024, 2}, {1024, 8});
+ test_pool_options({1024, 4}, {1024, 8});
+ test_pool_options({1024, 8}, {1024, 8});
+ test_pool_options({1024, 16}, {1024, 16});
+ test_pool_options({1024, 32}, {1024, 32});
+ test_pool_options({1024, 1024}, {1024, 1024});
+ test_pool_options({1024, 1048576}, {1024, 1048576});
+ test_pool_options({1024, 2097152}, {1024, 2097152});
+ test_pool_options({1024, 1073741824}, {1024, 1073741824});
+ test_pool_options({1024, 2147483648}, {1024, 1073741824});
+ test_pool_options({1048576, 0}, {1048576, 1048576});
+ test_pool_options({1048576, 1}, {1048576, 8});
+ test_pool_options({1048576, 2}, {1048576, 8});
+ test_pool_options({1048576, 4}, {1048576, 8});
+ test_pool_options({1048576, 8}, {1048576, 8});
+ test_pool_options({1048576, 16}, {1048576, 16});
+ test_pool_options({1048576, 32}, {1048576, 32});
+ test_pool_options({1048576, 1024}, {1048576, 1024});
+ test_pool_options({1048576, 1048576}, {1048576, 1048576});
+ test_pool_options({1048576, 2097152}, {1048576, 2097152});
+ test_pool_options({1048576, 1073741824}, {1048576, 1073741824});
+ test_pool_options({1048576, 2147483648}, {1048576, 1073741824});
+ test_pool_options({2097152, 0}, {1048576, 1048576});
+ test_pool_options({2097152, 1}, {1048576, 8});
+ test_pool_options({2097152, 2}, {1048576, 8});
+ test_pool_options({2097152, 4}, {1048576, 8});
+ test_pool_options({2097152, 8}, {1048576, 8});
+ test_pool_options({2097152, 16}, {1048576, 16});
+ test_pool_options({2097152, 32}, {1048576, 32});
+ test_pool_options({2097152, 1024}, {1048576, 1024});
+ test_pool_options({2097152, 1048576}, {1048576, 1048576});
+ test_pool_options({2097152, 2097152}, {1048576, 2097152});
+ test_pool_options({2097152, 1073741824}, {1048576, 1073741824});
+ test_pool_options({2097152, 2147483648}, {1048576, 1073741824});
+ test_pool_options({1073741824, 0}, {1048576, 1048576});
+ test_pool_options({1073741824, 1}, {1048576, 8});
+ test_pool_options({1073741824, 2}, {1048576, 8});
+ test_pool_options({1073741824, 4}, {1048576, 8});
+ test_pool_options({1073741824, 8}, {1048576, 8});
+ test_pool_options({1073741824, 16}, {1048576, 16});
+ test_pool_options({1073741824, 32}, {1048576, 32});
+ test_pool_options({1073741824, 1024}, {1048576, 1024});
+ test_pool_options({1073741824, 1048576}, {1048576, 1048576});
+ test_pool_options({1073741824, 2097152}, {1048576, 2097152});
+ test_pool_options({1073741824, 1073741824}, {1048576, 1073741824});
+ test_pool_options({1073741824, 2147483648}, {1048576, 1073741824});
+ test_pool_options({2147483648, 0}, {1048576, 1048576});
+ test_pool_options({2147483648, 1}, {1048576, 8});
+ test_pool_options({2147483648, 2}, {1048576, 8});
+ test_pool_options({2147483648, 4}, {1048576, 8});
+ test_pool_options({2147483648, 8}, {1048576, 8});
+ test_pool_options({2147483648, 16}, {1048576, 16});
+ test_pool_options({2147483648, 32}, {1048576, 32});
+ test_pool_options({2147483648, 1024}, {1048576, 1024});
+ test_pool_options({2147483648, 1048576}, {1048576, 1048576});
+ test_pool_options({2147483648, 2097152}, {1048576, 2097152});
+ test_pool_options({2147483648, 1073741824}, {1048576, 1073741824});
+ test_pool_options({2147483648, 2147483648}, {1048576, 1073741824});
+
+#if SIZE_MAX > UINT32_MAX
+ test_pool_options({0, 8589934592}, {1048576, 1073741824});
+ test_pool_options({1, 8589934592}, {16, 1073741824});
+ test_pool_options({2, 8589934592}, {16, 1073741824});
+ test_pool_options({4, 8589934592}, {16, 1073741824});
+ test_pool_options({8, 8589934592}, {16, 1073741824});
+ test_pool_options({16, 8589934592}, {16, 1073741824});
+ test_pool_options({32, 8589934592}, {32, 1073741824});
+ test_pool_options({1024, 8589934592}, {1024, 1073741824});
+ test_pool_options({1048576, 8589934592}, {1048576, 1073741824});
+ test_pool_options({2097152, 8589934592}, {1048576, 1073741824});
+ test_pool_options({1073741824, 8589934592}, {1048576, 1073741824});
+ test_pool_options({2147483648, 8589934592}, {1048576, 1073741824});
+ test_pool_options({8589934592, 0}, {1048576, 1048576});
+ test_pool_options({8589934592, 1}, {1048576, 8});
+ test_pool_options({8589934592, 2}, {1048576, 8});
+ test_pool_options({8589934592, 4}, {1048576, 8});
+ test_pool_options({8589934592, 8}, {1048576, 8});
+ test_pool_options({8589934592, 16}, {1048576, 16});
+ test_pool_options({8589934592, 32}, {1048576, 32});
+ test_pool_options({8589934592, 1024}, {1048576, 1024});
+ test_pool_options({8589934592, 1048576}, {1048576, 1048576});
+ test_pool_options({8589934592, 2097152}, {1048576, 2097152});
+ test_pool_options({8589934592, 1073741824}, {1048576, 1073741824});
+ test_pool_options({8589934592, 2147483648}, {1048576, 1073741824});
+ test_pool_options({8589934592, 8589934592}, {1048576, 1073741824});
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/mem.res/pmr.availability.verify.cpp b/libcxx/test/libcxx-03/utilities/utility/mem.res/pmr.availability.verify.cpp
new file mode 100644
index 0000000000000..34cf178b7a229
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/mem.res/pmr.availability.verify.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: availability-pmr-missing
+
+// TODO: This test doesn't work until https://github.com/llvm/llvm-project/issues/40340
+// has been fixed, because we actually disable availability markup.
+// XFAIL: *
+
+// Test the availability markup on std::pmr components.
+
+#include <deque>
+#include <forward_list>
+#include <list>
+#include <map>
+#include <memory_resource>
+#include <regex>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+void f() {
+ [[maybe_unused]] std::pmr::match_results<const char8_t*> m1; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::cmatch m2; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::wcmatch m3; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::smatch m4; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::wsmatch m5; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::deque<int> m6; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::forward_list<int> m7; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::list<int> m8; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::map<int, int> m9; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::multimap<int, int> m10; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::set<int> m11; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::multiset<int> m12; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::string m13; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::wstring m14; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::u8string m15; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::u16string m16; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::u32string m17; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::basic_string<char8_t> m18; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::unordered_map<int, int> m19; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::unordered_multimap<int, int> m20; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::unordered_set<int, int> m21; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::unordered_multiset<int, int> m22; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::vector<int> m23; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::polymorphic_allocator<int> poly; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::memory_resource* res = nullptr; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::synchronized_pool_resource r1; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::monotonic_buffer_resource r2; // expected-error {{is unavailable}}
+ [[maybe_unused]] std::pmr::unsynchronized_pool_resource r3; // expected-error {{is unavailable}}
+ (void)std::pmr::get_default_resource(); // expected-error {{is unavailable}}
+ (void)std::pmr::set_default_resource(nullptr); // expected-error {{is unavailable}}
+ (void)std::pmr::new_delete_resource(); // expected-error {{is unavailable}}
+ (void)std::pmr::null_memory_resource(); // expected-error {{is unavailable}}
+ (void)(*res == *res); // expected-error {{is unavailable}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/U_V.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/U_V.pass.cpp
new file mode 100644
index 0000000000000..98363b6a14f00
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/U_V.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
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template<class U, class V> pair(U&& x, V&& y);
+
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+int main(int, char**) {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>, int, int>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>, int, int>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>, int, int>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>, int, int>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>, int, int>::value, "");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp
new file mode 100644
index 0000000000000..1f5dae1232e37
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// The test suite needs to define the ABI macros on the command line when
+// modules are enabled.
+// UNSUPPORTED: clang-modules-build
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// Test that we provide the non-trivial copy operations when _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
+// is specified.
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
+// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -Wno-invalid-offsetof
+
+#include <utility>
+#include <type_traits>
+#include <cstdlib>
+#include <cstddef>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+struct HasNonTrivialABI : std::integral_constant<bool,
+ !std::is_trivially_destructible<T>::value
+ || (std::is_copy_constructible<T>::value && !std::is_trivially_copy_constructible<T>::value)
+#if TEST_STD_VER >= 11
+ || (std::is_move_constructible<T>::value && !std::is_trivially_move_constructible<T>::value)
+#endif
+> {};
+
+#if TEST_STD_VER >= 11
+struct NonTrivialDtor {
+ NonTrivialDtor(NonTrivialDtor const&) = default;
+ ~NonTrivialDtor();
+};
+NonTrivialDtor::~NonTrivialDtor() {}
+static_assert(HasNonTrivialABI<NonTrivialDtor>::value, "");
+
+struct NonTrivialCopy {
+ NonTrivialCopy(NonTrivialCopy const&);
+};
+NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {}
+static_assert(HasNonTrivialABI<NonTrivialCopy>::value, "");
+
+struct NonTrivialMove {
+ NonTrivialMove(NonTrivialMove const&) = default;
+ NonTrivialMove(NonTrivialMove&&);
+};
+NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {}
+static_assert(HasNonTrivialABI<NonTrivialMove>::value, "");
+
+struct DeletedCopy {
+ DeletedCopy(DeletedCopy const&) = delete;
+ DeletedCopy(DeletedCopy&&) = default;
+};
+static_assert(!HasNonTrivialABI<DeletedCopy>::value, "");
+
+struct TrivialMove {
+ TrivialMove(TrivialMove &&) = default;
+};
+static_assert(!HasNonTrivialABI<TrivialMove>::value, "");
+
+struct Trivial {
+ Trivial(Trivial const&) = default;
+};
+static_assert(!HasNonTrivialABI<Trivial>::value, "");
+#endif
+
+
+void test_trivial()
+{
+ {
+ typedef std::pair<int, short> P;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+#if TEST_STD_VER >= 11
+ {
+ typedef std::pair<int, short> P;
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<NonTrivialDtor, int>;
+ static_assert(!std::is_trivially_destructible<P>::value, "");
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<NonTrivialCopy, int>;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<NonTrivialMove, int>;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<DeletedCopy, int>;
+ static_assert(!std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<Trivial, int>;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<TrivialMove, int>;
+ static_assert(!std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasNonTrivialABI<P>::value, "");
+ }
+#endif
+}
+
+void test_layout() {
+ typedef std::pair<std::pair<char, char>, char> PairT;
+ static_assert(sizeof(PairT) == 3, "");
+ static_assert(TEST_ALIGNOF(PairT) == TEST_ALIGNOF(char), "");
+ static_assert(offsetof(PairT, first) == 0, "");
+}
+
+int main(int, char**) {
+ test_trivial();
+ test_layout();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp
new file mode 100644
index 0000000000000..3ec60c08b8eab
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp
@@ -0,0 +1,182 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// Test that we properly provide the trivial copy operations by default.
+
+// FreeBSD still provides the old ABI for std::pair.
+// XFAIL: freebsd
+// ADDITIONAL_COMPILE_FLAGS: -Wno-invalid-offsetof
+
+#include <utility>
+#include <type_traits>
+#include <cstdlib>
+#include <cstddef>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+struct HasTrivialABI : std::integral_constant<bool,
+ std::is_trivially_destructible<T>::value
+ && (!std::is_copy_constructible<T>::value || std::is_trivially_copy_constructible<T>::value)
+#if TEST_STD_VER >= 11
+ && (!std::is_move_constructible<T>::value || std::is_trivially_move_constructible<T>::value)
+#endif
+> {};
+
+#if TEST_STD_VER >= 11
+struct NonTrivialDtor {
+ NonTrivialDtor(NonTrivialDtor const&) = default;
+ ~NonTrivialDtor();
+};
+NonTrivialDtor::~NonTrivialDtor() {}
+static_assert(!HasTrivialABI<NonTrivialDtor>::value, "");
+
+struct NonTrivialCopy {
+ NonTrivialCopy(NonTrivialCopy const&);
+};
+NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {}
+static_assert(!HasTrivialABI<NonTrivialCopy>::value, "");
+
+struct NonTrivialMove {
+ NonTrivialMove(NonTrivialMove const&) = default;
+ NonTrivialMove(NonTrivialMove&&);
+};
+NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {}
+static_assert(!HasTrivialABI<NonTrivialMove>::value, "");
+
+struct DeletedCopy {
+ DeletedCopy(DeletedCopy const&) = delete;
+ DeletedCopy(DeletedCopy&&) = default;
+};
+static_assert(HasTrivialABI<DeletedCopy>::value, "");
+
+struct TrivialMove {
+ TrivialMove(TrivialMove &&) = default;
+};
+static_assert(HasTrivialABI<TrivialMove>::value, "");
+
+struct Trivial {
+ Trivial(Trivial const&) = default;
+};
+static_assert(HasTrivialABI<Trivial>::value, "");
+#endif
+
+struct TrivialNoAssignment {
+ int arr[4];
+ TrivialNoAssignment& operator=(const TrivialNoAssignment&) = delete;
+};
+
+struct TrivialNoConstruction {
+ int arr[4];
+ TrivialNoConstruction() = default;
+ TrivialNoConstruction(const TrivialNoConstruction&) = delete;
+ TrivialNoConstruction& operator=(const TrivialNoConstruction&) = default;
+};
+
+void test_trivial()
+{
+ {
+ typedef std::pair<int, short> P;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(HasTrivialABI<P>::value, "");
+ }
+#if TEST_STD_VER >= 11
+ {
+ typedef std::pair<int, short> P;
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(HasTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<NonTrivialDtor, int>;
+ static_assert(!std::is_trivially_destructible<P>::value, "");
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(!HasTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<NonTrivialCopy, int>;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(!HasTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<NonTrivialMove, int>;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+ static_assert(!HasTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<DeletedCopy, int>;
+ static_assert(!std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<Trivial, int>;
+ static_assert(std::is_copy_constructible<P>::value, "");
+ static_assert(std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasTrivialABI<P>::value, "");
+ }
+ {
+ using P = std::pair<TrivialMove, int>;
+ static_assert(!std::is_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_move_constructible<P>::value, "");
+ static_assert(std::is_trivially_move_constructible<P>::value, "");
+ static_assert(HasTrivialABI<P>::value, "");
+ }
+#endif
+ {
+ using P = std::pair<TrivialNoAssignment, int>;
+ static_assert(std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(std::is_trivially_move_constructible<P>::value, "");
+#if TEST_STD_VER >= 11 // This is https://llvm.org/PR90605
+ static_assert(!std::is_trivially_copy_assignable<P>::value, "");
+ static_assert(!std::is_trivially_move_assignable<P>::value, "");
+#endif // TEST_STD_VER >= 11
+ static_assert(std::is_trivially_destructible<P>::value, "");
+ }
+ {
+ using P = std::pair<TrivialNoConstruction, int>;
+#if TEST_STD_VER >= 11
+ static_assert(!std::is_trivially_copy_constructible<P>::value, "");
+ static_assert(!std::is_trivially_move_constructible<P>::value, "");
+#endif // TEST_STD_VER >= 11
+ static_assert(!std::is_trivially_copy_assignable<P>::value, "");
+ static_assert(!std::is_trivially_move_assignable<P>::value, "");
+ static_assert(std::is_trivially_destructible<P>::value, "");
+ }
+}
+
+void test_layout() {
+ typedef std::pair<std::pair<char, char>, char> PairT;
+ static_assert(sizeof(PairT) == 3, "");
+ static_assert(TEST_ALIGNOF(PairT) == TEST_ALIGNOF(char), "");
+ static_assert(offsetof(PairT, first) == 0, "");
+}
+
+int main(int, char**) {
+ test_trivial();
+ test_layout();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp
new file mode 100644
index 0000000000000..1132b3e5def18
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+//
+// This test pins down the ABI of std::pair with respect to being "trivially copyable".
+//
+
+// This test doesn't work when the deprecated ABI to turn off pair triviality is enabled.
+// See libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp instead.
+// UNSUPPORTED: libcpp-deprecated-abi-disable-pair-trivial-copy-ctor
+
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct trivially_copyable {
+ int arr[4];
+};
+
+struct trivially_copyable_no_copy_assignment {
+ int arr[4];
+ trivially_copyable_no_copy_assignment& operator=(const trivially_copyable_no_copy_assignment&) = delete;
+};
+static_assert(std::is_trivially_copyable<trivially_copyable_no_copy_assignment>::value, "");
+
+struct trivially_copyable_no_move_assignment {
+ int arr[4];
+ trivially_copyable_no_move_assignment& operator=(const trivially_copyable_no_move_assignment&) = delete;
+};
+static_assert(std::is_trivially_copyable<trivially_copyable_no_move_assignment>::value, "");
+
+struct trivially_copyable_no_construction {
+ int arr[4];
+ trivially_copyable_no_construction() = default;
+ trivially_copyable_no_construction(const trivially_copyable_no_construction&) = delete;
+ trivially_copyable_no_construction& operator=(const trivially_copyable_no_construction&) = default;
+};
+static_assert(std::is_trivially_copyable<trivially_copyable_no_construction>::value, "");
+
+static_assert(!std::is_trivially_copyable<std::pair<int&, int> >::value, "");
+static_assert(!std::is_trivially_copyable<std::pair<int, int&> >::value, "");
+static_assert(!std::is_trivially_copyable<std::pair<int&, int&> >::value, "");
+
+static_assert(!std::is_trivially_copyable<std::pair<int, int> >::value, "");
+static_assert(!std::is_trivially_copyable<std::pair<int, char> >::value, "");
+static_assert(!std::is_trivially_copyable<std::pair<char, int> >::value, "");
+static_assert(!std::is_trivially_copyable<std::pair<std::pair<char, char>, int> >::value, "");
+static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable, int> >::value, "");
+#if TEST_STD_VER == 03 // Known ABI difference
+static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, "");
+static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, "");
+#else
+static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, "");
+static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, "");
+#endif
+static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_construction, int> >::value, "");
+
+static_assert(std::is_trivially_copy_constructible<std::pair<int, int> >::value, "");
+static_assert(std::is_trivially_move_constructible<std::pair<int, int> >::value, "");
+static_assert(!std::is_trivially_copy_assignable<std::pair<int, int> >::value, "");
+static_assert(!std::is_trivially_move_assignable<std::pair<int, int> >::value, "");
+static_assert(std::is_trivially_destructible<std::pair<int, int> >::value, "");
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/assign_tuple_like.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/assign_tuple_like.pass.cpp
new file mode 100644
index 0000000000000..f8dfd9ad19226
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/assign_tuple_like.pass.cpp
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template<class U, class V> pair& operator=(tuple<U, V>&& p);
+
+#include <utility>
+#include <tuple>
+#include <array>
+#include <memory>
+#include <cassert>
+
+#include "archetypes.h"
+
+int main(int, char**)
+{
+ using C = TestTypes::TestType;
+ {
+ using P = std::pair<int, C>;
+ using T = std::tuple<int, C>;
+ T t(42, C{42});
+ P p(101, C{101});
+ C::reset_constructors();
+ p = t;
+ assert(C::constructed == 0);
+ assert(C::assigned == 1);
+ assert(C::copy_assigned == 1);
+ assert(C::move_assigned == 0);
+ assert(p.first == 42);
+ assert(p.second.value == 42);
+ }
+ {
+ using P = std::pair<int, C>;
+ using T = std::tuple<int, C>;
+ T t(42, -42);
+ P p(101, 101);
+ C::reset_constructors();
+ p = std::move(t);
+ assert(C::constructed == 0);
+ assert(C::assigned == 1);
+ assert(C::copy_assigned == 0);
+ assert(C::move_assigned == 1);
+ assert(p.first == 42);
+ assert(p.second.value == -42);
+ }
+ {
+ using P = std::pair<C, C>;
+ using T = std::array<C, 2>;
+ T t = {42, -42};
+ P p{101, 101};
+ C::reset_constructors();
+ p = t;
+ assert(C::constructed == 0);
+ assert(C::assigned == 2);
+ assert(C::copy_assigned == 2);
+ assert(C::move_assigned == 0);
+ assert(p.first.value == 42);
+ assert(p.second.value == -42);
+ }
+ {
+ using P = std::pair<C, C>;
+ using T = std::array<C, 2>;
+ T t = {42, -42};
+ P p{101, 101};
+ C::reset_constructors();
+ p = t;
+ assert(C::constructed == 0);
+ assert(C::assigned == 2);
+ assert(C::copy_assigned == 2);
+ assert(C::move_assigned == 0);
+ assert(p.first.value == 42);
+ assert(p.second.value == -42);
+ }
+ {
+ using P = std::pair<C, C>;
+ using T = std::array<C, 2>;
+ T t = {42, -42};
+ P p{101, 101};
+ C::reset_constructors();
+ p = std::move(t);
+ assert(C::constructed == 0);
+ assert(C::assigned == 2);
+ assert(C::copy_assigned == 0);
+ assert(C::move_assigned == 2);
+ assert(p.first.value == 42);
+ assert(p.second.value == -42);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
new file mode 100644
index 0000000000000..c68ed3e822305
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_first_const_second.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// pair(const T1& x, const T2& y);
+
+#include <type_traits>
+#include <utility>
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(ExplicitNothrowT const&) noexcept {}
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(ImplicitNothrowT const&) noexcept {}
+};
+
+int main(int, char**) {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>,
+ ExplicitT const&, ExplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>,
+ ExplicitNothrowT const&, ExplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>,
+ ExplicitT const&, ExplicitNothrowT const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>,
+ ExplicitNothrowT const&, ExplicitNothrowT const&>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>,
+ ImplicitT const&, ImplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>,
+ ImplicitNothrowT const&, ImplicitT const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>,
+ ImplicitT const&, ImplicitNothrowT const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>,
+ ImplicitNothrowT const&, ImplicitNothrowT const&>::value, "");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
new file mode 100644
index 0000000000000..497e4f4bd1faa
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/const_pair_U_V.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template <class U, class V> EXPLICIT constexpr pair(const pair<U, V>& p);
+
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ constexpr explicit ExplicitT(ExplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ constexpr ImplicitT(ImplicitT const& o) : value(o.value) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+int main(int, char**) {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>,
+ std::pair<int, int> const&>::value, "");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/default.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/default.pass.cpp
new file mode 100644
index 0000000000000..3ebf85107cf82
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/default.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
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// constexpr pair();
+
+#include <utility>
+#include <type_traits>
+
+#include "test_macros.h"
+
+
+struct ThrowingDefault {
+ ThrowingDefault() { }
+};
+
+struct NonThrowingDefault {
+ NonThrowingDefault() noexcept { }
+};
+
+int main(int, char**) {
+
+ static_assert(!std::is_nothrow_default_constructible<std::pair<ThrowingDefault, ThrowingDefault>>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<std::pair<NonThrowingDefault, ThrowingDefault>>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<std::pair<ThrowingDefault, NonThrowingDefault>>::value, "");
+ static_assert( std::is_nothrow_default_constructible<std::pair<NonThrowingDefault, NonThrowingDefault>>::value, "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.incomplete.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.incomplete.compile.pass.cpp
new file mode 100644
index 0000000000000..16ee000cd90fa
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.incomplete.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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that instantiating pair doesn't look up type traits "too early", before
+// the contained types have been completed.
+//
+// This is a regression test, to prevent a reoccurrance of the issue introduced
+// in 5e1de27f680591a870d78e9952b23f76aed7f456.
+
+#include <utility>
+#include <vector>
+
+struct Test {
+ std::vector<std::pair<int, Test> > v;
+};
+
+std::pair<int, Test> p;
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.tuple_element.verify.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.tuple_element.verify.cpp
new file mode 100644
index 0000000000000..7d10d8b23cee1
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/pair.tuple_element.verify.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// tuple_element<I, pair<T1, T2> >::type
+
+#include <utility>
+
+void f() {
+ typedef std::pair<int, double> P;
+ std::tuple_element<2, P>::type foo; // expected-note {{requested here}}
+ // expected-error-re@*:* {{static assertion failed{{( due to requirement '2U[L]{0,2} < 2')?}}{{.*}}Index out of bounds in std::tuple_element<std::pair<T1, T2>>}}
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
new file mode 100644
index 0000000000000..23238515f1729
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/piecewise.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template <class... Args1, class... Args2>
+// pair(piecewise_construct_t, tuple<Args1...> first_args,
+// tuple<Args2...> second_args);
+
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "archetypes.h"
+
+#include "test_macros.h"
+
+
+int main(int, char**) {
+ using NonThrowingConvert = NonThrowingTypes::ConvertingType;
+ using ThrowingConvert = NonTrivialTypes::ConvertingType;
+ static_assert(!std::is_nothrow_constructible<std::pair<ThrowingConvert, ThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<NonThrowingConvert, ThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ThrowingConvert, NonThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<NonThrowingConvert, NonThrowingConvert>,
+ std::piecewise_construct_t, std::tuple<int, int>, std::tuple<long, long>>::value, "");
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
new file mode 100644
index 0000000000000..57602844897f6
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/pairs/pairs.pair/rv_pair_U_V.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// template <class U, class V> pair(pair<U, V>&& p);
+
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+
+struct ExplicitT {
+ constexpr explicit ExplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ImplicitT {
+ constexpr ImplicitT(int x) : value(x) {}
+ int value;
+};
+
+struct ExplicitNothrowT {
+ explicit ExplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+struct ImplicitNothrowT {
+ ImplicitNothrowT(int x) noexcept : value(x) {}
+ int value;
+};
+
+int main(int, char**) {
+ { // explicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ExplicitT, ExplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ExplicitNothrowT, ExplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ }
+ { // implicit noexcept test
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert(!std::is_nothrow_constructible<std::pair<ImplicitT, ImplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ static_assert( std::is_nothrow_constructible<std::pair<ImplicitNothrowT, ImplicitNothrowT>,
+ std::pair<int, int>&&>::value, "");
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/utility/private_constructor_tag.compile.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/private_constructor_tag.compile.pass.cpp
new file mode 100644
index 0000000000000..1644819a02f7f
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/private_constructor_tag.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// struct __private_constructor_tag{};
+
+// The private constructor tag is intended to be a trivial type that can easily
+// be used to mark a constructor exposition-only.
+//
+// Tests whether the type is trivial.
+
+#include <__utility/private_constructor_tag.h>
+#include <type_traits>
+
+static_assert(std::is_trivially_copyable<std::__private_constructor_tag>::value, "");
+static_assert(std::is_trivially_default_constructible<std::__private_constructor_tag>::value, "");
diff --git a/libcxx/test/libcxx-03/utilities/utility/small_buffer.pass.cpp b/libcxx/test/libcxx-03/utilities/utility/small_buffer.pass.cpp
new file mode 100644
index 0000000000000..2214efa486870
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/utility/small_buffer.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
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: availability-aligned_allocation-missing
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+#include "test_macros.h"
+
+TEST_DIAGNOSTIC_PUSH
+TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#include <__utility/small_buffer.h>
+TEST_DIAGNOSTIC_POP
+
+#include <cassert>
+#include <memory>
+#include <utility>
+
+struct NotTriviallyRelocatable {
+ char c_;
+
+ NotTriviallyRelocatable(char c) : c_(c) {}
+ ~NotTriviallyRelocatable() {}
+};
+
+struct alignas(16) Overaligned {
+ int i;
+};
+
+int main(int, char**) {
+ using BufferT = std::__small_buffer<8, 8>;
+ static_assert(sizeof(BufferT) == 8);
+ static_assert(alignof(BufferT) == 8);
+ static_assert(BufferT::__fits_in_buffer<int>);
+ static_assert(!BufferT::__fits_in_buffer<Overaligned>);
+ static_assert(!BufferT::__fits_in_buffer<NotTriviallyRelocatable>);
+
+ BufferT buf;
+
+ { // construct/destroy in the same place
+ buf.__construct<int>(3);
+ assert(*buf.__get<int>() == 3);
+ std::destroy_at(buf.__get<int>());
+ buf.__dealloc<int>();
+
+ buf.__construct<NotTriviallyRelocatable>(3);
+ assert(buf.__get<NotTriviallyRelocatable>()->c_ == 3);
+ std::destroy_at(buf.__get<NotTriviallyRelocatable>());
+ buf.__dealloc<NotTriviallyRelocatable>();
+ }
+
+ { // Move the buffer around
+ buf.__construct<int>(3);
+ assert(*buf.__get<int>() == 3);
+ auto buf2 = std::move(buf);
+ assert(*buf2.__get<int>() == 3);
+ std::destroy_at(buf2.__get<int>());
+ buf2.__dealloc<int>();
+
+ buf.__construct<NotTriviallyRelocatable>(3);
+ assert(buf.__get<NotTriviallyRelocatable>()->c_ == 3);
+ auto buf3 = std::move(buf);
+ assert(buf3.__get<NotTriviallyRelocatable>()->c_ == 3);
+ std::destroy_at(buf3.__get<NotTriviallyRelocatable>());
+ buf3.__dealloc<NotTriviallyRelocatable>();
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/variant/no_specializations.verify.cpp b/libcxx/test/libcxx-03/utilities/variant/no_specializations.verify.cpp
new file mode 100644
index 0000000000000..d4743f4fd3f90
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/variant/no_specializations.verify.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// Check that user-specializations are diagnosed
+// See [variant.variant.general]/4
+
+#include <variant>
+
+#if !__has_warning("-Winvalid-specialization")
+// expected-no-diagnostics
+#else
+struct S {};
+
+template <>
+class std::variant<S>; // expected-error {{cannot be specialized}}
+#endif
diff --git a/libcxx/test/libcxx-03/utilities/variant/variant.variant/variant.helper/variant_alternative.verify.cpp b/libcxx/test/libcxx-03/utilities/variant/variant.variant/variant.helper/variant_alternative.verify.cpp
new file mode 100644
index 0000000000000..29f9ace51ca85
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/variant/variant.variant/variant.helper/variant_alternative.verify.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <variant>
+// UNSUPPORTED: c++03, c++11, c++14
+
+
+// template <size_t I, class T> struct variant_alternative; // undefined
+// template <size_t I, class T> struct variant_alternative<I, const T>;
+// template <size_t I, class T> struct variant_alternative<I, volatile T>;
+// template <size_t I, class T> struct variant_alternative<I, const volatile T>;
+// template <size_t I, class T>
+// using variant_alternative_t = typename variant_alternative<I, T>::type;
+//
+// template <size_t I, class... Types>
+// struct variant_alternative<I, variant<Types...>>;
+
+
+#include <variant>
+#include <cassert>
+
+
+int main(int, char**)
+{
+ {
+ typedef std::variant<int, double> T;
+ std::variant_alternative<2, T>::type foo; // expected-note {{requested here}}
+ // expected-error-re at variant:* {{static assertion failed{{( due to requirement '2U[L]{0,2} < sizeof...\(_Types\)')?}}{{.*}}Index out of bounds in std::variant_alternative<>}}
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/utilities/variant/variant.variant/variant_size.pass.cpp b/libcxx/test/libcxx-03/utilities/variant/variant.variant/variant_size.pass.cpp
new file mode 100644
index 0000000000000..2f1ea8bffb479
--- /dev/null
+++ b/libcxx/test/libcxx-03/utilities/variant/variant.variant/variant_size.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <variant>
+
+// template <class ...Types> class variant;
+
+#include <limits>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
+#include "test_macros.h"
+
+template <class Sequence>
+struct make_variant_imp;
+
+template <std::size_t ...Indices>
+struct make_variant_imp<std::integer_sequence<std::size_t, Indices...>> {
+ template <std::size_t> using AlwaysChar = char;
+ using type = std::variant<AlwaysChar<Indices>...>;
+};
+
+template <std::size_t N>
+using make_variant_t = typename make_variant_imp<std::make_index_sequence<N>>::type;
+
+constexpr bool ExpectEqual =
+#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+ false;
+#else
+ true;
+#endif
+
+template <class IndexType>
+void test_index_type() {
+ using Lim = std::numeric_limits<IndexType>;
+ using T1 = make_variant_t<Lim::max() - 1>;
+ using T2 = make_variant_t<Lim::max()>;
+ static_assert((sizeof(T1) == sizeof(T2)) == ExpectEqual, "");
+}
+
+template <class IndexType>
+void test_index_internals() {
+ using Lim = std::numeric_limits<IndexType>;
+#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+ static_assert(!std::is_same_v<decltype(std::__choose_index_type<Lim::max() - 1>()),
+ decltype(std::__choose_index_type<Lim::max()>())>);
+#endif
+ static_assert(
+ std::is_same_v<std::__variant_index_t<Lim::max() - 1>, std::__variant_index_t<Lim::max()> > == ExpectEqual, "");
+ using IndexT = std::__variant_index_t<Lim::max() - 1>;
+ using IndexLim = std::numeric_limits<IndexT>;
+ static_assert(std::__variant_npos<IndexT> == IndexLim::max(), "");
+}
+
+template <class LargestType>
+struct type_with_index {
+ LargestType largest;
+#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+ unsigned char index;
+#else
+ unsigned int index;
+#endif
+};
+
+int main(int, char**) {
+ test_index_type<unsigned char>();
+ // This won't compile due to template depth issues.
+ //test_index_type<unsigned short>();
+ test_index_internals<unsigned char>();
+ test_index_internals<unsigned short>();
+
+ // Test that std::variant achieves the expected size. See https://llvm.org/PR61095.
+ static_assert(sizeof(std::variant<char, char, char>) == sizeof(type_with_index<char>));
+ static_assert(sizeof(std::variant<int, int, int>) == sizeof(type_with_index<int>));
+ static_assert(sizeof(std::variant<long, long, long>) == sizeof(type_with_index<long>));
+ static_assert(sizeof(std::variant<char, int, long>) == sizeof(type_with_index<long>));
+ static_assert(sizeof(std::variant<std::size_t, std::size_t, std::size_t>) == sizeof(type_with_index<std::size_t>));
+
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/vendor/apple/availability-with-pedantic-errors.compile.pass.cpp b/libcxx/test/libcxx-03/vendor/apple/availability-with-pedantic-errors.compile.pass.cpp
new file mode 100644
index 0000000000000..118e4e687e115
--- /dev/null
+++ b/libcxx/test/libcxx-03/vendor/apple/availability-with-pedantic-errors.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: stdlib=apple-libc++
+
+// Test that using -pedantic-errors doesn't turn off availability annotations.
+// This used to be the case because we used __has_extension(...) to enable the
+// availability annotations, and -pedantic-errors changes the behavior of
+// __has_extension(...) in an incompatible way.
+
+// ADDITIONAL_COMPILE_FLAGS: -pedantic-errors
+
+#include <__config>
+
+#if !_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS
+# error Availability annotations should be enabled on Apple platforms in the system configuration!
+#endif
diff --git a/libcxx/test/libcxx-03/vendor/apple/disable-availability.sh.cpp b/libcxx/test/libcxx-03/vendor/apple/disable-availability.sh.cpp
new file mode 100644
index 0000000000000..474b3f83c6044
--- /dev/null
+++ b/libcxx/test/libcxx-03/vendor/apple/disable-availability.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: stdlib=apple-libc++
+
+// This test is dependent on the code generated by the compiler, and it doesn't
+// work properly with older AppleClangs.
+// UNSUPPORTED: apple-clang-15
+
+// This test ensures that we retain a way to disable availability markup on Apple platforms
+// in order to work around Clang bug https://github.com/llvm/llvm-project/issues/134151.
+//
+// Once that bug has been fixed or once we've made changes to libc++'s use of availability
+// that render that workaround unnecessary, the macro and this test can be removed.
+//
+// The test works by creating a final linked image that refers to a function marked with
+// both an availability attribute and with _LIBCPP_HIDE_FROM_ABI. We then check that this
+// generates a weak reference to the function -- without the bug, we'd expect a strong
+// reference or no reference at all instead.
+
+// First, test the test. Make sure that we do (incorrectly) produce a weak definition when we
+// don't define _LIBCPP_DISABLE_AVAILABILITY. Otherwise, something may have changed in libc++
+// and this test might not work anymore.
+// RUN: %{cxx} %s %{flags} %{compile_flags} %{link_flags} -fvisibility=hidden -fvisibility-inlines-hidden -shared -o %t.1.dylib
+// RUN: nm -m %t.1.dylib | c++filt | grep value > %t.1.symbols
+// RUN: grep weak %t.1.symbols
+
+// Now, make sure that 'weak' goes away when we define _LIBCPP_DISABLE_AVAILABILITY.
+// In fact, all references to the function might go away, so we just check that we don't emit
+// any weak reference.
+// RUN: %{cxx} %s %{flags} %{compile_flags} %{link_flags} -fvisibility=hidden -fvisibility-inlines-hidden -D_LIBCPP_DISABLE_AVAILABILITY -shared -o %t.2.dylib
+// RUN: nm -m %t.2.dylib | c++filt | grep value > %t.2.symbols
+// RUN: not grep weak %t.2.symbols
+
+#include <version>
+
+template <class T>
+struct optional {
+ T val_;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE T value() const { return val_; }
+};
+
+using PMF = int (optional<int>::*)() const;
+PMF f() { return &optional<int>::value; }
diff --git a/libcxx/test/libcxx-03/vendor/apple/system-install-properties.sh.cpp b/libcxx/test/libcxx-03/vendor/apple/system-install-properties.sh.cpp
new file mode 100644
index 0000000000000..eeae4fc0a3c00
--- /dev/null
+++ b/libcxx/test/libcxx-03/vendor/apple/system-install-properties.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: stdlib=apple-libc++
+
+// This file checks various properties of the installation of libc++ when built as
+// a system library on Apple platforms.
+
+// Make sure we install the libc++ headers in the right location.
+//
+// RUN: stat "%{include-dir}/__config"
+
+// Make sure we install libc++.1.dylib and libc++experimental.a in the right location.
+//
+// RUN: stat "%{lib-dir}/libc++.1.dylib"
+// RUN: stat "%{lib-dir}/libc++experimental.a"
+
+// Make sure we install a symlink from libc++.dylib to libc++.1.dylib.
+//
+// RUN: stat "%{lib-dir}/libc++.dylib"
+// RUN: readlink "%{lib-dir}/libc++.dylib" | grep "libc++.1.dylib"
+
+// Make sure the install_name is /usr/lib.
+//
+// In particular, make sure we don't use any @rpath in the load commands. When building as
+// a system library, it is important to hardcode the installation paths in the dylib, because
+// various tools like dyld and ld64 will treat us specially if they recognize us as being a
+// system library.
+//
+// RUN: otool -L "%{lib-dir}/libc++.1.dylib" | grep '/usr/lib/libc++.1.dylib'
+// RUN: otool -l "%{lib-dir}/libc++.1.dylib" | grep -vE "LC_RPATH|@loader_path|@rpath"
+
+// Make sure the compatibility_version of libc++ is 1.0.0.
+// Failure to respect this can result in applications not being able to find libc++
+// when they are loaded by dyld, if the compatibility version was bumped.
+//
+// RUN: otool -L "%{lib-dir}/libc++.1.dylib" | grep "libc++.1.dylib" | grep "compatibility version 1.0.0"
+
+// Make sure we use the libdispatch backend for the PSTL.
+//
+// RUN: grep "%{include-dir}/__config_site" -e '#define _LIBCPP_PSTL_BACKEND_LIBDISPATCH'
diff --git a/libcxx/test/libcxx-03/vendor/clang-cl/static-lib-exports.sh.cpp b/libcxx/test/libcxx-03/vendor/clang-cl/static-lib-exports.sh.cpp
new file mode 100644
index 0000000000000..7ed14921b1067
--- /dev/null
+++ b/libcxx/test/libcxx-03/vendor/clang-cl/static-lib-exports.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: msvc
+
+// This file checks that the built static libraries don't contain dllexport
+// directives in clang-cl builds.
+
+// RUN: llvm-readobj --coff-directives "%{lib-dir}/libc++.lib" | not grep -i "export:" > /dev/null
+
+// RUN: llvm-readobj --coff-directives "%{lib-dir}/libc++experimental.lib" | not grep -i "export:" > /dev/null
diff --git a/libcxx/test/libcxx-03/vendor/ibm/bad_function_call.pass.cpp b/libcxx/test/libcxx-03/vendor/ibm/bad_function_call.pass.cpp
new file mode 100644
index 0000000000000..3714e4037a2dc
--- /dev/null
+++ b/libcxx/test/libcxx-03/vendor/ibm/bad_function_call.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: target={{.+}}-aix{{.*}}
+// ADDITIONAL_COMPILE_FLAGS: -fvisibility-inlines-hidden
+
+// When there is a weak hidden symbol in user code and a strong definition
+// in the library, we test that the linker relies on the library version,
+// as the default weak resolution semantics don't favour weak local definitions
+// for XCOFF. This creates a conflict on std::bad_function_call, which is used
+// by the std::function template instantiated in main.
+#include <functional>
+#include "test_macros.h"
+#include "assert.h"
+
+void foo() {}
+
+void test_call() {
+ std::function<void()> r(foo);
+ r();
+}
+
+void test_throw() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ std::function<int()> f;
+ try {
+ f();
+ assert(false);
+ } catch (const std::bad_function_call&) {
+ return;
+ }
+ assert(false);
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+ test_call();
+ test_throw();
+ return 0;
+}
diff --git a/libcxx/test/libcxx-03/vendor/mingw/static-lib-exports.sh.cpp b/libcxx/test/libcxx-03/vendor/mingw/static-lib-exports.sh.cpp
new file mode 100644
index 0000000000000..e20269f91e485
--- /dev/null
+++ b/libcxx/test/libcxx-03/vendor/mingw/static-lib-exports.sh.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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: target={{.+}}-windows-gnu
+
+// This file checks that the built static libraries don't contain dllexport
+// directives in MinGW builds.
+
+// RUN: llvm-readobj --coff-directives "%{lib-dir}/libc++.a" | not grep -i "export:" > /dev/null
+
+// RUN: llvm-readobj --coff-directives "%{lib-dir}/libc++experimental.a" | not grep -i "export:" > /dev/null
diff --git a/libcxx/test/libcxx-03/xopen_source.gen.py b/libcxx/test/libcxx-03/xopen_source.gen.py
new file mode 100644
index 0000000000000..d4a3651181ca7
--- /dev/null
+++ b/libcxx/test/libcxx-03/xopen_source.gen.py
@@ -0,0 +1,56 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Make sure that libc++ headers work when defining _XOPEN_SOURCE=500.
+# We may not want to guarantee this forever, but since this works today and
+# it's something that users rely on, it makes sense to put a test on it.
+#
+# https://github.com/llvm/llvm-project/issues/117630
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+# END.
+
+import sys
+
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+ lit_header_restrictions,
+ lit_header_undeprecations,
+ public_headers,
+)
+
+for header in public_headers:
+ for version in (500, 600, 700):
+ # TODO: <fstream> currently uses ::fseeko unguarded, which fails with _XOPEN_SOURCE=500.
+ if header == "fstream" and version == 500:
+ continue
+
+ print(
+ f"""\
+//--- {header}.xopen_source_{version}.compile.pass.cpp
+
+// Some parts of the code like <fstream> use non-standard functions in their implementation,
+// and these functions are not provided when _XOPEN_SOURCE is set to older values. This
+// breaks when building with modules even when we don't use the offending headers directly.
+// UNSUPPORTED: clang-modules-build
+
+// The AIX localization support uses some functions as part of their headers that require a
+// recent value of _XOPEN_SOURCE.
+// UNSUPPORTED: LIBCXX-AIX-FIXME
+
+// This test fails on FreeBSD for an unknown reason.
+// UNSUPPORTED: LIBCXX-FREEBSD-FIXME
+
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+
+// ADDITIONAL_COMPILE_FLAGS: -D_XOPEN_SOURCE={version}
+
+#include <{header}>
+"""
+ )
diff --git a/libcxx/test/libcxx/lit.local.cfg b/libcxx/test/libcxx/lit.local.cfg
index 4467d8070cc70..d2a3bc85a26c1 100644
--- a/libcxx/test/libcxx/lit.local.cfg
+++ b/libcxx/test/libcxx/lit.local.cfg
@@ -3,3 +3,7 @@ import shlex
import sys
config.substitutions.append(("%{python}", shlex.quote(sys.executable)))
+
+# disable libcxx tests when running against the frozen headers. We have separate tests for C++03.
+if "FROZEN-CXX03-HEADERS-FIXME" in config.available_features:
+ config.unsupported = True
More information about the libcxx-commits
mailing list