Coverage Report

Created: 2025-09-19 18:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/test/fuzz/bitdeque.cpp
Line
Count
Source
1
// Copyright (c) 2022 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.
4
5
#include <random.h>
6
#include <test/fuzz/FuzzedDataProvider.h>
7
#include <test/fuzz/util.h>
8
#include <util/bitdeque.h>
9
10
#include <deque>
11
#include <vector>
12
13
namespace {
14
15
constexpr int LEN_BITS = 16;
16
constexpr int RANDDATA_BITS = 20;
17
18
using bitdeque_type = bitdeque<128>;
19
20
//! Deterministic random vector of bools, for begin/end insertions to draw from.
21
std::vector<bool> RANDDATA;
22
23
void InitRandData()
24
0
{
25
0
    FastRandomContext ctx(true);
26
0
    RANDDATA.clear();
27
0
    for (size_t i = 0; i < (1U << RANDDATA_BITS) + (1U << LEN_BITS); ++i) {
28
0
        RANDDATA.push_back(ctx.randbool());
29
0
    }
30
0
}
31
32
} // namespace
33
34
FUZZ_TARGET(bitdeque, .init = InitRandData)
35
0
{
36
0
    FuzzedDataProvider provider(buffer.data(), buffer.size());
37
0
    FastRandomContext ctx(true);
38
39
0
    size_t maxlen = (1U << provider.ConsumeIntegralInRange<size_t>(0, LEN_BITS)) - 1;
40
0
    size_t limitlen = 4 * maxlen;
41
42
0
    std::deque<bool> deq;
43
0
    bitdeque_type bitdeq;
44
45
0
    const auto& cdeq = deq;
46
0
    const auto& cbitdeq = bitdeq;
47
48
0
    size_t initlen = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
49
0
    while (initlen) {
50
0
        bool val = ctx.randbool();
51
0
        deq.push_back(val);
52
0
        bitdeq.push_back(val);
53
0
        --initlen;
54
0
    }
55
56
0
    const auto iter_limit{maxlen > 6000 ? 90U : 900U};
57
0
    LIMITED_WHILE(provider.remaining_bytes() > 0, iter_limit)
58
0
    {
59
0
        CallOneOf(
60
0
            provider,
61
0
            [&] {
62
                // constructor()
63
0
                deq = std::deque<bool>{};
64
0
                bitdeq = bitdeque_type{};
65
0
            },
66
0
            [&] {
67
                // clear()
68
0
                deq.clear();
69
0
                bitdeq.clear();
70
0
            },
71
0
            [&] {
72
                // resize()
73
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
74
0
                deq.resize(count);
75
0
                bitdeq.resize(count);
76
0
            },
77
0
            [&] {
78
                // assign(count, val)
79
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
80
0
                bool val = ctx.randbool();
81
0
                deq.assign(count, val);
82
0
                bitdeq.assign(count, val);
83
0
            },
84
0
            [&] {
85
                // constructor(count, val)
86
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
87
0
                bool val = ctx.randbool();
88
0
                deq = std::deque<bool>(count, val);
89
0
                bitdeq = bitdeque_type(count, val);
90
0
            },
91
0
            [&] {
92
                // constructor(count)
93
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
94
0
                deq = std::deque<bool>(count);
95
0
                bitdeq = bitdeque_type(count);
96
0
            },
97
0
            [&] {
98
                // construct(begin, end)
99
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
100
0
                auto rand_begin = RANDDATA.begin() + ctx.randbits(RANDDATA_BITS);
101
0
                auto rand_end = rand_begin + count;
102
0
                deq = std::deque<bool>(rand_begin, rand_end);
103
0
                bitdeq = bitdeque_type(rand_begin, rand_end);
104
0
            },
105
0
            [&] {
106
                // assign(begin, end)
107
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
108
0
                auto rand_begin = RANDDATA.begin() + ctx.randbits(RANDDATA_BITS);
109
0
                auto rand_end = rand_begin + count;
110
0
                deq.assign(rand_begin, rand_end);
111
0
                bitdeq.assign(rand_begin, rand_end);
112
0
            },
113
0
            [&] {
114
                // construct(initializer_list)
115
0
                std::initializer_list<bool> ilist{ctx.randbool(), ctx.randbool(), ctx.randbool(), ctx.randbool(), ctx.randbool()};
116
0
                deq = std::deque<bool>(ilist);
117
0
                bitdeq = bitdeque_type(ilist);
118
0
            },
119
0
            [&] {
120
                // assign(initializer_list)
121
0
                std::initializer_list<bool> ilist{ctx.randbool(), ctx.randbool(), ctx.randbool()};
122
0
                deq.assign(ilist);
123
0
                bitdeq.assign(ilist);
124
0
            },
125
0
            [&] {
126
                // operator=(const&)
127
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
128
0
                bool val = ctx.randbool();
129
0
                const std::deque<bool> deq2(count, val);
130
0
                deq = deq2;
131
0
                const bitdeque_type bitdeq2(count, val);
132
0
                bitdeq = bitdeq2;
133
0
            },
134
0
            [&] {
135
                // operator=(&&)
136
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
137
0
                bool val = ctx.randbool();
138
0
                std::deque<bool> deq2(count, val);
139
0
                deq = std::move(deq2);
140
0
                bitdeque_type bitdeq2(count, val);
141
0
                bitdeq = std::move(bitdeq2);
142
0
            },
143
0
            [&] {
144
                // deque swap
145
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
146
0
                auto rand_begin = RANDDATA.begin() + ctx.randbits(RANDDATA_BITS);
147
0
                auto rand_end = rand_begin + count;
148
0
                std::deque<bool> deq2(rand_begin, rand_end);
149
0
                bitdeque_type bitdeq2(rand_begin, rand_end);
150
0
                using std::swap;
151
0
                assert(deq.size() == bitdeq.size());
152
0
                assert(deq2.size() == bitdeq2.size());
153
0
                swap(deq, deq2);
154
0
                swap(bitdeq, bitdeq2);
155
0
                assert(deq.size() == bitdeq.size());
156
0
                assert(deq2.size() == bitdeq2.size());
157
0
            },
158
0
            [&] {
159
                // deque.swap
160
0
                auto count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
161
0
                auto rand_begin = RANDDATA.begin() + ctx.randbits(RANDDATA_BITS);
162
0
                auto rand_end = rand_begin + count;
163
0
                std::deque<bool> deq2(rand_begin, rand_end);
164
0
                bitdeque_type bitdeq2(rand_begin, rand_end);
165
0
                assert(deq.size() == bitdeq.size());
166
0
                assert(deq2.size() == bitdeq2.size());
167
0
                deq.swap(deq2);
168
0
                bitdeq.swap(bitdeq2);
169
0
                assert(deq.size() == bitdeq.size());
170
0
                assert(deq2.size() == bitdeq2.size());
171
0
            },
172
0
            [&] {
173
                // operator=(initializer_list)
174
0
                std::initializer_list<bool> ilist{ctx.randbool(), ctx.randbool(), ctx.randbool()};
175
0
                deq = ilist;
176
0
                bitdeq = ilist;
177
0
            },
178
0
            [&] {
179
                // iterator arithmetic
180
0
                auto pos1 = provider.ConsumeIntegralInRange<long>(0, cdeq.size());
181
0
                auto pos2 = provider.ConsumeIntegralInRange<long>(0, cdeq.size());
182
0
                auto it = deq.begin() + pos1;
183
0
                auto bitit = bitdeq.begin() + pos1;
184
0
                if ((size_t)pos1 != cdeq.size()) assert(*it == *bitit);
185
0
                assert(it - deq.begin() == pos1);
186
0
                assert(bitit - bitdeq.begin() == pos1);
187
0
                if (provider.ConsumeBool()) {
188
0
                    it += pos2 - pos1;
189
0
                    bitit += pos2 - pos1;
190
0
                } else {
191
0
                    it -= pos1 - pos2;
192
0
                    bitit -= pos1 - pos2;
193
0
                }
194
0
                if ((size_t)pos2 != cdeq.size()) assert(*it == *bitit);
195
0
                assert(deq.end() - it == bitdeq.end() - bitit);
196
0
                if (provider.ConsumeBool()) {
197
0
                    if ((size_t)pos2 != cdeq.size()) {
198
0
                        ++it;
199
0
                        ++bitit;
200
0
                    }
201
0
                } else {
202
0
                    if (pos2 != 0) {
203
0
                        --it;
204
0
                        --bitit;
205
0
                    }
206
0
                }
207
0
                assert(deq.end() - it == bitdeq.end() - bitit);
208
0
            },
209
0
            [&] {
210
                // begin() and end()
211
0
                assert(deq.end() - deq.begin() == bitdeq.end() - bitdeq.begin());
212
0
            },
213
0
            [&] {
214
                // begin() and end() (const)
215
0
                assert(cdeq.end() - cdeq.begin() == cbitdeq.end() - cbitdeq.begin());
216
0
            },
217
0
            [&] {
218
                // rbegin() and rend()
219
0
                assert(deq.rend() - deq.rbegin() == bitdeq.rend() - bitdeq.rbegin());
220
0
            },
221
0
            [&] {
222
                // rbegin() and rend() (const)
223
0
                assert(cdeq.rend() - cdeq.rbegin() == cbitdeq.rend() - cbitdeq.rbegin());
224
0
            },
225
0
            [&] {
226
                // cbegin() and cend()
227
0
                assert(cdeq.cend() - cdeq.cbegin() == cbitdeq.cend() - cbitdeq.cbegin());
228
0
            },
229
0
            [&] {
230
                // crbegin() and crend()
231
0
                assert(cdeq.crend() - cdeq.crbegin() == cbitdeq.crend() - cbitdeq.crbegin());
232
0
            },
233
0
            [&] {
234
                // size() and maxsize()
235
0
                assert(cdeq.size() == cbitdeq.size());
236
0
                assert(cbitdeq.size() <= cbitdeq.max_size());
237
0
            },
238
0
            [&] {
239
                // empty
240
0
                assert(cdeq.empty() == cbitdeq.empty());
241
0
            },
242
0
            [&] {
243
                // at (in range) and flip
244
0
                if (!cdeq.empty()) {
245
0
                    size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - 1);
246
0
                    auto& ref = deq.at(pos);
247
0
                    auto bitref = bitdeq.at(pos);
248
0
                    assert(ref == bitref);
249
0
                    if (ctx.randbool()) {
250
0
                        ref = !ref;
251
0
                        bitref.flip();
252
0
                    }
253
0
                }
254
0
            },
255
0
            [&] {
256
                // at (maybe out of range) and bit assign
257
0
                size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() + maxlen);
258
0
                bool newval = ctx.randbool();
259
0
                bool throw_deq{false}, throw_bitdeq{false};
260
0
                bool val_deq{false}, val_bitdeq{false};
261
0
                try {
262
0
                    auto& ref = deq.at(pos);
263
0
                    val_deq = ref;
264
0
                    ref = newval;
265
0
                } catch (const std::out_of_range&) {
266
0
                    throw_deq = true;
267
0
                }
268
0
                try {
269
0
                    auto ref = bitdeq.at(pos);
270
0
                    val_bitdeq = ref;
271
0
                    ref = newval;
272
0
                } catch (const std::out_of_range&) {
273
0
                    throw_bitdeq = true;
274
0
                }
275
0
                assert(throw_deq == throw_bitdeq);
276
0
                assert(throw_bitdeq == (pos >= cdeq.size()));
277
0
                if (!throw_deq) assert(val_deq == val_bitdeq);
278
0
            },
279
0
            [&] {
280
                // at (maybe out of range) (const)
281
0
                size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() + maxlen);
282
0
                bool throw_deq{false}, throw_bitdeq{false};
283
0
                bool val_deq{false}, val_bitdeq{false};
284
0
                try {
285
0
                    auto& ref = cdeq.at(pos);
286
0
                    val_deq = ref;
287
0
                } catch (const std::out_of_range&) {
288
0
                    throw_deq = true;
289
0
                }
290
0
                try {
291
0
                    auto ref = cbitdeq.at(pos);
292
0
                    val_bitdeq = ref;
293
0
                } catch (const std::out_of_range&) {
294
0
                    throw_bitdeq = true;
295
0
                }
296
0
                assert(throw_deq == throw_bitdeq);
297
0
                assert(throw_bitdeq == (pos >= cdeq.size()));
298
0
                if (!throw_deq) assert(val_deq == val_bitdeq);
299
0
            },
