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

PeterCDMcLean / BitLib / 14987214130

13 May 2025 03:02AM UTC coverage: 49.385% (-46.9%) from 96.333%
14987214130

Pull #7

github

web-flow
Merge aad228108 into 09dd4e61e
Pull Request #7: Add github workflow targets for warnings

5155 of 10638 branches covered (48.46%)

Branch coverage included in aggregate %.

39 of 70 new or added lines in 1 file covered. (55.71%)

128 existing lines in 10 files now uncovered.

5325 of 10583 relevant lines covered (50.32%)

3238286.52 hits per line

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

72.22
/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 <class WordType = uint8_t>
32
class bit_reference {
33
  // Assertions
34
  static_assert(binary_digits<WordType>::value, "");
35

36
  // Friendship
37
  template <class>
38
  friend class bit_reference;
39

40
  // Types
41
 public:
42
  using word_type = WordType;
43
  using size_type = std::size_t;
44
  using mask_type = std::make_unsigned_t<std::remove_cv_t<word_type>>;
45

46
  // Lifecycle
47
 public:
48
  template <class T>
49
  requires (std::is_const_v<WordType> == std::is_const_v<T>)
50
  constexpr bit_reference(const bit_reference<T>& other) noexcept;
51
  constexpr bit_reference(const bit_reference& other) noexcept;
52
  explicit constexpr bit_reference(word_type& ref) noexcept;
53
  constexpr bit_reference(word_type& ref, size_type pos);
54

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

64
  // Bitwise assignment operators
65
 public:
66
  constexpr bit_reference& operator&=(bit_value other) const noexcept;
67
  constexpr bit_reference& operator|=(bit_value other) const noexcept;
68
  constexpr bit_reference& operator^=(bit_value other) const noexcept;
69

70
  // Conversion
71
 public:
72
  explicit constexpr operator bool() const noexcept;
73

74
  // Access
75
 public:
76
  constexpr bit_pointer<WordType> operator&() const noexcept;
77

78
  // Swap members
79
 public:
80
  template <class T>
81
  void swap(bit_reference<T> other) const;
82
  void swap(bit_value& other) const;
83

84
  // Bit manipulation
85
 public:
86
  constexpr bit_reference& set(bool b) const noexcept;
87
  constexpr bit_reference& set() const noexcept;
88
  constexpr bit_reference& reset() const noexcept;
89
  constexpr bit_reference& flip() const noexcept;
90

91
  // Implementation details: function members
92
 private:
93
  bit_reference() noexcept = default;
94
  explicit constexpr bit_reference(word_type* ptr) noexcept;
95
  constexpr bit_reference(word_type* ptr, size_type pos);
96

97
  // Implementation details: data members
98
 private:
99
  word_type& _ref;
100
  const mask_type _mask;
101
};
102
static_assert(bit_reference_c<bit_reference<uint8_t>>, "bit_reference does not satisfy bit_reference_c concept!");
103

104
// Swap
105
template <class T, class U>
106
void swap(bit_reference<T> lhs, bit_reference<U> rhs) noexcept;
107
template <class T>
108
void swap(bit_reference<T> lhs, bit_value& rhs) noexcept;
109
template <class U>
110
void swap(bit_value& lhs, bit_reference<U> rhs) noexcept;
111

112
// Stream functions
113
template <class CharT, class Traits, class T>
114
std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, bit_reference<T>& x);
115
template <class CharT, class Traits, class T>
116
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, bit_reference<T> x);
117
/* ************************************************************************** */
118

119

120

121
// ------------------------ BIT REFERENCE: LIFECYCLE ------------------------ //
122
// Implicitly constructs a bit reference from another bit reference
123
template <class WordType>
124
template <class T>
125
requires (std::is_const_v<WordType> == std::is_const_v<T>)
126
constexpr bit_reference<WordType>::bit_reference(const bit_reference<T>& other) noexcept
127
    : _ref(other._ref), _mask(other._mask) {
128
}
129

130
template <class WordType>
131
constexpr bit_reference<WordType>::bit_reference(const bit_reference<WordType>& other) noexcept
132
    : _ref(other._ref), _mask(other._mask) {
829,564,272✔
133
}
829,564,272✔
134

135
// Explicitly constructs an aligned bit reference
136
template <class WordType>
137
constexpr bit_reference<WordType>::bit_reference(word_type& ref) noexcept
138
    : _ref(ref), _mask(1) {
139
}
140

