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

PeterCDMcLean / BitLib / 14949319596

10 May 2025 09:32PM UTC coverage: 96.898% (-0.1%) from 97.036%
14949319596

Pull #8

github

web-flow
Merge 153e605bc into a837637fd
Pull Request #8: Common bit array base

171 of 179 new or added lines in 5 files covered. (95.53%)

1 existing line in 1 file now uncovered.

1312 of 1354 relevant lines covered (96.9%)

16164538.6 hits per line

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

94.74
/include/bitlib/bit-containers/bit_array_ref.hpp
1
// ================================= BIT_ARRAY_REF =================================== //
2
// Project:     The Experimental Bit Algorithms Library
3
// \file        bit_array_ref.hpp
4
// Description: Implementation of bit_array_ref
5
// Creator:     Vincent Reverdy
6
// Contributor: Peter McLean [2025]
7
// License:     BSD 3-Clause License
8
// ========================================================================== //
9
#ifndef _BIT_ARRAY_REF_HPP_INCLUDED
10
#define _BIT_ARRAY_REF_HPP_INCLUDED
11

12
#include <algorithm>
13
#include <cstddef>
14
#include <cstring>  // memcpy
15
#include <initializer_list>
16
#include <memory>
17
#include <new>
18
#include <span>  // std::dynamic_extent
19
#include <stdexcept>
20

21
#include "bitlib/bit-algorithms/bit_algorithm.hpp"
22
#include "bitlib/bit-containers/bit_array_base.hpp"
23
#include "bitlib/bit-containers/bit_bitsof.hpp"
24
#include "bitlib/bit-containers/bit_span.hpp"
25
#include "bitlib/bit-iterator/bit.hpp"
26

