Skip to content

Commit 9da6c14

Browse files
committed
Inline and group tests for vector<bool> together
1 parent b83e03d commit 9da6c14

File tree

3 files changed

+82
-71
lines changed

3 files changed

+82
-71
lines changed

libcxx/include/__bit_reference

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,18 @@ struct __size_difference_type_traits<_Cp, __void_t<typename _Cp::difference_type
6565
template <class _StorageType>
6666
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __trailing_mask(unsigned __clz) {
6767
static_assert(is_unsigned<_StorageType>::value, "__trailing_mask only works with unsigned types");
68-
return static_cast<_StorageType>(static_cast<_StorageType>(~static_cast<_StorageType>(0)) >> __clz);
68+
return static_cast<_StorageType>(~static_cast<_StorageType>(0)) >> __clz;
6969
}
7070

7171
template <class _StorageType>
7272
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __middle_mask(unsigned __clz, unsigned __ctz) {
7373
static_assert(is_unsigned<_StorageType>::value, "__middle_mask only works with unsigned types");
74-
return static_cast<_StorageType>(static_cast<_StorageType>(~static_cast<_StorageType>(0)) << __ctz) &
74+
return (static_cast<_StorageType>(~static_cast<_StorageType>(0)) << __ctz) &
7575
std::__trailing_mask<_StorageType>(__clz);
7676
}
7777

7878
// This function is designed to operate correctly even for smaller integral types like `uint8_t`, `uint16_t`,
79-
// or `unsigned short`. Casting back to _StorageType is crucial to prevent undefined behavior that can arise
80-
// from integral promotions.
79+
// or `unsigned short`.
8180
// See https://github.com/llvm/llvm-project/pull/122410.
8281
template <class _StoragePointer>
8382
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
@@ -91,7 +90,7 @@ __fill_masked_range(_StoragePointer __word, unsigned __clz, unsigned __ctz, bool
9190
if (__fill_val)
9291
*__word |= __m;
9392
else
94-
*__word &= static_cast<_StorageType>(~__m);
93+
*__word &= ~__m;
9594
}
9695

9796
template <class _Cp, bool = __has_storage_type<_Cp>::value>

libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -38,45 +38,51 @@ struct Test {
3838
}
3939
};
4040