141
// Explicitly constructs an unaligned bit reference
142
template <class WordType>
143
constexpr bit_reference<WordType>::bit_reference(word_type& ref, size_type pos)
144
    : _ref(ref), _mask(static_cast<word_type>(1) << pos) {
1,078,978,178✔
145
  assert(pos < binary_digits<word_type>::value);
1,078,978,178!
146
}
1,078,978,178✔
147
// -------------------------------------------------------------------------- //
148

149

150

151
// ----------------------- BIT REFERENCE: ASSIGNMENT ------------------------ //
152
// Copies a bit reference to the bit reference
153
template <class WordType>
154
constexpr bit_reference<WordType>& bit_reference<WordType>::operator=(const bit_reference& other) const noexcept {
53✔
155
  other ? set() : reset();
53✔
156
  return const_cast<bit_reference<WordType>&>(*this);
53✔
157
}
53✔
158

159
// Assigns a bit reference to the bit reference
160
template <class WordType>
161
template <class T>
162
constexpr bit_reference<WordType>& bit_reference<WordType>::operator=(const bit_reference<T>& other) const noexcept {
200✔
163
  other ? set() : reset();
200✔
164
  return const_cast<bit_reference<WordType>&>(*this);
200✔
165
}
200✔
166

167
// Assigns a bit value to the bit reference
168
template <class WordType>
169
constexpr bit_reference<WordType>& bit_reference<WordType>::operator=(const bit_value val) const noexcept {
16,632,371✔
170
  val ? set() : reset();
16,632,371✔
171
  return const_cast<bit_reference<WordType>&>(*this);
16,632,371✔
172
}
16,632,371✔
173

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

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

190

191

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

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

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

215

216

217
// ----------------------- BIT REFERENCE: CONVERSION ------------------------ //
218
// Explicitly converts the bit reference to a boolean value
219
template <class WordType>
220
constexpr bit_reference<WordType>::operator bool() const noexcept {
1,062,345,540✔
221
  return _ref & _mask;
1,062,345,540✔
222
}
1,062,345,540✔
223
// -------------------------------------------------------------------------- //
224

225

226

227
// ------------------------- BIT REFERENCE: ACCESS -------------------------- //
228
// Gets a bit pointer from the bit reference
229
template <class WordType>
230
constexpr bit_pointer<WordType> bit_reference<WordType>::operator&() const noexcept {
14✔
231
  return bit_pointer<WordType>(&_ref, _tzcnt(_mask));
14✔
232
}
14✔
233
// -------------------------------------------------------------------------- //
234

235

236

237
// ---------------------- BIT REFERENCE: SWAP MEMBERS ----------------------- //
238
// Swaps the value of the referenced bit with another bit reference
239
template <class WordType>
240
template <class T>
241
void bit_reference<WordType>::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 WordType>
250
void bit_reference<WordType>::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 WordType>
263
constexpr bit_reference<WordType>& bit_reference<WordType>::set(
264
    bool b) const noexcept {
265
  b ? set() : reset();
266
  return const_cast<bit_reference<WordType>&>(*this);
267
}
268

269
// Sets the value of the referenced bit to 1
270
template <class WordType>
271
constexpr bit_reference<WordType>& bit_reference<WordType>::set() const noexcept {
8,338,767✔
272
  _ref |= _mask;
8,338,767✔
273
  return const_cast<bit_reference<WordType>&>(*this);
8,338,767✔
274
}
8,338,767✔
275

276
// Resets the value of the referenced bit to 0
277
template <class WordType>
278
constexpr bit_reference<WordType>& bit_reference<WordType>::reset() const noexcept {
8,293,857✔
279
  _ref &= ~_mask;
8,293,857✔
280
  return const_cast<bit_reference<WordType>&>(*this);
8,293,857✔
281
}
8,293,857✔
282

283
// Flips the value of the referenced bit
284
template <class WordType>
285
constexpr bit_reference<WordType>& bit_reference<WordType>::flip() const noexcept {
286
  _ref ^= _mask;
287
  return const_cast<bit_reference<WordType>&>(*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);
×
UNCOV
377
}
×
378
// -------------------------------------------------------------------------- //
379

380
// -------- BIT REFERENCE: IMPLEMENTATION DETAILS: FUNCTION MEMBERS --------- //
381
// Privately explicitly constructs an aligned bit reference from a pointer
382
template <class WordType>
383
constexpr bit_reference<WordType>::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 WordType>
389
constexpr bit_reference<WordType>::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