300
0
            [&] {
301
                // operator[]
302
0
                if (!cdeq.empty()) {
303
0
                    size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - 1);
304
0
                    assert(deq[pos] == bitdeq[pos]);
305
0
                    if (ctx.randbool()) {
306
0
                        deq[pos] = !deq[pos];
307
0
                        bitdeq[pos].flip();
308
0
                    }
309
0
                }
310
0
            },
311
0
            [&] {
312
                // operator[] const
313
0
                if (!cdeq.empty()) {
314
0
                    size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - 1);
315
0
                    assert(deq[pos] == bitdeq[pos]);
316
0
                }
317
0
            },
318
0
            [&] {
319
                // front()
320
0
                if (!cdeq.empty()) {
321
0
                    auto& ref = deq.front();
322
0
                    auto bitref = bitdeq.front();
323
0
                    assert(ref == bitref);
324
0
                    if (ctx.randbool()) {
325
0
                        ref = !ref;
326
0
                        bitref = !bitref;
327
0
                    }
328
0
                }
329
0
            },
330
0
            [&] {
331
                // front() const
332
0
                if (!cdeq.empty()) {
333
0
                    auto& ref = cdeq.front();
334
0
                    auto bitref = cbitdeq.front();
335
0
                    assert(ref == bitref);
336
0
                }
337
0
            },
