Skip to content

Commit 0b64744

Browse files
committed
Augment ranges::{fill, fill_n, find} with missing tests
1 parent 657fb44 commit 0b64744

File tree

7 files changed

+250
-205
lines changed

7 files changed

+250
-205
lines changed

libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp

+11-42
Original file line numberDiff line numberDiff line change
@@ -49,50 +49,19 @@ struct Test {
4949
TEST_CONSTEXPR_CXX20 bool test() {
5050
types::for_each(types::forward_iterator_list<char*>(), Test<char>());
5151
types::for_each(types::forward_iterator_list<int*>(), Test<int>());
52-
{ // test vector<bool>::iterator optimization
53-
{ // simple case
54-
std::vector<bool> in(4, false);
55-
std::vector<bool> expected(4, true);
56-
std::fill(in.begin(), in.end(), true);
57-
assert(in == expected);
58-
}
59-
{ // partial byte in the front is not filled
60-
std::vector<bool> in(8, false);
61-
std::vector<bool> expected(8, true);
62-
expected[0] = false;
63-
expected[1] = false;
64-
std::fill(in.begin() + 2, in.end(), true);
65-
assert(in == expected);
66-
}
67-
{ // partial byte in the back is not filled
68-
std::vector<bool> in(8, false);
69-
std::vector<bool> expected(8, true);
70-
expected[6] = false;
71-
expected[7] = false;
72-
std::fill(in.begin(), in.end() - 2, true);
73-
assert(in == expected);
74-
}
75-
{ // partial byte in the front and back is not filled
76-
std::vector<bool> in(16, false);
77-
std::vector<bool> expected(16, true);
78-
expected[0] = false;
79-
expected[1] = false;
80-
expected[14] = false;
81-
expected[15] = false;
82-
std::fill(in.begin() + 2, in.end() - 2, true);
83-
assert(in == expected);
84-
}
85-
{ // only a few bits of a byte are set
86-
std::vector<bool> in(8, false);
87-
std::vector<bool> expected(8, true);
88-
expected[0] = false;
89-
expected[1] = false;
90-
expected[6] = false;
91-
expected[7] = false;
92-
std::fill(in.begin() + 2, in.end() - 2, true);
93-
assert(in == expected);
52+
53+
{ // Test vector<bool>::iterator optimization
54+
for (std::size_t N = 8; N <= 256; N *= 2) {
55+
// Test with both full and partial bytes
56+
for (std::size_t offset = 0; offset <= 4; offset += 4) {
57+
std::vector<bool> in(N + 2 * offset);
58+
std::vector<bool> expected(N, true);
59+
std::fill(in.begin() + offset, in.end() - offset, true);
60+
assert(std::equal(in.begin() + offset, in.end() - offset, expected.begin()));
61+
}
9462
}
9563
}
64+
9665
return true;
9766
}
9867

libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp

+100-106
Original file line numberDiff line numberDiff line change
@@ -15,159 +15,153 @@
1515

1616
#include <algorithm>
1717
#include <cassert>
18+
#include <vector>
1819

1920
#include "test_macros.h"
2021
#include "test_iterators.h"
2122
#include "user_defined_integral.h"
2223

2324
#if TEST_STD_VER > 17
2425
TEST_CONSTEXPR bool test_constexpr() {
25-
const std::size_t N = 5;
26-
int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger than N
27-
28-
auto it = std::fill_n(std::begin(ib), N, 5);
29-
return it == (std::begin(ib) + N)
30-
&& std::all_of(std::begin(ib), it, [](int a) {return a == 5; })
31-
&& *it == 0 // don't overwrite the last value in the output array
32-
;
33-
}
26+
const std::size_t N = 5;
27+
int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger than N
28+
29+
auto it = std::fill_n(std::begin(ib), N, 5);
30+
return it == (std::begin(ib) + N) && std::all_of(std::begin(ib), it, [](int a) { return a == 5; }) &&
31+
*it == 0 // don't overwrite the last value in the output array
32+
;
33+
}
3434
#endif
3535

3636
typedef UserDefinedIntegral<unsigned> UDI;
3737

3838
template <class Iter>
39-
void
40-
test_char()
41-
{
42-
char a[4] = {};
43-
Iter it = std::fill_n(Iter(a), UDI(4), char(1));
44-
assert(base(it) == a + 4);
45-
assert(a[0] == 1);
46-
assert(a[1] == 1);
47-
assert(a[2] == 1);
48-
assert(a[3] == 1);
39+
void test_char() {
40+
char a[4] = {};
41+
Iter it = std::fill_n(Iter(a), UDI(4), char(1));
42+
assert(base(it) == a + 4);
43+
assert(a[0] == 1);
44+
assert(a[1] == 1);
45+
assert(a[2] == 1);
46+
assert(a[3] == 1);
4947
}
5048

5149
template <class Iter>
52-
void
53-
test_int()
54-
{
55-
int a[4] = {};
56-
Iter it = std::fill_n(Iter(a), UDI(4), 1);
57-
assert(base(it) == a + 4);
58-
assert(a[0] == 1);
59-
assert(a[1] == 1);
60-
assert(a[2] == 1);
61-
assert(a[3] == 1);
50+
void test_int() {
51+
int a[4] = {};
52+
Iter it = std::fill_n(Iter(a), UDI(4), 1);
53+
assert(base(it) == a + 4);
54+
assert(a[0] == 1);
55+
assert(a[1] == 1);
56+
assert(a[2] == 1);
57+
assert(a[3] == 1);
6258
}
6359

64-
void
65-
test_int_array()
66-
{
67-
int a[4] = {};
68-
assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
69-
assert(a[0] == 1);
70-
assert(a[1] == 1);
71-
assert(a[2] == 1);
72-
assert(a[3] == 1);
60+
void test_int_array() {
61+
int a[4] = {};
62+
assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4);
63+
assert(a[0] == 1);
64+
assert(a[1] == 1);
65+
assert(a[2] == 1);
66+
assert(a[3] == 1);
7367
}
7468

7569
struct source {
76-
source() : i(0) { }
70+
source() : i(0) {}
7771

78-
operator int() const { return i++; }
79-
mutable int i;
72+
operator int() const { return i++; }
73+
mutable int i;
8074
};
8175

82-
void
83-
test_int_array_struct_source()
84-
{
85-
int a[4] = {};
86-
assert(std::fill_n(a, UDI(4), source()) == a + 4);
87-
assert(a[0] == 0);
88-
assert(a[1] == 1);
89-
assert(a[2] == 2);
90-
assert(a[3] == 3);
76+
void test_int_array_struct_source() {
77+
int a[4] = {};
78+
assert(std::fill_n(a, UDI(4), source()) == a + 4);
79+
assert(a[0] == 0);
80+
assert(a[1] == 1);
81+
assert(a[2] == 2);
82+
assert(a[3] == 3);
9183
}
9284

9385
struct test1 {
94-
test1() : c(0) { }
95-
test1(char xc) : c(xc + 1) { }
96-
char c;
86+
test1() : c(0) {}
87+
test1(char xc) : c(xc + 1) {}
88+
char c;
9789
};
9890

99-
void
100-
test_struct_array()
101-
{
102-
test1 test1a[4] = {};
103-
assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
104-
assert(test1a[0].c == 11);
105-
assert(test1a[1].c == 11);
106-
assert(test1a[2].c == 11);
107-
assert(test1a[3].c == 11);
91+
void test_struct_array() {
92+
test1 test1a[4] = {};
93+
assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4);
94+
assert(test1a[0].c == 11);
95+
assert(test1a[1].c == 11);
96+
assert(test1a[2].c == 11);
97+
assert(test1a[3].c == 11);
10898
}
10999

110-
class A
111-
{
112-
char a_;
100+
class A {
101+
char a_;
102+
113103
public:
114-
A() {}
115-
explicit A(char a) : a_(a) {}
116-
operator unsigned char() const {return 'b';}
104+
A() {}
105+
explicit A(char a) : a_(a) {}
106+
operator unsigned char() const { return 'b'; }
117107

118-
friend bool operator==(const A& x, const A& y)
119-
{return x.a_ == y.a_;}
108+
friend bool operator==(const A& x, const A& y) { return x.a_ == y.a_; }
120109
};
121110

122-
void
123-
test5()
124-
{
125-
A a[3];
126-
assert(std::fill_n(&a[0], UDI(3), A('a')) == a+3);
127-
assert(a[0] == A('a'));
128-
assert(a[1] == A('a'));
129-
assert(a[2] == A('a'));
111+
void test5() {
112+
A a[3];
113+
assert(std::fill_n(&a[0], UDI(3), A('a')) == a + 3);
114+
assert(a[0] == A('a'));
115+
assert(a[1] == A('a'));
116+
assert(a[2] == A('a'));
130117
}
131118

132-
struct Storage
133-
{
134-
union
135-
{
119+
struct Storage {
120+
union {
136121
unsigned char a;
137122
unsigned char b;
138123
};
139124
};
140125

141-
void test6()
142-
{
126+
void test6() {
143127
Storage foo[5];
144128
std::fill_n(&foo[0], UDI(5), Storage());
145129
}
146130

147-
148-
int main(int, char**)
149-
{
150-
test_char<cpp17_output_iterator<char*> >();
151-
test_char<forward_iterator<char*> >();
152-
test_char<bidirectional_iterator<char*> >();
153-
test_char<random_access_iterator<char*> >();
154-
test_char<char*>();
155-
156-
test_int<cpp17_output_iterator<int*> >();
157-
test_int<forward_iterator<int*> >();
158-
test_int<bidirectional_iterator<int*> >();
159-
test_int<random_access_iterator<int*> >();
160-
test_int<int*>();
161-
162-
test_int_array();
163-
test_int_array_struct_source();
164-
test_struct_array();
165-
166-
test5();
167-
test6();
131+
int main(int, char**) {
132+
test_char<cpp17_output_iterator<char*> >();
133+
test_char<forward_iterator<char*> >();
134+
test_char<bidirectional_iterator<char*> >();
135+
test_char<random_access_iterator<char*> >();
136+
test_char<char*>();
137+
138+
test_int<cpp17_output_iterator<int*> >();
139+
test_int<forward_iterator<int*> >();
140+
test_int<bidirectional_iterator<int*> >();
141+
test_int<random_access_iterator<int*> >();
142+
test_int<int*>();
143+
144+
test_int_array();
145+
test_int_array_struct_source();
146+
test_struct_array();
147+
148+
test5();
149+
test6();
150+
151+
{ // Test vector<bool>::iterator optimization
152+
for (std::size_t N = 8; N <= 256; N *= 2) {
153+
// Test with both full and partial bytes
154+
for (std::size_t offset = 0; offset <= 4; offset += 4) {
155+
std::vector<bool> in(N + 2 * offset);
156+
std::vector<bool> expected(N, true);
157+
std::fill_n(in.begin() + offset, N + offset, true);
158+
assert(std::equal(in.begin() + offset, in.end() - offset, expected.begin()));
159+
}
160+
}
161+
}
168162

169163
#if TEST_STD_VER > 17
170-
static_assert(test_constexpr());
164+
static_assert(test_constexpr());
171165
#endif
172166

173167
return 0;

libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/ranges.fill.pass.cpp

+21-5
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
#include <cassert>
2121
#include <ranges>
2222
#include <string>
23+
#include <vector>
2324

2425
#include "almost_satisfies_types.h"
2526
#include "test_iterators.h"
27+
#include "test_macros.h"
2628

2729
template <class Iter, class Sent = sentinel_wrapper<Iter>>
2830
concept HasFillIt = requires(Iter iter, Sent sent) { std::ranges::fill(iter, sent, int{}); };
@@ -53,7 +55,7 @@ constexpr void test_iterators() {
5355
}
5456
{
5557
int a[3];
56-
auto range = std::ranges::subrange(It(a), Sent(It(a + 3)));
58+
auto range = std::ranges::subrange(It(a), Sent(It(a + 3)));
5759
std::same_as<It> auto ret = std::ranges::fill(range, 1);
5860
assert(std::all_of(a, a + 3, [](int i) { return i == 1; }));
5961
assert(base(ret) == a + 3);
@@ -69,7 +71,7 @@ constexpr void test_iterators() {
6971
{
7072
std::array<int, 0> a;
7173
auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data())));
72-
auto ret = std::ranges::fill(range, 1);
74+
auto ret = std::ranges::fill(range, 1);
7375
assert(base(ret) == a.data());
7476
}
7577
}
@@ -94,19 +96,19 @@ constexpr bool test() {
9496
};
9597
{
9698
S a[5];
97-
std::ranges::fill(a, a + 5, S {true});
99+
std::ranges::fill(a, a + 5, S{true});
98100
assert(std::all_of(a, a + 5, [](S& s) { return s.copied; }));
99101
}
100102
{
101103
S a[5];
102-
std::ranges::fill(a, S {true});
104+
std::ranges::fill(a, S{true});
103105
assert(std::all_of(a, a + 5, [](S& s) { return s.copied; }));
104106
}
105107
}
106108

107109
{ // check that std::ranges::dangling is returned
108110
[[maybe_unused]] std::same_as<std::ranges::dangling> decltype(auto) ret =
109-
std::ranges::fill(std::array<int, 10> {}, 1);
111+
std::ranges::fill(std::array<int, 10>{}, 1);
110112
}
111113

112114
{ // check that std::ranges::dangling isn't returned with a borrowing range
@@ -131,6 +133,20 @@ constexpr bool test() {
131133
}
132134
}
133135

136+
#if TEST_STD_VER >= 23
137+
{ // Test vector<bool>::iterator optimization
138+
for (std::size_t N = 8; N <= 256; N *= 2) {
139+
// Test with both full and partial bytes
140+
for (std::size_t offset : {0, 4}) {
141+
std::vector<bool> in(N + 2 * offset);
142+
std::vector<bool> expected(N, true);
143+
std::ranges::fill(std::ranges::begin(in) + offset, std::ranges::end(in) - offset, true);
144+
assert(std::equal(in.begin() + offset, in.end() - offset, expected.begin()));
145+
}
146+
}
147+
}
148+
#endif
149+
134150
return true;
135151
}
136152

0 commit comments

Comments
 (0)