From cf3255debc88ea8a63b04b82aab2df67b3fbc7d4 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Sun, 24 Aug 2025 13:42:08 +0300 Subject: [PATCH] [libc++][ranges] LWG3505: split_view::outer-iterator::operator++ misspecified Implented in LLVM15: https://github.com/llvm/llvm-project/commit/e53c461bf3f0feebb4fd6b43e05a0047f8edb945 Fixes #104320 - https://wg21.link/LWG3505 - https://wg21.link/range.split.outer --- libcxx/docs/Status/Cxx23Issues.csv | 2 +- .../range.lazy.split.outer/increment.pass.cpp | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv index 189f8452e0678..85acbb09f518a 100644 --- a/libcxx/docs/Status/Cxx23Issues.csv +++ b/libcxx/docs/Status/Cxx23Issues.csv @@ -58,7 +58,7 @@ "`LWG3495 `__","``constexpr launder`` makes pointers to inactive members of unions usable","2021-02 (Virtual)","|Nothing To Do|","","" "`LWG3500 `__","``join_view::iterator::operator->()`` is bogus","2021-02 (Virtual)","|Complete|","14","" "`LWG3502 `__","``elements_view`` should not be allowed to return dangling reference","2021-02 (Virtual)","|Complete|","16","" -"`LWG3505 `__","``split_view::outer-iterator::operator++`` misspecified","2021-02 (Virtual)","","","" +"`LWG3505 `__","``split_view::outer-iterator::operator++`` misspecified","2021-02 (Virtual)","|Complete|","15","" "","","","","","" "`LWG2774 `__","``std::function`` construction vs assignment","2021-06 (Virtual)","","","" "`LWG2818 `__","``::std::`` everywhere rule needs tweaking","2021-06 (Virtual)","|Nothing To Do|","","" diff --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp index 4d765d71407f5..b557346588306 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/increment.pass.cpp @@ -75,6 +75,56 @@ constexpr bool test() { } } + // LWG3505 + { + using namespace std::string_view_literals; + + { // Motivational example + auto v = std::views::lazy_split("xxyx"sv, "xy"sv); + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "x"s)); + + decltype(auto) i2 = ++i; + static_assert(std::is_lvalue_reference_v); + assert(std::ranges::equal(*i2, "x"s)); + } + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "x"s)); + + decltype(auto) i2 = i++; + static_assert(!std::is_reference_v); + assert(std::ranges::equal(*i2, "x"s)); + assert(std::ranges::equal(*i, "x"s)); + } + } + { + auto v = std::views::lazy_split("zzht"sv, "zh"sv); + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "z"s)); + + decltype(auto) i2 = ++i; + static_assert(std::is_lvalue_reference_v); + assert(std::ranges::equal(*i2, "t"s)); + } + + { + auto i = v.begin(); + assert(std::ranges::equal(*i, "z"s)); + + decltype(auto) i2 = i++; + static_assert(!std::is_reference_v); + assert(std::ranges::equal(*i2, "z"s)); + assert(std::ranges::equal(*i, "t"s)); + } + } + } + return true; }