338
0
            [&] {
339
                // back() and swap(bool, ref)
340
0
                if (!cdeq.empty()) {
341
0
                    auto& ref = deq.back();
342
0
                    auto bitref = bitdeq.back();
343
0
                    assert(ref == bitref);
344
0
                    if (ctx.randbool()) {
345
0
                        ref = !ref;
346
0
                        bitref.flip();
347
0
                    }
348
0
                }
349
0
            },
350
0
            [&] {
351
                // back() const
352
0
                if (!cdeq.empty()) {
353
0
                    const auto& cdeq = deq;
354
0
                    const auto& cbitdeq = bitdeq;
355
0
                    auto& ref = cdeq.back();
356
0
                    auto bitref = cbitdeq.back();
357
0
                    assert(ref == bitref);
358
0
                }
359
0
            },
360
0
            [&] {
361
                // push_back()
362
0
                if (cdeq.size() < limitlen) {
363
0
                    bool val = ctx.randbool();
364
0
                    if (cdeq.empty()) {
365
0
                        deq.push_back(val);
366
0
                        bitdeq.push_back(val);
367
0
                    } else {
368
0
                        size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - 1);
369
0
                        auto& ref = deq[pos];
370
0
                        auto bitref = bitdeq[pos];
371
0
                        assert(ref == bitref);
372
0
                        deq.push_back(val);
373
0
                        bitdeq.push_back(val);
374
0
                        assert(ref == bitref); // references are not invalidated
375
0
                    }
376
0
                }
