• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PeterCDMcLean / BitLib / 16820722729

08 Aug 2025 02:52AM UTC coverage: 76.434% (-0.4%) from 76.797%
16820722729

Pull #29

github

web-flow
Merge e2ea9d579 into 4adca69e9
Pull Request #29: Explicitly cast inside _mask

3353 of 5056 branches covered (66.32%)

Branch coverage included in aggregate %.

188 of 196 new or added lines in 17 files covered. (95.92%)

11 existing lines in 2 files now uncovered.

2563 of 2684 relevant lines covered (95.49%)

29389233.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.29
/include/bitlib/bit-containers/bit_vector.hpp
1
// ================================= BIT_VECTOR =================================== //
2
// Project:     The Experimental Bit Algorithms Library
3
// \file        bit_vector.hpp
4
// Description: Implementation of bit_vector
5
// Contributor: Bryce Kille
6
// License:     BSD 3-Clause License
7
// ========================================================================== //
8
#ifndef _BIT_VECTOR_HPP_INCLUDED
9
#define _BIT_VECTOR_HPP_INCLUDED
10
// ========================================================================== //
11

12

13

14
// ================================ PREAMBLE ================================ //
15
// C++ standard library
16
#include <algorithm>
17
#include <cmath>
18
#include <iostream>
19
#include <ranges>
20
#include <string>
21
#include <type_traits>
22
#include <vector>
23
// Project sources
24
#include "bitlib/bit-algorithms/bit_algorithm.hpp"
25
#include "bitlib/bit_concepts.hpp"
26
#include "bitlib/bit-containers/bit_array_ref.hpp"
27
#include "bitlib/bit-iterator/bit.hpp"
28

