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

PeterCDMcLean / BitLib / 14842851936

05 May 2025 05:55PM UTC coverage: 97.036% (-0.05%) from 97.086%
14842851936

push

github

web-flow
Fix Wdeprecated-copy implicitly declared ... is deprecated (#4)

14 of 14 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

1277 of 1316 relevant lines covered (97.04%)

16631270.71 hits per line

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

97.26
/include/bitlib/bit-iterator/bit_iterator.hpp
1
// ============================== BIT ITERATOR ============================== //
2
// Project:         The C++ Bit Library
3
// Name:            bit_iterator.hpp
4
// Description:     A class representing an iterator on bit sequences
5
// Creator:         Vincent Reverdy
6
// Contributor(s):  Vincent Reverdy [2015-2017]
7
// License:         BSD 3-Clause License
8
// ========================================================================== //
9
#ifndef _BIT_ITERATOR_HPP_INCLUDED
10
#define _BIT_ITERATOR_HPP_INCLUDED
11
// ========================================================================== //
12

13

14

15
// ================================ PREAMBLE ================================ //
16
// C++ standard library
17
#include <compare>
18
#include <concepts>
19
#include <cstddef>
20
#include <iterator>
21
#include <type_traits>
22

23
#include "bitlib/bit-containers/bit_bitsof.hpp"
24
#include "bitlib/bit_concepts.hpp"
25
// Project sources
26
#include "bit_details.hpp"
27
#include "bit_reference.hpp"
28
// Third-party libraries
29
// Miscellaneous
30
namespace bit {
31

32
/* ****************************** BIT ITERATOR ****************************** */
33
// Bit iterator class definition
34
template <class Iterator>
35
class bit_iterator
36
{
37
  template <class>
38
  friend class bit_iterator;
39

40
  // Assertions
41
 private:
42
  using _traits_t = _cv_iterator_traits<Iterator>;
43
  static_assert(binary_digits<typename _traits_t::value_type>::value, "");
44

45
  // Types
46
 public:
47
  using iterator_type = Iterator;
48
  using word_type = typename _traits_t::value_type;
49
  using iterator_category = typename _traits_t::iterator_category;
50
  using value_type = bit_value;
51
  using difference_type = std::ptrdiff_t;
52
  using pointer = bit_pointer<word_type>;
53
  using reference = bit_reference<word_type>;
54
  using size_type = std::size_t;
55
  using mask_type = std::make_unsigned_t<std::remove_cv_t<word_type>>;
56

57
  // Lifecycle
58
 public:
59
  constexpr bit_iterator();
60
  template <class T>
61
  constexpr bit_iterator(const bit_iterator<T>& other)
62
    requires std::constructible_from<iterator_type, T>;
63
  explicit constexpr bit_iterator(iterator_type i);
64
  constexpr bit_iterator(iterator_type i, size_type pos);
65
  explicit constexpr bit_iterator(const pointer& ptr)
66
    requires std::constructible_from<iterator_type, word_type*>;
67

68
  // Assignment
69
 public:
70
  template <class T>
71
  constexpr bit_iterator& operator=(const bit_iterator<T>& other);
72

73
  // Access
74
 public:
75
  constexpr reference operator*() const noexcept;
76
  constexpr pointer operator->() const noexcept;
77
  constexpr reference operator[](difference_type n) const;
78

79
  // Increment and decrement operators
80
 public:
81
  constexpr bit_iterator& operator++();
82
  constexpr bit_iterator& operator--();
83
  constexpr bit_iterator operator++(int);
84
  constexpr bit_iterator operator--(int);
85
  constexpr bit_iterator operator+(difference_type n) const;
86
  constexpr bit_iterator operator-(difference_type n) const;
87
  constexpr bit_iterator& operator+=(difference_type n);
88
  constexpr bit_iterator& operator-=(difference_type n);
89
  constexpr difference_type operator-(const bit_iterator&) const;
90

91
  // Underlying details
92
 public:
93
  constexpr iterator_type base() const;
94
  constexpr iterator_type address() const;
95
  constexpr size_type position() const noexcept;
96

97
  auto operator<=>(const bit_iterator&) const = default;
98
  // Implementation details: data members
99
 private:
100
  iterator_type _current;
101
  size_type _position;
102

103
  // Non-member arithmetic operators
104
  template <class T>
105
  friend constexpr bit_iterator<T> operator+(
106
      typename bit_iterator<T>::difference_type n,
107
      const bit_iterator<T>& i);
108
  template <class T, class U>
109
  friend constexpr typename std::common_type<
110
      typename bit_iterator<T>::difference_type,
111
      typename bit_iterator<U>::difference_type>::type
112
  operator-(
113
      const bit_iterator<T>& lhs,
114
      const bit_iterator<U>& rhs);
115
};
116
/* ************************************************************************** */
117

118

119

120
// ------------------------ BIT ITERATOR: LIFECYCLE ------------------------- //
121
// Implicitly default constructs a bit iterator
122
template <class Iterator>
123
constexpr bit_iterator<Iterator>::bit_iterator()
124
    : _current(), _position() {
125
}
126

127
// Implicitly constructs a bit iterator from another bit iterator
128
template <class Iterator>
129
template <class T>
130
constexpr bit_iterator<Iterator>::bit_iterator(const bit_iterator<T>& other)
25,575✔
131
  requires std::constructible_from<iterator_type, T>
132
    : _current(other.base()), _position(other.position()) {
25,575✔
133
  assert(_position < bitsof<word_type>());
25,575✔
134
}
25,575✔
135

136
// Explicitly constructs an aligned bit iterator from an iterator
137
template <class Iterator>
138
constexpr bit_iterator<Iterator>::bit_iterator(const iterator_type i)
6,416,677✔
139
    : _current(i), _position(0) {
6,416,677✔
140
}
6,416,677✔
141

142
// Explicitly constructs an unaligned bit iterator from an iterator
143
template <class Iterator>
144
constexpr bit_iterator<Iterator>::bit_iterator(const iterator_type i, size_type pos)
751,690✔
145
    : _current(i), _position((assert(pos < binary_digits<word_type>::value), pos)) {
751,690✔
146
}
751,690✔
147

148
// Explicitly constructs an unaligned bit iterator from a pointer
149
template <class Iterator>
150
constexpr bit_iterator<Iterator>::bit_iterator(const pointer& ptr)
120✔
151
  requires std::constructible_from<iterator_type, word_type*>
152
    : _current(ptr._current), _position(ptr.position()) {
120✔
153
  assert(_position < bitsof<word_type>());
120✔
154
}
120✔
155
// -------------------------------------------------------------------------- //
156

157

158

159
// ------------------------ BIT ITERATOR: ASSIGNMENT ------------------------ //
160
// Assigns a bit iterator to the bit iterator
161
template <class Iterator>
162
template <class T>
163
constexpr bit_iterator<Iterator>& bit_iterator<Iterator>::operator=(
164
    const bit_iterator<T>& other) {
165
  _current = other._current;
166
  _position = other._position;
167
  assert(_position < bitsof<word_type>());
168
  return *this;
169
}
170
// -------------------------------------------------------------------------- //
171

172

173

174
// -------------------------- BIT ITERATOR: ACCESS -------------------------- //
175
// Gets a bit reference from the bit iterator
176
template <class Iterator>
177
constexpr typename bit_iterator<Iterator>::reference
178
bit_iterator<Iterator>::operator*() const noexcept {
1,067,874,023✔
179
  return reference(*_current, _position);
1,067,874,023✔
180
}
181

182
// Gets a pointer to a bit
183
template <class Iterator>
184
constexpr typename bit_iterator<Iterator>::pointer bit_iterator<Iterator>::operator->() const noexcept {
185
  return pointer(&*_current, _position);
186
}
187

188
// Gets a bit reference, decrementing or incrementing the iterator
189
template <class Iterator>
190
constexpr typename bit_iterator<Iterator>::reference bit_iterator<Iterator>::operator[](difference_type n) const {
5,621,817✔
191
  constexpr difference_type digits = binary_digits<word_type>::value;
5,621,817✔
192
  const difference_type sum = _position + n;
5,621,817✔
193
  difference_type diff = sum / digits;
5,621,817✔
194
  if (sum < 0 && diff * digits != sum) {
5,621,817✔
195
    --diff;
×
196
  }
197
  return reference(*std::next(_current, diff), sum - diff * digits);
16,865,451✔
198
}
199
// -------------------------------------------------------------------------- //
200

201

202

203
// ------------- BIT ITERATOR: INCREMENT AND DECREMENT OPERATORS ------------ //
204
// Increments the bit iterator and returns it
205
template <class Iterator>
206
constexpr bit_iterator<Iterator>& bit_iterator<Iterator>::operator++() {
1,067,873,970✔
207
  constexpr size_type digits = binary_digits<word_type>::value;
1,067,873,970✔
208
  if (_position + 1 < digits) {
1,067,873,970✔
209
    ++_position;
1,031,902,534✔
210
  } else {
211
    ++_current;
35,971,436✔
212
    _position = 0;
35,971,436✔
213
  }
214
  return *this;
1,067,873,970✔
215
}
216

217
// Decrements the bit iterator and returns it
218
template <class Iterator>
219
constexpr bit_iterator<Iterator>& bit_iterator<Iterator>::operator--() {
220
  constexpr size_type digits = binary_digits<word_type>::value;
221
  if (_position) {
222
    --_position;
223
  } else {
224
    --_current;
225
    _position = digits - 1;
226
  }
227
  return *this;
228
}
229

230
// Increments the bit iterator and returns the old one
231
template <class Iterator>
232
constexpr bit_iterator<Iterator> bit_iterator<Iterator>::operator++(int) {
64✔
233
  bit_iterator old = *this;
64✔
234
  ++(*this);
64✔
235
  return old;
96✔
236
}
237

238
// Decrements the bit iterator and returns the old one
239
template <class Iterator>
240
constexpr bit_iterator<Iterator> bit_iterator<Iterator>::operator--(int) {
241
  bit_iterator old = *this;
242
  --(*this);
243
  return old;
244
}
245

246
// Looks forward several bits and gets an iterator at this position
247
template <class Iterator>
248
constexpr bit_iterator<Iterator> bit_iterator<Iterator>::operator+(difference_type n) const {
532,771✔
249
  constexpr difference_type digits = binary_digits<word_type>::value;
532,771✔
250
  const difference_type sum = _position + n;
532,771✔
251
  difference_type diff = sum / digits;
532,771✔
252
  if (sum < 0 && diff * digits != sum) {
532,771✔
UNCOV
253
    --diff;
×
254
  }
255
  return bit_iterator(std::next(_current, diff), sum - diff * digits);
1,598,313✔
256
}
257

258
// Looks backward several bits and gets an iterator at this position
259
template <class Iterator>
260
constexpr bit_iterator<Iterator> bit_iterator<Iterator>::operator-(difference_type n) const {
155,897✔
261
  constexpr difference_type digits = binary_digits<word_type>::value;
155,897✔
262
  const difference_type sum = _position - n;
155,897✔
263
  difference_type diff = sum / digits;
155,897✔
264
  if (sum < 0 && diff * digits != sum) {
155,897✔
265
    --diff;
107,560✔
266
  }
267
  return bit_iterator(std::next(_current, diff), sum - diff * digits);
467,691✔
268
}
269

270
// Increments the iterator by several bits and returns it
271
template <class Iterator>
272
constexpr bit_iterator<Iterator>& bit_iterator<Iterator>::operator+=(difference_type n) {
531,268✔
273
  constexpr difference_type digits = binary_digits<word_type>::value;
531,268✔
274
  const difference_type sum = _position + n;
531,268✔
275
  difference_type diff = sum / digits;
531,268✔
276
  if (sum < 0 && diff * digits != sum) {
531,268✔
277
    --diff;
65,865✔
278
  }
279
  _current = std::next(_current, diff);
1,062,536✔
280
  _position = (sum - diff * digits);
531,268✔
281
  return *this;
1,062,536✔
282
}
283

284
// Decrements the iterator by several bits and returns it
285
template <class Iterator>
286
constexpr bit_iterator<Iterator>& bit_iterator<Iterator>::operator-=(difference_type n) {
58,151✔
287
  constexpr difference_type digits = binary_digits<word_type>::value;
58,151✔
288
  const difference_type sum = _position - n;
58,151✔
289
  difference_type diff = sum / digits;
58,151✔
290
  if (sum < 0 && diff * digits != sum) {
58,151✔
291
    --diff;
38,376✔
292
  }
293
  _current = std::next(_current, diff);
116,302✔
294
  _position = (sum - diff * digits);
58,151✔
295
  return *this;
116,302✔
296
}
297
// -------------------------------------------------------------------------- //
298

299
template <class Iterator>
300
constexpr bit_iterator<Iterator>::difference_type
301
bit_iterator<Iterator>::operator-(const bit_iterator<Iterator>& other) const {
485,446✔
302
  constexpr difference_type digits = binary_digits<word_type>::value;
485,446✔
303
  return (_current - other._current) * digits + (_position - other._position);
485,446✔
304
}
305

306
// -------------------- BIT ITERATOR: UNDERLYING DETAILS -------------------- //
307
// Returns a copy of the underlying iterator
308
template <class Iterator>
309
constexpr typename bit_iterator<Iterator>::iterator_type bit_iterator<Iterator>::base() const {
12,161,645✔
310
  return _current;
12,161,645✔
311
}
312

313
template <class Iterator>
314
constexpr typename bit_iterator<Iterator>::iterator_type bit_iterator<Iterator>::address() const {
315
  return _current;
316
}
317

318
// Returns the position of the bit within the underlying word
319
template <class Iterator>
320
constexpr typename bit_iterator<Iterator>::size_type bit_iterator<Iterator>::position() const noexcept {
7,271,052✔
321
  return _position;
7,271,052✔
322
}
323

324
// -------------- BIT ITERATOR: NON-MEMBER ARITHMETIC OPERATORS ------------- //
325
// Advances the bit iterator several times
326
template <class T>
327
constexpr bit_iterator<T> operator+(typename bit_iterator<T>::difference_type n, const bit_iterator<T>& i) {
328
  return i + n;
329
}
330

331
// Computes the distance in bits separating two bit iterators
332
template <class T, class U>
333
constexpr typename std::common_type<
334
    typename bit_iterator<T>::difference_type,
335
    typename bit_iterator<U>::difference_type>::type
336
operator-(const bit_iterator<T>& lhs, const bit_iterator<U>& rhs) {
337
  using lhs_utype = typename bit_iterator<T>::word_type;
338
  using rhs_utype = typename bit_iterator<U>::word_type;
339
  using lhs_type = typename bit_iterator<T>::difference_type;
340
  using rhs_type = typename bit_iterator<U>::difference_type;
341
  using difference_type = typename std::common_type<lhs_type, rhs_type>::type;
342
  constexpr difference_type lhs_digits = binary_digits<lhs_utype>::value;
343
  constexpr difference_type rhs_digits = binary_digits<rhs_utype>::value;
344
  constexpr difference_type digits = rhs_digits;
345
  static_assert(lhs_digits == rhs_digits, "");
346
  const difference_type main = lhs._current - rhs._current;
347
  return main * digits + (lhs._position - rhs._position);
348
}
349

350
static_assert(bit_iterator_c<bit_iterator<uint8_t*>>, "bit_iterator does not satisfy bit_iterator_c concept!");
351
static_assert(bit_pointer_c<bit_pointer<uint8_t>, bit_reference<uint8_t>>, "bit_pointer does not satisfy bit_pointer_c concept!");
352
static_assert(bit_iterator_c<bit_pointer<uint8_t>>, "bit_pointer does not satisfy bit_iterator_c concept!");
353

354
// ========================================================================== //
355
} // namespace bit
356
#endif // _BIT_ITERATOR_HPP_INCLUDED
357
// ========================================================================== //
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