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
1723using namespace std ;
@@ -20,7 +26,7 @@ constexpr int blockSize = 32;
2026static_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>());
13541381static_assert (test_gh_5345<64 , 16 >());
13551382static_assert (test_gh_5345<120 >());
13561383static_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
13591395int 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