Skip to content

Commit 8691337

Browse files
[libc++] views::split and views::lazy_split shouldn't be range adaptor closures (#75266)
Fixes #75002. Found while running libc++'s tests with MSVC's STL. This is a superset of #74961 that also fixes the product code and adds a regression test. Thanks again, @cpplearner! To summarize: `views::split` and `views::lazy_split` aren't unary, aren't range adaptor **closure** objects, and can't be piped. However, \[range.adaptor.object\]/8 says that `views::split(pattern)` and `views::lazy_split(pattern)` produce unary, pipeable, range adaptor closure objects. This PR adjusts the test coverage accordingly, allowing it to portably pass for libc++ and MSVC's STL.
1 parent 9505cf4 commit 8691337

File tree

4 files changed

+22
-10
lines changed

4 files changed

+22
-10
lines changed

libcxx/include/__ranges/lazy_split_view.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ lazy_split_view(_Range&&, range_value_t<_Range>)
437437

438438
namespace views {
439439
namespace __lazy_split_view {
440-
struct __fn : __range_adaptor_closure<__fn> {
440+
struct __fn {
441441
template <class _Range, class _Pattern>
442442
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
443443
constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const

libcxx/include/__ranges/split_view.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ struct split_view<_View, _Pattern>::__sentinel {
194194

195195
namespace views {
196196
namespace __split_view {
197-
struct __fn : __range_adaptor_closure<__fn> {
197+
struct __fn {
198198
// clang-format off
199199
template <class _Range, class _Pattern>
200200
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI

libcxx/test/std/ranges/range.adaptors/range.lazy.split/adaptor.pass.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,16 @@ static_assert(!std::is_invocable_v<decltype(std::views::lazy_split), SomeView, N
4040
static_assert(!std::is_invocable_v<decltype(std::views::lazy_split), NotAView, SomeView>);
4141
static_assert( std::is_invocable_v<decltype(std::views::lazy_split), SomeView, SomeView>);
4242

43-
static_assert( CanBePiped<SomeView&, decltype(std::views::lazy_split)>);
44-
static_assert( CanBePiped<char(&)[10], decltype(std::views::lazy_split)>);
45-
static_assert(!CanBePiped<char(&&)[10], decltype(std::views::lazy_split)>);
46-
static_assert(!CanBePiped<NotAView, decltype(std::views::lazy_split)>);
43+
// Regression test for #75002, views::lazy_split shouldn't be a range adaptor closure
44+
static_assert(!CanBePiped<SomeView&, decltype(std::views::lazy_split)>);
45+
static_assert(!CanBePiped<char (&)[10], decltype(std::views::lazy_split)>);
46+
static_assert(!CanBePiped<char (&&)[10], decltype(std::views::lazy_split)>);
47+
static_assert(!CanBePiped<NotAView, decltype(std::views::lazy_split)>);
48+
49+
static_assert(CanBePiped<SomeView&, decltype(std::views::lazy_split('x'))>);
50+
static_assert(CanBePiped<char (&)[10], decltype(std::views::lazy_split('x'))>);
51+
static_assert(!CanBePiped<char (&&)[10], decltype(std::views::lazy_split('x'))>);
52+
static_assert(!CanBePiped<NotAView, decltype(std::views::lazy_split('x'))>);
4753

4854
static_assert(std::same_as<decltype(std::views::lazy_split), decltype(std::ranges::views::lazy_split)>);
4955

libcxx/test/std/ranges/range.adaptors/range.split/adaptor.pass.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,16 @@ static_assert(!std::is_invocable_v<decltype(std::views::split), SomeView, NotAVi
3939
static_assert(!std::is_invocable_v<decltype(std::views::split), NotAView, SomeView>);
4040
static_assert( std::is_invocable_v<decltype(std::views::split), SomeView, SomeView>);
4141

42-
static_assert( CanBePiped<SomeView&, decltype(std::views::split)>);
43-
static_assert( CanBePiped<char(&)[10], decltype(std::views::split)>);
44-
static_assert(!CanBePiped<char(&&)[10], decltype(std::views::split)>);
45-
static_assert(!CanBePiped<NotAView, decltype(std::views::split)>);
42+
// Regression test for #75002, views::split shouldn't be a range adaptor closure
43+
static_assert(!CanBePiped<SomeView&, decltype(std::views::split)>);
44+
static_assert(!CanBePiped<char (&)[10], decltype(std::views::split)>);
45+
static_assert(!CanBePiped<char (&&)[10], decltype(std::views::split)>);
46+
static_assert(!CanBePiped<NotAView, decltype(std::views::split)>);
47+
48+
static_assert(CanBePiped<SomeView&, decltype(std::views::split('x'))>);
49+
static_assert(CanBePiped<char (&)[10], decltype(std::views::split('x'))>);
50+
static_assert(!CanBePiped<char (&&)[10], decltype(std::views::split('x'))>);
51+
static_assert(!CanBePiped<NotAView, decltype(std::views::split('x'))>);
4652

4753
static_assert(std::same_as<decltype(std::views::split), decltype(std::ranges::views::split)>);
4854

0 commit comments

Comments
 (0)