Skip to content

Commit 9ea524d

Browse files
Split left_folds.pass.cpp into four files; each for an algorithm
1 parent 8396d9e commit 9ea524d

File tree

4 files changed

+602
-147
lines changed

4 files changed

+602
-147
lines changed

libcxx/test/std/algorithms/alg.nonmodifying/alg.fold/left_folds.pass.cpp renamed to libcxx/test/std/algorithms/alg.nonmodifying/alg.fold/ranges.fold_left.pass.cpp

Lines changed: 17 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,17 @@
88

99
// <algorithm>
1010

11-
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
12-
13-
// MSVC warning C4244: 'argument': conversion from 'double' to 'const int', possible loss of data
14-
// ADDITIONAL_COMPILE_FLAGS(cl-style-warnings): /wd4244
15-
1611
// template<input_iterator I, sentinel_for<I> S, class T,
17-
// indirectly-binary-left-foldable<T, I> F>
18-
// constexpr see below ranges::fold_left_with_iter(I first, S last, T init, F f);
19-
//
20-
// template<input_range R, class T, indirectly-binary-left-foldable<T, iterator_t<R>> F>
21-
// constexpr see below ranges::fold_left_with_iter(R&& r, T init, F f);
12+
// indirectly-binary-left-foldable<T, I> F>
13+
// constexpr auto fold_left(I first, S last, T init, F f); // since C++23
2214

23-
// template<input_iterator I, sentinel_for<I> S, class T,
24-
// indirectly-binary-left-foldable<T, I> F>
25-
// constexpr see below ranges::fold_left(I first, S last, T init, F f);
26-
//
2715
// template<input_range R, class T, indirectly-binary-left-foldable<T, iterator_t<R>> F>
28-
// constexpr see below ranges::fold_left(R&& r, T init, F f);
16+
// constexpr auto fold_left(R&& r, T init, F f); // since C++23
17+
18+
// REQUIRES: std-at-least-c++23
19+
20+
// MSVC warning C4244: 'argument': conversion from 'double' to 'const int', possible loss of data
21+
// ADDITIONAL_COMPILE_FLAGS(cl-style-warnings): /wd4244
2922

3023
#include <algorithm>
3124
#include <cassert>
@@ -39,7 +32,6 @@
3932
#include <string_view>
4033
#include <string>
4134
#include <vector>
42-
#include <optional>
4335

4436
#include "test_macros.h"
4537
#include "test_range.h"
@@ -50,18 +42,10 @@
5042
# include <sstream>
5143
#endif
5244

53-
using std::ranges::fold_left;
54-
using std::ranges::fold_left_first;
55-
using std::ranges::fold_left_first_with_iter;
56-
using std::ranges::fold_left_with_iter;
57-
5845
template <class Result, class Range, class T>
5946
concept is_in_value_result =
6047
std::same_as<Result, std::ranges::fold_left_with_iter_result<std::ranges::iterator_t<Range>, T>>;
6148

