[libcxx-commits] [libcxx] [libc++][ranges] LWG4013: Make lazy_split_view::outer-iterator::value_type non-default-constructible (PR #221919)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Sep 8 01:33:29 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Vishank Singh (VishankSingh)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/221919.diff


3 Files Affected:

- (modified) libcxx/include/__ranges/lazy_split_view.h (+2-2) 
- (modified) libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.default.pass.cpp (+9-15) 
- (modified) libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer.value/ctor.iter.pass.cpp (+7-2) 


``````````diff
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());
   }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/221919


More information about the libcxx-commits mailing list