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

PeterCDMcLean / BitLib / 15624655410

13 Jun 2025 01:54AM UTC coverage: 53.519% (+0.7%) from 52.785%
15624655410

push

github

web-flow
Small buffer optimization (#16)

* Remove alignment. Expose algorithm issues with differing types

* Add iterator adapter class (big to small)

* Use new iterator adapter. Set more default words to uintptr_t

* Add dispatch to workflow trigger options

* Dummy change

* Try rerranging

* Remove distinct iterator adapter test target

* Try GLIBCXX_RELEASE macro

* Fix type for test

* bit_reference now templated on ref type to allow for it to wrap proxy references

* Now with proxy reference and proxy pointer

* Fix some ops

* Remove wider_t narrower_t

* Small buffer optimized dynamic bit array

* Clean up more of bit_details

* small improvement to bitsof

* Don't measure coverage on tests (too error prone)

* Adapter prelude wip

* Add test for mixed type equals

* Adapted copy

* Test adapted copy

* Fix conversion from adapter back to iterator

* Remove unnecessary return type template parameter

10266 of 19000 branches covered (54.03%)

Branch coverage included in aggregate %.

771 of 792 new or added lines in 20 files covered. (97.35%)

1 existing line in 1 file now uncovered.

5880 of 11169 relevant lines covered (52.65%)

4735435.26 hits per line

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

69.54
/include/bitlib/bit-iterator/bit_word_pointer_adapter.hpp
1
#ifndef _BIT_WORD_POINTER_ADAPTER_HPP_
2
#define _BIT_WORD_POINTER_ADAPTER_HPP_
3

4
#include "bit_details.hpp"
5

6
namespace bit {
7

8
template <typename target_word_ref, typename source_word_ref>
9
class bit_word_reference_adapter;
10

11
template <typename target_word_ptr, typename source_word_ptr>
12
class bit_word_pointer_adapter {
13
 private:
14
  // Assertions
15
  using _traits_t = _cv_iterator_traits<target_word_ptr>;
16
  static_assert(binary_digits<typename _traits_t::value_type>::value, "");
17

18
 public:
19
  using target_word = std::remove_const_t<typename _traits_t::value_type>;
20
  using target_word_ref = _traits_t::reference;
21
  using source_word = typename _cv_iterator_traits<source_word_ptr>::value_type;
22
  using source_word_ref = std::add_lvalue_reference_t<source_word>;
23

24
  using size_type = std::size_t;
25
  using difference_type = std::ptrdiff_t;
26
  using reference = bit_word_reference_adapter<target_word_ref, source_word_ref>;
27
  using pointer = bit_word_pointer_adapter<target_word, source_word_ptr>;
28

29
  using iterator_type = target_word_ptr;
30
  using iterator_category = typename _cv_iterator_traits<source_word_ptr>::iterator_category;
31
  using value_type = target_word;
32

33
 private:
34
  static_assert(std::is_integral_v<source_word>, "source_word_ptr must be a pointer to a integral type");
35
  static_assert(std::is_integral_v<target_word>, "target_word must be an integral type");
36

37
  static constexpr bool is_small_to_big = sizeof(target_word) > sizeof(source_word);
38
  static constexpr bool is_big_to_small = sizeof(target_word) < sizeof(source_word);
39
  static constexpr size_t ratio = is_small_to_big ? sizeof(target_word) / sizeof(source_word)
40
                                                  : sizeof(source_word) / sizeof(target_word);
41

42
  source_word_ptr _source;
1,453,815✔
43
  size_type _index;
3,712✔
44

45
 public:
46
  explicit constexpr bit_word_pointer_adapter(source_word_ptr source)
9✔
47
    requires(is_small_to_big)
48
      : _source(source) {
18✔
49
  }
18✔
50
  explicit constexpr bit_word_pointer_adapter(source_word_ptr source, const size_type index = 0)
13,583✔
51
    requires(is_big_to_small)
52
      : _source(source), _index(index) {
27,166✔
53
  }
27,166✔
54

55
  constexpr bit_word_pointer_adapter(const bit_word_pointer_adapter&) = default;
56
  constexpr bit_word_pointer_adapter& operator=(const bit_word_pointer_adapter&) = default;
57
  constexpr bit_word_pointer_adapter(bit_word_pointer_adapter&&) = default;
58
  constexpr bit_word_pointer_adapter& operator=(bit_word_pointer_adapter&&) = default;
59
  constexpr ~bit_word_pointer_adapter() = default;
60

61
  constexpr reference operator*() const noexcept {
17,415,561✔
62
    if constexpr (is_small_to_big) {
8,708,247✔
63
      return reference(*_source);
22✔
64
    } else {
8,708,236✔
65
      return reference(*_source, _index);
17,415,539✔
66
    }
8,708,236✔
67
  }
8,708,247✔
68

69
  constexpr bit_word_pointer_adapter operator->() const noexcept {
70
    return bit_word_pointer_adapter(&*_source, _index);
71
  }
72

73
  constexpr reference operator[](difference_type n) const noexcept {
24✔
74
    if constexpr (is_small_to_big) {
75
      return reference(*std::next(_source, n*ratio));
76
    } else {
12✔
77
      const difference_type sum = _index + n;
24✔
78
      difference_type src_diff = sum / static_cast<difference_type>(ratio);
24✔
79
      const size_type new_index = sum % ratio;
24✔
80
      if (n < 0 && new_index > _index) {
24!
NEW
81
        --src_diff;
×
82
      }
83
      return reference(*std::next(_source, src_diff), new_index);
36✔
84
    }
12✔
85
  }
12✔
86

87
  constexpr bit_word_pointer_adapter& operator++() noexcept {
17,387,454✔
88
    if constexpr (is_small_to_big) {
8,694,084✔
89
      _source = std::next(_source, ratio);
6✔
90
    } else {
8,694,082✔
91
      ++_index;
17,387,450✔
92
      if (_index >= ratio) {
17,387,450!
93
        _source = std::next(_source);
7,102,894✔
94
        _index -= ratio;
4,735,314✔
95
      }
2,367,734✔
96
    }
8,694,082✔
97
    return *this;
17,387,454✔
98
  }
8,694,084✔
99
  constexpr bit_word_pointer_adapter operator++(int) noexcept {
5,692✔
100
    bit_word_pointer_adapter old = *this;
5,692✔
101
    ++(*this);
5,692✔
102
    return old;
5,692✔
103
  }
2,792✔
104
  constexpr bit_word_pointer_adapter& operator--() noexcept {
105
    if constexpr (is_small_to_big) {
106
      _source = std::next(_source, -ratio);
107
    } else {
108
      if ((_index--) == 0) {
109
        _source = std::prev(_source);
110
        _index += ratio;
111
      }
112
    }
113
    return *this;
114
  }
115
  constexpr bit_word_pointer_adapter operator--(int) noexcept {
116
    bit_word_pointer_adapter old = *this;
117
    --(*this);
118
    return old;
119
  }
120
  constexpr bit_word_pointer_adapter operator+(difference_type n) const noexcept {
14✔
121
    if constexpr (is_small_to_big) {
7✔
122
      return bit_word_pointer_adapter(std::next(_source, n*ratio));
9✔
123
    } else {
4✔
124
      const difference_type sum = _index + n;
8✔
125
      difference_type src_diff = sum / static_cast<difference_type>(ratio);
8✔
126
      const size_type new_index = sum % ratio;
8✔
127
      if (n < 0 && new_index > _index) {
8!
NEW
128
        --src_diff;
×
129
      }
130
      return bit_word_pointer_adapter(std::next(_source, src_diff), new_index);
12✔
131
    }
4✔
132
  }
7✔
133
  constexpr bit_word_pointer_adapter operator-(difference_type n) const noexcept {
2✔
134
    if constexpr (is_small_to_big) {
135
      return bit_word_pointer_adapter(std::next(_source, -n*ratio));
136
    } else {
1✔
137
      const difference_type sum = _index - n;
2✔
138
      difference_type src_diff = sum / static_cast<difference_type>(ratio);
2✔
139
      const size_type new_index = sum % ratio;
2✔
140
      if (n > 0 && new_index > _index) {
2!
141
        --src_diff;
2✔
142
      }
1✔
143
      return bit_word_pointer_adapter(std::next(_source, src_diff), new_index);
3✔
144
    }
1✔
145
  }
1✔
146
  constexpr bit_word_pointer_adapter& operator+=(difference_type n) noexcept {
17,293✔
147
    if constexpr (is_small_to_big) {
8,732✔
148
      _source = std::next(_source, n * ratio);
6✔
149
    } else {
8,730✔
150
      const difference_type sum = _index + n;
17,289✔
151
      difference_type src_diff = sum / static_cast<difference_type>(ratio);
17,289✔
152
      const size_type new_index = sum % ratio;
17,289✔
153
      if (n < 0 && new_index > _index) {
17,289!
NEW
154
        --src_diff;
×
155
      }
156
      _source = std::next(_source, src_diff);
25,848✔
157
      _index = new_index;
17,289✔
158
    }
8,730✔
159
    return *this;
17,293✔
160
  }
8,732✔
161
  constexpr bit_word_pointer_adapter& operator-=(difference_type n) noexcept {
2✔
162
    if constexpr (is_small_to_big) {
1✔
163
      _source = std::next(_source, -n * ratio);
3✔
164
    } else {
165
      const difference_type sum = _index - n;
166
      difference_type src_diff = sum / static_cast<difference_type>(ratio);
167
      const size_type new_index = sum % ratio;
168
      if (n > 0 && new_index > _index) {
169
        --src_diff;
170
      }
171
      _source = std::next(_source, src_diff);
172
      _index = new_index;
173
    }
174
    return *this;
2✔
175
  }
1✔
176
  constexpr bool operator==(const bit_word_pointer_adapter&) const = default;
7,277,049✔
177
  constexpr auto operator<=>(const bit_word_pointer_adapter&) const = default;
178

179
  constexpr size_type index() const noexcept {
4,544✔
180
    return _index;
4,544✔
181
  }
2,272✔
182
  constexpr source_word_ptr base() const noexcept {
4,532✔
183
    return _source;
4,532✔
184
  }
2,266✔
185
  template <typename T, typename U, typename V, typename W>
186
  friend constexpr auto operator-(
187
      const bit_word_pointer_adapter<T, U>& lhs,
188
      const bit_word_pointer_adapter<V, W>& rhs);
189
};
190

191
template <typename T, typename U, typename V, typename W>
192
constexpr auto operator-(
17,808✔
193
    const bit_word_pointer_adapter<T, U>& lhs,
194
    const bit_word_pointer_adapter<V, W>& rhs) {
16,643✔
195
  using lhs_type = typename bit_word_pointer_adapter<T, U>::difference_type;
16,643✔
196
  using rhs_type = typename bit_word_pointer_adapter<V, W>::difference_type;
16,643✔
197
  static_assert(
16,643✔
198
      bit_word_pointer_adapter<T, U>::ratio ==
16,643✔
199
          bit_word_pointer_adapter<V, W>::ratio,
16,643✔
200
      "Cannot subtract iterators with different ratios");
16,643✔
201
  if constexpr (bit_word_pointer_adapter<T, U>::is_big_to_small) {
16,643✔
202
    auto main = (lhs._source - rhs._source);
34,439✔
203
    return main * static_cast<std::common_type_t<lhs_type, rhs_type>>(bit_word_pointer_adapter<T, U>::ratio) + (static_cast<lhs_type>(lhs._index) - static_cast<lhs_type>(rhs._index));
34,439✔
204
  } else {
16,637✔
205
    // “small→large” mode: each base‐step is 1 small word, but difference is in big words:
206
    auto small_diff = (lhs._source - rhs._source);
12✔
207
    return small_diff / static_cast<std::common_type_t<lhs_type, rhs_type>>(bit_word_pointer_adapter<T, U>::ratio);
12✔
208
  }
6✔
209
}
16,643✔
210

211
} // namespace bit
212

213
#endif  // _BIT_WORD_POINTER_ADAPTER_HPP_
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

© 2025 Coveralls, Inc