[libcxx-commits] [libcxx] e3a60a7 - [libc++][ranges] Implement LWG4013: Make `lazy_split_view::outer-iterator::value_type` non-default-constructible (#221919)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Sep 8 23:29:40 PDT 2026
Author: Vishank Singh
Date: 2026-09-09T14:29:35+08:00
New Revision: e3a60a700dfa488adebd546705424aae7c8b3a35
URL: https://github.com/llvm/llvm-project/commit/e3a60a700dfa488adebd546705424aae7c8b3a35
DIFF: https://github.com/llvm/llvm-project/commit/e3a60a700dfa488adebd546705424aae7c8b3a35.diff
LOG: [libc++][ranges] Implement LWG4013: Make `lazy_split_view::outer-iterator::value_type` non-default-constructible (#221919)
Remove the 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` and `ctor.iter.pass.cpp` are now deleted.
- `ctor.compile.pass.cpp` is added to verify `value_type` is not
default-constructible and its construction from iterator is not
available.
- Cases testing construction of `value_type` via `operator*` are moved
to `range.lazy.split.outer/deref.pass.cpp`.
Closes #105321
Added:
libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.compile.pass.cpp
Modified:
libcxx/docs/Status/Cxx26Issues.csv
libcxx/include/__ranges/lazy_split_view.h
libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/deref.pass.cpp
Removed:
libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp
libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp
################################################################################
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index bc69548295fb5..b98f3ee12f3af 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -47,7 +47,7 @@
"`LWG3984 <https://wg21.link/LWG3984>`__","``ranges::to``'s recursion branch may be ill-formed","2024-03 (Tokyo)","|Complete|","19","`#105318 <https://github.com/llvm/llvm-project/issues/105318>`__",""
"`LWG4011 <https://wg21.link/LWG4011>`__","""``Effects``: Equivalent to return"" in ``[span.elem]``","2024-03 (Tokyo)","|Nothing To Do|","","`#105319 <https://github.com/llvm/llvm-project/issues/105319>`__",""
"`LWG4012 <https://wg21.link/LWG4012>`__","``common_view::begin/end`` are missing the ``simple-view`` check","2024-03 (Tokyo)","|Complete|","23","`#105320 <https://github.com/llvm/llvm-project/issues/105320>`__",""
-"`LWG4013 <https://wg21.link/LWG4013>`__","``lazy_split_view::outer-iterator::value_type`` should not provide default constructor","2024-03 (Tokyo)","","","`#105321 <https://github.com/llvm/llvm-project/issues/105321>`__",""
+"`LWG4013 <https://wg21.link/LWG4013>`__","``lazy_split_view::outer-iterator::value_type`` should not provide default constructor","2024-03 (Tokyo)","|Complete|","24","`#105321 <https://github.com/llvm/llvm-project/issues/105321>`__",""
"`LWG4016 <https://wg21.link/LWG4016>`__","container-insertable checks do not match what container-inserter does","2024-03 (Tokyo)","|Complete|","20","`#105322 <https://github.com/llvm/llvm-project/issues/105322>`__",""
"`LWG4023 <https://wg21.link/LWG4023>`__","Preconditions of ``std::basic_streambuf::setg/setp``","2024-03 (Tokyo)","|Complete|","19","`#105323 <https://github.com/llvm/llvm-project/issues/105323>`__",""
"`LWG4025 <https://wg21.link/LWG4025>`__","Move assignment operator of ``std::expected<cv void, E>`` should not be conditionally deleted","2024-03 (Tokyo)","|Complete|","20","`#105324 <https://github.com/llvm/llvm-project/issues/105324>`__",""
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.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.compile.pass.cpp
new file mode 100644
index 0000000000000..427804b9ee066
--- /dev/null
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+// std::ranges::lazy_split_view::outer-iterator::value_type
+
+#include <ranges>
+#include <type_traits>
+
+#include "../types.h"
+
+// outer-iterator::value_type should not be default-constructible (LWG 4013).
+static_assert(!std::is_default_constructible_v<ValueTypeForward>);
+static_assert(!std::is_default_constructible_v<ValueTypeInput>);
+
+// outer-iterator::value_type constructor from outer-iterator is private / not constructible by users (LWG 4013).
+static_assert(!std::is_constructible_v<ValueTypeForward, OuterIterForward>);
+static_assert(!std::is_constructible_v<ValueTypeInput, OuterIterInput>);
+static_assert(!std::is_convertible_v<OuterIterForward, ValueTypeForward>);
+static_assert(!std::is_convertible_v<OuterIterInput, ValueTypeInput>);
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
deleted file mode 100644
index f92ea01ccd1db..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// std::ranges::lazy_split_view::outer-iterator::value_type::value_type()
-
-#include <ranges>
-
-#include "../types.h"
-
-constexpr bool test() {
- {
- [[maybe_unused]] ValueTypeForward val;
- }
-
- {
- [[maybe_unused]] ValueTypeForward val = {};
- }
-
- {
- [[maybe_unused]] ValueTypeInput val;
- }
-
- {
- [[maybe_unused]] ValueTypeInput val = {};
- }
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
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
deleted file mode 100644
index f533c1b9fbebd..0000000000000
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// explicit outer-iterator::value_type::value_type(outer-iterator i)
-
-#include <ranges>
-
-#include <cassert>
-#include "../types.h"
-
-// Verify that the constructor is `explicit`.
-static_assert(!std::is_convertible_v<OuterIterForward, ValueTypeForward>);
-static_assert(!std::is_convertible_v<OuterIterInput, ValueTypeInput>);
-
-constexpr bool test() {
- // `View` is a forward range.
- {
- CopyableView input = "a";
- SplitViewCopyable v(input, "b");
- ValueTypeCopyable val(v.begin());
- assert(val.begin().base() == input.begin());
- }
-
- // `View` is an input range.
- {
- InputView input = "a";
- SplitViewInput v(input, 'b');
- ValueTypeInput val(v.begin());
- assert(*val.begin().base() == *input.begin());
- }
-
- return true;
-}
-
-int main(int, char**) {
- test();
- static_assert(test());
-
- return 0;
-}
diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/deref.pass.cpp
index aa1edd2f9ff95..4955857d8fb70 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/deref.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/deref.pass.cpp
@@ -48,6 +48,19 @@ constexpr bool test() {
test_one<SplitViewDiff>(" ");
test_one<SplitViewInput>(' ');
+ {
+ CopyableView input = "a";
+ SplitViewCopyable v(input, "b");
+ auto val = *v.begin();
+ assert(val.begin().base() == input.begin());
+ }
+ {
+ InputView input = "a";
+ SplitViewInput v(input, 'b');
+ auto val = *v.begin();
+ assert(*val.begin().base() == *input.begin());
+ }
+
return true;
}
More information about the libcxx-commits
mailing list