From 2b106389aff6d39b5ccda530470343738bc652bb Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 5 Oct 2025 19:13:45 +0100 Subject: [PATCH 1/3] [libc++] Implement P3567R2 flat_meow fixes --- libcxx/include/__flat_map/flat_map.h | 25 +++- libcxx/include/__flat_map/flat_multimap.h | 23 +++- libcxx/include/__flat_set/flat_multiset.h | 25 +++- libcxx/include/__flat_set/flat_set.h | 24 +++- .../insert_range_sorted_unique.pass.cpp | 121 +++++++++++++++++ .../swap_exception.pass.cpp | 27 ++-- .../flat.map.modifiers/swap_free.pass.cpp | 5 +- .../flat.map.modifiers/swap_member.pass.cpp | 6 +- .../insert_range_sorted_equivalent.pass.cpp | 123 ++++++++++++++++++ .../swap_exception.pass.cpp | 22 +++- .../swap_free.pass.cpp | 5 +- .../swap_member.pass.cpp | 4 +- .../insert_range_sorted_equivalent.pass.cpp | 100 ++++++++++++++ .../swap_exception.pass.cpp | 12 +- .../swap_free.pass.cpp | 5 +- .../swap_member.pass.cpp | 4 +- .../insert_range_sorted_unique.pass.cpp | 108 +++++++++++++++ .../swap_exception.pass.cpp | 12 +- .../flat.set.modifiers/swap_free.pass.cpp | 5 +- .../flat.set.modifiers/swap_member.pass.cpp | 4 +- 20 files changed, 600 insertions(+), 60 deletions(-) create mode 100644 libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_sorted_unique.pass.cpp create mode 100644 libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_range_sorted_equivalent.pass.cpp create mode 100644 libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range_sorted_equivalent.pass.cpp create mode 100644 libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_range_sorted_unique.pass.cpp diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h index 7bb235ba76503..0b27b5a0d5f9c 100644 --- a/libcxx/include/__flat_map/flat_map.h +++ b/libcxx/include/__flat_map/flat_map.h @@ -587,6 +587,15 @@ class flat_map { __append_sort_merge_unique(ranges::begin(__range), ranges::end(__range)); } + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(sorted_unique_t, _Range&& __range) { + if constexpr (ranges::sized_range<_Range>) { + __reserve(ranges::size(__range)); + } + + __append_sort_merge_unique(ranges::begin(__range), ranges::end(__range)); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list __il) { insert(__il.begin(), __il.end()); } @@ -736,14 +745,17 @@ class flat_map { return iterator(std::move(__key_it), std::move(__mapped_it)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __y) noexcept { - // warning: The spec has unconditional noexcept, which means that - // if any of the following functions throw an exception, - // std::terminate will be called. - // This is discussed in P2767, which hasn't been voted on yet. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + swap(flat_map& __y) noexcept(is_nothrow_swappable_v && + is_nothrow_swappable_v && is_nothrow_swappable_v) { + auto __on_failure = std::__make_exception_guard([&]() noexcept { + clear() /* noexcept */; + __y.clear() /* noexcept */; + }); ranges::swap(__compare_, __y.__compare_); ranges::swap(__containers_.keys, __y.__containers_.keys); ranges::swap(__containers_.values, __y.__containers_.values); + __on_failure.__complete(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { @@ -876,7 +888,8 @@ class flat_map { __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); } - friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __x, flat_map& __y) noexcept { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + swap(flat_map& __x, flat_map& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } diff --git a/libcxx/include/__flat_map/flat_multimap.h b/libcxx/include/__flat_map/flat_multimap.h index 96d945405cffe..27fe6547bbdfe 100644 --- a/libcxx/include/__flat_map/flat_multimap.h +++ b/libcxx/include/__flat_map/flat_multimap.h @@ -568,6 +568,15 @@ class flat_multimap { __append_sort_merge(ranges::begin(__range), ranges::end(__range)); } + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(sorted_equivalent_t, _Range&& __range) { + if constexpr (ranges::sized_range<_Range>) { + __reserve(ranges::size(__range)); + } + + __append_sort_merge(ranges::begin(__range), ranges::end(__range)); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list __il) { insert(__il.begin(), __il.end()); } @@ -628,13 +637,17 @@ class flat_multimap { return iterator(std::move(__key_it), std::move(__mapped_it)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_multimap& __y) noexcept { - // warning: The spec has unconditional noexcept, which means that - // if any of the following functions throw an exception, - // std::terminate will be called + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_multimap& __y) noexcept( + is_nothrow_swappable_v && is_nothrow_swappable_v && + is_nothrow_swappable_v) { + auto __on_failure = std::__make_exception_guard([&]() noexcept { + clear() /* noexcept */; + __y.clear() /* noexcept */; + }); ranges::swap(__compare_, __y.__compare_); ranges::swap(__containers_.keys, __y.__containers_.keys); ranges::swap(__containers_.values, __y.__containers_.values); + __on_failure.__complete(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { @@ -771,7 +784,7 @@ class flat_multimap { } friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void - swap(flat_multimap& __x, flat_multimap& __y) noexcept { + swap(flat_multimap& __x, flat_multimap& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } diff --git a/libcxx/include/__flat_set/flat_multiset.h b/libcxx/include/__flat_set/flat_multiset.h index b1a4917659c49..19f8b0ff01539 100644 --- a/libcxx/include/__flat_set/flat_multiset.h +++ b/libcxx/include/__flat_set/flat_multiset.h @@ -401,6 +401,15 @@ class flat_multiset { __append_sort_merge(std::forward<_Range>(__range)); } + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI void insert_range(sorted_equivalent_t, _Range&& __range) { + if constexpr (ranges::sized_range<_Range>) { + __reserve(ranges::size(__range)); + } + + __append_sort_merge(std::forward<_Range>(__range)); + } + _LIBCPP_HIDE_FROM_ABI void insert(initializer_list __il) { insert(__il.begin(), __il.end()); } _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, initializer_list __il) { @@ -454,13 +463,15 @@ class flat_multiset { return iterator(std::move(__key_it)); } - _LIBCPP_HIDE_FROM_ABI void swap(flat_multiset& __y) noexcept { - // warning: The spec has unconditional noexcept, which means that - // if any of the following functions throw an exception, - // std::terminate will be called - // This is discussed in P3567, which hasn't been voted on yet. + _LIBCPP_HIDE_FROM_ABI void + swap(flat_multiset& __y) noexcept(is_nothrow_swappable_v && is_nothrow_swappable_v) { + auto __on_failure = std::__make_exception_guard([&]() noexcept { + clear() /* noexcept */; + __y.clear() /* noexcept */; + }); ranges::swap(__compare_, __y.__compare_); ranges::swap(__keys_, __y.__keys_); + __on_failure.__complete(); } _LIBCPP_HIDE_FROM_ABI void clear() noexcept { __keys_.clear(); } @@ -578,7 +589,9 @@ class flat_multiset { __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); } - friend _LIBCPP_HIDE_FROM_ABI void swap(flat_multiset& __x, flat_multiset& __y) noexcept { __x.swap(__y); } + friend _LIBCPP_HIDE_FROM_ABI void swap(flat_multiset& __x, flat_multiset& __y) noexcept(noexcept(__x.swap(__y))) { + __x.swap(__y); + } private: template diff --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h index 5fa1f2d8acb9b..b4ef9ead2b70b 100644 --- a/libcxx/include/__flat_set/flat_set.h +++ b/libcxx/include/__flat_set/flat_set.h @@ -458,6 +458,15 @@ class flat_set { __append_sort_merge_unique(std::forward<_Range>(__range)); } + template <_ContainerCompatibleRange _Range> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(std::sorted_unique_t, _Range&& __range) { + if constexpr (ranges::sized_range<_Range>) { + __reserve(ranges::size(__range)); + } + + __append_sort_merge_unique(std::forward<_Range>(__range)); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list __il) { insert(__il.begin(), __il.end()); } @@ -516,13 +525,15 @@ class flat_set { return iterator(std::move(__key_it)); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __y) noexcept { - // warning: The spec has unconditional noexcept, which means that - // if any of the following functions throw an exception, - // std::terminate will be called. - // This is discussed in P2767, which hasn't been voted on yet. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + swap(flat_set& __y) noexcept(is_nothrow_swappable_v && is_nothrow_swappable_v) { + auto __on_failure = std::__make_exception_guard([&]() noexcept { + clear() /* noexcept */; + __y.clear() /* noexcept */; + }); ranges::swap(__compare_, __y.__compare_); ranges::swap(__keys_, __y.__keys_); + __on_failure.__complete(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); } @@ -647,7 +658,8 @@ class flat_set { __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); } - friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __x, flat_set& __y) noexcept { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + swap(flat_set& __x, flat_set& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_sorted_unique.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_sorted_unique.pass.cpp new file mode 100644 index 0000000000000..124130aa3e108 --- /dev/null +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_sorted_unique.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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// template R> +// void insert_range(sorted_unique, R&& rg); + +#include +#include +#include +#include +#include +#include + +#include "MinSequenceContainer.h" +#include "../helpers.h" +#include "MoveOnly.h" +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" + +// test constraint container-compatible-range +template +concept CanInsertRangeSortedUnique = requires(M m, R&& r) { m.insert_range(std::sorted_unique, std::forward(r)); }; + +using Map = std::flat_map; + +static_assert(CanInsertRangeSortedUnique*>>); +static_assert(CanInsertRangeSortedUnique*>>); +static_assert(!CanInsertRangeSortedUnique>); +static_assert(!CanInsertRangeSortedUnique>); + +template +constexpr void test() { + using Key = typename KeyContainer::value_type; + using Value = typename ValueContainer::value_type; + + { + using P = std::pair; + using M = std::flat_map, KeyContainer, ValueContainer>; + using It = forward_iterator; + M m = {{10, 1}, {8, 2}, {5, 3}, {2, 4}, {1, 5}}; + P ar[] = {{1, 2}, {3, 1}, {4, 3}, {5, 5}, {9, 6}}; + std::ranges::subrange r = {It(ar), It(ar + 5)}; + static_assert(std::ranges::common_range); + m.insert_range(std::sorted_unique, r); + assert((m == M{{1, 5}, {2, 4}, {3, 1}, {4, 3}, {5, 3}, {8, 2}, {9, 6}, {10, 1}})); + } + { + using P = std::pair; + using M = std::flat_map, KeyContainer, ValueContainer>; + using It = cpp20_input_iterator; + M m = {{8, 1}, {5, 2}, {3, 3}, {2, 4}}; + P ar[] = {{9, 6}, {5, 5}, {4, 3}, {3, 1}, {1, 2}}; + std::ranges::subrange r = {It(ar), sentinel_wrapper(It(ar + 5))}; + static_assert(!std::ranges::common_range); + m.insert_range(std::sorted_unique, r); + assert((m == M{{1, 2}, {2, 4}, {3, 3}, {4, 3}, {5, 2}, {8, 1}, {9, 6}})); + } + { + // was empty + using P = std::pair; + using M = std::flat_map, KeyContainer, ValueContainer>; + M m; + P ar[] = {{1, 2}, {3, 1}, {4, 3}, {5, 5}, {9, 6}}; + m.insert_range(std::sorted_unique, ar); + assert(std::ranges::equal(m, ar)); + } +} + +constexpr bool test() { + test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + { + test, std::vector>(); + } + test, MinSequenceContainer>(); + test>, std::vector>>(); + { + // Items are forwarded correctly from the input range + std::pair a[] = {{1, 1}, {3, 3}, {4, 4}, {5, 5}}; + std::flat_map m; + m.insert_range(std::sorted_unique, a | std::views::as_rvalue); + std::pair expected[] = {{1, 1}, {3, 3}, {4, 4}, {5, 5}}; + assert(std::ranges::equal(m, expected)); + } + { + // The element type of the range doesn't need to be std::pair + std::pair pa[] = {{1, 1}, {3, 3}, {4, 4}, {5, 5}}; + std::vector>> a(pa, pa + 4); + std::flat_map m; + m.insert_range(std::sorted_unique, a); + std::pair expected[] = {{1, 1}, {3, 3}, {4, 4}, {5, 5}}; + assert(std::ranges::equal(m, expected)); + } + if (!TEST_IS_CONSTANT_EVALUATED) { + auto insert_func = [](auto& m, const auto& newValues) { m.insert_range(std::sorted_unique, newValues); }; + test_insert_range_exception_guarantee(insert_func); + } + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + + return 0; +} diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp index f9708aac62c7e..96b88a5fbfacb 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp @@ -7,9 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// `check_assertion.h` requires Unix headers and regex support. -// REQUIRES: has-unix-headers -// UNSUPPORTED: no-localization // UNSUPPORTED: no-exceptions // @@ -17,7 +14,7 @@ // void swap(flat_map& y) noexcept; // friend void swap(flat_map& x, flat_map& y) noexcept -// Test that std::terminate is called if any exception is thrown during swap +// Test that the variants are hold if any exception is thrown during swap #include #include @@ -42,8 +39,15 @@ void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { m1.emplace(2, 2); m2.emplace(3, 3); m2.emplace(4, 4); - // swap is noexcept - EXPECT_STD_TERMINATE([&] { swap_function(m1, m2); }); + try { + swap_function(m1, m2); + assert(false); + } catch (int) { + check_invariant(m1); + check_invariant(m2); + LIBCPP_ASSERT(m1.size() == 0); + LIBCPP_ASSERT(m2.size() == 0); + } } { @@ -58,8 +62,15 @@ void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { m2.emplace(3, 3); m2.emplace(4, 4); - // swap is noexcept - EXPECT_STD_TERMINATE([&] { swap_function(m1, m2); }); + try { + swap_function(m1, m2); + assert(false); + } catch (int) { + check_invariant(m1); + check_invariant(m2); + LIBCPP_ASSERT(m1.size() == 0); + LIBCPP_ASSERT(m2.size() == 0); + } } } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_free.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_free.pass.cpp index 37f2914ebfdb2..c7410960ef5a8 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_free.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_free.pass.cpp @@ -31,11 +31,10 @@ concept NoExceptAdlSwap = requires(T t1, T t2) { { swap(t1, t2) } noexcept; }; -static_assert(NoExceptAdlSwap>); - +static_assert(NoExceptAdlSwap, std::vector, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS static_assert( - NoExceptAdlSwap, ThrowOnMoveContainer, ThrowOnMoveContainer>>); + !NoExceptAdlSwap, ThrowOnMoveContainer, ThrowOnMoveContainer>>); #endif template diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_member.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_member.pass.cpp index 771bcd3de2c09..6a00a155f8e16 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_member.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_member.pass.cpp @@ -10,7 +10,7 @@ // -// void swap(flat_map& y) noexcept; +// void swap(flat_map& y) noexcept(see below); #include #include @@ -31,10 +31,10 @@ concept NoExceptMemberSwap = requires(T t1, T t2) { { t1.swap(t2) } noexcept; }; -static_assert(NoExceptMemberSwap>); +static_assert(NoExceptMemberSwap, std::vector, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS static_assert( - NoExceptMemberSwap, ThrowOnMoveContainer, ThrowOnMoveContainer>>); + !NoExceptMemberSwap, ThrowOnMoveContainer, ThrowOnMoveContainer>>); #endif template diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_range_sorted_equivalent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_range_sorted_equivalent.pass.cpp new file mode 100644 index 0000000000000..95d56478970e9 --- /dev/null +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_range_sorted_equivalent.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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// class flat_multimap + +// template R> +// void insert_range(sorted_equivalent_t, R&& rg); + +#include +#include +#include +#include +#include +#include + +#include "MinSequenceContainer.h" +#include "../helpers.h" +#include "MoveOnly.h" +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" + +// test constraint container-compatible-range +template +concept CanInsertRangeSortedEquivalent = + requires(M m, R&& r) { m.insert_range(std::sorted_equivalent, std::forward(r)); }; + +using Map = std::flat_multimap; + +static_assert(CanInsertRangeSortedEquivalent*>>); +static_assert(CanInsertRangeSortedEquivalent*>>); +static_assert(!CanInsertRangeSortedEquivalent>); +static_assert(!CanInsertRangeSortedEquivalent>); + +template +constexpr void test() { + using Key = typename KeyContainer::value_type; + using Value = typename ValueContainer::value_type; + + { + using P = std::pair; + using M = std::flat_multimap, KeyContainer, ValueContainer>; + using It = forward_iterator; + M m = {{10, 1}, {8, 2}, {5, 3}, {2, 4}, {1, 5}}; + P ar[] = {{1, 2}, {1, 4}, {3, 1}, {4, 3}, {5, 5}, {9, 6}}; + std::ranges::subrange r = {It(ar), It(ar + 6)}; + static_assert(std::ranges::common_range); + m.insert_range(std::sorted_equivalent, r); + std::vector

expected = {{1, 5}, {1, 2}, {1, 4}, {2, 4}, {3, 1}, {4, 3}, {5, 3}, {5, 5}, {8, 2}, {9, 6}, {10, 1}}; + assert(std::ranges::equal(m, expected)); + } + { + using P = std::pair; + using M = std::flat_multimap, KeyContainer, ValueContainer>; + using It = cpp20_input_iterator; + M m = {{8, 1}, {5, 2}, {3, 3}, {2, 4}}; + P ar[] = {{9, 6}, {5, 5}, {4, 3}, {3, 1}, {1, 2}, {1, 4}}; + std::ranges::subrange r = {It(ar), sentinel_wrapper(It(ar + 6))}; + static_assert(!std::ranges::common_range); + m.insert_range(std::sorted_equivalent, r); + std::vector

expected = {{9, 6}, {8, 1}, {5, 2}, {5, 5}, {4, 3}, {3, 3}, {3, 1}, {2, 4}, {1, 2}, {1, 4}}; + assert(std::ranges::equal(m, expected)); + } + { + // was empty + using P = std::pair; + using M = std::flat_multimap, KeyContainer, ValueContainer>; + M m; + P ar[] = {{1, 2}, {1, 4}, {3, 1}, {4, 3}, {5, 5}, {9, 6}}; + m.insert_range(std::sorted_equivalent, ar); + assert(std::ranges::equal(m, ar)); + } +} + +constexpr bool test() { + test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test, std::vector>(); + test, MinSequenceContainer>(); + test>, std::vector>>(); + { + // Items are forwarded correctly from the input range + std::pair a[] = {{1, 1}, {1, 1}, {3, 3}, {4, 4}, {5, 5}}; + std::flat_multimap m; + m.insert_range(std::sorted_equivalent, a | std::views::as_rvalue); + std::pair expected[] = {{1, 1}, {1, 1}, {3, 3}, {4, 4}, {5, 5}}; + assert(std::ranges::equal(m, expected)); + } + { + // The element type of the range doesn't need to be std::pair + std::pair pa[] = {{1, 1}, {1, 1}, {3, 3}, {4, 4}, {5, 5}}; + std::vector>> a(pa, pa + 5); + std::flat_multimap m; + m.insert_range(a); + std::pair expected[] = {{1, 1}, {1, 1}, {3, 3}, {4, 4}, {5, 5}}; + assert(std::ranges::equal(m, expected)); + } + if (!TEST_IS_CONSTANT_EVALUATED) { + auto insert_func = [](auto& m, const auto& newValues) { m.insert_range(std::sorted_equivalent, newValues); }; + test_insert_range_exception_guarantee(insert_func); + } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + + return 0; +} diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp index a1252f301309a..85e2df982a7fc 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp @@ -44,8 +44,15 @@ void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { m1.emplace(1, 2); m2.emplace(3, 3); m2.emplace(3, 4); - // swap is noexcept - EXPECT_STD_TERMINATE([&] { swap_function(m1, m2); }); + try { + swap_function(m1, m2); + assert(false); + } catch (int) { + check_invariant(m1); + check_invariant(m2); + LIBCPP_ASSERT(m1.size() == 0); + LIBCPP_ASSERT(m2.size() == 0); + } } { @@ -60,8 +67,15 @@ void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { m2.emplace(3, 3); m2.emplace(3, 4); - // swap is noexcept - EXPECT_STD_TERMINATE([&] { swap_function(m1, m2); }); + try { + swap_function(m1, m2); + assert(false); + } catch (int) { + check_invariant(m1); + check_invariant(m2); + LIBCPP_ASSERT(m1.size() == 0); + LIBCPP_ASSERT(m2.size() == 0); + } } } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_free.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_free.pass.cpp index efad2d78d5b76..f714af77ca647 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_free.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_free.pass.cpp @@ -33,10 +33,9 @@ concept NoExceptAdlSwap = requires(T t1, T t2) { { swap(t1, t2) } noexcept; }; -static_assert(NoExceptAdlSwap>); - +static_assert(NoExceptAdlSwap< std::flat_multimap, std::vector, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS -static_assert(NoExceptAdlSwap< +static_assert(!NoExceptAdlSwap< std::flat_multimap, ThrowOnMoveContainer, ThrowOnMoveContainer>>); #endif diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_member.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_member.pass.cpp index 8f31884aa3a5f..0c6211ab3c2cc 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_member.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_member.pass.cpp @@ -33,9 +33,9 @@ concept NoExceptMemberSwap = requires(T t1, T t2) { { t1.swap(t2) } noexcept; }; -static_assert(NoExceptMemberSwap>); +static_assert(NoExceptMemberSwap< std::flat_multimap, std::vector, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS -static_assert(NoExceptMemberSwap< +static_assert(!NoExceptMemberSwap< std::flat_multimap, ThrowOnMoveContainer, ThrowOnMoveContainer>>); #endif diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range_sorted_equivalent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range_sorted_equivalent.pass.cpp new file mode 100644 index 0000000000000..f6382a200250b --- /dev/null +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range_sorted_equivalent.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, c++11, c++14, c++17, c++20 + +// + +// template R> +// void insert_range(sorted_equivalent_t, R&& rg); + +#include +#include +#include +#include +#include +#include + +#include "MinSequenceContainer.h" +#include "../helpers.h" +#include "MoveOnly.h" +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" + +// test constraint container-compatible-range +template +concept CanInsertRange = requires(M m, R&& r) { m.insert_range(std::forward(r)); }; + +using Set = std::flat_multiset; + +static_assert(CanInsertRange>); +static_assert(CanInsertRange>); +static_assert(!CanInsertRange*>>); +static_assert(!CanInsertRange*>>); + +template +void test_one() { + using Key = typename KeyContainer::value_type; + + { + using M = std::flat_multiset, KeyContainer>; + using It = forward_iterator; + M m = {10, 10, 8, 5, 2, 1, 1}; + int ar[] = {1, 1, 3, 4, 5, 9}; + std::ranges::subrange r = {It(ar), It(ar + 6)}; + static_assert(std::ranges::common_range); + m.insert_range(std::sorted_equivalent, r); + assert((m == M{1, 1, 1, 1, 2, 3, 4, 5, 5, 8, 9, 10, 10})); + } + { + using M = std::flat_multiset, KeyContainer>; + using It = cpp20_input_iterator; + M m = {10, 10, 8, 5, 2, 1, 1}; + int ar[] = {9, 5, 4, 3, 1, 1}; + std::ranges::subrange r = {It(ar), sentinel_wrapper(It(ar + 6))}; + static_assert(!std::ranges::common_range); + m.insert_range(std::sorted_equivalent, r); + assert((m == M{1, 1, 1, 1, 2, 3, 4, 5, 5, 8, 9, 10, 10})); + } + { + // was empty + using M = std::flat_multiset, KeyContainer>; + M m; + int ar[] = {1, 1, 3, 4, 5, 9}; + m.insert_range(std::sorted_equivalent, ar); + assert((m == M{1, 1, 3, 4, 5, 9})); + } +} + +void test() { + test_one>(); + test_one>(); + test_one>(); + test_one>>(); + { + // Items are forwarded correctly from the input range. + MoveOnly a[] = {1, 1, 3, 4, 5}; + std::flat_multiset m; + m.insert_range(std::sorted_equivalent, a | std::views::as_rvalue); + MoveOnly expected[] = {1, 1, 3, 4, 5}; + assert(std::ranges::equal(m, expected)); + } +} + +void test_exception() { + auto insert_func = [](auto& m, const auto& newValues) { m.insert_range(std::sorted_equivalent, newValues); }; + test_insert_range_exception_guarantee(insert_func); +} + +int main(int, char**) { + test(); + test_exception(); + + return 0; +} diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp index 705ee88994872..03dbe95c4e221 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp @@ -41,8 +41,16 @@ void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { m1.emplace(1); m2.emplace(1); m2.emplace(4); - // swap is noexcept - EXPECT_STD_TERMINATE([&] { swap_function(m1, m2); }); + + try { + swap_function(m1, m2); + assert(false); + } catch (int) { + check_invariant(m1); + check_invariant(m2); + LIBCPP_ASSERT(m1.size() == 0); + LIBCPP_ASSERT(m2.size() == 0); + } } } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp index 2e3ed02c3c00e..7746e40c96d8c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp @@ -31,10 +31,9 @@ concept NoExceptAdlSwap = requires(T t1, T t2) { { swap(t1, t2) } noexcept; }; -static_assert(NoExceptAdlSwap>); - +static_assert(NoExceptAdlSwap, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS -static_assert(NoExceptAdlSwap, ThrowOnMoveContainer>>); +static_assert(!NoExceptAdlSwap, ThrowOnMoveContainer>>); #endif template diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_member.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_member.pass.cpp index 1d0d9152d1c1f..ca641fdc9f113 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_member.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_member.pass.cpp @@ -31,9 +31,9 @@ concept NoExceptMemberSwap = requires(T t1, T t2) { { t1.swap(t2) } noexcept; }; -static_assert(NoExceptMemberSwap>); +static_assert(NoExceptMemberSwap, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS -static_assert(NoExceptMemberSwap, ThrowOnMoveContainer>>); +static_assert(!NoExceptMemberSwap, ThrowOnMoveContainer>>); #endif template diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_range_sorted_unique.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_range_sorted_unique.pass.cpp new file mode 100644 index 0000000000000..8d41914fe7ac9 --- /dev/null +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_range_sorted_unique.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, c++20 + +// + +// template R> +// void insert_range(sorted_unique_t, R&& rg); + +#include +#include +#include +#include +#include +#include + +#include "MinSequenceContainer.h" +#include "../helpers.h" +#include "MoveOnly.h" +#include "test_macros.h" +#include "test_iterators.h" +#include "min_allocator.h" + +// test constraint container-compatible-range +template +concept CanInsertRangeSortedUnique = requires(M m, R&& r) { m.insert_range(std::sorted_unique, std::forward(r)); }; + +using Set = std::flat_set; + +static_assert(CanInsertRangeSortedUnique>); +static_assert(CanInsertRangeSortedUnique>); +static_assert(!CanInsertRangeSortedUnique*>>); +static_assert(!CanInsertRangeSortedUnique*>>); + +template +constexpr void test_one() { + using Key = typename KeyContainer::value_type; + + { + using M = std::flat_set, KeyContainer>; + using It = forward_iterator; + M m = {10, 8, 5, 2, 1}; + int ar[] = {1, 3, 4, 5, 9}; + std::ranges::subrange r = {It(ar), It(ar + 5)}; + static_assert(std::ranges::common_range); + m.insert_range(std::sorted_unique, r); + assert((m == M{1, 2, 3, 4, 5, 8, 9, 10})); + } + { + using M = std::flat_set, KeyContainer>; + using It = cpp20_input_iterator; + M m = {8, 5, 3, 2}; + int ar[] = {9, 5, 4, 3, 1}; + std::ranges::subrange r = {It(ar), sentinel_wrapper(It(ar + 5))}; + static_assert(!std::ranges::common_range); + m.insert_range(std::sorted_unique, r); + assert((m == M{1, 2, 3, 4, 5, 8, 9})); + } + { + // was empty + using M = std::flat_set, KeyContainer>; + M m; + int ar[] = {1, 3, 4, 5, 9}; + m.insert_range(std::sorted_unique, ar); + assert((m == M{1, 3, 4, 5, 9})); + } +} + +constexpr bool test() { + test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); + test_one>(); + test_one>>(); + { + // Items are forwarded correctly from the input range. + MoveOnly a[] = {1, 3, 4, 5}; + std::flat_set m; + m.insert_range(std::sorted_unique, a | std::views::as_rvalue); + MoveOnly expected[] = {1, 3, 4, 5}; + assert(std::ranges::equal(m, expected)); + } + + return true; +} + +void test_exception() { + auto insert_func = [](auto& m, const auto& newValues) { m.insert_range(std::sorted_unique, newValues); }; + test_insert_range_exception_guarantee(insert_func); +} + +int main(int, char**) { + test(); + test_exception(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + + return 0; +} diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp index 23a2dc85989bb..268dd11fe83df 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp @@ -41,8 +41,16 @@ void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { m1.emplace(2); m2.emplace(3); m2.emplace(4); - // swap is noexcept - EXPECT_STD_TERMINATE([&] { swap_function(m1, m2); }); + + try { + swap_function(m1, m2); + assert(false); + } catch (int) { + check_invariant(m1); + check_invariant(m2); + LIBCPP_ASSERT(m1.size() == 0); + LIBCPP_ASSERT(m2.size() == 0); + } } } diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_free.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_free.pass.cpp index 6b4a65e4701b2..b07af85063093 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_free.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_free.pass.cpp @@ -31,10 +31,9 @@ concept NoExceptAdlSwap = requires(T t1, T t2) { { swap(t1, t2) } noexcept; }; -static_assert(NoExceptAdlSwap>); - +static_assert(NoExceptAdlSwap, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS -static_assert(NoExceptAdlSwap, ThrowOnMoveContainer>>); +static_assert(!NoExceptAdlSwap, ThrowOnMoveContainer>>); #endif template diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_member.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_member.pass.cpp index a3b605ee94cfb..eaecd5f15a661 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_member.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_member.pass.cpp @@ -31,9 +31,9 @@ concept NoExceptMemberSwap = requires(T t1, T t2) { { t1.swap(t2) } noexcept; }; -static_assert(NoExceptMemberSwap>); +static_assert(NoExceptMemberSwap, std::vector>>); #ifndef TEST_HAS_NO_EXCEPTIONS -static_assert(NoExceptMemberSwap, ThrowOnMoveContainer>>); +static_assert(!NoExceptMemberSwap, ThrowOnMoveContainer>>); #endif template From 90923829109cc2196b9575e1f553d4bede04bbb7 Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 5 Oct 2025 21:13:41 +0100 Subject: [PATCH 2/3] ci --- libcxx/include/__flat_set/flat_multiset.h | 2 +- .../flat.map/flat.map.modifiers/swap_exception.pass.cpp | 1 + .../flat.multimap.modifiers/swap_exception.pass.cpp | 2 -- .../flat.multiset.modifiers/swap_exception.pass.cpp | 2 -- .../flat.set/flat.set.modifiers/swap_exception.pass.cpp | 2 -- 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/libcxx/include/__flat_set/flat_multiset.h b/libcxx/include/__flat_set/flat_multiset.h index 19f8b0ff01539..7754e9435d4f4 100644 --- a/libcxx/include/__flat_set/flat_multiset.h +++ b/libcxx/include/__flat_set/flat_multiset.h @@ -603,7 +603,7 @@ class flat_multiset { ranges::sort(__keys_.begin() + __old_size, __keys_.end(), __compare_); } else { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( - ranges::is_sorted(__keys_ | ranges::views::drop(__old_size)), "Key container is not sorted"); + ranges::is_sorted(__keys_ | ranges::views::drop(__old_size), __compare_), "Key container is not sorted"); } ranges::inplace_merge(__keys_.begin(), __keys_.begin() + __old_size, __keys_.end(), __compare_); __on_failure.__complete(); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp index 96b88a5fbfacb..a5db32813bf46 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// UNSUPPORTED: no-localization // UNSUPPORTED: no-exceptions // diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp index 85e2df982a7fc..1ad7d9697b8e4 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// `check_assertion.h` requires Unix headers and regex support. -// REQUIRES: has-unix-headers // UNSUPPORTED: no-localization // UNSUPPORTED: no-exceptions diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp index 03dbe95c4e221..76903f30353b7 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// `check_assertion.h` requires Unix headers and regex support. -// REQUIRES: has-unix-headers // UNSUPPORTED: no-localization // UNSUPPORTED: no-exceptions diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp index 268dd11fe83df..e4b5f24b3e824 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// `check_assertion.h` requires Unix headers and regex support. -// REQUIRES: has-unix-headers // UNSUPPORTED: no-localization // UNSUPPORTED: no-exceptions From b2373bbff4cfce90eb9d63e8ed8b9039dd3969ec Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 5 Oct 2025 21:14:44 +0100 Subject: [PATCH 3/3] remove headers from test --- .../flat.map/flat.map.modifiers/swap_exception.pass.cpp | 1 - .../flat.multimap.modifiers/swap_exception.pass.cpp | 1 - .../flat.multiset.modifiers/swap_exception.pass.cpp | 1 - .../flat.set/flat.set.modifiers/swap_exception.pass.cpp | 1 - 4 files changed, 4 deletions(-) diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp index a5db32813bf46..8b8e70fab41e1 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/swap_exception.pass.cpp @@ -25,7 +25,6 @@ #include "test_macros.h" #include "../helpers.h" -#include "check_assertion.h" template void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp index 1ad7d9697b8e4..d426944c9463a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/swap_exception.pass.cpp @@ -27,7 +27,6 @@ #include "test_macros.h" #include "../helpers.h" -#include "check_assertion.h" template void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp index 76903f30353b7..af035f6464696 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_exception.pass.cpp @@ -25,7 +25,6 @@ #include "test_macros.h" #include "../helpers.h" -#include "check_assertion.h" template void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp index e4b5f24b3e824..ae0d4f0950fa7 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/swap_exception.pass.cpp @@ -25,7 +25,6 @@ #include "test_macros.h" #include "../helpers.h" -#include "check_assertion.h" template void test_swap_exception_guarantee([[maybe_unused]] F&& swap_function) {