1e53c461bSKonstantin Varlamov //===----------------------------------------------------------------------===//
2e53c461bSKonstantin Varlamov //
3e53c461bSKonstantin Varlamov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e53c461bSKonstantin Varlamov // See https://llvm.org/LICENSE.txt for license information.
5e53c461bSKonstantin Varlamov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e53c461bSKonstantin Varlamov //
7e53c461bSKonstantin Varlamov //===----------------------------------------------------------------------===//
8e53c461bSKonstantin Varlamov
9e53c461bSKonstantin Varlamov // UNSUPPORTED: c++03, c++11, c++14, c++17
10e53c461bSKonstantin Varlamov
11e53c461bSKonstantin Varlamov // std::views::lazy_split
12e53c461bSKonstantin Varlamov
13e53c461bSKonstantin Varlamov #include <ranges>
14e53c461bSKonstantin Varlamov
15e53c461bSKonstantin Varlamov #include <array>
16e53c461bSKonstantin Varlamov #include <cassert>
17e53c461bSKonstantin Varlamov #include <concepts>
18e53c461bSKonstantin Varlamov #include <string_view>
19e53c461bSKonstantin Varlamov #include <utility>
20e53c461bSKonstantin Varlamov
21e53c461bSKonstantin Varlamov #include "test_iterators.h"
22*ba2236d3SWill Hawkins #include "test_range.h"
23e53c461bSKonstantin Varlamov #include "types.h"
24e53c461bSKonstantin Varlamov
25e53c461bSKonstantin Varlamov struct SomeView : std::ranges::view_base {
26e53c461bSKonstantin Varlamov const std::string_view* v_;
SomeViewSomeView27e53c461bSKonstantin Varlamov constexpr SomeView(const std::string_view& v) : v_(&v) {}
beginSomeView28e53c461bSKonstantin Varlamov constexpr auto begin() const { return v_->begin(); }
endSomeView29e53c461bSKonstantin Varlamov constexpr auto end() const { return v_->end(); }
30e53c461bSKonstantin Varlamov };
31e53c461bSKonstantin Varlamov
32e53c461bSKonstantin Varlamov struct NotAView { };
33e53c461bSKonstantin Varlamov
34e53c461bSKonstantin Varlamov static_assert(!std::is_invocable_v<decltype(std::views::lazy_split)>);
35e53c461bSKonstantin Varlamov static_assert(!std::is_invocable_v<decltype(std::views::lazy_split), SomeView, NotAView>);
36e53c461bSKonstantin Varlamov static_assert(!std::is_invocable_v<decltype(std::views::lazy_split), NotAView, SomeView>);
37e53c461bSKonstantin Varlamov static_assert( std::is_invocable_v<decltype(std::views::lazy_split), SomeView, SomeView>);
38e53c461bSKonstantin Varlamov
3986913377SStephan T. Lavavej // Regression test for #75002, views::lazy_split shouldn't be a range adaptor closure
4086913377SStephan T. Lavavej static_assert(!CanBePiped<SomeView&, decltype(std::views::lazy_split)>);
4186913377SStephan T. Lavavej static_assert(!CanBePiped<char (&)[10], decltype(std::views::lazy_split)>);
42e53c461bSKonstantin Varlamov static_assert(!CanBePiped<char (&&)[10], decltype(std::views::lazy_split)>);
43e53c461bSKonstantin Varlamov static_assert(!CanBePiped<NotAView, decltype(std::views::lazy_split)>);
44e53c461bSKonstantin Varlamov
4586913377SStephan T. Lavavej static_assert(CanBePiped<SomeView&, decltype(std::views::lazy_split('x'))>);
4686913377SStephan T. Lavavej static_assert(CanBePiped<char (&)[10], decltype(std::views::lazy_split('x'))>);
4786913377SStephan T. Lavavej static_assert(!CanBePiped<char (&&)[10], decltype(std::views::lazy_split('x'))>);
4886913377SStephan T. Lavavej static_assert(!CanBePiped<NotAView, decltype(std::views::lazy_split('x'))>);
4986913377SStephan T. Lavavej
50e53c461bSKonstantin Varlamov static_assert(std::same_as<decltype(std::views::lazy_split), decltype(std::ranges::views::lazy_split)>);
51e53c461bSKonstantin Varlamov
test()52e53c461bSKonstantin Varlamov constexpr bool test() {
53e53c461bSKonstantin Varlamov std::string_view input = "abc";
54e53c461bSKonstantin Varlamov std::string_view sep = "a";
55e53c461bSKonstantin Varlamov
56e53c461bSKonstantin Varlamov // Test that `std::views::lazy_split` is a range adaptor.
57e53c461bSKonstantin Varlamov
58e53c461bSKonstantin Varlamov // Test `views::lazy_split(input, sep)`.
59e53c461bSKonstantin Varlamov {
60e53c461bSKonstantin Varlamov SomeView view(input);
61e53c461bSKonstantin Varlamov
62e53c461bSKonstantin Varlamov using Result = std::ranges::lazy_split_view<SomeView, std::string_view>;
63e53c461bSKonstantin Varlamov std::same_as<Result> decltype(auto) result = std::views::lazy_split(view, sep);
64e53c461bSKonstantin Varlamov assert(result.base().begin() == input.begin());
65e53c461bSKonstantin Varlamov assert(result.base().end() == input.end());
66e53c461bSKonstantin Varlamov }
67e53c461bSKonstantin Varlamov
68e53c461bSKonstantin Varlamov // Test `views::lazy_split(sep)(input)`.
69e53c461bSKonstantin Varlamov {
70e53c461bSKonstantin Varlamov SomeView view(input);
71e53c461bSKonstantin Varlamov
72e53c461bSKonstantin Varlamov using Result = std::ranges::lazy_split_view<SomeView, std::string_view>;
73e53c461bSKonstantin Varlamov std::same_as<Result> decltype(auto) result = std::views::lazy_split(sep)(view);
74e53c461bSKonstantin Varlamov assert(result.base().begin() == input.begin());
75e53c461bSKonstantin Varlamov assert(result.base().end() == input.end());
76e53c461bSKonstantin Varlamov }
77e53c461bSKonstantin Varlamov
78e53c461bSKonstantin Varlamov // Test `view | views::lazy_split`.
79e53c461bSKonstantin Varlamov {
80e53c461bSKonstantin Varlamov SomeView view(input);
81e53c461bSKonstantin Varlamov
82e53c461bSKonstantin Varlamov using Result = std::ranges::lazy_split_view<SomeView, std::string_view>;
83e53c461bSKonstantin Varlamov std::same_as<Result> decltype(auto) result = view | std::views::lazy_split(sep);
84e53c461bSKonstantin Varlamov assert(result.base().begin() == input.begin());
85e53c461bSKonstantin Varlamov assert(result.base().end() == input.end());
86e53c461bSKonstantin Varlamov }
87e53c461bSKonstantin Varlamov
88e53c461bSKonstantin Varlamov // Test `adaptor | views::lazy_split`.
89e53c461bSKonstantin Varlamov {
90e53c461bSKonstantin Varlamov SomeView view(input);
91e53c461bSKonstantin Varlamov auto f = [](char c) { return c; };
92e53c461bSKonstantin Varlamov auto partial = std::views::transform(f) | std::views::lazy_split(sep);
93e53c461bSKonstantin Varlamov
94e53c461bSKonstantin Varlamov using Result = std::ranges::lazy_split_view<std::ranges::transform_view<SomeView, decltype(f)>, std::string_view>;
95e53c461bSKonstantin Varlamov std::same_as<Result> decltype(auto) result = partial(view);
96e53c461bSKonstantin Varlamov assert(result.base().base().begin() == input.begin());
97e53c461bSKonstantin Varlamov assert(result.base().base().end() == input.end());
98e53c461bSKonstantin Varlamov }
99e53c461bSKonstantin Varlamov
100e53c461bSKonstantin Varlamov // Test `views::lazy_split | adaptor`.
101e53c461bSKonstantin Varlamov {
102e53c461bSKonstantin Varlamov SomeView view(input);
103e53c461bSKonstantin Varlamov auto f = [](auto v) { return v; };
104e53c461bSKonstantin Varlamov auto partial = std::views::lazy_split(sep) | std::views::transform(f);
105e53c461bSKonstantin Varlamov
106e53c461bSKonstantin Varlamov using Result = std::ranges::transform_view<std::ranges::lazy_split_view<SomeView, std::string_view>, decltype(f)>;
107e53c461bSKonstantin Varlamov std::same_as<Result> decltype(auto) result = partial(view);
108e53c461bSKonstantin Varlamov assert(result.base().base().begin() == input.begin());
109e53c461bSKonstantin Varlamov assert(result.base().base().end() == input.end());
110e53c461bSKonstantin Varlamov }
111e53c461bSKonstantin Varlamov
112e53c461bSKonstantin Varlamov // Test that one can call `std::views::lazy_split` with arbitrary stuff, as long as we
113e53c461bSKonstantin Varlamov // don't try to actually complete the call by passing it a range.
114e53c461bSKonstantin Varlamov //
115e53c461bSKonstantin Varlamov // That makes no sense and we can't do anything with the result, but it's valid.
116e53c461bSKonstantin Varlamov {
117e53c461bSKonstantin Varlamov struct X { };
118e53c461bSKonstantin Varlamov [[maybe_unused]] auto partial = std::views::lazy_split(X{});
119e53c461bSKonstantin Varlamov }
120e53c461bSKonstantin Varlamov
121e53c461bSKonstantin Varlamov return true;
122e53c461bSKonstantin Varlamov }
123e53c461bSKonstantin Varlamov
main(int,char **)124e53c461bSKonstantin Varlamov int main(int, char**) {
125e53c461bSKonstantin Varlamov test();
126e53c461bSKonstantin Varlamov static_assert(test());
127e53c461bSKonstantin Varlamov
128e53c461bSKonstantin Varlamov return 0;
129e53c461bSKonstantin Varlamov }
130