377
0
            },
378
0
            [&] {
379
                // push_front()
380
0
                if (cdeq.size() < limitlen) {
381
0
                    bool val = ctx.randbool();
382
0
                    if (cdeq.empty()) {
383
0
                        deq.push_front(val);
384
0
                        bitdeq.push_front(val);
385
0
                    } else {
386
0
                        size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - 1);
387
0
                        auto& ref = deq[pos];
388
0
                        auto bitref = bitdeq[pos];
389
0
                        assert(ref == bitref);
390
0
                        deq.push_front(val);
391
0
                        bitdeq.push_front(val);
392
0
                        assert(ref == bitref); // references are not invalidated
393
0
                    }
394
0
                }
395
0
            },
396
0
            [&] {
397
                // pop_back()
398
0
                if (!cdeq.empty()) {
399
0
                    if (cdeq.size() == 1) {
400
0
                        deq.pop_back();
401
0
                        bitdeq.pop_back();
402
0
                    } else {
403
0
                        size_t pos = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - 2);
404
0
                        auto& ref = deq[pos];
405
0
                        auto bitref = bitdeq[pos];
406
0
                        assert(ref == bitref);
407
0
                        deq.pop_back();
408
0
                        bitdeq.pop_back();
409
0
                        assert(ref == bitref); // references to other elements are not invalidated
410
0
                    }
411
0
                }
