[libcxx-commits] [libcxx] [libc++][ranges] LWG4013: Make lazy_split_view::outer-iterator::value_type non-default-constructible (PR #221919)
Vishank Singh via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Sep 8 02:11:35 PDT 2026
https://github.com/VishankSingh updated https://github.com/llvm/llvm-project/pull/221919
>From ec2bc7935b0aa58da3e8ba785ef6982d39f49e2d Mon Sep 17 00:00:00 2001
From: vishanksingh <vishanksinghh at gmail.com>
Date: Tue, 8 Sep 2026 13:51:25 +0530
Subject: [PATCH] [libc++][ranges] LWG4013: Make
lazy_split_view::outer-iterator::value_type non-default-constructible
Remove the public default constructor of outer-iterator::value_type and
make the remaining constructor private (exposition-only), as required by
LWG 4013.
Update the corresponding tests:
- ctor.default.pass.cpp now verifies the type is not default-constructible
- ctor.iter.pass.cpp verifies the constructor is private while still
testing construction via operator*
Closes #105321
---
libcxx/include/__ranges/lazy_split_view.h | 4 ++--
.../ctor.default.pass.cpp | 24 +++++++------------
.../ctor.iter.pass.cpp | 9 +++++--
3 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/libcxx/include/__ranges/lazy_split_view.h b/libcxx/include/__ranges/lazy_split_view.h
index de7105944aa59..735cc0cfd63b7 100644
--- a/libcxx/include/__ranges/lazy_split_view.h
+++ b/libcxx/include/__ranges/lazy_split_view.h
@@ -193,12 +193,12 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>
struct value_type : view_interface<value_type> {
private:
+ friend struct __outer_iterator;
__outer_iterator __i_ = __outer_iterator();
- public:
- _LIBCPP_HIDE_FROM_ABI value_type() = default;
_LIBCPP_HIDE_FROM_ABI constexpr explicit value_type(__outer_iterator __i) : __i_(std::move(__i)) {}
+ public:
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __inner_iterator<_Const> begin() const {
return __inner_iterator<_Const>{__i_};
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp
index f92ea01ccd1db..d99857c48ab39 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp
@@ -8,28 +8,22 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
-// std::ranges::lazy_split_view::outer-iterator::value_type::value_type()
+// LWG 4013: lazy_split_view::outer-iterator::value_type should not provide a default constructor
+// class std::ranges::lazy_split_view::outer-iterator::value_type
+
+#include <concepts>
#include <ranges>
+#include <type_traits>
#include "../types.h"
constexpr bool test() {
- {
- [[maybe_unused]] ValueTypeForward val;
- }
-
- {
- [[maybe_unused]] ValueTypeForward val = {};
- }
-
- {
- [[maybe_unused]] ValueTypeInput val;
- }
+ static_assert(!std::default_initializable<ValueTypeForward>);
+ static_assert(!std::is_default_constructible_v<ValueTypeForward>);
- {
- [[maybe_unused]] ValueTypeInput val = {};
- }
+ static_assert(!std::default_initializable<ValueTypeInput>);
+ static_assert(!std::is_default_constructible_v<ValueTypeInput>);
return true;
}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp
index f533c1b9fbebd..318a859ed2b37 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp
@@ -9,12 +9,17 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
// explicit outer-iterator::value_type::value_type(outer-iterator i)
+// LWG 4013: outer-iterator::value_type constructor taking outer-iterator should be private
#include <ranges>
#include <cassert>
#include "../types.h"
+// Verify that the constructor is private / not constructible by users (LWG 4013).
+static_assert(!std::is_constructible_v<ValueTypeForward, OuterIterForward>);
+static_assert(!std::is_constructible_v<ValueTypeInput, OuterIterInput>);
+
// Verify that the constructor is `explicit`.
static_assert(!std::is_convertible_v<OuterIterForward, ValueTypeForward>);
static_assert(!std::is_convertible_v<OuterIterInput, ValueTypeInput>);
@@ -24,7 +29,7 @@ constexpr bool test() {
{
CopyableView input = "a";
SplitViewCopyable v(input, "b");
- ValueTypeCopyable val(v.begin());
+ ValueTypeCopyable val = *v.begin();
assert(val.begin().base() == input.begin());
}
@@ -32,7 +37,7 @@ constexpr bool test() {
{
InputView input = "a";
SplitViewInput v(input, 'b');
- ValueTypeInput val(v.begin());
+ ValueTypeInput val = *v.begin();
assert(*val.begin().base() == *input.begin());
}
More information about the libcxx-commits
mailing list