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

PeterCDMcLean / BitLib / 15574317715

11 Jun 2025 02:02AM UTC coverage: 53.774% (+1.0%) from 52.785%
15574317715

Pull #16

github

web-flow
Merge c4534fd50 into a32e9aeba
Pull Request #16: Small buffer optimization

9875 of 18300 branches covered (53.96%)

Branch coverage included in aggregate %.

619 of 655 new or added lines in 16 files covered. (94.5%)

2 existing lines in 1 file now uncovered.

5912 of 11058 relevant lines covered (53.46%)

7914739.4 hits per line

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

73.74
/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 = _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,451,551✔
43
  size_type _index;
3,069✔
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)
6,794✔
51
    requires(is_big_to_small)
52
      : _source(source), _index(index) {
13,588✔
53
  }
13,588✔
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 {
5,806,521✔
62
    if constexpr (is_small_to_big) {
2,903,275✔
63
      return reference(*_source);
22✔
64
    } else {
2,903,264✔
65
      return reference(*_source, _index);
5,806,499✔
66
    }
2,903,264✔
67
  }
2,903,275✔
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;
×
NEW
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 {
5,796,324✔
88
    if constexpr (is_small_to_big) {
2,898,098✔
89
      _source = std::next(_source, ratio);
6✔
90
    } else {
2,898,096✔
91
      ++_index;
5,796,320✔
92
      if (_index >= ratio) {
5,796,320!
93
        _source = std::next(_source);
2,367,666✔
94
        _index -= ratio;
1,578,458✔
95
      }
789,250✔
96
    }
2,898,096✔
97
    return *this;
5,796,324✔
98
  }
2,898,098✔
99
  constexpr bit_word_pointer_adapter operator++(int) noexcept {
2,359✔
100
    bit_word_pointer_adapter old = *this;
2,359✔
101
    ++(*this);
2,359✔
102
    return old;
2,359✔
103
  }
1,107✔
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;
×
NEW
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 {
5,804✔
147
    if constexpr (is_small_to_big) {
3,007✔
148
      _source = std::next(_source, n * ratio);
6✔
149
    } else {
3,005✔
150
      const difference_type sum = _index + n;
5,800✔
151
      difference_type src_diff = sum / static_cast<difference_type>(ratio);
5,800✔
152
      const size_type new_index = sum % ratio;
5,800✔
153
      if (n < 0 && new_index > _index) {
5,800!
NEW
154
        --src_diff;
×
NEW
155
      }
156
      _source = std::next(_source, src_diff);
8,595✔
157
      _index = new_index;
5,800✔
158
    }
3,005✔
159
    return *this;
5,804✔
160
  }
3,007✔
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;
4,362,916✔
177
  constexpr auto operator<=>(const bit_word_pointer_adapter&) const = default;
178

179
  constexpr size_type index() const noexcept {
22✔
180
    return _index;
22✔
181
  }
11✔
182
  constexpr source_word_ptr base() const noexcept {
10✔
183
    return _source;
10✔
184
  }
5✔
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-(
7,596✔
193
    const bit_word_pointer_adapter<T, U>& lhs,
194
    const bit_word_pointer_adapter<V, W>& rhs) {
8,119✔
195
  using lhs_type = typename bit_word_pointer_adapter<T, U>::difference_type;
8,119✔
196
  using rhs_type = typename bit_word_pointer_adapter<V, W>::difference_type;
8,119✔
197
  static_assert(
8,119✔
198
      bit_word_pointer_adapter<T, U>::ratio ==
8,119✔
199
          bit_word_pointer_adapter<V, W>::ratio,
8,119✔
200
      "Cannot subtract iterators with different ratios");
8,119✔
201
  if constexpr (bit_word_pointer_adapter<T, U>::is_big_to_small) {
8,119✔
202
    auto main = (lhs._source - rhs._source);
15,703✔
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));
15,703✔
204
  } else {
8,113✔
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
}
8,119✔
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