412
0
            },
413
0
            [&] {
414
                // pop_front()
415
0
                if (!cdeq.empty()) {
416
0
                    if (cdeq.size() == 1) {
417
0
                        deq.pop_front();
418
0
                        bitdeq.pop_front();
419
0
                    } else {
420
0
                        size_t pos = provider.ConsumeIntegralInRange<size_t>(1, cdeq.size() - 1);
421
0
                        auto& ref = deq[pos];
422
0
                        auto bitref = bitdeq[pos];
423
0
                        assert(ref == bitref);
424
0
                        deq.pop_front();
425
0
                        bitdeq.pop_front();
426
0
                        assert(ref == bitref); // references to other elements are not invalidated
427
0
                    }
428
0
                }
429
0
            },
430
0
            [&] {
431
                // erase (in middle, single)
432
0
                if (!cdeq.empty()) {
433
0
                    size_t before = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - 1);
434
0
                    size_t after = cdeq.size() - 1 - before;
435
0
                    auto it = deq.erase(cdeq.begin() + before);
436
0
                    auto bitit = bitdeq.erase(cbitdeq.begin() + before);
437
0
                    assert(it == cdeq.begin() + before && it == cdeq.end() - after);
438
0
                    assert(bitit == cbitdeq.begin() + before && bitit == cbitdeq.end() - after);
439
0
                }
440
0
            },
441
0
            [&] {
442
                // erase (at front, range)
443
0
                size_t count = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size());
444
0
                auto it = deq.erase(cdeq.begin(), cdeq.begin() + count);
445
0
                auto bitit = bitdeq.erase(cbitdeq.begin(), cbitdeq.begin() + count);
446
0
                assert(it == deq.begin());
447
0
                assert(bitit == bitdeq.begin());
448
0
            },
449
0
            [&] {
450
                // erase (at back, range)
451
0
                size_t count = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size());
452
0
                auto it = deq.erase(cdeq.end() - count, cdeq.end());
453
0
                auto bitit = bitdeq.erase(cbitdeq.end() - count, cbitdeq.end());
454
0
                assert(it == deq.end());
455
0
                assert(bitit == bitdeq.end());
456
0
            },
457
0
            [&] {
458
                // erase (in middle, range)
459
0
                size_t count = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size());
460
0
                size_t before = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size() - count);
461
0
                size_t after = cdeq.size() - count - before;
462
0
                auto it = deq.erase(cdeq.begin() + before, cdeq.end() - after);
463
0
                auto bitit = bitdeq.erase(cbitdeq.begin() + before, cbitdeq.end() - after);
464
0
                assert(it == cdeq.begin() + before && it == cdeq.end() - after);
465
0
                assert(bitit == cbitdeq.begin() + before && bitit == cbitdeq.end() - after);
