[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