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

PeterCDMcLean / BitLib / 16781103655

06 Aug 2025 03:17PM UTC coverage: 74.757%. Remained the same
16781103655

push

github

web-flow
Use upload / download action instead of cache (#28)

* Use upload / download action instead of cache

* Try without single quotes

* Rerun base_ref build if possible

3451 of 5352 branches covered (64.48%)

Branch coverage included in aggregate %.

2555 of 2682 relevant lines covered (95.26%)

29850565.99 hits per line

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

59.05
/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 <bit>
19
#include <type_traits>
20

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

28

29

30
/* ***************************** BIT REFERENCE ****************************** */
31
// Bit reference class definition
32
template <typename WordRef = uintptr_t&>
33
class bit_reference {
34
 public:
35
  using WordType = exact_floor_integral_t<std::remove_cv_t<WordRef>>;
36
  using const_word_type = std::add_const_t<WordType>;
37

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

42
  // Friendship
43
  template <class>
44
  friend class bit_reference;
45

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

52
  // Lifecycle
53
 public:
54
  constexpr bit_reference(const bit_reference& other) noexcept;
55
  explicit constexpr bit_reference(const WordRef& ref) noexcept;
56
  constexpr bit_reference(const WordRef& ref, size_type pos);
57

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

67
  // Bitwise assignment operators
68
 public:
69
  constexpr bit_reference& operator&=(bit_value other) const noexcept;
70
  constexpr bit_reference& operator|=(bit_value other) const noexcept;
71
  constexpr bit_reference& operator^=(bit_value other) const noexcept;
72

73
  // Conversion
74
 public:
75
  explicit constexpr operator bool() const noexcept;
76

77
  // Access
78
 public:
79
  constexpr bit_pointer<const_word_type> operator&() const noexcept;
80
  constexpr bit_pointer<WordType> operator&() noexcept;
81

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

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

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

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

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

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

123
// ------------------------ BIT REFERENCE: LIFECYCLE ------------------------ //
124

125
template <class WordRef>
126
constexpr bit_reference<WordRef>::bit_reference(const bit_reference<WordRef>& other) noexcept
4,362✔
127
    : _ref(other._ref), _mask(other._mask) {
1,907,640,078✔
128
}
1,907,640,078✔
129

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

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

144

145

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

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

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

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

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

185

186

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

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

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

210

211

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

220

221

222
// ------------------------- BIT REFERENCE: ACCESS -------------------------- //
223
// Gets a bit pointer from the bit reference
224
template <class WordRef>
225
constexpr bit_pointer<typename bit_reference<WordRef>::const_word_type> bit_reference<WordRef>::operator&() const noexcept {
226
  return bit_pointer<const_word_type>(&_ref, std::countr_zero(_mask));
227
}
228

229
template <class WordRef>
230
constexpr bit_pointer<typename bit_reference<WordRef>::WordType> bit_reference<WordRef>::operator&() noexcept {
34✔
231
  return bit_pointer<WordType>(&_ref, std::countr_zero(_mask));
34✔
232
}
17✔
233
// -------------------------------------------------------------------------- //
234

235

236

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

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

258

259

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

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

276
// Resets the value of the referenced bit to 0
277
template <class WordRef>
278
constexpr bit_reference<WordRef>& bit_reference<WordRef>::reset() const noexcept {
33,153,772✔
279
  _ref &= ~_mask;
33,153,772✔
280
  return const_cast<bit_reference<WordRef>&>(*this);
33,153,772✔
281
}
16,589,940✔
282

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

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

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

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

320

321

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

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

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

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

395

396

397
// ========================================================================== //
398
} // namespace bit
399
#endif // _BIT_REFERENCE_HPP_INCLUDED
400
// ========================================================================== //
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