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

PeterCDMcLean / BitLib / 15668665368

15 Jun 2025 11:49PM UTC coverage: 54.208% (+0.7%) from 53.519%
15668665368

Pull #17

github

web-flow
Merge 650153c4f into 0f0b787a1
Pull Request #17: Truncation policy

10212 of 18774 branches covered (54.39%)

Branch coverage included in aggregate %.

180 of 219 new or added lines in 12 files covered. (82.19%)

214 existing lines in 11 files now uncovered.

6038 of 11203 relevant lines covered (53.9%)

7753027.29 hits per line

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

60.19
/include/bitlib/bit-iterator/bit_reference.hpp
1
// ============================= BIT REFERENCE ============================== //
2
// Project:         The C++ Bit Library
3
// Name:            bit_reference.hpp
4
// Description:     A class representing a reference to a bit
5
// Creator:         Vincent Reverdy
6
// Contributor(s):  Vincent Reverdy [2015-2017]
7
// License:         BSD 3-Clause License
8
// ========================================================================== //
9
#ifndef _BIT_REFERENCE_HPP_INCLUDED
10
#define _BIT_REFERENCE_HPP_INCLUDED
11
// ========================================================================== //
12

13

14

15
// ================================ PREAMBLE ================================ //
16
// C++ standard library
17
// Project sources
18
#include <type_traits>
19

20
#include "bit_details.hpp"
21
#include "bit_value.hpp"
22
// Third-party libraries
23
// Miscellaneous
24
namespace bit {
25
// ========================================================================== //
26

27

28

29
/* ***************************** BIT REFERENCE ****************************** */
30
// Bit reference class definition
31
template <typename WordRef = uintptr_t&>
32
class bit_reference {
33
 public:
34
  using WordType = std::remove_reference_t<WordRef>;
35

36
 private:
37
  // Assertions
38
  static_assert(binary_digits<WordType>::value, "");
39

40
  // Friendship
41
  template <class>
42
  friend class bit_reference;
43

44
  // Types
45
 public:
46
  using word_type = WordType;
47
  using size_type = std::size_t;
48
  using mask_type = std::make_unsigned_t<std::remove_cv_t<word_type>>;
49

50
  // Lifecycle
51
 public:
52
  template <class T>
53
    requires(std::is_const_v<std::remove_reference_t<WordRef>> == std::is_const_v<std::remove_reference_t<T>>)
54
  constexpr bit_reference(const bit_reference<T>& other) noexcept
210✔
55
      : _ref(other._ref), _mask(other._mask) {
420✔
56
  }
420✔
57
  constexpr bit_reference(const bit_reference& other) noexcept;
58
  explicit constexpr bit_reference(WordRef ref) noexcept;
59
  constexpr bit_reference(WordRef ref, size_type pos);
60

61
  // Assignment
62
 public:
63
  constexpr bit_reference& operator=(const bit_reference& other) const noexcept;
64
  template <class T>
65
  constexpr bit_reference& operator=(const bit_reference<T>& other) const noexcept;
66
  constexpr bit_reference& operator=(const bit_value val) const noexcept;
67
  constexpr bit_reference& assign(word_type val) const noexcept;
68
  constexpr bit_reference& assign(word_type val, size_type pos) const;
69

70
  // Bitwise assignment operators
71
 public:
72
  constexpr bit_reference& operator&=(bit_value other) const noexcept;
73
  constexpr bit_reference& operator|=(bit_value other) const noexcept;
74
  constexpr bit_reference& operator^=(bit_value other) const noexcept;
75

76
  // Conversion
77
 public:
78
  explicit constexpr operator bool() const noexcept;
79

80
  // Access
81
 public:
82
  constexpr bit_pointer<WordType> operator&() const noexcept;
83

84
  // Swap members
85
 public:
86
  template <class T>
87
  void swap(bit_reference<T> other) const;
88
  void swap(bit_value& other) const;
89

90
  // Bit manipulation
91
 public:
92
  constexpr bit_reference& set(bool b) const noexcept;
93
  constexpr bit_reference& set() const noexcept;
94
  constexpr bit_reference& reset() const noexcept;
95
  constexpr bit_reference& flip() const noexcept;
96

97
  // Implementation details: function members
98
 private:
99
  bit_reference() noexcept = default;
100
  explicit constexpr bit_reference(word_type* ptr) noexcept;
101
  constexpr bit_reference(word_type* ptr, size_type pos);
102

103
  // Implementation details: data members
104
 private:
105
  WordRef _ref;
106
  const mask_type _mask;
107
};
108
static_assert(bit_reference_c<bit_reference<uint8_t>>, "bit_reference does not satisfy bit_reference_c concept!");
109

110
// Swap
111
template <class T, class U>
112
void swap(bit_reference<T> lhs, bit_reference<U> rhs) noexcept;
113
template <class T>
114
void swap(bit_reference<T> lhs, bit_value& rhs) noexcept;
115
template <class U>
116
void swap(bit_value& lhs, bit_reference<U> rhs) noexcept;
117

118
// Stream functions
119
template <class CharT, class Traits, class T>
120
std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, bit_reference<T>& x);
121
template <class CharT, class Traits, class T>
122
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, bit_reference<T> x);
123
/* ************************************************************************** */
124

