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

PeterCDMcLean / BitLib / 15599073802

12 Jun 2025 01:00AM UTC coverage: 53.427% (+0.6%) from 52.785%
15599073802

Pull #16

github

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

10022 of 18552 branches covered (54.02%)

Branch coverage included in aggregate %.

724 of 745 new or added lines in 20 files covered. (97.18%)

3 existing lines in 2 files now uncovered.

5831 of 11120 relevant lines covered (52.44%)

4634541.42 hits per line

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

70.3
/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,452,685✔
43
  size_type _index;
3,395✔
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)
10,193✔
51
    requires(is_big_to_small)
52
      : _source(source), _index(index) {
20,386✔
53
  }
20,386✔
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 {
11,611,766✔
62
    if constexpr (is_small_to_big) {
5,805,562✔
63
      return reference(*_source);
22✔
64
    } else {
5,805,551✔
65
      return reference(*_source, _index);
11,611,744✔
66
    }
5,805,551✔
67
  }
5,805,562✔
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 {
11,592,218✔
88
    if constexpr (is_small_to_big) {
5,795,918✔
89
      _source = std::next(_source, ratio);
6✔
90
    } else {
5,795,916✔
91
      ++_index;
11,592,214✔
92
      if (_index >= ratio) {
11,592,214!
93
        _source = std::next(_source);
4,735,319✔
94
        _index -= ratio;
3,156,907✔
95
      }
1,578,495✔
96
    }
5,795,916✔
97
    return *this;
11,592,218✔
98
  }
5,795,918✔
99
  constexpr bit_word_pointer_adapter operator++(int) noexcept {
4,316✔
100
    bit_word_pointer_adapter old = *this;
4,316✔
101
    ++(*this);
4,316✔
102
    return old;
4,316✔
103
  }
1,950✔
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 {
11,648✔
147
    if constexpr (is_small_to_big) {
5,870✔
148
      _source = std::next(_source, n * ratio);
6✔
149
    } else {
5,868✔
150
      const difference_type sum = _index + n;
11,644✔
151
      difference_type src_diff = sum / static_cast<difference_type>(ratio);
11,644✔
152
      const size_type new_index = sum % ratio;
11,644✔
153
      if (n < 0 && new_index > _index) {
11,644!
NEW
154
        --src_diff;
×
155
      }
156
      _source = std::next(_source, src_diff);
17,420✔
157
      _index = new_index;
11,644✔
158
    }
5,868✔
159
    return *this;
11,648✔
160
  }
5,870✔
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;
5,820,125✔
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
  constexpr operator source_word_ptr() const noexcept {
2,262✔
191
    if constexpr (is_small_to_big) {
192
      return _source;
193
    } else {
1,131✔
194
      return std::next(_source, _index / ratio);
3,393✔
195
    }
1,131✔
196
  }
1,131✔
197
};
198

199
template <typename T, typename U, typename V, typename W>
200
constexpr auto operator-(
12,678✔
201
    const bit_word_pointer_adapter<T, U>& lhs,
202
    const bit_word_pointer_adapter<V, W>& rhs) {
12,392✔
203
  using lhs_type = typename bit_word_pointer_adapter<T, U>::difference_type;
12,392✔
204
  using rhs_type = typename bit_word_pointer_adapter<V, W>::difference_type;
12,392✔
205
  static_assert(
12,392✔
206
      bit_word_pointer_adapter<T, U>::ratio ==
12,392✔
207
          bit_word_pointer_adapter<V, W>::ratio,
12,392✔
208
      "Cannot subtract iterators with different ratios");
12,392✔
209
  if constexpr (bit_word_pointer_adapter<T, U>::is_big_to_small) {
12,392✔
210
    auto main = (lhs._source - rhs._source);
25,058✔
211
    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));
25,058✔
212
  } else {
12,386✔
213
    // “small→large” mode: each base‐step is 1 small word, but difference is in big words:
214
    auto small_diff = (lhs._source - rhs._source);
12✔
215
    return small_diff / static_cast<std::common_type_t<lhs_type, rhs_type>>(bit_word_pointer_adapter<T, U>::ratio);
12✔
216
  }
6✔
217
}
12,392✔
218

219
} // namespace bit
220

221
#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