]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/std/ranges/adaptors/split.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / adaptors / split.cc
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
69d80f0f
PP
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
d4ac20b0 18// { dg-do run { target c++20 } }
69d80f0f
PP
19
20#include <algorithm>
21#include <ranges>
22#include <string>
23#include <string_view>
ac73c944 24#include <vector>
69d80f0f
PP
25#include <testsuite_hooks.h>
26#include <testsuite_iterators.h>
27
28using __gnu_test::test_range;
29using __gnu_test::forward_iterator_wrapper;
30using __gnu_test::input_iterator_wrapper;
31
32namespace ranges = std::ranges;
33namespace views = std::ranges::views;
34
35using namespace std::literals;
36
37void
38test01()
39{
40 auto from_chars = [] (auto v) {
41 return std::stoi(std::string(v.data(), v.data() + v.size()));
42 };
43 auto ints = "1.2.3.4"sv
44 | views::split('.')
45 | views::transform(from_chars);
46 VERIFY( ranges::equal(ints, (int[]){1,2,3,4}) );
47}
48
73464a47
PP
49void
50test02()
51{
52 // PR libstdc++/101214
53 auto v = views::iota(0) | views::take(5) | views::split(0);
54 static_assert(!ranges::common_range<decltype(v)>);
55 static_assert(std::default_initializable<decltype(v.end())>);
56 static_assert(std::sentinel_for<decltype(v.end()), decltype(v.begin())>);
57}
58
69d80f0f
PP
59// The following testcases are adapted from lazy_split.cc.
60namespace from_lazy_split_cc
61{
62void
63test01()
64{
65 auto x = "the quick brown fox"sv;
66 auto p = std::string{" "};
67 auto v = x | views::split(views::all(p)); // views::all is needed here after P2281.
68 auto i = v.begin();
69 VERIFY( ranges::equal(*i++, "the"sv) );
70 VERIFY( ranges::equal(*i++, "quick"sv) );
71 VERIFY( ranges::equal(*i++, "brown"sv) );
72 VERIFY( ranges::equal(*i++, "fox"sv) );
73 VERIFY( i == v.end() );
74}
75
76void
77test02()
78{
79 auto x = "the quick brown fox"sv;
80 auto v = x | views::split(' ');
81 auto i = v.begin();
82 VERIFY( ranges::equal(*i++, "the"sv) );
83 VERIFY( ranges::equal(*i++, "quick"sv) );
84 VERIFY( ranges::equal(*i++, "brown"sv) );
85 VERIFY( ranges::equal(*i++, "fox"sv) );
86 VERIFY( i == v.end() );
87}
88
89void
90test03()
91{
92 char x[] = "the quick brown fox";
93 test_range<char, forward_iterator_wrapper> rx(x, x+sizeof(x)-1);
94 auto v = rx | views::split(' ');
95 auto i = v.begin();
96 VERIFY( ranges::equal(*i++, "the"sv) );
97 VERIFY( ranges::equal(*i++, "quick"sv) );
98 VERIFY( ranges::equal(*i++, "brown"sv) );
99 VERIFY( ranges::equal(*i++, "fox"sv) );
100 VERIFY( i == v.end() );
101}
102
103void
104test04()
105{
106 auto x = "the quick brown fox"sv;
107 std::initializer_list<char> p = {' ', ' '};
108 static_assert(!ranges::view<decltype(p)>);
109 static_assert(std::same_as<decltype(p | views::all),
110 ranges::ref_view<decltype(p)>>);
111 auto v = x | views::split(views::all(p)); // views::all is needed here after P2281.
112 auto i = v.begin();
113 VERIFY( ranges::equal(*i++, "the"sv) );
114 VERIFY( ranges::equal(*i++, "quick"sv) );
115 VERIFY( ranges::equal(*i++, "brown"sv) );
116 VERIFY( ranges::equal(*i++, "fox"sv) );
117 VERIFY( i == v.end() );
118}
119
120void
121test05()
122{
123 auto as_string = [](ranges::view auto rng) {
124 auto in = rng | views::common;
125 return std::string(in.begin(), in.end());
126 };
127 std::string str
128 = "Now is the time for all good men to come to the aid of their county.";
129 auto rng
130 = str | views::split(' ') | views::transform(as_string) | views::common;
131 std::vector<std::string> words(rng.begin(), rng.end());
132 auto not_space_p = [](char c) { return c != ' '; };
133 VERIFY( ranges::equal(words | views::join,
134 str | views::filter(not_space_p)) );
135}
136
137template<auto split = views::split>
138void
139test06()
140{
141 // Verify SFINAE behavior.
142 std::string s, p;
143 static_assert(!requires { split(); });
144 static_assert(!requires { split(s, p, 0); });
145 static_assert(!requires { split(p)(); });
146 static_assert(!requires { s | split; });
147
5e1b17f0
PP
148 // Test the case where the closure object is used as an rvalue and therefore
149 // the copy of p is forwarded as an rvalue.
150 // This used to be invalid, but is now well-formed after P2415R2 relaxed
151 // the requirements of viewable_range to admit rvalue non-view non-borrowed
152 // ranges such as std::string&&.
153 static_assert(requires { s | split(p); });
154 static_assert(requires { split(p)(s); });
155 static_assert(requires { s | (split(p) | views::all); });
156 static_assert(requires { (split(p) | views::all)(s); });
69d80f0f
PP
157
158 static_assert(requires { s | split(views::all(p)); });
159 static_assert(requires { split(views::all(p))(s); });
160 static_assert(requires { s | (split(views::all(p)) | views::all); });
161 static_assert(requires { (split(views::all(p)) | views::all)(s); });
162
163 auto adapt = split(p);
164 static_assert(requires { s | adapt; });
165 static_assert(requires { adapt(s); });
166
167 auto adapt2 = split(p) | views::all;
168 static_assert(requires { s | adapt2; });
169 static_assert(requires { adapt2(s); });
170}
171
172void
173test10()
174{
175 // LWG 3505
176 auto to_string = [] (auto r) {
177 return std::string(r.begin(), ranges::next(r.begin(), r.end()));
178 };
179 auto v = "xxyx"sv | views::split("xy"sv) | views::transform(to_string);
180 VERIFY( ranges::equal(v, (std::string_view[]){"x", "x"}) );
181}
182
183void
184test11()
185{
186 // LWG 3478
187 auto v = views::split("text"sv, "text"sv);
188 auto i = v.begin();
189 VERIFY( ranges::empty(*i++) );
190 VERIFY( ranges::empty(*i++) );
191 VERIFY( i == v.end() );
192
193 static_assert(ranges::distance(views::split(" text "sv, ' ')) == 3);
194 static_assert(ranges::distance(views::split(" t e x t "sv, ' ')) == 6);
195 static_assert(ranges::distance(views::split(" text "sv, " "sv)) == 3);
196 static_assert(ranges::distance(views::split(" text "sv, " "sv)) == 4);
197 static_assert(ranges::distance(views::split(" text "sv, " "sv)) == 4);
198 static_assert(ranges::distance(views::split("t"sv, 't')) == 2);
199 static_assert(ranges::distance(views::split("text"sv, ""sv)) == 4);
200}
201} // namespace from_lazy_split_cc
202
203int
204main()
205{
206 test01();
73464a47 207 test02();
69d80f0f
PP
208
209 from_lazy_split_cc::test01();
210 from_lazy_split_cc::test02();
211 from_lazy_split_cc::test03();
212 from_lazy_split_cc::test04();
213 from_lazy_split_cc::test05();
214 from_lazy_split_cc::test06();
215 from_lazy_split_cc::test10();
216 from_lazy_split_cc::test11();
217}