Skip to content

Commit 783ef78

Browse files
committed
Inline call to std::copy and enhance test coverage
1 parent 42c5224 commit 783ef78

File tree

5 files changed

+302
-260
lines changed

5 files changed

+302
-260
lines changed

libcxx/include/__vector/vector_bool.h

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,6 @@ class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator> {
417417
__guard.__complete();
418418
}
419419

420-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __alloc_and_copy(const vector& __v);
421-
422420
template <class _Iterator, class _Sentinel>
423421
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last);
424422

@@ -697,30 +695,27 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
697695

698696
#endif // _LIBCPP_CXX03_LANG
699697

700-
// This function copies each storage word as a whole, which is substantially more efficient than copying
701-
// individual bits within each word
702-
template <class _Allocator>
703-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void vector<bool, _Allocator>::__alloc_and_copy(const vector& __v) {
704-
if (__v.__size_) {
705-
__vallocate(__v.__size_);
706-
std::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_);
707-
}
708-
__size_ = __v.__size_;
709-
}
710-
711698
template <class _Allocator>
712699
_LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const vector& __v)
713700
: __begin_(nullptr),
714701
__size_(0),
715702
__cap_(0),
716703
__alloc_(__storage_traits::select_on_container_copy_construction(__v.__alloc_)) {
717-
__alloc_and_copy(__v);
704+
if (__v.size() > 0) {
705+
__vallocate(__v.size());
706+
std::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.size()), __begin_);
707+
__size_ = __v.size();
708+
}
718709
}
719710

720711
template <class _Allocator>
721712
_LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
722713
: __begin_(nullptr), __size_(0), __cap_(0), __alloc_(__a) {
723-
__alloc_and_copy(__v);
714+
if (__v.size() > 0) {
715+
__vallocate(__v.size());
716+
std::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.size()), __begin_);
717+
__size_ = __v.size();
718+
}
724719
}
725720

726721
template <class _Allocator>
@@ -765,8 +760,10 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator
765760
this->__cap_ = __v.__cap_;
766761
__v.__begin_ = nullptr;
767762
__v.__cap_ = __v.__size_ = 0;
768-
} else {
769-
__alloc_and_copy(__v);
763+
} else if (__v.size() > 0) {
764+
__vallocate(__v.size());
765+
std::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.size()), __begin_);
766+
__size_ = __v.size();
770767
}
771768
}
772769

libcxx/test/std/containers/sequences/vector.bool/copy.pass.cpp

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,64 +11,76 @@
1111

1212
// vector(const vector& v);
1313

14-
#include <vector>
1514
#include <cassert>
15+
#include <memory>
16+
#include <vector>
1617

17-
#include "test_macros.h"
18-
#include "test_allocator.h"
1918
#include "min_allocator.h"
19+
#include "test_allocator.h"
20+
#include "test_macros.h"
2021

21-
template <class C>
22-
TEST_CONSTEXPR_CXX20 void test(const C& x)
23-
{
24-
typename C::size_type s = x.size();
25-
C c(x);
26-
LIBCPP_ASSERT(c.__invariants());
27-
assert(c.size() == s);
28-
assert(c == x);
29-
}
30-
31-
TEST_CONSTEXPR_CXX20 bool tests()
32-
{
33-
{
34-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
35-
bool* an = a + sizeof(a)/sizeof(a[0]);
36-
test(std::vector<bool>(a, an));
37-
}
38-
{
39-
std::vector<bool, test_allocator<bool> > v(3, true, test_allocator<bool>(5));
40-
std::vector<bool, test_allocator<bool> > v2 = v;
41-
assert(v2 == v);
42-
assert(v2.get_allocator() == v.get_allocator());
43-
}
22+
template <class A>
23+
TEST_CONSTEXPR_CXX20 void test(const std::vector<bool, A>& x) {
24+
std::vector<bool, A> c(x);
25+
LIBCPP_ASSERT(c.__invariants());
26+
assert(c.size() == x.size());
27+
assert(c == x);
4428
#if TEST_STD_VER >= 11
45-
{
46-
std::vector<bool, other_allocator<bool> > v(3, true, other_allocator<bool>(5));
47-
std::vector<bool, other_allocator<bool> > v2 = v;
48-
assert(v2 == v);
49-
assert(v2.get_allocator() == other_allocator<bool>(-2));
50-
}
51-
{
52-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
53-
bool* an = a + sizeof(a)/sizeof(a[0]);
54-
test(std::vector<bool, min_allocator<bool>>(a, an));
55-
}
56-
{
57-
std::vector<bool, min_allocator<bool> > v(3, true, min_allocator<bool>());
58-
std::vector<bool, min_allocator<bool> > v2 = v;
59-
assert(v2 == v);
60-
assert(v2.get_allocator() == v.get_allocator());
61-
}
29+
assert(c.get_allocator() == std::allocator_traits<A>::select_on_container_copy_construction(x.get_allocator()));
6230
#endif
31+
}
32+
33+
TEST_CONSTEXPR_CXX20 bool tests() {
34+
bool a05[5] = {1, 0, 1, 0, 1};
35+
bool a17[17] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1};
36+
bool a33[33] = {1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1};
37+
bool a65[65] = {0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0};
38+
39+
{ // Test the copy constructor with the default allocator
40+
test(std::vector<bool>(a05, a05 + sizeof(a05) / sizeof(a05[0])));
41+
test(std::vector<bool>(a17, a17 + sizeof(a17) / sizeof(a17[0])));
42+
test(std::vector<bool>(a33, a33 + sizeof(a33) / sizeof(a33[0])));
43+
test(std::vector<bool>(a65, a65 + sizeof(a65) / sizeof(a65[0])));
44+
test(std::vector<bool>(257, true));
45+
}
46+
47+
{ // Test the copy constructor with test_allocator
48+
using A = test_allocator<bool>;
49+
using C = std::vector<bool, A>;
50+
test(C(a05, a05 + sizeof(a05) / sizeof(a05[0]), A(5)));
51+
test(C(a17, a17 + sizeof(a17) / sizeof(a17[0]), A(5)));
52+
test(C(a33, a33 + sizeof(a33) / sizeof(a33[0]), A(5)));
53+
test(C(a65, a65 + sizeof(a65) / sizeof(a65[0]), A(5)));
54+
test(C(257, true, A(5)));
55+
}
56+
57+
{ // Test the copy constructor with other_allocator
58+
using A = other_allocator<bool>;
59+
using C = std::vector<bool, A>;
60+
test(C(a05, a05 + sizeof(a05) / sizeof(a05[0]), A(5)));
61+
test(C(a17, a17 + sizeof(a17) / sizeof(a17[0]), A(5)));
62+
test(C(a33, a33 + sizeof(a33) / sizeof(a33[0]), A(5)));
63+
test(C(a65, a65 + sizeof(a65) / sizeof(a65[0]), A(5)));
64+
test(C(257, true, A(5)));
65+
}
66+
67+
{ // Test the copy constructor with min_allocator
68+
using A = min_allocator<bool>;
69+
using C = std::vector<bool, A>;
70+
test(C(a05, a05 + sizeof(a05) / sizeof(a05[0]), A()));
71+
test(C(a17, a17 + sizeof(a17) / sizeof(a17[0]), A()));
72+
test(C(a33, a33 + sizeof(a33) / sizeof(a33[0]), A()));
73+
test(C(a65, a65 + sizeof(a65) / sizeof(a65[0]), A()));
74+
test(C(257, true, A()));
75+
}
6376

64-
return true;
77+
return true;
6578
}
6679

67-
int main(int, char**)
68-
{
69-
tests();
70-
#if TEST_STD_VER > 17
71-
static_assert(tests());
80+
int main(int, char**) {
81+
tests();
82+
#if TEST_STD_VER >= 20
83+
static_assert(tests());
7284
#endif
73-
return 0;
85+
return 0;
7486
}

libcxx/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,67 +7,77 @@
77
//===----------------------------------------------------------------------===//
88

99
// <vector>
10+
// vector<bool>
1011

1112
// vector(const vector& v, const allocator_type& a);
1213

13-
#include <vector>
1414
#include <cassert>
15+
#include <vector>
1516

16-
#include "test_macros.h"
17-
#include "test_allocator.h"
1817
#include "min_allocator.h"
18+
#include "test_allocator.h"
19+
#include "test_macros.h"
1920

20-
template <class C>
21-
TEST_CONSTEXPR_CXX20 void test(const C& x, const typename C::allocator_type& a)
22-
{
23-
typename C::size_type s = x.size();
24-
C c(x, a);
25-
LIBCPP_ASSERT(c.__invariants());
26-
assert(c.size() == s);
27-
assert(c == x);
21+
template <class A>
22+
TEST_CONSTEXPR_CXX20 void test(const std::vector<bool, A>& x, const A& a) {
23+
std::vector<bool, A> c(x, a);
24+
LIBCPP_ASSERT(c.__invariants());
25+
assert(c.size() == x.size());
26+
assert(c == x);
27+
assert(c.get_allocator() == a);
2828
}
2929

30-
TEST_CONSTEXPR_CXX20 bool tests()
31-
{
32-
{
33-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
34-
bool* an = a + sizeof(a)/sizeof(a[0]);
35-
test(std::vector<bool>(a, an), std::allocator<bool>());
36-
}
37-
{
38-
std::vector<bool, test_allocator<bool> > l(3, true, test_allocator<bool>(5));
39-
std::vector<bool, test_allocator<bool> > l2(l, test_allocator<bool>(3));
40-
assert(l2 == l);
41-
assert(l2.get_allocator() == test_allocator<bool>(3));
42-
}
43-
{
44-
std::vector<bool, other_allocator<bool> > l(3, true, other_allocator<bool>(5));
45-
std::vector<bool, other_allocator<bool> > l2(l, other_allocator<bool>(3));
46-
assert(l2 == l);
47-
assert(l2.get_allocator() == other_allocator<bool>(3));
48-
}
49-
#if TEST_STD_VER >= 11
50-
{
51-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
52-
bool* an = a + sizeof(a)/sizeof(a[0]);
53-
test(std::vector<bool, min_allocator<bool>>(a, an), min_allocator<bool>());
54-
}
55-
{
56-
std::vector<bool, min_allocator<bool> > l(3, true, min_allocator<bool>());
57-
std::vector<bool, min_allocator<bool> > l2(l, min_allocator<bool>());
58-
assert(l2 == l);
59-
assert(l2.get_allocator() == min_allocator<bool>());
60-
}
61-
#endif
30+
TEST_CONSTEXPR_CXX20 bool tests() {
31+
bool a05[5] = {1, 0, 1, 0, 1};
32+
bool a17[17] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1};
33+
bool a33[33] = {1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1};
34+
bool a65[65] = {0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0};
35+
36+
{ // Test with the default allocator
37+
test(std::vector<bool>(a05, a05 + sizeof(a05) / sizeof(a05[0])), std::allocator<bool>());
38+
test(std::vector<bool>(a17, a17 + sizeof(a17) / sizeof(a17[0])), std::allocator<bool>());
39+
test(std::vector<bool>(a33, a33 + sizeof(a33) / sizeof(a33[0])), std::allocator<bool>());
40+
test(std::vector<bool>(a65, a65 + sizeof(a65) / sizeof(a65[0])), std::allocator<bool>());
41+
test(std::vector<bool>(257, true), std::allocator<bool>());
42+
}
43+
44+
{ // Test with test_allocator
45+
using A = test_allocator<bool>;
46+
using C = std::vector<bool, A>;
47+
test(C(a05, a05 + sizeof(a05) / sizeof(a05[0]), A(5)), A(3));
48+
test(C(a17, a17 + sizeof(a17) / sizeof(a17[0]), A(5)), A(3));
49+
test(C(a33, a33 + sizeof(a33) / sizeof(a33[0]), A(5)), A(3));
50+
test(C(a65, a65 + sizeof(a65) / sizeof(a65[0]), A(5)), A(3));
51+
test(C(257, true, A(5)), A(3));
52+
}
53+
54+
{ // Test with other_allocator
55+
using A = other_allocator<bool>;
56+
using C = std::vector<bool, A>;
57+
test(C(a05, a05 + sizeof(a05) / sizeof(a05[0]), A(5)), A(3));
58+
test(C(a17, a17 + sizeof(a17) / sizeof(a17[0]), A(5)), A(3));
59+
test(C(a33, a33 + sizeof(a33) / sizeof(a33[0]), A(5)), A(3));
60+
test(C(a65, a65 + sizeof(a65) / sizeof(a65[0]), A(5)), A(3));
61+
test(C(257, true, A(5)), A(3));
62+
}
63+
64+
{ // Test with min_allocator
65+
using A = min_allocator<bool>;
66+
using C = std::vector<bool, A>;
67+
test(C(a05, a05 + sizeof(a05) / sizeof(a05[0]), A()), A());
68+
test(C(a17, a17 + sizeof(a17) / sizeof(a17[0]), A()), A());
69+
test(C(a33, a33 + sizeof(a33) / sizeof(a33[0]), A()), A());
70+
test(C(a65, a65 + sizeof(a65) / sizeof(a65[0]), A()), A());
71+
test(C(257, true, A()), A());
72+
}
6273

6374
return true;
6475
}
6576

66-
int main(int, char**)
67-
{
68-
tests();
69-
#if TEST_STD_VER > 17
70-
static_assert(tests());
77+
int main(int, char**) {
78+
tests();
79+
#if TEST_STD_VER >= 20
80+
static_assert(tests());
7181
#endif
72-
return 0;
82+
return 0;
7383
}

0 commit comments

Comments
 (0)