41-
TEST_CONSTEXPR_CXX20 void test_bit_iterator_with_custom_sized_types() {
42-
{
43-
using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>;
44-
std::vector<bool, Alloc> in(100, true, Alloc(1));
45-
assert(std::count(in.begin(), in.end(), true) == 100);
46-
}
47-
{
48-
using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>;
49-
std::vector<bool, Alloc> in(199, true, Alloc(1));
50-
assert(std::count(in.begin(), in.end(), true) == 199);
51-
}
52-
{
53-
using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>;
54-
std::vector<bool, Alloc> in(200, true, Alloc(1));
55-
assert(std::count(in.begin(), in.end(), true) == 200);
56-
}
57-
{
58-
using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>;
59-
std::vector<bool, Alloc> in(257, true, Alloc(1));
60-
assert(std::count(in.begin(), in.end(), true) == 257);
61-
}
62-
}
63-
6441
TEST_CONSTEXPR_CXX20 bool test() {
6542
types::for_each(types::cpp17_input_iterator_list<const int*>(), Test());
6643

67-
if (TEST_STD_AT_LEAST_20_OR_RUNTIME_EVALUATED) {
68-
std::vector<bool> vec(256 + 64);
69-
for (ptrdiff_t i = 0; i != 256; ++i) {
70-
for (size_t offset = 0; offset != 64; ++offset) {
71-
std::fill(vec.begin(), vec.end(), false);
72-
std::fill(vec.begin() + offset, vec.begin() + i + offset, true);
73-
assert(std::count(vec.begin() + offset, vec.begin() + offset + 256, true) == i);
74-
assert(std::count(vec.begin() + offset, vec.begin() + offset + 256, false) == 256 - i);
44+
// Tests for std::count with std::vector<bool>::iterator optimizations.
45+
{
46+
{ // check that vector<bool>::iterator optimization works as expected
47+
std::vector<bool> vec(256 + 64);
48+
for (ptrdiff_t i = 0; i != 256; ++i) {
49+
for (size_t offset = 0; offset != 64; ++offset) {
50+
std::fill(vec.begin(), vec.end(), false);
51+
std::fill(vec.begin() + offset, vec.begin() + i + offset, true);
52+
assert(std::count(vec.begin() + offset, vec.begin() + offset + 256, true) == i);
53+
assert(std::count(vec.begin() + offset, vec.begin() + offset + 256, false) == 256 - i);
54+
}
7555
}
7656
}
77-
}
7857

79-
test_bit_iterator_with_custom_sized_types();
58+
// Fix std::count for std::vector<bool> with small storage types, e.g., std::uint16_t, unsigned short.
59+
// See https://github.com/llvm/llvm-project/issues/122528
60+
{
61+
using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>;
62+
std::vector<bool, Alloc> in(100, true, Alloc(1));
63+
assert(std::count(in.begin(), in.end(), true) == 100);
64+
}
65+
{
66+
using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>;
67+
std::vector<bool, Alloc> in(199, true, Alloc(1));
68+
assert(std::count(in.begin(), in.end(), true) == 199);
69+
}
70+
{
71+
using Alloc = sized_allocator<bool, unsigned short, short>;
72+
std::vector<bool, Alloc> in(200, true, Alloc(1));
73+
assert(std::count(in.begin(), in.end(), true) == 200);
74+
}
75+
{
76+
using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>;
77+
std::vector<bool, Alloc> in(205, true, Alloc(1));
78+
assert(std::count(in.begin(), in.end(), true) == 205);
79+
}
80+
{
81+
using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>;
82+
std::vector<bool, Alloc> in(257, true, Alloc(1));
83+
assert(std::count(in.begin(), in.end(), true) == 257);
84+
}
85+
}
8086

8187
return true;
8288
}

libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -156,29 +156,6 @@ constexpr void test_iterators() {
156156
}
157157
}
158158

159-
TEST_CONSTEXPR_CXX20 void test_bit_iterator_with_custom_sized_types() {
160-
{
161-
using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>;
162-
std::vector<bool, Alloc> in(100, true, Alloc(1));
163-
assert(std::ranges::count(in, true) == 100);
164-
}
165-
{
166-
using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>;
167-
std::vector<bool, Alloc> in(199, true, Alloc(1));
168-
assert(std::ranges::count(in, true) == 199);
169-
}
170-
{
171-
using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>;
172-
std::vector<bool, Alloc> in(200, true, Alloc(1));
173-
assert(std::ranges::count(in, true) == 200);
174-
}
175-
{
176-
using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>;
177-
std::vector<bool, Alloc> in(257, true, Alloc(1));
178-
assert(std::ranges::count(in, true) == 257);
179-
}
180-
}
181-
182159
constexpr bool test() {
183160
test_iterators<int*>();
184161
test_iterators<const int*>();
@@ -293,19 +270,48 @@ constexpr bool test() {
293270
}
294271
}
295272

296-
{ // check that __bit_iterator optimizations work as expected
297-
std::vector<bool> vec(256 + 64);
298-
for (ptrdiff_t i = 0; i != 256; ++i) {
299-
for (size_t offset = 0; offset != 64; ++offset) {
300-
std::fill(vec.begin(), vec.end(), false);
301-
std::fill(vec.begin() + offset, vec.begin() + i + offset, true);
302-
assert(std::ranges::count(vec.begin() + offset, vec.begin() + offset + 256, true) == i);
303-
assert(std::ranges::count(vec.begin() + offset, vec.begin() + offset + 256, false) == 256 - i);
273+
// Tests for std::count with std::vector<bool>::iterator optimizations.
274+
{
275+
{ // check that vector<bool>::iterator optimization works as expected
276+
std::vector<bool> vec(256 + 64);
277+
for (ptrdiff_t i = 0; i != 256; ++i) {
278+
for (size_t offset = 0; offset != 64; ++offset) {
279+
std::fill(vec.begin(), vec.end(), false);
280+
std::fill(vec.begin() + offset, vec.begin() + i + offset, true);
281+
assert(std::ranges::count(vec.begin() + offset, vec.begin() + offset + 256, true) == i);
282+
assert(std::ranges::count(vec.begin() + offset, vec.begin() + offset + 256, false) == 256 - i);
283+
}
304284
}
305285
}
306-
}
307286

308-
test_bit_iterator_with_custom_sized_types();
287+
// Fix std::ranges::count for std::vector<bool> with small storage types, e.g., std::uint16_t, unsigned short.
288+
// See https://github.com/llvm/llvm-project/issues/122528
289+
{
290+
using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>;
291+
std::vector<bool, Alloc> in(100, true, Alloc(1));
292+
assert(std::ranges::count(in, true) == 100);
293+
}
294+
{
295+
using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>;
296+
std::vector<bool, Alloc> in(199, true, Alloc(1));
297+
assert(std::ranges::count(in, true) == 199);
298+
}
299+
{
300+
using Alloc = sized_allocator<bool, unsigned short, short>;
301+
std::vector<bool, Alloc> in(200, true, Alloc(1));
302+
assert(std::ranges::count(in, true) == 200);
303+
}
304+
{
305+
using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>;
306+
std::vector<bool, Alloc> in(205, true, Alloc(1));
307+
assert(std::ranges::count(in, true) == 205);
308+
}
309+
{
310+
using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>;
311+
std::vector<bool, Alloc> in(257, true, Alloc(1));
312+
assert(std::ranges::count(in, true) == 257);
313+
}
314+
}
309315

310316
return true;
311317
}

0 commit comments

Comments
 (0)