125
// ------------------------ BIT REFERENCE: LIFECYCLE ------------------------ //
126

127
template <class WordRef>
128
constexpr bit_reference<WordRef>::bit_reference(const bit_reference<WordRef>& other) noexcept
3,942✔
129
    : _ref(other._ref), _mask(other._mask) {
1,907,639,238✔
130
}
1,907,639,238✔
131

132
// Explicitly constructs an aligned bit reference
133
template <class WordRef>
134
constexpr bit_reference<WordRef>::bit_reference(WordRef ref) noexcept
135
    : _ref(ref), _mask(1) {
136
}
137

138
// Explicitly constructs an unaligned bit reference
139
template <class WordRef>
140
constexpr bit_reference<WordRef>::bit_reference(WordRef ref, size_type pos)
2,147,483,647✔
141
    : _ref(ref), _mask(static_cast<word_type>(1) << pos) {
4,294,967,294✔
142
  assert(pos < binary_digits<word_type>::value);
4,294,967,294!
143
}
4,294,967,294✔
144
// -------------------------------------------------------------------------- //
145

146

147

148
// ----------------------- BIT REFERENCE: ASSIGNMENT ------------------------ //
149
// Copies a bit reference to the bit reference
150
template <class WordRef>
151
constexpr bit_reference<WordRef>& bit_reference<WordRef>::operator=(const bit_reference& other) const noexcept {
64✔
152
  other ? set() : reset();
64✔
153
  return const_cast<bit_reference<WordRef>&>(*this);
64✔
154
}
32✔
155

156
// Assigns a bit reference to the bit reference
157
template <class WordRef>
158
template <class T>
159
constexpr bit_reference<WordRef>& bit_reference<WordRef>::operator=(const bit_reference<T>& other) const noexcept {
20✔
160
  other ? set() : reset();
20!
161
  return const_cast<bit_reference<WordRef>&>(*this);
20✔
162
}
10✔
163

164
// Assigns a bit value to the bit reference
165
template <class WordRef>
166
constexpr bit_reference<WordRef>& bit_reference<WordRef>::operator=(const bit_value val) const noexcept {
66,526,707✔
167
  val ? set() : reset();
66,526,707✔
168
  return const_cast<bit_reference<WordRef>&>(*this);
66,526,707✔
169
}
33,263,612✔
170

171
// Assigns the aligned bit of a value to the bit reference
172
template <class WordRef>
173
constexpr bit_reference<WordRef>& bit_reference<WordRef>::assign(word_type val) const noexcept {
174
  val & 1 ? set() : reset();
175
  return const_cast<bit_reference<WordRef>&>(*this);
176
}
177

178
// Assigns an unaligned bit of a value to the bit reference
179
template <class WordRef>
180
constexpr bit_reference<WordRef>& bit_reference<WordRef>::assign(word_type val, size_type pos) const {
181
  assert(pos < binary_digits<word_type>::value);
182
  ((val >> pos) & 1) ? set() : reset();
183
  return const_cast<bit_reference<WordRef>&>(*this);
184
}
185
// -------------------------------------------------------------------------- //
186

187

188

