1 // Copyright (c) 2015-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
11 #include "test/test_bitcoin.h"
13 #include <boost/test/unit_test.hpp>
15 BOOST_FIXTURE_TEST_SUITE(PrevectorTests
, TestingSetup
)
17 template<unsigned int N
, typename T
>
18 class prevector_tester
{
19 typedef std::vector
<T
> realtype
;
21 realtype real_vector_alt
;
23 typedef prevector
<N
, T
> pretype
;
25 pretype pre_vector_alt
;
27 typedef typename
pretype::size_type Size
;
29 FastRandomContext rand_cache
;
33 template <typename A
, typename B
>
34 void local_check_equal(A a
, B b
)
38 void local_check(bool b
)
43 const pretype
& const_pre_vector
= pre_vector
;
44 local_check_equal(real_vector
.size(), pre_vector
.size());
45 local_check_equal(real_vector
.empty(), pre_vector
.empty());
46 for (Size s
= 0; s
< real_vector
.size(); s
++) {
47 local_check(real_vector
[s
] == pre_vector
[s
]);
48 local_check(&(pre_vector
[s
]) == &(pre_vector
.begin()[s
]));
49 local_check(&(pre_vector
[s
]) == &*(pre_vector
.begin() + s
));
50 local_check(&(pre_vector
[s
]) == &*((pre_vector
.end() + s
) - real_vector
.size()));
52 // local_check(realtype(pre_vector) == real_vector);
53 local_check(pretype(real_vector
.begin(), real_vector
.end()) == pre_vector
);
54 local_check(pretype(pre_vector
.begin(), pre_vector
.end()) == pre_vector
);
56 BOOST_FOREACH(const T
& v
, pre_vector
) {
57 local_check(v
== real_vector
[pos
++]);
59 BOOST_REVERSE_FOREACH(const T
& v
, pre_vector
) {
60 local_check(v
== real_vector
[--pos
]);
62 BOOST_FOREACH(const T
& v
, const_pre_vector
) {
63 local_check(v
== real_vector
[pos
++]);
65 BOOST_REVERSE_FOREACH(const T
& v
, const_pre_vector
) {
66 local_check(v
== real_vector
[--pos
]);
68 CDataStream
ss1(SER_DISK
, 0);
69 CDataStream
ss2(SER_DISK
, 0);
72 local_check_equal(ss1
.size(), ss2
.size());
73 for (Size s
= 0; s
< ss1
.size(); s
++) {
74 local_check_equal(ss1
[s
], ss2
[s
]);
80 real_vector
.resize(s
);
81 local_check_equal(real_vector
.size(), s
);
83 local_check_equal(pre_vector
.size(), s
);
87 void reserve(Size s
) {
88 real_vector
.reserve(s
);
89 local_check(real_vector
.capacity() >= s
);
90 pre_vector
.reserve(s
);
91 local_check(pre_vector
.capacity() >= s
);
95 void insert(Size position
, const T
& value
) {
96 real_vector
.insert(real_vector
.begin() + position
, value
);
97 pre_vector
.insert(pre_vector
.begin() + position
, value
);
101 void insert(Size position
, Size count
, const T
& value
) {
102 real_vector
.insert(real_vector
.begin() + position
, count
, value
);
103 pre_vector
.insert(pre_vector
.begin() + position
, count
, value
);
108 void insert_range(Size position
, I first
, I last
) {
109 real_vector
.insert(real_vector
.begin() + position
, first
, last
);
110 pre_vector
.insert(pre_vector
.begin() + position
, first
, last
);
114 void erase(Size position
) {
115 real_vector
.erase(real_vector
.begin() + position
);
116 pre_vector
.erase(pre_vector
.begin() + position
);
120 void erase(Size first
, Size last
) {
121 real_vector
.erase(real_vector
.begin() + first
, real_vector
.begin() + last
);
122 pre_vector
.erase(pre_vector
.begin() + first
, pre_vector
.begin() + last
);
126 void update(Size pos
, const T
& value
) {
127 real_vector
[pos
] = value
;
128 pre_vector
[pos
] = value
;
132 void push_back(const T
& value
) {
133 real_vector
.push_back(value
);
134 pre_vector
.push_back(value
);
139 real_vector
.pop_back();
140 pre_vector
.pop_back();
149 void assign(Size n
, const T
& value
) {
150 real_vector
.assign(n
, value
);
151 pre_vector
.assign(n
, value
);
155 return real_vector
.size();
159 return pre_vector
.capacity();
162 void shrink_to_fit() {
163 pre_vector
.shrink_to_fit();
168 real_vector
.swap(real_vector_alt
);
169 pre_vector
.swap(pre_vector_alt
);
174 real_vector
= std::move(real_vector_alt
);
175 real_vector_alt
.clear();
176 pre_vector
= std::move(pre_vector_alt
);
177 pre_vector_alt
.clear();
181 real_vector
= real_vector_alt
;
182 pre_vector
= pre_vector_alt
;
185 ~prevector_tester() {
186 BOOST_CHECK_MESSAGE(passed
, "insecure_rand: " + rand_seed
.ToString());
190 seed_insecure_rand();
191 rand_seed
= insecure_rand_seed
;
192 rand_cache
= insecure_rand_ctx
;
196 BOOST_AUTO_TEST_CASE(PrevectorTestInt
)
198 for (int j
= 0; j
< 64; j
++) {
199 prevector_tester
<8, int> test
;
200 for (int i
= 0; i
< 2048; i
++) {
201 if (insecure_randbits(2) == 0) {
202 test
.insert(insecure_randrange(test
.size() + 1), insecure_rand());
204 if (test
.size() > 0 && insecure_randbits(2) == 1) {
205 test
.erase(insecure_randrange(test
.size()));
207 if (insecure_randbits(3) == 2) {
208 int new_size
= std::max
<int>(0, std::min
<int>(30, test
.size() + (insecure_randrange(5)) - 2));
209 test
.resize(new_size
);
211 if (insecure_randbits(3) == 3) {
212 test
.insert(insecure_randrange(test
.size() + 1), 1 + insecure_randrange(2), insecure_rand());
214 if (insecure_randbits(3) == 4) {
215 int del
= std::min
<int>(test
.size(), 1 + (insecure_randrange(2)));
216 int beg
= insecure_randrange(test
.size() + 1 - del
);
217 test
.erase(beg
, beg
+ del
);
219 if (insecure_randbits(4) == 5) {
220 test
.push_back(insecure_rand());
222 if (test
.size() > 0 && insecure_randbits(4) == 6) {
225 if (insecure_randbits(5) == 7) {
227 int num
= 1 + (insecure_randrange(4));
228 for (int k
= 0; k
< num
; k
++) {
229 values
[k
] = insecure_rand();
231 test
.insert_range(insecure_randrange(test
.size() + 1), values
, values
+ num
);
233 if (insecure_randbits(5) == 8) {
234 int del
= std::min
<int>(test
.size(), 1 + (insecure_randrange(4)));
235 int beg
= insecure_randrange(test
.size() + 1 - del
);
236 test
.erase(beg
, beg
+ del
);
238 if (insecure_randbits(5) == 9) {
239 test
.reserve(insecure_randrange(32));
241 if (insecure_randbits(6) == 10) {
242 test
.shrink_to_fit();
244 if (test
.size() > 0) {
245 test
.update(insecure_randrange(test
.size()), insecure_rand());
247 if (insecure_randbits(10) == 11) {
250 if (insecure_randbits(9) == 12) {
251 test
.assign(insecure_randrange(32), insecure_rand());
253 if (insecure_randbits(3) == 3) {
256 if (insecure_randbits(4) == 8) {
259 if (insecure_randbits(5) == 18) {
266 BOOST_AUTO_TEST_SUITE_END()