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