189
// -------------- BIT REFERENCE: BITWISE ASSIGNMENT OPERATORS --------------- //
190
// Assigns the value of the referenced bit through a bitwise and operation
191
template <class WordRef>
192
constexpr bit_reference<WordRef>& bit_reference<WordRef>::operator&=(bit_value other) const noexcept {
193
  _ref &= ~(_mask * static_cast<word_type>(!other._value));
194
  return const_cast<bit_reference<WordRef>&>(*this);
195
}
196

197
// Assigns the value of the referenced bit through a bitwise or operation
198
template <class WordRef>
199
constexpr bit_reference<WordRef>& bit_reference<WordRef>::operator|=(bit_value other) const noexcept {
200
  _ref |= _mask * static_cast<word_type>(other._value);
201
  return const_cast<bit_reference<WordRef>&>(*this);
202
}
203

204
// Assigns the value of the referenced bit through a bitwise xor operation
205
template <class WordRef>
206
constexpr bit_reference<WordRef>& bit_reference<WordRef>::operator^=(bit_value other) const noexcept {
207
  _ref ^= _mask * static_cast<word_type>(other._value);
208
  return const_cast<bit_reference<WordRef>&>(*this);
209
}
210
// -------------------------------------------------------------------------- //
211

212

213

214
// ----------------------- BIT REFERENCE: CONVERSION ------------------------ //
215
// Explicitly converts the bit reference to a boolean value
216
template <class WordRef>
217
constexpr bit_reference<WordRef>::operator bool() const noexcept {
4,294,967,294✔
218
  return _ref & _mask;
4,294,967,294✔
219
}
2,147,483,647✔
220
// -------------------------------------------------------------------------- //
221

222

223

224
// ------------------------- BIT REFERENCE: ACCESS -------------------------- //
225
// Gets a bit pointer from the bit reference
226
template <class WordRef>
227
constexpr bit_pointer<std::remove_reference_t<WordRef>> bit_reference<WordRef>::operator&() const noexcept {
30✔
228
  return bit_pointer<WordType>(&_ref, _tzcnt(_mask));
30✔
229
}
15✔
230
// -------------------------------------------------------------------------- //
231

232

233

234
// ---------------------- BIT REFERENCE: SWAP MEMBERS ----------------------- //
235
// Swaps the value of the referenced bit with another bit reference
236
template <class WordRef>
237
template <class T>
238
void bit_reference<WordRef>::swap(bit_reference<T> other) const {
239
  if (other != *this) {
240
    flip();
241
    other.flip();
242
  }
243
}
244

245
// Swaps the value of the referenced bit with a bit value
246
template <class WordRef>
247
void bit_reference<WordRef>::swap(bit_value& other) const {
248
  if (other != *this) {
249
    flip();
250
    other.flip();
251
  }
252
}
253
// -------------------------------------------------------------------------- //
254

255

256

257
// -------------------- BIT REFERENCE: BIT MANIPULATION --------------------- //
258
// Sets the value of the referenced bit to the provided boolean value
259
template <class WordRef>
260
constexpr bit_reference<WordRef>& bit_reference<WordRef>::set(
261
    bool b) const noexcept {
262
  b ? set() : reset();
263
  return const_cast<bit_reference<WordRef>&>(*this);
264
}
265

266
// Sets the value of the referenced bit to 1
267
template <class WordRef>
268
constexpr bit_reference<WordRef>& bit_reference<WordRef>::set() const noexcept {
33,372,833✔
269
  _ref |= _mask;
33,372,833✔
270
  return const_cast<bit_reference<WordRef>&>(*this);
33,372,833✔
271
}
16,673,483✔
272

273
// Resets the value of the referenced bit to 0
274
template <class WordRef>
275
constexpr bit_reference<WordRef>& bit_reference<WordRef>::reset() const noexcept {
33,153,958✔
276
  _ref &= ~_mask;
33,153,958✔
277
  return const_cast<bit_reference<WordRef>&>(*this);
33,153,958✔
278
}
16,590,171✔
279

280
// Flips the value of the referenced bit
281
template <class WordRef>
282
constexpr bit_reference<WordRef>& bit_reference<WordRef>::flip() const noexcept {
283
  _ref ^= _mask;
284
  return const_cast<bit_reference<WordRef>&>(*this);
285
}
286
// -------------------------------------------------------------------------- //
287

