Skip to content

Commit 5adcb9a

Browse files
committed
Simplify vector<bool>::flip() and add new tests
1 parent dd647e3 commit 5adcb9a

File tree

2 files changed

+104
-8
lines changed

2 files changed

+104
-8
lines changed

libcxx/include/__vector/vector_bool.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,18 +1049,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::resize(size_type __
10491049

10501050
template <class _Allocator>
10511051
_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::flip() _NOEXCEPT {
1052-
// do middle whole words
1052+
// Process the whole words in the front
10531053
size_type __n = __size_;
10541054
__storage_pointer __p = __begin_;
10551055
for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
10561056
*__p = ~*__p;
1057-
// do last partial word
1058-
if (__n > 0) {
1059-
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
1060-
__storage_type __b = *__p & __m;
1061-
*__p &= ~__m;
1062-
*__p |= ~__b & __m;
1063-
}
1057+
// Process the last partial word, if it exists
1058+
if (__n > 0)
1059+
*__p ^= ~__storage_type(0) >> (__bits_per_word - __n);
10641060
}
10651061

10661062
template <class _Allocator>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <vector>
10+
11+
// flip()
12+
13+
#include <cassert>
14+
#include <vector>
15+
16+
#include "min_allocator.h"
17+
#include "test_allocator.h"
18+
#include "test_macros.h"
19+
20+
TEST_CONSTEXPR_CXX20 bool tests() {
21+
//
22+
// Testing flip() function with small vectors and various allocators
23+
//
24+
{
25+
std::vector<bool> v;
26+
v.push_back(true);
27+
v.push_back(false);
28+
v.push_back(true);
29+
v.flip();
30+
assert(!v[0]);
31+
assert(v[1]);
32+
assert(!v[2]);
33+
}
34+
{
35+
std::vector<bool, min_allocator<bool> > v;
36+
v.push_back(true);
37+
v.push_back(false);
38+
v.push_back(true);
39+
v.flip();
40+
assert(!v[0]);
41+
assert(v[1]);
42+
assert(!v[2]);
43+
}
44+
{
45+
std::vector<bool, test_allocator<bool> > v(test_allocator<bool>(5));
46+
v.push_back(true);
47+
v.push_back(false);
48+
v.push_back(true);
49+
v.flip();
50+
assert(!v[0]);
51+
assert(v[1]);
52+
assert(!v[2]);
53+
}
54+
55+
//
56+
// Testing flip() function with larger vectors
57+
//
58+
{
59+
std::vector<bool> v(1000);
60+
for (std::size_t i = 0; i < v.size(); ++i)
61+
v[i] = i & 1;
62+
std::vector<bool> original = v;
63+
v.flip();
64+
for (size_t i = 0; i < v.size(); ++i) {
65+
assert(v[i] == !original[i]);
66+
}
67+
}
68+
{
69+
std::vector<bool, min_allocator<bool> > v(1000, false, min_allocator<bool>());
70+
for (std::size_t i = 0; i < v.size(); ++i)
71+
v[i] = i & 1;
72+
std::vector<bool, min_allocator<bool> > original = v;
73+
v.flip();
74+
for (size_t i = 0; i < v.size(); ++i)
75+
assert(v[i] == !original[i]);
76+
v.flip();
77+
assert(v == original);
78+
}
79+
{
80+
std::vector<bool, test_allocator<bool> > v(1000, false, test_allocator<bool>(5));
81+
for (std::size_t i = 0; i < v.size(); ++i)
82+
v[i] = i & 1;
83+
std::vector<bool, test_allocator<bool> > original = v;
84+
v.flip();
85+
for (size_t i = 0; i < v.size(); ++i)
86+
assert(v[i] == !original[i]);
87+
v.flip();
88+
assert(v == original);
89+
}
90+
91+
return true;
92+
}
93+
94+
int main(int, char**) {
95+
tests();
96+
#if TEST_STD_VER > 17
97+
static_assert(tests());
98+
#endif
99+
return 0;
100+
}

0 commit comments

Comments
 (0)