466
0
            },
467
0
            [&] {
468
                // insert/emplace (in middle, single)
469
0
                if (cdeq.size() < limitlen) {
470
0
                    size_t before = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size());
471
0
                    bool val = ctx.randbool();
472
0
                    bool do_emplace = provider.ConsumeBool();
473
0
                    auto it = deq.insert(cdeq.begin() + before, val);
474
0
                    auto bitit = do_emplace ? bitdeq.emplace(cbitdeq.begin() + before, val)
475
0
                                            : bitdeq.insert(cbitdeq.begin() + before, val);
476
0
                    assert(it == deq.begin() + before);
477
0
                    assert(bitit == bitdeq.begin() + before);
478
0
                }
479
0
            },
480
0
            [&] {
481
                // insert (at front, begin/end)
482
0
                if (cdeq.size() < limitlen) {
483
0
                    size_t count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
484
0
                    auto rand_begin = RANDDATA.begin() + ctx.randbits(RANDDATA_BITS);
485
0
                    auto rand_end = rand_begin + count;
486
0
                    auto it = deq.insert(cdeq.begin(), rand_begin, rand_end);
487
0
                    auto bitit = bitdeq.insert(cbitdeq.begin(), rand_begin, rand_end);
488
0
                    assert(it == cdeq.begin());
489
0
                    assert(bitit == cbitdeq.begin());
490
0
                }
491
0
            },
492
0
            [&] {
493
                // insert (at back, begin/end)
494
0
                if (cdeq.size() < limitlen) {
495
0
                    size_t count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
496
0
                    auto rand_begin = RANDDATA.begin() + ctx.randbits(RANDDATA_BITS);
497
0
                    auto rand_end = rand_begin + count;
498
0
                    auto it = deq.insert(cdeq.end(), rand_begin, rand_end);
499
0
                    auto bitit = bitdeq.insert(cbitdeq.end(), rand_begin, rand_end);
500
0
                    assert(it == cdeq.end() - count);
501
0
                    assert(bitit == cbitdeq.end() - count);
502
0
                }
503
0
            },
504
0
            [&] {
505
                // insert (in middle, range)
506
0
                if (cdeq.size() < limitlen) {
507
0
                    size_t count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
508
0
                    size_t before = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size());
509
0
                    bool val = ctx.randbool();
510
0
                    auto it = deq.insert(cdeq.begin() + before, count, val);
511
0
                    auto bitit = bitdeq.insert(cbitdeq.begin() + before, count, val);
512
0
                    assert(it == deq.begin() + before);
513
0
                    assert(bitit == bitdeq.begin() + before);
514
0
                }
515
0
            },
516
0
            [&] {
517
                // insert (in middle, begin/end)
518
0
                if (cdeq.size() < limitlen) {
519
0
                    size_t count = provider.ConsumeIntegralInRange<size_t>(0, maxlen);
520
0
                    size_t before = provider.ConsumeIntegralInRange<size_t>(0, cdeq.size());
521
0
                    auto rand_begin = RANDDATA.begin() + ctx.randbits(RANDDATA_BITS);
522
0
                    auto rand_end = rand_begin + count;
523
0
                    auto it = deq.insert(cdeq.begin() + before, rand_begin, rand_end);
524
0
                    auto bitit = bitdeq.insert(cbitdeq.begin() + before, rand_begin, rand_end);
525
0
                    assert(it == deq.begin() + before);
526
0
                    assert(bitit == bitdeq.begin() + before);
527
0
                }
528
0
            });
529
0
    }
530
0
    {
531
0
        assert(deq.size() == bitdeq.size());
532
0
        auto it = deq.begin();
533
0
        auto bitit = bitdeq.begin();
534
0
        auto itend = deq.end();
535
0
        while (it != itend) {
536
0
            assert(*it == *bitit);
537
0
            ++it;
538
0
            ++bitit;
539
0
        }
540
0
    }
541
0
}