288
// -------------------------- BIT REFERENCE: SWAP --------------------------- //
289
// Swaps two bit references
290
template <class T, class U>
291
void swap(bit_reference<T> lhs, bit_reference<U> rhs) noexcept {
292
  if (lhs != rhs) {
293
    lhs.flip();
294
    rhs.flip();
295
  }
296
}
297

298
// Swaps a bit reference and a bit value
299
template <class T>
300
void swap(bit_reference<T> lhs, bit_value& rhs) noexcept {
301
  if (lhs != rhs) {
302
    lhs.flip();
303
    rhs.flip();
304
  }
305
}
306

307
// Swaps a bit value and a bit reference
308
template <class U>
309
void swap(bit_value& lhs, bit_reference<U> rhs) noexcept {
310
  if (lhs != rhs) {
311
    lhs.flip();
312
    rhs.flip();
313
  }
314
}
315
// -------------------------------------------------------------------------- //
316

317

318

319
// -------------------- BIT REFERENCE: STREAM FUNCTIONS --------------------- //
320
// Extracts a bit reference from an input stream
321
template <class CharT, class Traits, class T>
322
std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, bit_reference<T>& x) {
323
  using stream_type = std::basic_istream<CharT, Traits>;
324
  using traits_type = typename stream_type::traits_type;
325
  using ios_base = typename stream_type::ios_base;
326
  constexpr char zero = '0';
327
  constexpr char one = '1';
328
  constexpr typename stream_type::int_type eof = traits_type::eof();
329
  typename ios_base::iostate state = ios_base::goodbit;
330
  typename stream_type::char_type char_value = 0;
331
  typename stream_type::int_type int_value = 0;
332
  typename stream_type::sentry sentry(is);
333
  bool ok = false;
334
  bit_value tmp = x;
335
  if (sentry) {
336
    try {
337
      int_value = is.rdbuf()->sbumpc();
338
      if (traits_type::eq_int_type(int_value, eof)) {
339
        state |= ios_base::eofbit;
340
      } else {
341
        char_value = traits_type::to_char_type(int_value);
342
        if (traits_type::eq(char_value, is.widen(zero))) {
343
          tmp.reset();
344
          ok = true;
345
        } else if (traits_type::eq(char_value, is.widen(one))) {
346
          tmp.set();
347
          ok = true;
348
        } else {
349
          int_value = is.rdbuf()->sputbackc(char_value);
350
          if (traits_type::eq_int_type(int_value, eof)) {
351
            state |= ios_base::failbit;
352
          }
353
        }
354
      }
355
    } catch (...) {
356
      is.setstate(ios_base::badbit);
357
    }
358
  }
359
  if (ok) {
360
    x = tmp;
361
  } else {
362
    state |= ios_base::failbit;
363
  }
364
  state ? is.setstate(state) : void();
365
  return is;
366
}
367

368
// Inserts a bit reference in an output stream
369
template <class CharT, class Traits, class T>
370
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, bit_reference<T> x) {
×
371
  constexpr char zero = '0';
×
372
  constexpr char one = '1';
×
373
  return os << os.widen(x ? one : zero);
×
UNCOV
374
}
375
// -------------------------------------------------------------------------- //
376

377
// -------- BIT REFERENCE: IMPLEMENTATION DETAILS: FUNCTION MEMBERS --------- //
378
// Privately explicitly constructs an aligned bit reference from a pointer
379
template <class WordRef>
380
constexpr bit_reference<WordRef>::bit_reference(word_type* ptr) noexcept
381
    : _ref(*ptr), _mask(1) {
382
}
383

384
// Privately explicitly constructs an unaligned bit reference from a pointer
385
template <class WordRef>
386
constexpr bit_reference<WordRef>::bit_reference(word_type* ptr, size_type pos)
387
    : _ref(*ptr), _mask(static_cast<word_type>(1) << pos) {
388
  assert(pos < binary_digits<word_type>::value);
389
}
390
// -------------------------------------------------------------------------- //
391

392

393

394
// ========================================================================== //
395
} // namespace bit
396
#endif // _BIT_REFERENCE_HPP_INCLUDED
397
// ========================================================================== //
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