diff --git a/libcxx/include/__flat_set/utils.h b/libcxx/include/__flat_set/utils.h index ed3b4c48580fb..542bfd886aef5 100644 --- a/libcxx/include/__flat_set/utils.h +++ b/libcxx/include/__flat_set/utils.h @@ -11,6 +11,7 @@ #define _LIBCPP___FLAT_SET_UTILS_H #include <__config> +#include <__iterator/iterator_traits.h> #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__type_traits/container_traits.h> @@ -60,7 +61,8 @@ struct __flat_set_utils { // C++23 Sequence Container should have insert_range member function // Note that not all Sequence Containers provide append_range. __set.__keys_.insert_range(__set.__keys_.end(), std::forward<_Range>(__rng)); - } else if constexpr (ranges::common_range<_Range>) { + } else if constexpr (ranges::common_range<_Range> && + __has_input_iterator_category>::value) { __set.__keys_.insert(__set.__keys_.end(), ranges::begin(__rng), ranges::end(__rng)); } else { for (auto&& __x : __rng) { diff --git a/libcxx/test/libcxx/containers/container.adaptors/flat.multiset/insert_range.pass.cpp b/libcxx/test/libcxx/containers/container.adaptors/flat.multiset/insert_range.pass.cpp new file mode 100644 index 0000000000000..3ca021c2ac650 --- /dev/null +++ b/libcxx/test/libcxx/containers/container.adaptors/flat.multiset/insert_range.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 +// UNSUPPORTED: no-localization + +// + +// 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 +#include +#include +#include + +#include "MinSequenceContainer.h" +#include "test_macros.h" + +void test() { + MinSequenceContainer v; + std::flat_multiset s(v); + std::istringstream ints("0 1 1 0"); + auto r = std::ranges::subrange(std::istream_iterator(ints), std::istream_iterator()) | + std::views::transform([](int i) { return i * i; }); + static_assert( + ![](auto& t) { return requires { t.insert_range(r); }; }(v), + "This test is to test the case where the underlying container does not provide insert_range"); + s.insert_range(r); +} + +int main(int, char**) { + test(); + + return 0; +} diff --git a/libcxx/test/libcxx/containers/container.adaptors/flat.set/insert_range.pass.cpp b/libcxx/test/libcxx/containers/container.adaptors/flat.set/insert_range.pass.cpp new file mode 100644 index 0000000000000..8023e251ccb17 --- /dev/null +++ b/libcxx/test/libcxx/containers/container.adaptors/flat.set/insert_range.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 +// UNSUPPORTED: no-localization + +// + +// 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 +#include +#include +#include + +#include "MinSequenceContainer.h" +#include "test_macros.h" + +void test() { + MinSequenceContainer v; + std::flat_set s(v); + std::istringstream ints("0 1 1 0"); + auto r = std::ranges::subrange(std::istream_iterator(ints), std::istream_iterator()) | + std::views::transform([](int i) { return i * i; }); + static_assert( + ![](auto& t) { return requires { t.insert_range(r); }; }(v), + "This test is to test the case where the underlying container does not provide insert_range"); + s.insert_range(r); +} + +int main(int, char**) { + test(); + + return 0; +}