29
// Third-party libraries
30
// Miscellaneous
31
namespace bit {
32
// ========================================================================== //
33

34
/* ****************************** BIT VECTOR ****************************** */
35
//! A bit-vector with a similar interface to std::vector<bool>
36
template <class WordType = uint8_t, class Allocator = std::allocator<WordType>>
37
class bit_vector {
38
 private:
39
  static constexpr size_t digits = binary_digits<WordType>::value;
40
  std::vector<WordType, Allocator> word_vector;
41
  size_t length_ = 0;
42

43
  // TODO are privates always inlined?
44
  // @brief Get the number of words needed to represet num_bits bits
45
  constexpr uint64_t word_count(unsigned int num_bits) {
286,279✔
46
    return ((num_bits + digits - 1) / digits);
286,279✔
47
  }
143,140✔
48

49
  // Iterator pair constructor specializations
50
  // Passing in iterator over bool
51
  template <class RandomAccessIt>
52
  typename std::enable_if<
53
      std::is_same<
54
          typename std::iterator_traits<RandomAccessIt>::value_type,
55
          bool>::value>::type constexpr range_constructor(RandomAccessIt first,
56
                                                          RandomAccessIt last,
57
                                                          const Allocator& alloc);
58

59
  // Passing in iterator over WordType constructs via whole words
60
  template <class RandomAccessIt>
61
  typename std::enable_if<
62
      std::is_same<
63
          typename std::iterator_traits<RandomAccessIt>::value_type,
64
          WordType>::value>::type constexpr range_constructor(RandomAccessIt first,
65
                                                              RandomAccessIt last,
66
                                                              const Allocator& alloc);
67

68
 public:
69
  /*
70
         * Types and typedefs
71
         */
72
  using value_type = bit_value;
73
  using base_type = WordType;
74
  using allocator_type = Allocator;
75
  using size_type = std::size_t;
76
  using difference_type = std::ptrdiff_t;
77
  using reference = bit_reference<WordType&>;  // typename std::vector<WordType>::reference>;
78
  using const_reference = const reference;
79
  using pointer = bit_pointer<WordType>;
80
  using iterator = bit_iterator<typename std::vector<WordType>::iterator>;
81
  using const_iterator = bit_iterator<typename std::vector<WordType>::const_iterator>;
82

83
  /*
84
         * Constructors, copies and moves...
85
         */
86
  constexpr bit_vector() noexcept(noexcept(Allocator()));
87
  constexpr explicit bit_vector(const Allocator& alloc) noexcept;
88
  constexpr bit_vector(
89
      size_type count,
90
      value_type bit_val,
91
      const Allocator& alloc = Allocator());
92
  constexpr explicit bit_vector(
93
      size_type count,
94
      const Allocator& alloc = Allocator());
95
  template <bit_iterator_c Iterator>
96
  constexpr bit_vector(Iterator first, Iterator last, const Allocator& alloc = Allocator());
97

98
  template <bit_range _Range>
99
  constexpr bit_vector(std::from_range_t, _Range&& rg, const Allocator& alloc = Allocator());
100

101
  template <class RandomAccessIt>
102
  constexpr bit_vector(
103
      RandomAccessIt first,
104
      RandomAccessIt last,
105
      const Allocator& alloc = Allocator());
106
  constexpr bit_vector(const bit_vector<WordType, Allocator>& other) = default;
570,816✔
107
  constexpr bit_vector(const bit_vector<WordType, Allocator>& other, const Allocator& alloc);
108
  constexpr bit_vector(const bit_vector<WordType, Allocator>&& other) noexcept;
109
  constexpr bit_vector(const bit_vector<WordType, Allocator>&& other, const Allocator& alloc);
110
  constexpr bit_vector(std::initializer_list<bit_value> init, const Allocator& alloc = Allocator());
111
  constexpr bit_vector(std::initializer_list<bool> init, const Allocator& alloc = Allocator());
112
  constexpr bit_vector(std::initializer_list<WordType> init, const Allocator& alloc = Allocator());
113
  constexpr bit_vector(std::string_view s);
114

115
#if __cplusplus == 201703L
116
        ~bit_vector();
117
#else
118
        constexpr ~bit_vector();
119
#endif
120

121

122
        /*
123
         * Assignment
124
         */
125
        constexpr bit_vector& operator=(const bit_vector<WordType, Allocator>& other) = default;
8,160✔
126
        constexpr bit_vector& operator=(bit_vector<WordType, Allocator>&& other) noexcept;
127

128

129
        /*
130
         * Element Access
131
         */
132
        constexpr reference operator[](size_type pos);
133
        constexpr reference operator[](size_type pos) const;
134
        constexpr reference at(size_type pos);
135
        constexpr const_reference at(size_type pos) const;
136
        constexpr reference front();
137
        constexpr const_reference front() const;
138
        constexpr reference back();
139
        constexpr const_reference back() const;
140
        constexpr WordType* data() noexcept;
141
        constexpr const WordType* data() const noexcept;
142

143
        /*
144
         * Iterators
145
         */
146
        constexpr iterator begin() noexcept;
147
        constexpr iterator end() noexcept;
148
        constexpr const_iterator begin() const noexcept;
149
        constexpr const_iterator end() const noexcept;
150
        constexpr const_iterator cbegin() const noexcept;
151
        constexpr const_iterator cend() const noexcept;
152

153

154
        /*
155
         * Capacity
156
         */
157
        constexpr bool empty() const noexcept;
158
        constexpr size_type size() const noexcept;
159
        constexpr size_type max_size() const noexcept;
160
        constexpr void reserve(size_type new_cap);
161
        constexpr size_type capacity() const noexcept;
162
        constexpr void shrink_to_fit();
163

164

165
        /*
166
         * Modifiers
167
         */
168
        constexpr void clear() noexcept;
169
        constexpr iterator insert(const_iterator pos, const value_type& value);
170
        constexpr iterator insert(const_iterator pos, size_type count, const value_type& value);
171
        template <bit_iterator_c OtherIt>
172
        constexpr iterator insert(const_iterator pos, OtherIt first, OtherIt last);
173
        constexpr iterator erase(iterator pos);
174
        constexpr iterator erase(iterator first, iterator last);
175
        constexpr void push_back(const value_type& value);
176
        constexpr void pop_back();
177
        constexpr void resize(size_type count);
178
        constexpr void resize(size_type count, const value_type& value);
179
        template <bit_range R>
180
        constexpr iterator insert_range(const_iterator pos, R&& range);
181
        template <bit_range R>
182
        constexpr void append_range(R&& range);
183

184
        /*
185
          * Slice
186
        */
187
        constexpr bit_array_ref<std::dynamic_extent, WordType /*, Policy*/> operator()(size_type begin, size_type end) const noexcept;
188

189
        /*
190
         * Helper functions
191
         */
192
        constexpr std::string debug_string(const_iterator first, const_iterator end);
193
        constexpr std::string debug_string();
194

195
        // TODO Make constexpr
196
        //friend std::ostream& operator<<(std::ostream& os, bit_vector bv) {
197
            //return os << bv.debug_string(bv.cbegin(), bv.cend());;
198
        //}
199
};
200
static_assert(bit_range<bit_vector<uint8_t>>, "bit_vector<integral> does not satisfy bit_range concept!");
201
static_assert(bit_sized_range<bit_vector<uint8_t>>, "bit_vector<integral> does not satisfy bit_sized_range concept!");
202
#ifdef CONTIGUOUS_RANGE
203
static_assert(bit_contiguous_range<bit_vector<uint8_t>>, "bit_vector<integral> does not satisfy bit_contiguous_range concept!");
204
static_assert(bit_contiguous_sized_range<bit_vector<uint8_t>>, "bit_vector<integral> does not satisfy bit_contiguous_sized_range concept!");
205
#endif
206

207
/* ************************************************************************** */
208

209

210

211
// ------------------------ BIT VECTOR: LIFECYCLE ------------------------- //
212
template<class WordType, class Allocator>
213
constexpr bit_vector<WordType, Allocator>::bit_vector() noexcept(noexcept(Allocator())) : word_vector{}, length_(0) {}
1,729✔
214

215
template<class WordType, class Allocator>
216
constexpr bit_vector<WordType, Allocator>::bit_vector(const Allocator& alloc) noexcept : word_vector(alloc), length_(0) {}
217

218
template<class WordType, class Allocator>
219
constexpr bit_vector<WordType, Allocator>::bit_vector(size_type count, value_type bit_val, const Allocator& alloc)
1,920✔
220
    : word_vector(word_count(count), static_cast<WordType>(bit_val == bit1 ? -1 : 0), alloc),
3,840✔
221
      length_(count)
3,840✔
222
      {}
3,840✔
223

224
template<class WordType, class Allocator>
225
constexpr bit_vector<WordType, Allocator>::bit_vector(size_type count, const Allocator& alloc)
71,305✔
226
    : word_vector(word_count(count), alloc), length_(count) {}
213,915✔
227

228
//TODO needs to work for input iterators
229
template <class WordType, class Allocator>
230

231
template <bit_iterator_c Iterator>
232
constexpr bit_vector<WordType, Allocator>::bit_vector(Iterator first, Iterator last, const Allocator& alloc)
1✔
233
    : word_vector(distance(first, last), alloc), length_(distance(first, last)) {
2✔
234
  copy(first, last, this->begin());
2✔
235
}
2✔
236

237
template <class WordType, class Allocator>
238
template <bit_range _Range>
239
constexpr bit_vector<WordType, Allocator>::bit_vector(std::from_range_t, _Range&& rg, const Allocator& alloc)
1✔
240
    : bit_vector(rg.begin(), rg.end(), alloc) {
2✔
241
}
2✔
242

243
template<class WordType, class Allocator>
244
template<class RandomAccessIt>
245
constexpr bit_vector<WordType, Allocator>::bit_vector(
1,976✔
246
        RandomAccessIt first,
247
        RandomAccessIt last,
248
        const Allocator& alloc) {
3,952✔
249
    bit_vector<WordType, Allocator>::range_constructor(
3,952✔
250
        first,
1,976✔
251
        last,
1,976✔
252
        alloc
1,976✔
253
    );
1,976✔
254
}
3,952✔
255

256
template<class WordType, class Allocator>
257
constexpr bit_vector<WordType, Allocator>::bit_vector(const bit_vector<WordType, Allocator>&& other) noexcept
131,184✔
258
    : word_vector(std::move(other.word_vector)), length_(other.length_) {}
262,368✔
259

260
template<class WordType, class Allocator>
261
constexpr bit_vector<WordType, Allocator>::bit_vector(const bit_vector<WordType, Allocator>&& other, const Allocator& alloc)
262
    : word_vector(std::move(other.word_vector), alloc), length_(other.length_) {}
263

264
template<class WordType, class Allocator>
265
constexpr bit_vector<WordType, Allocator>::bit_vector(std::initializer_list<bit_value> init, const Allocator& alloc)
266
    : word_vector(alloc), length_(0) {
267
    for (const_reference b : init) {
268
        this->push_back(b);
269
    }
270
}
271

272
template<class WordType, class Allocator>
273
constexpr bit_vector<WordType, Allocator>::bit_vector(std::initializer_list<bool> init, const Allocator& alloc)
8✔
274
    : word_vector(alloc), length_(0) {
16✔
275
    for (const bool& b : init) {
200✔
276
        this->push_back(static_cast<bit_value>(b));
192✔
277
    }
96✔
278
}
16✔
279

280
template<class WordType, class Allocator>
281
constexpr bit_vector<WordType, Allocator>::bit_vector(
282
        std::initializer_list<WordType> init,
283
        const Allocator& alloc)
284
    : word_vector(init, alloc), length_(this->word_vector.size() * digits) {}
285

286
// Skip all characters that are not 0/1. This allows punctuation/spacing for byte/word boundaries
287
template<class WordType, class Allocator>
288
constexpr bit_vector<WordType, Allocator>::bit_vector(std::string_view s) {
3,744✔
289
    this->length_ = std::count(s.begin(), s.end(), '0') + std::count(s.begin(), s.end(), '1');
2,496✔
290
    this->word_vector = std::vector<WordType, Allocator>(this->length_);
4,992✔
291
    size_type i = 0;
2,496✔
292
    for (char c : s) {
179,552✔
293
        if (c == '0') {
178,304✔
294
            begin()[i++] = bit0;
116,320✔
295
        } else if (c == '1') {
121,792!
296
            begin()[i++] = bit1;
61,984✔
297
        }
14,672✔
298
    }
89,152✔
299
}
2,496✔
300

301
// Iterator pair constructor specializations
302
// Passing in iterator over bool
303
template<class WordType, class Allocator>
304
template<class RandomAccessIt>
305
typename std::enable_if<
306
    std::is_same<
307
        typename std::iterator_traits<RandomAccessIt>::value_type,
308
        bool
309
    >::value
310
>::type
311
constexpr bit_vector<WordType, Allocator>::range_constructor(
1,016✔
312
        RandomAccessIt first,
313
        RandomAccessIt last,
314
        const Allocator& alloc) {
1,016✔
315
    word_vector = std::vector<WordType, Allocator>(std::distance(first, last), alloc);
3,048✔
316
    length_ = std::distance(first, last);
2,032✔
317
    std::transform(
2,032✔
318
            first,
1,016✔
319
            last,
1,016✔
320
            begin(),
1,016✔
321
            [](bool b) {return static_cast<bit_value>(b);}
8,123,904✔
322
    );
1,016✔
323
}
2,032✔
324

325
// Passing in iterator over WordType constructs via whole words
326
template<class WordType, class Allocator>
327
template<class RandomAccessIt>
328
typename std::enable_if<
329
    std::is_same<
330
        typename std::iterator_traits<RandomAccessIt>::value_type,
331
        WordType
332
    >::value
333
>::type
334
constexpr bit_vector<WordType, Allocator>::range_constructor(
960✔
335
        RandomAccessIt first,
336
        RandomAccessIt last,
337
        const Allocator& alloc) {
960✔
338
    word_vector = std::vector<WordType, Allocator>(first, last, alloc);
1,920✔
339
    length_ = digits * std::distance(first, last);
1,920✔
340
}
1,920✔
341

342
template<class WordType, class Allocator>
343
#if __cplusplus == 201703L
344
bit_vector<WordType, Allocator>::~bit_vector() {
345
#else
346
constexpr bit_vector<WordType, Allocator>::~bit_vector() {
701,846✔
347
#endif
350,923✔
348
    length_ = 0;
701,846✔
349
}
701,846✔
350
// -------------------------------------------------------------------------- //
351

352

353

354
// ------------------------ BIT VECTOR: ASSIGNMENT ------------------------ //
355
template<class WordType, class Allocator>
356
constexpr bit_vector<WordType, Allocator>&
357
bit_vector<WordType, Allocator>::operator=(bit_vector<WordType, Allocator>&& other) noexcept {
12,224✔
358
    length_ = other.length_;
12,224✔
359
    word_vector = std::move(other.word_vector);
12,224✔
360
    other.length_ = 0;
12,224✔
361
    return *this;
12,224✔
362
}
6,112✔
363
// -------------------------------------------------------------------------- //
364

365

366

367
// -------------------------- BIT VECTOR: ACCESS -------------------------- //
368
template<class WordType, class Allocator>
369
constexpr typename bit_vector<WordType, Allocator>::reference
370
bit_vector<WordType, Allocator>::operator[](size_type pos) {return begin()[pos];}
32,858,336✔
371

372
template<class WordType, class Allocator>
373
constexpr typename bit_vector<WordType, Allocator>::reference
374
bit_vector<WordType, Allocator>::operator[](size_type pos) const {return begin()[pos];}
375

376
template<class WordType, class Allocator>
377
constexpr typename bit_vector<WordType, Allocator>::reference
378
bit_vector<WordType, Allocator>::at(size_type pos) {
5,779,600✔
379
    if (pos < length_) {
5,779,600✔
380
        return begin()[pos];
8,123,952✔
381
    } else {
2,707,984✔
382
        throw std::out_of_range("Position is out of range");
363,632✔
383
    }
181,816✔
384
}
2,889,800✔
385

386
template<class WordType, class Allocator>
387
constexpr typename bit_vector<WordType, Allocator>::const_reference
388
bit_vector<WordType, Allocator>::at(size_type pos) const {
389
    if (pos < length_) {
390
        return begin()[pos];
391
    } else {
392
        throw std::out_of_range("Position is out of range");
393
    }
394
}
395

396
template<class WordType, class Allocator>
397
constexpr typename bit_vector<WordType, Allocator>::reference
398
bit_vector<WordType, Allocator>::front() {
399
    return begin()[0];
400
}
401

402
template<class WordType, class Allocator>
403
constexpr typename bit_vector<WordType, Allocator>::const_reference
404
bit_vector<WordType, Allocator>::front() const {
405
    return begin()[0];
406
}
407

408
template<class WordType, class Allocator>
409
constexpr typename bit_vector<WordType, Allocator>::reference
410
bit_vector<WordType, Allocator>::back() {
411
    return begin()[length_ - 1];
412
}
413

414
template<class WordType, class Allocator>
415
constexpr typename bit_vector<WordType, Allocator>::const_reference
416
bit_vector<WordType, Allocator>::back() const {
417
    return begin()[length_ - 1];
418
}
419

420
template<class WordType, class Allocator>
421
constexpr WordType*
422
bit_vector<WordType, Allocator>::data() noexcept {
423
    return length_ ? &(word_vector[0]) : 0;
424
}
425

426
template<class WordType, class Allocator>
427
constexpr const WordType*
428
bit_vector<WordType, Allocator>::data() const noexcept {
429
    return word_vector.size() ? &(word_vector[0]) : 0;
430
}
431
// -------------------------------------------------------------------------- //
432

433

434

435
// ------------------------ BIT VECTOR: ITERATORS --------------------------- //
436
template<class WordType, class Allocator>
437
constexpr typename bit_vector<WordType, Allocator>::iterator
438
bit_vector<WordType, Allocator>::begin() noexcept {
25,747,993✔
439
    return iterator(word_vector.begin());
25,747,993✔
440
}
12,874,124✔
441

442
template<class WordType, class Allocator>
443
constexpr typename bit_vector<WordType, Allocator>::iterator
444
bit_vector<WordType, Allocator>::end() noexcept {
1,232,548✔
445
    return begin() + length_;
1,232,548✔
446
}
616,299✔
447

448
template<class WordType, class Allocator>
449
constexpr typename bit_vector<WordType, Allocator>::const_iterator
450
bit_vector<WordType, Allocator>::begin() const noexcept {
451
    return const_iterator(word_vector.begin());
452
}
453

454
template<class WordType, class Allocator>
455
constexpr typename bit_vector<WordType, Allocator>::const_iterator
456
bit_vector<WordType, Allocator>::end() const noexcept {
457
    return const_iterator(word_vector.cbegin()) + length_;
458
}
459

460
template<class WordType, class Allocator>
461
constexpr typename bit_vector<WordType, Allocator>::const_iterator
462
bit_vector<WordType, Allocator>::cbegin() const noexcept {
99,844✔
463
    return const_iterator(word_vector.begin());
99,844✔
464
}
49,922✔
465

466
template<class WordType, class Allocator>
467
constexpr typename bit_vector<WordType, Allocator>::const_iterator
468
bit_vector<WordType, Allocator>::cend() const noexcept {
469
    return const_iterator(word_vector.cbegin()) + length_;
470
}
471
// -------------------------------------------------------------------------- //
472

473

474

475
// ------------------------ BIT VECTOR: CAPACITY ---------------------------- //
476
template<class WordType, class Allocator>
477
constexpr bool bit_vector<WordType, Allocator>::empty() const noexcept {
48✔
478
    return length_ == 0;
48✔
479
}
24✔
480

481
template<class WordType, class Allocator>
482
constexpr typename bit_vector<WordType, Allocator>::size_type
483
bit_vector<WordType, Allocator>::size() const noexcept {
280,709✔
484
    return length_;
280,709✔
485
}
140,360✔
486

487
template<class WordType, class Allocator>
488
constexpr typename bit_vector<WordType, Allocator>::size_type
489
bit_vector<WordType, Allocator>::max_size() const noexcept {
490
    return word_vector.max_size() * digits;
491
}
492

493
template<class WordType, class Allocator>
494
constexpr void bit_vector<WordType, Allocator>::reserve(size_type new_cap) {
80✔
495
    word_vector.reserve(word_count(new_cap));
80✔
496
}
80✔
497

498
template<class WordType, class Allocator>
499
constexpr typename bit_vector<WordType, Allocator>::size_type
500
bit_vector<WordType, Allocator>::capacity() const noexcept {
4,144✔
501
    return word_vector.capacity() * digits;
4,144✔
502
}
2,072✔
503

504
template<class WordType, class Allocator>
505
constexpr void bit_vector<WordType, Allocator>::shrink_to_fit() {
2,064✔
506
    word_vector.shrink_to_fit();
2,064✔
507
}
2,064✔
508
// -------------------------------------------------------------------------- //
509

510

511

512
// ------------------------ BIT VECTOR: MODIFYING -------------------------- //
513
template<class WordType, class Allocator>
514
constexpr void bit_vector<WordType, Allocator>::clear() noexcept {
2,112✔
515
    word_vector.clear(); length_ = 0;
2,112✔
516
}
2,112✔
517

518
template<class WordType, class Allocator>
519
constexpr typename bit_vector<WordType, Allocator>::iterator
520
bit_vector<WordType, Allocator>::insert(
49,152✔
521
        const_iterator pos,
522
        const value_type& value) {
49,152✔
523
    const auto d = distance(cbegin(), pos);
98,304✔
524
    if (this->word_vector.size()*digits == length_) {
98,304✔
525
        word_vector.push_back(0U);
3,432✔
526
    }
1,716✔
527
    length_ += 1;
98,304✔
528
    shift_right(begin() + d, begin() + length_, 1);
98,304✔
529
    begin()[d] = value;
98,304✔
530
    return begin() + d;
147,456✔
531
}
49,152✔
532

533
// TODO should use std::insert to maintain the constant amortized time.
534
template<class WordType, class Allocator>
535
constexpr typename bit_vector<WordType, Allocator>::iterator
536
bit_vector<WordType, Allocator>::insert(
384✔
537
        const_iterator pos,
538
        size_type count,
539
        const bit_vector<WordType, Allocator>::value_type& value) {
384✔
540
    const auto d = distance(cbegin(), pos);
768✔
541
    if (count == 0) {
768!
542
        return begin() + d;
16✔
NEW
543
    }
544
    const float bits_available = word_vector.size() * digits;
752✔
545
    const bool need_to_add = length_ + count > bits_available;
752✔
546
    if (need_to_add) {
752!
547
        const auto words_to_add = word_count(length_ + count - bits_available);
716✔
548
        word_vector.resize(word_vector.size() + words_to_add);
716✔
549
    }
369✔
550
    length_ += count;
752✔
551
    shift_right(begin() + d, begin() + length_, count);
752✔
552
    fill(begin() + d, begin() + d + count, value);
752✔
553
    return begin() + d;
752✔
554
}
384✔
555

556
template <class WordType, class Allocator>
557
template <bit_iterator_c OtherIt>
558
constexpr typename bit_vector<WordType, Allocator>::iterator
559
bit_vector<WordType, Allocator>::insert(
386✔
560
    const_iterator pos,
561
    OtherIt first,
562
    OtherIt last) {
386✔
563
  const auto d = distance(cbegin(), pos);
772✔
564
  const size_t count = distance(first, last);
772✔
565
  if (count == 0) {
772!
566
    return begin() + d;
×
567
  }
568
  const float bits_available = word_vector.size() * digits;
772✔
569
  const auto need_to_add = length_ + count > bits_available;
772✔
570
  if (need_to_add) {
772!
571
    const auto words_to_add = word_count(length_ + count - bits_available);
732✔
572
    word_vector.resize(word_vector.size() + words_to_add);
732✔
573
  }
354✔
574
  length_ += count;
772✔
575
  shift_right(begin() + d, begin() + length_, count);
772✔
576
  copy(first, last, begin() + d);
772✔
577
  return begin() + d;
772✔
578
}
386✔
579

580
template<class WordType, class Allocator>
581
constexpr typename bit_vector<WordType, Allocator>::iterator
582
bit_vector<WordType, Allocator>::erase(iterator pos) {
677✔
583
  difference_type d = distance(begin(), pos);
677✔
584
  shift_left(pos, begin() + length_, 1);
677✔
585
  length_ -= 1;
677✔
586
  if (length_ % digits == 0) {
677!
587
    word_vector.pop_back();
41✔
588
  }
18✔
589
  return begin() + d;
1,001✔
590
}
353✔
591

592
template<class WordType, class Allocator>
593
constexpr typename bit_vector<WordType, Allocator>::iterator
594
bit_vector<WordType, Allocator>::erase(iterator first, iterator last) {
579✔
595
    const auto d = distance(begin(), first);
579✔
596
    auto count = distance(first, last);
579✔
597
    if (count == 0) {
579!
598
        return last;
246✔
599
    }
120✔
600
    shift_left(first, end(), count);
333✔
601
    length_ -= count;
333✔
602
    word_vector.resize(word_count(length_));
333✔
603
    return begin() + d;
333✔
604
}
288✔
605

606
template<class WordType, class Allocator>
607
constexpr void bit_vector<WordType, Allocator>::push_back(const value_type& value) {
361,794✔
608
    if (this->word_vector.size()*digits == length_) {
361,794✔
609
        word_vector.push_back(0U);
8,150✔
610
    }
4,075✔
611
    begin()[length_] = value;
361,794✔
612
    length_ += 1;
361,794✔
613
    return;
542,691✔
614
}
180,897✔
615

616
template<class WordType, class Allocator>
617
constexpr void bit_vector<WordType, Allocator>::pop_back() {
278,880✔
618
    length_ -= 1;
278,880✔
619
    if (length_ % digits == 0) {
278,880✔
620
        word_vector.pop_back();
7,280✔
621
    }
3,640✔
622
    return;
278,880✔
623
}
139,440✔
624

625
template<class WordType, class Allocator>
626
constexpr void bit_vector<WordType, Allocator>::resize(size_type count) {
137,968✔
627
    word_vector.resize(word_count(count));
137,968✔
628
    length_ = count;
137,968✔
629
    return;
206,952✔
630
}
68,984✔
631

632
template<class WordType, class Allocator>
633
constexpr void bit_vector<WordType, Allocator>::resize(size_type count, const value_type& value) {
634
    auto old_length = length_;
635
    word_vector.resize(word_count(count));
636
    length_ = count;
637
    if (length_ > old_length) {
638
        fill(begin() + length_, end(), value);
639
    }
640
    return;
641
}
642
// -------------------------------------------------------------------------- //
643

644
template <class WordType, class Allocator>
645
template <bit_range R>
646
constexpr bit_vector<WordType, Allocator>::iterator bit_vector<WordType, Allocator>::insert_range(const_iterator pos, R&& range) {
647
  return this->insert(pos, range.begin(), range.end());
648
}
649

650
template <class WordType, class Allocator>
651
template <bit_range R>
652
constexpr void bit_vector<WordType, Allocator>::append_range(R&& range) {
4✔
653
  this->insert(this->end(), range.begin(), range.end());
4✔
654
}
4✔
655

656
/*
657
  * Slice
658
*/
659
template <class WordType, class Allocator>
660
constexpr bit_array_ref<std::dynamic_extent, WordType /*, Policy*/> bit_vector<WordType, Allocator>::operator()(size_type begin, size_type end) const noexcept {
661
  return bit_array_ref<std::dynamic_extent, WordType /*, Policy*/>(&this->at(begin), end - begin);
662
}
663

664
// ------------------------ BIT VECTOR: DEBUGGING -------------------------- //
665
template <class WordType, class Allocator>
666
constexpr std::string bit_vector<WordType, Allocator>::debug_string(const_iterator first, const_iterator end) {
667
  std::string ret = "";
668
  auto position = 0;
669
  for (const_iterator it = first; it != end; ++it) {
670
    if (position % digits == 0 && position != 0) {
671
      ret += " ";
672
    } else if (position % 8 == 0 && position != 0) {
673
      ret += '.';
674
    }
675
    ret += *it == bit1 ? '1' : '0';
676
    ++position;
677
  }
678
  return ret;
679
}
680

681
template<class WordType, class Allocator>
682
constexpr std::string bit_vector<WordType, Allocator>::debug_string() {
683
  return debug_string(begin(), end());
684
}
685
// -------------------------------------------------------------------------- //
686

687

688
// ========================================================================== //
689
} // namespace bit
690
#endif // _BIT_VECTOR_HPP_INCLUDED
691
// ========================================================================== //
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc