2020#include < cassert>
2121#include < iterator>
2222#include < memory>
23+ #include < vector>
2324
2425#include " MoveOnly.h"
2526#include " test_iterators.h"
@@ -45,15 +46,15 @@ struct Test {
4546 template <class OutIter >
4647 TEST_CONSTEXPR_CXX20 void operator ()() {
4748 const unsigned N = 1000 ;
48- int ia[N] = {};
49+ int ia[N] = {};
4950 for (unsigned i = 0 ; i < N; ++i)
50- ia[i] = i;
51+ ia[i] = i;
5152 int ib[N] = {0 };
5253
53- OutIter r = std::move (InIter (ia), InIter (ia+ N), OutIter (ib));
54- assert (base (r) == ib+ N);
54+ OutIter r = std::move (InIter (ia), InIter (ia + N), OutIter (ib));
55+ assert (base (r) == ib + N);
5556 for (unsigned i = 0 ; i < N; ++i)
56- assert (ia[i] == ib[i]);
57+ assert (ia[i] == ib[i]);
5758 }
5859};
5960
@@ -73,13 +74,13 @@ struct Test1 {
7374 const unsigned N = 100 ;
7475 std::unique_ptr<int > ia[N];
7576 for (unsigned i = 0 ; i < N; ++i)
76- ia[i].reset (new int (i));
77+ ia[i].reset (new int (i));
7778 std::unique_ptr<int > ib[N];
7879
79- OutIter r = std::move (InIter (ia), InIter (ia+ N), OutIter (ib));
80- assert (base (r) == ib+ N);
80+ OutIter r = std::move (InIter (ia), InIter (ia + N), OutIter (ib));
81+ assert (base (r) == ib + N);
8182 for (unsigned i = 0 ; i < N; ++i)
82- assert (*ib[i] == static_cast <int >(i));
83+ assert (*ib[i] == static_cast <int >(i));
8384 }
8485};
8586
@@ -92,6 +93,26 @@ struct Test1OutIters {
9293 }
9394};
9495
96+ TEST_CONSTEXPR_CXX20 bool test_vector_bool (std::size_t N) {
97+ std::vector<bool > in (N, false );
98+ for (std::size_t i = 0 ; i < N; i += 2 )
99+ in[i] = true ;
100+
101+ { // Test move with aligned bytes
102+ std::vector<bool > out (N);
103+ std::move (in.begin (), in.end (), out.begin ());
104+ assert (in == out);
105+ }
106+ { // Test move with unaligned bytes
107+ std::vector<bool > out (N + 8 );
108+ std::move (in.begin (), in.end (), out.begin () + 4 );
109+ for (std::size_t i = 0 ; i < N; ++i)
110+ assert (out[i + 4 ] == in[i]);
111+ }
112+
113+ return true ;
114+ }
115+
95116TEST_CONSTEXPR_CXX20 bool test () {
96117 types::for_each (types::cpp17_input_iterator_list<int *>(), TestOutIters ());
97118 if (TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED)
@@ -118,7 +139,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
118139 // When non-trivial
119140 {
120141 MoveOnly from[3 ] = {1 , 2 , 3 };
121- MoveOnly to[3 ] = {};
142+ MoveOnly to[3 ] = {};
122143 std::move (std::begin (from), std::end (from), std::begin (to));
123144 assert (to[0 ] == MoveOnly (1 ));
124145 assert (to[1 ] == MoveOnly (2 ));
@@ -127,14 +148,24 @@ TEST_CONSTEXPR_CXX20 bool test() {
127148 // When trivial
128149 {
129150 TrivialMoveOnly from[3 ] = {1 , 2 , 3 };
130- TrivialMoveOnly to[3 ] = {};
151+ TrivialMoveOnly to[3 ] = {};
131152 std::move (std::begin (from), std::end (from), std::begin (to));
132153 assert (to[0 ] == TrivialMoveOnly (1 ));
133154 assert (to[1 ] == TrivialMoveOnly (2 ));
134155 assert (to[2 ] == TrivialMoveOnly (3 ));
135156 }
136157 }
137158
159+ { // Test vector<bool>::iterator optimization
160+ assert (test_vector_bool (8 ));
161+ assert (test_vector_bool (19 ));
162+ assert (test_vector_bool (32 ));
163+ assert (test_vector_bool (49 ));
164+ assert (test_vector_bool (64 ));
165+ assert (test_vector_bool (199 ));
166+ assert (test_vector_bool (256 ));
167+ }
168+
138169 return true ;
139170}
140171
0 commit comments