Skip to content

Commit 46ec4fc

Browse files
AlexGutenievcpplearnerStephanTLavavej
authored
Add some coverage of constexpr vector<bool> (#5728)
Co-authored-by: cpplearner <[email protected]> Co-authored-by: Stephan T. Lavavej <[email protected]>
1 parent b7c03bb commit 46ec4fc

File tree

2 files changed

+62
-21
lines changed
  • stl/inc
  • tests/std/tests/GH_000625_vector_bool_optimization

2 files changed

+62
-21
lines changed

stl/inc/vector

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3738,7 +3738,11 @@ _NODISCARD _CONSTEXPR20 _VbIt _Find_vbool(_VbIt _First, const _VbIt _Last, const
37383738
const auto _SourceMask = _FirstSourceMask & _LastSourceMask;
37393739
const auto _SelectVal = (_Val ? *_VbFirst : ~*_VbFirst) & _SourceMask;
37403740
const auto _Count = _Countr_zero(_SelectVal);
3741-
return _Count == _VBITS ? _Last : _First + static_cast<_Iter_diff_t<_VbIt>>(_Count - _First._Myoff);
3741+
if (_Count == _VBITS) {
3742+
return _Last;
3743+
} else {
3744+
return _First + static_cast<_Iter_diff_t<_VbIt>>(_Count - _First._Myoff);
3745+
}
37423746
}
37433747

37443748
const auto _FirstVal = (_Val ? *_VbFirst : ~*_VbFirst) & _FirstSourceMask;

tests/std/tests/GH_000625_vector_bool_optimization/test.cpp

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
#include <random>
1313
#include <vector>
1414

15+
#if _HAS_CXX20
16+
#define CONSTEXPR20 constexpr
17+
#else
18+
#define CONSTEXPR20 inline
19+
#endif
20+
1521
#pragma warning(disable : 4365) // conversion from 'unsigned __int64' to 'const __int64', signed/unsigned mismatch
1622

1723
using namespace std;
@@ -20,7 +26,7 @@ constexpr int blockSize = 32;
2026
static_assert(blockSize == _VBITS, "Invalid block size");
2127

2228
// This test data is not random, but irregular enough to ensure confidence in the tests
23-
const vector<bool> source = { //
29+
constexpr bool source_raw[] = { //
2430
true, false, true, false, true, true, true, false, //
2531
true, false, true, false, true, true, true, false, //
2632
true, false, true, false, true, true, true, false, //
@@ -39,8 +45,7 @@ const vector<bool> source = { //
3945
true, false, true, false, true, true, true, false, //
4046
true, false, true, false, true, true, true, false};
4147

42-
43-
void test_fill_helper(const size_t length) {
48+
CONSTEXPR20 void test_fill_helper(const size_t length) {
4449
// No offset
4550
{
4651
vector<bool> result_true(length, true);
@@ -102,7 +107,7 @@ void test_fill_helper(const size_t length) {
102107
}
103108
}
104109

105-
bool test_fill() {
110+
CONSTEXPR20 bool test_fill() {
106111
// Empty
107112
test_fill_helper(0);
108113

@@ -126,7 +131,7 @@ bool test_fill() {
126131
return true;
127132
}
128133

129-
void test_find_helper(const size_t length) {
134+
CONSTEXPR20 void test_find_helper(const size_t length) {
130135
// No offset
131136
{
132137
vector<bool> input_true(length + 3, false);
@@ -160,7 +165,7 @@ void test_find_helper(const size_t length) {
160165
}
161166
}
162167

163-
bool test_find() {
168+
CONSTEXPR20 bool test_find() {
164169
// Empty range
165170
test_find_helper(0);
166171

@@ -178,10 +183,11 @@ bool test_find() {
178183
return true;
179184
}
180185

181-
void test_count_helper(const ptrdiff_t length) {
186+
CONSTEXPR20 void test_count_helper(const ptrdiff_t length) {
187+
const vector<bool> source(begin(source_raw), end(source_raw));
182188
const int counts_true[] = {0, 1, 1, 2, 2, 3, 4, 5};
183189
const int counts_false[] = {0, 0, 1, 1, 2, 2, 2, 2};
184-
const auto expected = div(static_cast<int>(length), 8);
190+
const div_t expected = {static_cast<int>(length) / 8, static_cast<int>(length) % 8};
185191
// No offset
186192
{
187193
const auto result_true = static_cast<int>(count(source.cbegin(), next(source.cbegin(), length), true));
@@ -203,7 +209,7 @@ void test_count_helper(const ptrdiff_t length) {
203209
}
204210
}
205211

206-
bool test_count() {
212+
CONSTEXPR20 bool test_count() {
207213
// Empty range
208214
test_count_helper(0);
209215

@@ -259,7 +265,7 @@ void test_huge_vector_bool() {
259265
assert(count(v.begin(), v.end(), false) == large_bit_diff - 3);
260266
}
261267

262-
void test_copy_no_offset(const size_t length) {
268+
CONSTEXPR20 void test_copy_no_offset(const size_t length) {
263269
vector<bool> result;
264270
switch (length) {
265271
case 3:
@@ -304,6 +310,8 @@ void test_copy_no_offset(const size_t length) {
304310
assert(false);
305311
}
306312

313+
const vector<bool> source(begin(source_raw), end(source_raw));
314+
307315
{
308316
vector<bool> dest(length, false);
309317
const auto res_copy = copy(source.begin(), next(source.begin(), length), dest.begin());
@@ -341,7 +349,7 @@ void test_copy_no_offset(const size_t length) {
341349
}
342350
}
343351

344-
void test_copy_offset_source(const size_t length) {
352+
CONSTEXPR20 void test_copy_offset_source(const size_t length) {
345353
vector<bool> result;
346354
switch (length) {
347355
case 3:
@@ -389,6 +397,8 @@ void test_copy_offset_source(const size_t length) {
389397
assert(false);
390398
}
391399

400+
const vector<bool> source(begin(source_raw), end(source_raw));
401+
392402
{
393403
vector<bool> dest(length, false);
394404
const auto res_copy = copy(next(source.begin()), next(source.begin(), length + 1), dest.begin());
@@ -427,7 +437,7 @@ void test_copy_offset_source(const size_t length) {
427437
}
428438
}
429439

430-
void test_copy_offset_dest(const size_t length) {
440+
CONSTEXPR20 void test_copy_offset_dest(const size_t length) {
431441
vector<bool> result;
432442
switch (length) {
433443
case 3:
@@ -480,6 +490,8 @@ void test_copy_offset_dest(const size_t length) {
480490
assert(false);
481491
}
482492

493+
const vector<bool> source(begin(source_raw), end(source_raw));
494+
483495
{
484496
vector<bool> dest(length + 1, false);
485497
const auto res_copy = copy(source.begin(), next(source.begin(), length), next(dest.begin()));
@@ -517,7 +529,7 @@ void test_copy_offset_dest(const size_t length) {
517529
}
518530
}
519531

520-
void test_copy_offset_match(const size_t length) {
532+
CONSTEXPR20 void test_copy_offset_match(const size_t length) {
521533
vector<bool> result;
522534
switch (length) {
523535
case 3:
@@ -570,6 +582,8 @@ void test_copy_offset_match(const size_t length) {
570582
assert(false);
571583
}
572584

585+
const vector<bool> source(begin(source_raw), end(source_raw));
586+
573587
{
574588
vector<bool> dest(length, false);
575589
const auto res_copy = copy(next(source.begin()), next(source.begin(), length), next(dest.begin()));
@@ -608,7 +622,7 @@ void test_copy_offset_match(const size_t length) {
608622
}
609623
}
610624

611-
void test_copy_offset_mismatch_leftshift(const size_t length) {
625+
CONSTEXPR20 void test_copy_offset_mismatch_leftshift(const size_t length) {
612626
vector<bool> result;
613627
switch (length) {
614628
case 3:
@@ -661,6 +675,8 @@ void test_copy_offset_mismatch_leftshift(const size_t length) {
661675
assert(false);
662676
}
663677

678+
const vector<bool> source(begin(source_raw), end(source_raw));
679+
664680
{
665681
vector<bool> dest(length + 1, false);
666682
const auto res_copy = copy(next(source.begin()), next(source.begin(), length), next(dest.begin(), 2));
@@ -699,7 +715,7 @@ void test_copy_offset_mismatch_leftshift(const size_t length) {
699715
}
700716
}
701717

702-
void test_copy_offset_mismatch_rightshift(const size_t length) {
718+
CONSTEXPR20 void test_copy_offset_mismatch_rightshift(const size_t length) {
703719
vector<bool> result;
704720
switch (length) {
705721
case 3:
@@ -754,6 +770,8 @@ void test_copy_offset_mismatch_rightshift(const size_t length) {
754770
assert(false);
755771
}
756772

773+
const vector<bool> source(begin(source_raw), end(source_raw));
774+
757775
{
758776
vector<bool> dest(length, false);
759777
const auto res_copy = copy(next(source.begin(), 2), next(source.begin(), length + 1), next(dest.begin()));
@@ -792,7 +810,7 @@ void test_copy_offset_mismatch_rightshift(const size_t length) {
792810
}
793811
}
794812

795-
void test_copy_offset_aligned(const size_t length) {
813+
CONSTEXPR20 void test_copy_offset_aligned(const size_t length) {
796814
vector<bool> result;
797815
switch (length) {
798816
case 3:
@@ -845,6 +863,8 @@ void test_copy_offset_aligned(const size_t length) {
845863
assert(false);
846864
}
847865

866+
const vector<bool> source(begin(source_raw), end(source_raw));
867+
848868
{
849869
vector<bool> dest(length, false);
850870
const auto res_copy = copy(next(source.begin(), 9), next(source.begin(), length + 8), next(dest.begin()));
@@ -883,7 +903,9 @@ void test_copy_offset_aligned(const size_t length) {
883903
}
884904
}
885905

886-
void test_copy_sub_char() {
906+
CONSTEXPR20 void test_copy_sub_char() {
907+
const vector<bool> source(begin(source_raw), end(source_raw));
908+
887909
{ // sub char copy unaligned
888910
const vector<bool> result = {false, false, true, false, true, false, false, false};
889911

@@ -1092,7 +1114,7 @@ void test_copy_sub_char() {
10921114
}
10931115
}
10941116

1095-
void test_copy_regression() {
1117+
CONSTEXPR20 void test_copy_regression() {
10961118
// This specific case was found by the randomized coverage below.
10971119
const vector<bool> src = {0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0,
10981120
1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
@@ -1115,7 +1137,8 @@ void test_copy_regression() {
11151137
assert(dst == correct);
11161138
}
11171139

1118-
bool test_copy() {
1140+
// Test copy() in multiple parts to stay within constexpr step limits.
1141+
CONSTEXPR20 bool test_copy_part_1() {
11191142
test_copy_no_offset(3);
11201143
test_copy_no_offset(8);
11211144
test_copy_no_offset(22);
@@ -1144,6 +1167,10 @@ bool test_copy() {
11441167
test_copy_offset_match(32);
11451168
test_copy_offset_match(67);
11461169

1170+
return true;
1171+
}
1172+
1173+
CONSTEXPR20 bool test_copy_part_2() {
11471174
test_copy_offset_mismatch_leftshift(3);
11481175
test_copy_offset_mismatch_leftshift(8);
11491176
test_copy_offset_mismatch_leftshift(22);
@@ -1354,13 +1381,23 @@ static_assert(test_gh_5345<64>());
13541381
static_assert(test_gh_5345<64, 16>());
13551382
static_assert(test_gh_5345<120>());
13561383
static_assert(test_gh_5345<120, 31>());
1384+
1385+
static_assert(test_fill());
1386+
static_assert(test_find());
1387+
static_assert(test_count());
1388+
1389+
#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-2574489
1390+
static_assert(test_copy_part_1());
1391+
static_assert(test_copy_part_2());
1392+
#endif // ^^^ no workaround ^^^
13571393
#endif // _HAS_CXX20
13581394

13591395
int main() {
13601396
test_fill();
13611397
test_find();
13621398
test_count();
1363-
test_copy();
1399+
test_copy_part_1();
1400+
test_copy_part_2();
13641401

13651402
test_huge_vector_bool();
13661403

0 commit comments

Comments
 (0)