27
namespace bit {
28

29
/**
30
 * @brief A non-owning reference to a bit array
31
 *
32
 * Similar to bit_array_dynamic_extent but does not allocate or deallocate memory.
33
 * The pointer and size are const class members and cannot be re-bound.
34
 * Assignment operations always copy content and can't rebind the pointer/size.
35
 *
36
 * @tparam T The value type (typically bit_value)
37
 * @tparam W The word type used for storage
38
 */
39
template <typename T = bit_value, typename W = std::uint8_t>
40
class bit_array_ref
41
    : public bit_array_base<bit_array_ref<T, W>, T, W, bit_iterator<W*>, bit_iterator<const W*>> {
42
 public:
43
  using base = bit_array_base<bit_array_ref<T, W>, T, W, bit_iterator<W*>, bit_iterator<const W*>>;
44
  using typename base::const_iterator;
45
  using typename base::const_pointer;
46
  using typename base::const_reference;
47
  using typename base::difference_type;
48
  using typename base::iterator;
49
  using typename base::pointer;
50
  using typename base::reference;
51
  using typename base::size_type;
52
  using typename base::value_type;
53
  using typename base::word_type;
54

55
 private:
56
  const bit_pointer<word_type> m_storage;
57
  const size_type m_size;
58

59
 protected:
60
  static constexpr size_type Words(size_type N) {
61
    return (N * bitsof<value_type>() + bitsof<word_type>() - 1) / bitsof<word_type>();
62
  }
63

64
 public:
65
  // Constructors
66
  bit_array_ref() = delete;
67

68
  /**
69
   * @brief Constructs a non-owning reference to a bit array
70
   *
71
   * @param storage Pointer to the storage
72
   * @param size Number of bits
73
   */
74
  constexpr bit_array_ref(word_type* storage, size_type size)
9✔
75
      : m_storage(storage),
9✔
76
        m_size(size) {
9✔
77
  }
9✔
78

79
  /**
80
   * @brief Constructs a non-owning reference to a bit array using a bit_pointer
81
   *
82
   * @param storage bit_pointer to the storage
83
   * @param size Number of bits
84
   */
85
  constexpr bit_array_ref(bit_pointer<word_type> storage, size_type size)
8✔
86
      : m_storage(storage),
8✔
87
        m_size(size) {
8✔
88
  }
8✔
89

90
  /**
91
   * @brief Copy constructor
92
   */
93
  constexpr bit_array_ref(const bit_array_ref& other) = default;
94

95
  /**
96
   * @brief Move constructor
97
   */
98
  constexpr bit_array_ref(bit_array_ref&& other) = default;
99

100
  /**
101
   * @brief Assignment operator - copies content but doesn't rebind
102
   */
103
  constexpr bit_array_ref& operator=(const bit_array_ref& other) {
1✔
104
    if (this != &other) {
1✔
105
      if (m_size != other.m_size) {
1✔
NEW
106
        throw std::invalid_argument("Cannot assign from bit_array_ref of different size");
×
107
      }
108
      std::copy(other.begin(), other.end(), this->begin());
1✔
109
    }
110
    return *this;
2✔
111
  }
112

113
  /**
114
   * @brief Move assignment operator - copies content but doesn't rebind
115
   */
116
  constexpr bit_array_ref& operator=(bit_array_ref&& other) {
117
    if (this != &other) {
118
      if (m_size != other.m_size) {
119
        throw std::invalid_argument("Cannot assign from bit_array_ref of different size");
120
      }
121
      std::copy(other.begin(), other.end(), this->begin());
122
    }
123
    return *this;
124
  }
125

126
  /**
127
   * @brief No destructor needed as we don't own the memory
128
   */
129
  ~bit_array_ref() = default;
130

131
  /*
132
   * Element Access
133
   */
134
  constexpr word_type* data() noexcept {
135
    throw new std::invalid_argument("Not valid for this class. may be unaligned");
136
    return const_cast<word_type*>(m_storage.base());
137
  }
138

139
  constexpr const word_type* data() const noexcept {
140
    throw new std::invalid_argument("Not valid for this class. may be unaligned");
141
    return m_storage.base();
142
  }
143

144
  /*
145
   * Iterators
146
   */
147
  constexpr iterator begin() noexcept {
119✔
148
    return iterator(m_storage);
119✔
149
  }
150

151
  constexpr iterator end() noexcept {
6✔
152
    return begin() + size();
6✔
153
  }
154

155
  constexpr const_iterator begin() const noexcept {
12✔
156
    return const_iterator(m_storage);
12✔
157
  }
158

159
  constexpr const_iterator end() const noexcept {
3✔
160
    return const_iterator(begin() + size());
3✔
161
  }
162

163
  constexpr const_iterator cbegin() const noexcept {
164
    return const_iterator(begin());
165
  }
166

167
  constexpr const_iterator cend() const noexcept {
168
    return const_iterator(end());
169
  }
170

171
  /*
172
   * Capacity
173
   */
174
  constexpr size_type size() const noexcept {
91✔
175
    return m_size;
91✔
176
  }
177

178
  /*
179
   * Operations
180
   */
181
  constexpr void swap(bit_array_ref& other) noexcept {
1✔
182
    if (m_size != other.m_size) {
1✔
NEW
183
      throw std::invalid_argument("Cannot swap bit_array_ref of different sizes");
×
184
    }
185
    swap_ranges(begin(), end(), other.begin());
1✔
186
  }
1✔
187

188
  /**
189
   * @brief Slice operations - returns a bit_array_ref
190
   */
191
  constexpr auto operator()(size_type offset, size_type right) const noexcept {
192
    return bit_array_ref<T, W>(bit_pointer<word_type>(const_cast<word_type*>(m_storage.base()), m_storage.position()) + offset, right - offset);
193
  }
194

195
  constexpr auto operator()(size_type offset, size_type right) noexcept {
1✔
196
    return bit_array_ref<T, W>(bit_pointer<word_type>(m_storage.base(), m_storage.position()) + offset, right - offset);
1✔
197
  }
198

199
  /**
200
   * @brief Explicit conversion to integral types
201
   */
202
  template <std::integral U>
203
  explicit constexpr operator U() const noexcept {
2✔
204
    assert(size() <= bitsof<U>());
2✔
205
    U integral;
2✔
206
    bit_array_ref<> integral_ref(reinterpret_cast<uint8_t*>(&integral), bitsof<U>());
2✔
207
    copy(begin(), begin() + bitsof<U>(), integral_ref.begin());
2✔
208
    if constexpr (std::is_signed_v<U>) {
209
      fill(integral_ref.begin() + size(), integral_ref.end(), integral_ref[bitsof<U>() - 1]);
210
    } else {
211
      fill(integral_ref.begin() + size(), integral_ref.end(), bit0);
2✔
212
    }
213
    return integral;
2✔
214
  }
215
};
216

217
static_assert(bit_range<bit_array_ref<>>, "bit_array_ref<> does not satisfy bit_range concept!");
218
static_assert(bit_sized_range<bit_array_ref<>>, "bit_array_ref<> does not satisfy bit_sized_range concept!");
219
#ifdef CONTIGUOUS_RANGE
220
static_assert(bit_contiguous_range<bit_array_ref<>>, "bit_array_ref<> does not satisfy bit_contiguous_range concept!");
221
static_assert(bit_contiguous_sized_range<bit_array_ref<>>, "bit_array_ref<> does not satisfy bit_contiguous_sized_range concept!");
222
#endif
223

224
// ========================================================================== //
225
}  // namespace bit
226

227
#endif  // _BIT_ARRAY_REF_HPP_INCLUDED
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