diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h index f5e9756ff6a60..97e863c85371a 100644 --- a/libcxx/include/__flat_map/flat_map.h +++ b/libcxx/include/__flat_map/flat_map.h @@ -11,16 +11,15 @@ #define _LIBCPP___FLAT_MAP_FLAT_MAP_H #include <__algorithm/lexicographical_compare_three_way.h> +#include <__algorithm/lower_bound.h> #include <__algorithm/min.h> #include <__algorithm/ranges_adjacent_find.h> #include <__algorithm/ranges_equal.h> #include <__algorithm/ranges_inplace_merge.h> -#include <__algorithm/ranges_lower_bound.h> -#include <__algorithm/ranges_partition_point.h> #include <__algorithm/ranges_sort.h> #include <__algorithm/ranges_unique.h> -#include <__algorithm/ranges_upper_bound.h> #include <__algorithm/remove_if.h> +#include <__algorithm/upper_bound.h> #include <__assert> #include <__compare/synth_three_way.h> #include <__concepts/swappable.h> @@ -863,6 +862,13 @@ class flat_map { __containers_.values.erase(__containers_.values.begin() + __dist, __containers_.values.end()); } + template + _LIBCPP_HIDE_FROM_ABI static auto __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) { + return __self.__containers_.values.begin() + + static_cast>( + ranges::distance(__self.__containers_.keys.begin(), __key_iter)); + } + template _LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); @@ -903,7 +909,8 @@ class flat_map { template _LIBCPP_HIDE_FROM_ABI static auto __key_equal_range(_Self&& __self, const _Kp& __key) { - auto __it = ranges::lower_bound(__self.__containers_.keys, __key, __self.__compare_); + auto __it = + std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_); auto __last = __self.__containers_.keys.end(); if (__it == __last || __self.__compare_(__key, *__it)) { return std::make_pair(__it, __it); @@ -914,42 +921,30 @@ class flat_map { template _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { auto [__key_first, __key_last] = __key_equal_range(__self, __key); - - const auto __make_mapped_iter = [&](const auto& __key_iter) { - return __self.__containers_.values.begin() + - static_cast>( - ranges::distance(__self.__containers_.keys.begin(), __key_iter)); - }; - - using __iterator_type = ranges::iterator_t; - return std::make_pair(__iterator_type(__key_first, __make_mapped_iter(__key_first)), - __iterator_type(__key_last, __make_mapped_iter(__key_last))); + using __iterator_type = ranges::iterator_t; + return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)), + __iterator_type(__key_last, __corresponding_mapped_it(__self, __key_last))); } template _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) { - return __binary_search<_Res>(__self, ranges::lower_bound, __x); + auto __key_iter = + std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); + auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); + return _Res(std::move(__key_iter), std::move(__mapped_iter)); } template _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) { - return __binary_search<_Res>(__self, ranges::upper_bound, __x); - } - - template - _LIBCPP_HIDE_FROM_ABI static _Res __binary_search(_Self&& __self, _Fn __search_fn, _Kp& __x) { - auto __key_iter = __search_fn(__self.__containers_.keys, __x, __self.__compare_); - auto __mapped_iter = - __self.__containers_.values.begin() + - static_cast>( - ranges::distance(__self.__containers_.keys.begin(), __key_iter)); - + auto __key_iter = + std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); + auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); return _Res(std::move(__key_iter), std::move(__mapped_iter)); } template _LIBCPP_HIDE_FROM_ABI pair __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) { - auto __key_it = ranges::lower_bound(__containers_.keys, __key, __compare_); + auto __key_it = std::lower_bound(__containers_.keys.begin(), __containers_.keys.end(), __key, __compare_); auto __mapped_it = __containers_.values.begin() + ranges::distance(__containers_.keys.begin(), __key_it); if (__key_it == __containers_.keys.end() || __compare_(__key, *__key_it)) { diff --git a/libcxx/include/__flat_map/flat_multimap.h b/libcxx/include/__flat_map/flat_multimap.h index 15fcd7995ad0a..d56d2bdb60462 100644 --- a/libcxx/include/__flat_map/flat_multimap.h +++ b/libcxx/include/__flat_map/flat_multimap.h @@ -10,18 +10,16 @@ #ifndef _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H #define _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H +#include <__algorithm/equal_range.h> #include <__algorithm/lexicographical_compare_three_way.h> +#include <__algorithm/lower_bound.h> #include <__algorithm/min.h> #include <__algorithm/ranges_equal.h> -#include <__algorithm/ranges_equal_range.h> #include <__algorithm/ranges_inplace_merge.h> #include <__algorithm/ranges_is_sorted.h> -#include <__algorithm/ranges_lower_bound.h> -#include <__algorithm/ranges_partition_point.h> #include <__algorithm/ranges_sort.h> -#include <__algorithm/ranges_unique.h> -#include <__algorithm/ranges_upper_bound.h> #include <__algorithm/remove_if.h> +#include <__algorithm/upper_bound.h> #include <__assert> #include <__compare/synth_three_way.h> #include <__concepts/convertible_to.h> @@ -443,7 +441,7 @@ class flat_multimap { is_move_constructible_v _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) { std::pair __pair(std::forward<_Args>(__args)...); - auto __key_it = ranges::upper_bound(__containers_.keys, __pair.first, __compare_); + auto __key_it = std::upper_bound(__containers_.keys.begin(), __containers_.keys.end(), __pair.first, __compare_); auto __mapped_it = __corresponding_mapped_it(*this, __key_it); return __flat_map_utils::__emplace_exact_pos( @@ -473,7 +471,7 @@ class flat_multimap { // | // hint // We want to insert "2" after the last existing "2" - __key_iter = ranges::upper_bound(__containers_.keys.begin(), __key_iter, __pair.first, __compare_); + __key_iter = std::upper_bound(__containers_.keys.begin(), __key_iter, __pair.first, __compare_); __mapped_iter = __corresponding_mapped_it(*this, __key_iter); } else { _LIBCPP_ASSERT_INTERNAL(!__prev_larger && __next_smaller, "this means that the multimap is not sorted"); @@ -485,7 +483,7 @@ class flat_multimap { // | // hint // We want to insert "2" before the first existing "2" - __key_iter = ranges::lower_bound(__key_iter, __containers_.keys.end(), __pair.first, __compare_); + __key_iter = std::lower_bound(__key_iter, __containers_.keys.end(), __pair.first, __compare_); __mapped_iter = __corresponding_mapped_it(*this, __key_iter); } return __flat_map_utils::__emplace_exact_pos( @@ -804,7 +802,8 @@ class flat_multimap { template _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { - auto [__key_first, __key_last] = ranges::equal_range(__self.__containers_.keys, __key, __self.__compare_); + auto [__key_first, __key_last] = + std::equal_range(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_); using __iterator_type = ranges::iterator_t; return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)), @@ -813,14 +812,16 @@ class flat_multimap { template _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) { - auto __key_iter = ranges::lower_bound(__self.__containers_.keys, __x, __self.__compare_); + auto __key_iter = + std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); return _Res(std::move(__key_iter), std::move(__mapped_iter)); } template _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) { - auto __key_iter = ranges::upper_bound(__self.__containers_.keys, __x, __self.__compare_); + auto __key_iter = + std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); return _Res(std::move(__key_iter), std::move(__mapped_iter)); } diff --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h index a87496bb9916e..35ca8feab0fd2 100644 --- a/libcxx/include/__flat_set/flat_set.h +++ b/libcxx/include/__flat_set/flat_set.h @@ -16,7 +16,6 @@ #include <__algorithm/ranges_adjacent_find.h> #include <__algorithm/ranges_equal.h> #include <__algorithm/ranges_inplace_merge.h> -#include <__algorithm/ranges_partition_point.h> #include <__algorithm/ranges_sort.h> #include <__algorithm/ranges_unique.h> #include <__algorithm/remove_if.h> diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp index 456f12e0c0d29..bc3fbfca5762b 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp @@ -106,6 +106,13 @@ int main(int, char**) { TEST_IGNORE_NODISCARD m.at(Transparent{3}); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + int& x = m.at("alpha"); + assert(x == 1); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp index 24c08464f3158..760ec69ae878d 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp @@ -94,6 +94,13 @@ int main(int, char**) { m[ConvertibleTransparent{3}]; assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + int& x = m["alpha"]; + assert(x == 1); + } { auto index_func = [](auto& m, auto key_arg, auto value_arg) { using FlatMap = std::decay_t; diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key_transparent.pass.cpp index 3ba30757bf2c7..ecc71a65caa83 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/erase_key_transparent.pass.cpp @@ -139,6 +139,13 @@ int main(int, char**) { }; test_erase_exception_guarantee(erase_transparent); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto n = m.erase("beta"); + assert(n == 1); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign_transparent.pass.cpp index 636c4edfe551d..bd6d176e26e23 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_or_assign_transparent.pass.cpp @@ -254,6 +254,18 @@ int main(int, char**) { }; test_emplace_exception_guarantee(insert_or_assign_iter); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto [it, inserted] = m.insert_or_assign("alpha", 2); + assert(!inserted); + assert(it == m.begin()); + assert(it->second == 2); + auto it2 = m.insert_or_assign(m.begin(), "beta2", 2); + assert(it2 == m.begin() + 2); + assert(it2->second == 2); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_transparent.pass.cpp index 75cabb70630f3..c24c8373f51e9 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_transparent.pass.cpp @@ -163,5 +163,15 @@ int main(int, char**) { }; test_emplace_exception_guarantee(insert_func_iter); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto [it, inserted] = m.insert({"alpha", 1}); + assert(!inserted); + assert(it == m.begin()); + auto it2 = m.insert(m.begin(), {"beta2", 2}); + assert(it2 == m.begin() + 2); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp index 21fda43780967..c301f07937ea7 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/try_emplace_transparent.pass.cpp @@ -160,6 +160,17 @@ int main(int, char**) { assert(p->second == 3); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto [it1, inserted] = m.try_emplace("charlie", 4); + assert(it1 == m.begin() + 2); + assert(inserted); + + auto it2 = m.try_emplace(m.begin(), "beta2", 2); + assert(it2 == m.begin() + 2); + } { auto try_emplace = [](auto& m, auto key_arg, auto value_arg) { using M = std::decay_t; diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/contains_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/contains_transparent.pass.cpp index 0493538ab6dad..e28e94c3d8fb9 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/contains_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/contains_transparent.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -67,5 +68,12 @@ int main(int, char**) { assert(b); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + assert(m.contains("beta") == true); + assert(m.contains("charlie") == false); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/count_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/count_transparent.pass.cpp index cd195ff1fa8b4..37d815b2ce988 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/count_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/count_transparent.pass.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,13 @@ int main(int, char**) { assert(n == 1); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + assert(m.count("alpha") == 1); + assert(m.count("charlie") == 0); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/equal_range_transparent.pass.cpp index 0198f433bdc4f..bff70a320928a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/equal_range_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/equal_range_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -95,6 +96,14 @@ int main(int, char**) { assert(p.first != p.second); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto [first, last] = m.equal_range("beta"); + assert(first == m.begin() + 1); + assert(last == m.begin() + 2); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/find_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/find_transparent.pass.cpp index 291577a89fc8f..b1d1301fce63a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/find_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/find_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,13 @@ int main(int, char**) { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto it = m.find("beta"); + assert(it == m.begin() + 1); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound_transparent.pass.cpp index 6a923c197e91e..9e25616311963 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/lower_bound_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -90,6 +91,13 @@ int main(int, char**) { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto it = m.lower_bound("charlie"); + assert(it == m.begin() + 2); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound_transparent.pass.cpp index 4e83f920835df..c87113f670184 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.operations/upper_bound_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,13 @@ int main(int, char**) { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_map>; + M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}}; + auto it = m.upper_bound("charlie"); + assert(it == m.begin() + 2); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key_transparent.pass.cpp index 75a2d205b8f87..5627a67b29e9d 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/erase_key_transparent.pass.cpp @@ -156,6 +156,13 @@ int main(int, char**) { }; test_erase_exception_guarantee(erase_transparent); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + auto n = m.erase("beta"); + assert(n == 2); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_transparent.pass.cpp index 33ca4d4e30469..760479ade76e4 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.modifiers/insert_transparent.pass.cpp @@ -131,5 +131,14 @@ int main(int, char**) { }; test_emplace_exception_guarantee(insert_func_iter); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + auto it = m.insert({"beta", 1}); + assert(it == m.begin() + 3); + auto it2 = m.insert(m.begin(), {"beta2", 2}); + assert(it2 == m.begin() + 4); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/contains_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/contains_transparent.pass.cpp index 8a66ec63768d7..42feeb0c93416 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/contains_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/contains_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -69,5 +70,12 @@ int main(int, char**) { assert(b); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + assert(m.contains("beta") == true); + assert(m.contains("charlie") == false); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/count_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/count_transparent.pass.cpp index 41f71065b2f75..6811be5de1f02 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/count_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/count_transparent.pass.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,13 @@ int main(int, char**) { assert(n == 2); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + assert(m.count("beta") == 2); + assert(m.count("charlie") == 0); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/equal_range_transparent.pass.cpp index 3666492bb921f..d80c37feecc07 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/equal_range_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/equal_range_transparent.pass.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -105,6 +106,14 @@ int main(int, char**) { assert(p.second == m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + auto [first, last] = m.equal_range("beta"); + assert(first == m.begin() + 1); + assert(last == m.begin() + 3); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/find_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/find_transparent.pass.cpp index be8c6f2e35440..dff63560c3cb4 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/find_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/find_transparent.pass.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,13 @@ int main(int, char**) { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + auto it = m.find("beta"); + assert(it == m.begin() + 1); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/lower_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/lower_bound_transparent.pass.cpp index b757af132e677..3161ca01e5579 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/lower_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/lower_bound_transparent.pass.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -102,6 +103,13 @@ int main(int, char**) { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + auto it = m.lower_bound("charlie"); + assert(it == m.begin() + 3); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/upper_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/upper_bound_transparent.pass.cpp index 969489d0fe619..d51d87ce77882 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/upper_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/upper_bound_transparent.pass.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -101,6 +102,13 @@ int main(int, char**) { assert(it == m.begin() + 3); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_multimap>; + M m{{"alpha", 1}, {"beta", 2}, {"beta", 1}, {"eta", 3}, {"gamma", 3}}; + auto it = m.upper_bound("charlie"); + assert(it == m.begin() + 3); + } return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_key_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_key_transparent.pass.cpp index 9dd91628d1c29..f4b373364cab2 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_key_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/erase_key_transparent.pass.cpp @@ -138,6 +138,13 @@ void test() { assert(n == 1); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + auto n = m.erase("beta"); + assert(n == 1); + } } void test_exception() { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_transparent.pass.cpp index f60fd78008a30..4b5779a10ee7a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/insert_transparent.pass.cpp @@ -123,6 +123,14 @@ void test() { ASSERT_SAME_TYPE(decltype(m.insert(m.begin(), Evil())), M::iterator); ASSERT_SAME_TYPE(decltype(m.insert(m.begin(), m.end())), void); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + auto [iter, inserted] = m.insert("beta"); + assert(!inserted); + assert(iter == m.begin() + 1); + } } void test_exception() { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/contains_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/contains_transparent.pass.cpp index cae8eea89471b..91f49305cd71b 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/contains_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/contains_transparent.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -74,6 +75,13 @@ void test() { assert(b); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + assert(m.contains("beta")); + assert(!m.contains("eta2")); + } } int main(int, char**) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/count_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/count_transparent.pass.cpp index b24b6fa712fa9..84e7b9a18b83b 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/count_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/count_transparent.pass.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,13 @@ void test() { assert(n == 1); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + assert(m.count("beta") == 1); + assert(m.count("eta2") == 0); + } } int main(int, char**) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/equal_range_transparent.pass.cpp index 8a270ffa15915..31081eb970397 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/equal_range_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/equal_range_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -101,6 +102,14 @@ void test() { assert(p.first != p.second); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + auto [first, last] = m.equal_range("beta"); + assert(first == m.begin() + 1); + assert(last == m.begin() + 2); + } } int main(int, char**) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/find_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/find_transparent.pass.cpp index 6ba91bd5ebe43..b8d454c58f54c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/find_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/find_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,15 @@ void test() { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + auto it = m.find("beta"); + assert(it == m.begin() + 1); + auto it2 = m.find("beta2"); + assert(it2 == m.end()); + } } int main(int, char**) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/lower_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/lower_bound_transparent.pass.cpp index 8fcfe4d9d432b..0c3e25f795f33 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/lower_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/lower_bound_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -97,6 +98,15 @@ void test() { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + auto it = m.lower_bound("beta"); + assert(it == m.begin() + 1); + auto it2 = m.lower_bound("beta2"); + assert(it2 == m.begin() + 2); + } } int main(int, char**) { diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/upper_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/upper_bound_transparent.pass.cpp index db89614dd815b..36f2a20946496 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/upper_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.operations/upper_bound_transparent.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -97,6 +98,15 @@ void test() { assert(it != m.end()); assert(transparent_used); } + { + // LWG4239 std::string and C string literal + using M = std::flat_set>; + M m{"alpha", "beta", "epsilon", "eta", "gamma"}; + auto it = m.upper_bound("beta"); + assert(it == m.begin() + 2); + auto it2 = m.upper_bound("beta2"); + assert(it2 == m.begin() + 2); + } } int main(int, char**) {