62-
template <class Result, class T>
63-
concept is_dangling_with = std::same_as<Result, std::ranges::fold_left_with_iter_result<std::ranges::dangling, T>>;
64-
6549
struct Integer {
6650
int value;
6751

@@ -76,108 +60,43 @@ template <std::ranges::input_range R, class T, class F, std::equality_comparable
7660
requires std::copyable<R>
7761
constexpr void check_iterator(R& r, T const& init, F f, Expected const& expected) {
7862
{
79-
is_in_value_result<R, Expected> decltype(auto) result = fold_left_with_iter(r.begin(), r.end(), init, f);
80-
assert(result.in == r.end());
81-
assert(result.value == expected);
82-
}
83-
84-
{
85-
auto telemetry = invocable_telemetry();
86-
auto f2 = invocable_with_telemetry(f, telemetry);
87-
is_in_value_result<R, Expected> decltype(auto) result = fold_left_with_iter(r.begin(), r.end(), init, f2);
88-
assert(result.in == r.end());
89-
assert(result.value == expected);
90-
assert(telemetry.invocations == std::ranges::distance(r));
91-
assert(telemetry.moves == 0);
92-
assert(telemetry.copies == 1);
93-
}
94-
95-
{
96-
std::same_as<Expected> decltype(auto) result = fold_left(r.begin(), r.end(), init, f);
63+
std::same_as<Expected> decltype(auto) result = std::ranges::fold_left(r.begin(), r.end(), init, f);
9764
assert(result == expected);
9865
}
9966

10067
{
10168
auto telemetry = invocable_telemetry();
10269
auto f2 = invocable_with_telemetry(f, telemetry);
103-
std::same_as<Expected> decltype(auto) result = fold_left(r.begin(), r.end(), init, f2);
70+
std::same_as<Expected> decltype(auto) result = std::ranges::fold_left(r.begin(), r.end(), init, f2);
10471
assert(result == expected);
10572
assert(telemetry.invocations == std::ranges::distance(r));
10673
assert(telemetry.moves == 0);
10774
assert(telemetry.copies == 1);
10875
}
10976
}
11077

111-
template <std::ranges::input_range R, class F, std::equality_comparable Expected>
112-
requires std::copyable<R>
113-
constexpr void check_iterator(R& r, F f, std::optional<Expected> const& expected) {
114-
{
115-
is_in_value_result<R, std::optional<Expected>> decltype(auto) result =
116-
fold_left_first_with_iter(r.begin(), r.end(), f);
117-
assert(result.in == r.end());
118-
assert(result.value == expected);
119-
}
120-
121-
{
122-
auto telemetry = invocable_telemetry();
123-
auto f2 = invocable_with_telemetry(f, telemetry);
124-
is_in_value_result<R, std::optional<Expected>> decltype(auto) result =
125-
fold_left_first_with_iter(r.begin(), r.end(), f2);
126-
assert(result.in == r.end());
127-
assert(result.value == expected);
128-
if (result.value.has_value()) {
129-
assert(telemetry.invocations == std::ranges::distance(r) - 1);
130-
assert(telemetry.moves == 0);
131-
assert(telemetry.copies == 1);
132-
}
133-
}
134-
135-
{
136-
std::same_as<std::optional<Expected>> decltype(auto) result = fold_left_first(r.begin(), r.end(), f);
137-
assert(result == expected);
138-
}
139-
140-
{
141-
auto telemetry = invocable_telemetry();
142-
auto f2 = invocable_with_telemetry(f, telemetry);
143-
std::same_as<std::optional<Expected>> decltype(auto) result = fold_left_first(r.begin(), r.end(), f2);
144-
assert(result == expected);
145-
if (result.has_value()) {
146-
assert(telemetry.invocations == std::ranges::distance(r) - 1);
147-
assert(telemetry.moves == 0);
148-
assert(telemetry.copies == 1);
149-
}
150-
}
151-
}
152-
15378
template <std::ranges::input_range R, class T, class F, std::equality_comparable Expected>
15479
requires std::copyable<R>
15580
constexpr void check_lvalue_range(R& r, T const& init, F f, Expected const& expected) {
156-
{
157-
is_in_value_result<R, Expected> decltype(auto) result = fold_left_with_iter(r, init, f);
158-
assert(result.in == r.end());
159-
assert(result.value == expected);
160-
}
161-
16281
{
16382
auto telemetry = invocable_telemetry();
16483
auto f2 = invocable_with_telemetry(f, telemetry);
165-
std::same_as<Expected> decltype(auto) result = fold_left(r, init, f2);
84+
std::same_as<Expected> decltype(auto) result = std::ranges::fold_left(r, init, f2);
16685
assert(result == expected);
16786
assert(telemetry.invocations == std::ranges::distance(r));
16887
assert(telemetry.moves == 0);
16988
assert(telemetry.copies == 1);
17089
}
17190

17291
{
173-
std::same_as<Expected> decltype(auto) result = fold_left(r, init, f);
92+
std::same_as<Expected> decltype(auto) result = std::ranges::fold_left(r, init, f);
17493
assert(result == expected);
17594
}
17695

17796
{
17897
auto telemetry = invocable_telemetry();
17998
auto f2 = invocable_with_telemetry(f, telemetry);
180-
std::same_as<Expected> decltype(auto) result = fold_left(r, init, f2);
99+
std::same_as<Expected> decltype(auto) result = std::ranges::fold_left(r, init, f2);
181100
assert(result == expected);
182101
assert(telemetry.invocations == std::ranges::distance(r));
183102
assert(telemetry.moves == 0);
@@ -188,34 +107,17 @@ constexpr void check_lvalue_range(R& r, T const& init, F f, Expected const& expe
188107
template <std::ranges::input_range R, class T, class F, std::equality_comparable Expected>
189108
requires std::copyable<R>
190109
constexpr void check_rvalue_range(R& r, T const& init, F f, Expected const& expected) {
191-
{
192-
auto r2 = r;
193-
is_dangling_with<Expected> decltype(auto) result = fold_left_with_iter(std::move(r2), init, f);
194-
assert(result.value == expected);
195-
}
196-
197-
{
198-
auto telemetry = invocable_telemetry();
199-
auto f2 = invocable_with_telemetry(f, telemetry);
200-
auto r2 = r;
201-
is_dangling_with<Expected> decltype(auto) result = fold_left_with_iter(std::move(r2), init, f2);
202-
assert(result.value == expected);
203-
assert(telemetry.invocations == std::ranges::distance(r));
204-
assert(telemetry.moves == 0);
205-
assert(telemetry.copies == 1);
206-
}
207-
208110
{
209111
auto r2 = r;
210-
std::same_as<Expected> decltype(auto) result = fold_left(std::move(r2), init, f);
112+
std::same_as<Expected> decltype(auto) result = std::ranges::fold_left(std::move(r2), init, f);
211113
assert(result == expected);
212114
}
213115

214116
{
215117
auto telemetry = invocable_telemetry();
216118
auto f2 = invocable_with_telemetry(f, telemetry);
217119
auto r2 = r;
218-
std::same_as<Expected> decltype(auto) result = fold_left(std::move(r2), init, f2);
120+
std::same_as<Expected> decltype(auto) result = std::ranges::fold_left(std::move(r2), init, f2);
219121
assert(result == expected);
220122
assert(telemetry.invocations == std::ranges::distance(r));
221123
assert(telemetry.moves == 0);
@@ -231,37 +133,26 @@ constexpr void check(R r, T const& init, F f, Expected const& expected) {
231133
check_rvalue_range(r, init, f, expected);
232134
}
233135

234-
template <std::ranges::input_range R, class F, std::equality_comparable Expected>
235-
requires std::copyable<R>
236-
constexpr void check(R r, F f, std::optional<Expected> const& expected) {
237-
check_iterator(r, f, expected);
238-
}
239-
240136
constexpr void empty_range_test_case() {
241137
auto const data = std::vector<int>{};
242138
check(data, 100, std::plus(), 100);
243139
check(data, -100, std::multiplies(), -100);
244-
check(data, std::plus(), std::optional<int>());
245140

246141
check(data | std::views::take_while([](auto) { return false; }), 1.23, std::plus(), 1.23);
247142
check(data, Integer(52), &Integer::plus, Integer(52));
248-
check(data | std::views::take_while([](auto) { return false; }), std::plus(), std::optional<int>());
249143
}
250144

251145
constexpr void common_range_test_case() {
252146
auto const data = std::vector<int>{1, 2, 3, 4};
253147
check(data, 0, std::plus(), triangular_sum(data));
254148
check(data, 1, std::multiplies(), factorial(data.back()));
255-
check(data, std::plus(), std::optional(triangular_sum(data)));
256-
check(data, std::multiplies(), std::optional(factorial(data.back())));
257149

258150
auto multiply_with_prev = [n = 1](auto const x, auto const y) mutable {
259151
auto const result = x * y * n;
260152
n = y;
261153
return static_cast<std::size_t>(result);
262154
};
263155
check(data, 1, multiply_with_prev, factorial(data.size()) * factorial(data.size() - 1));
264-
check(data, multiply_with_prev, std::optional(factorial(data.size()) * factorial(data.size() - 1)));
265156

266157
auto fib = [n = 1](auto x, auto) mutable {
267158
auto old_x = x;
@@ -293,7 +184,6 @@ constexpr void non_common_range_test_case() {
293184
auto data = std::vector<std::string>{"five", "three", "two", "six", "one", "four"};
294185
auto range = data | std::views::transform(parse);
295186
check(range, 0, std::plus(), triangular_sum(range));
296-
check(range, std::plus(), std::optional(triangular_sum(range)));
297187
}
298188

299189
{
@@ -305,7 +195,6 @@ constexpr void non_common_range_test_case() {
305195
auto range =
306196
std::views::lazy_split(data, ' ') | std::views::transform(to_string_view) | std::views::transform(parse);
307197
check(range, 0, std::plus(), triangular_sum(range));
308-
check(range, std::plus(), std::optional(triangular_sum(range)));
309198
}
310199
}
311200

@@ -327,32 +216,13 @@ void runtime_only_test_case() {
327216
{
328217
auto input = std::istringstream(raw_data);
329218
auto data = std::views::istream<std::string>(input);
330-
is_in_value_result<std::ranges::basic_istream_view<std::string, char>, std::string> decltype(auto) result =
331-
fold_left_with_iter(data.begin(), data.end(), init, std::plus());
332-
333-
assert(result.in == data.end());
334-
assert(result.value == expected);
335-
}
336-
337-
{
338-
auto input = std::istringstream(raw_data);
339-
auto data = std::views::istream<std::string>(input);
340-
is_in_value_result<std::ranges::basic_istream_view<std::string, char>, std::string> decltype(auto) result =
341-
fold_left_with_iter(data, init, std::plus());
342-
assert(result.in == data.end());
343-
assert(result.value == expected);
344-
}
345-
346-
{
347-
auto input = std::istringstream(raw_data);
348-
auto data = std::views::istream<std::string>(input);
349-
assert(fold_left(data.begin(), data.end(), init, std::plus()) == expected);
219+
assert(std::ranges::fold_left(data.begin(), data.end(), init, std::plus()) == expected);
350220
}
351221

352222
{
353223
auto input = std::istringstream(raw_data);
354224
auto data = std::views::istream<std::string>(input);
355-
assert(fold_left(data, init, std::plus()) == expected);
225+
assert(std::ranges::fold_left(data, init, std::plus()) == expected);
356226
}
357227
}
358228
#endif

0 commit comments

Comments
 (0)