[libcxx-commits] [libcxx] 21f78d9 - [libc++][ranges] Fix the LWG 3568 test for `basic_istream_view` (#215589)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 13 03:32:38 PDT 2026
Author: Iskandar Emomzoda
Date: 2026-08-13T18:32:32+08:00
New Revision: 21f78d9c5dd6c92464093facae4c24a52a0fd846
URL: https://github.com/llvm/llvm-project/commit/21f78d9c5dd6c92464093facae4c24a52a0fd846
DIFF: https://github.com/llvm/llvm-project/commit/21f78d9c5dd6c92464093facae4c24a52a0fd846.diff
LOG: [libc++][ranges] Fix the LWG 3568 test for `basic_istream_view` (#215589)
The previous test was dereferencing `begin()` iterator on empty view
which is UB, because `begin() == end()`.
A new test case was suggested in a post-merge feedback in #193891, which
verifies LWG3568 through constant evaluation. Such a `constexpr`
`basic_istream_view` variable can only be created if it is completely
initialized, including its exposition-only _`value_`_ member.
The existing test case is changed to use a non-empty stream and a
testing class type for which `operator>>` is no-op. The state of the
class object stored in `basic_istream_view` is unchanged even after the
initial `operator>>` call.
This avoids dereferencing a past-the-end iterator while testing LWG3568.
Added:
Modified:
libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp
index beeeea4c1bbe1..7e9ec8bf631a8 100644
--- a/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.istream.view/ctor.pass.cpp
@@ -27,6 +27,15 @@ static_assert(std::constructible_from<std::ranges::wistream_view<int>, std::wist
static_assert(!std::convertible_to<std::wistream&, std::ranges::wistream_view<int>>);
#endif
+struct NoopExtraction {
+ int n_; // intentionally doesn't have default member initializer
+};
+
+template <class CharT, class Traits>
+std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, const NoopExtraction&) {
+ return is; // intentionally doesn't modify the NoopExtraction object
+}
+
template <class CharT>
void test() {
// test constructor init the stream pointer to the passed one
@@ -37,12 +46,18 @@ void test() {
assert(*it == 123);
}
+ // LWG 3568. value_ must be initialized for basic_istream_view to be constexpr-constructible
+ {
+ static auto fn_local_iss = make_string_stream<CharT>("");
+ [[maybe_unused]] constexpr auto isv = std::views::istream<int>(fn_local_iss);
+ }
+
// LWG 3568. basic_istream_view needs to initialize value_
{
- auto iss = make_string_stream<CharT>("");
- std::ranges::basic_istream_view<int, CharT> isv{iss};
- auto iter = isv.begin();
- assert(*iter == 0);
+ auto iss = make_string_stream<CharT>("123");
+ std::ranges::basic_istream_view<NoopExtraction, CharT> isv{iss};
+ auto it = isv.begin();
+ assert((*it).n_ == 0);
}
}
More information about the libcxx-commits
mailing list