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

PeterCDMcLean / BitLib / 16830646477

08 Aug 2025 12:40PM UTC coverage: 76.518% (-0.3%) from 76.797%
16830646477

Pull #29

github

web-flow
Merge e5718e6eb into 4adca69e9
Pull Request #29: Explicitly cast inside _mask

3353 of 5048 branches covered (66.42%)

Branch coverage included in aggregate %.

199 of 204 new or added lines in 16 files covered. (97.55%)

17 existing lines in 3 files now uncovered.

2571 of 2694 relevant lines covered (95.43%)

29278116.18 hits per line

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

88.06
/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 <initializer_list>
15
#include <memory>
16
#include <span>  // std::dynamic_extent
17
#include <stdexcept>
18

19
#include "bitlib/bit-algorithms/bit_algorithm.hpp"
20
#include "bitlib/bit-containers/bit_array_base.hpp"
21
#include "bitlib/bit-containers/bit_bitsof.hpp"
22
#include "bitlib/bit-containers/bit_policy.hpp"
23
#include "bitlib/bit-iterator/bit.hpp"
24
#include "bitlib/bit_concepts.hpp"
25

26
namespace bit {
27

28
template <typename T = bit_value, size_t N = std::dynamic_extent, typename W = std::uintptr_t, typename Policy = policy::typical<std::remove_cvref_t<W>>>
29
class array_ref;
30

31
template <size_t N = std::dynamic_extent, typename W = std::uintptr_t, typename Policy = policy::typical<std::remove_cvref_t<W>>>
32
using bit_array_ref = array_ref<bit_value, N, W, Policy>;
33

34
namespace detail {
35
template <typename word_type>
36
struct array_ref_iterator_types {
37
  using iterator = bit_iterator<word_type*>;
38
  using const_iterator = bit_iterator<const word_type*>;
39
};
40
}  // namespace detail
41
/**
42
 * @brief A non-owning reference to a bit array
43
 *
44
 * Similar to array_dynamic_extent but does not allocate or deallocate memory.
45
 * The pointer and size are const class members and cannot be re-bound.
46
 * Assignment operations always copy content and can't rebind the pointer/size.
47
 *
48
 * @tparam T The value type (typically bit_value)
49
 * @tparam W The word type used for storage
50
 */
51
template <typename T, size_t N, typename W, typename Policy>
52
class array_ref
53
    : public array_base<array_ref<T, N, W, Policy>, T, N, W, false, Policy, detail::array_ref_iterator_types<W>> {
54
 public:
55
  using base = array_base<array_ref<T, N, W, Policy>, T, N, W, false, Policy, detail::array_ref_iterator_types<W>>;
56
  using base::end;
57
  using base::size;
58
  using typename base::const_iterator;
59
  using typename base::const_pointer;
60
  using typename base::const_reference;
61
  using typename base::difference_type;
62
  using typename base::iterator;
63
  using typename base::pointer;
64
  using typename base::reference;
65
  using typename base::size_type;
66
  using typename base::value_type;
67
  using typename base::word_type;
68

69
 private:
70
  const bit_pointer<word_type> m_storage;
71

72
 public:
73
  // Constructors
74
  array_ref() = delete;
75

76
  /**
77
   * @brief Constructs a non-owning reference to a bit array
78
   *
79
   * @param storage Pointer to the storage
80
   * @param extent Number of bits
81
   */
82
  constexpr array_ref(word_type* storage, size_type extent)
7✔
83
    requires(N == std::dynamic_extent)
84
      : base(extent), m_storage(storage) {
14✔
85
  }
14✔
86
  constexpr array_ref(word_type* storage)
87
    requires(N != std::dynamic_extent)
88
      : base(), m_storage(storage) {
89
  }
90

91
  /**
92
   * @brief Constructs a non-owning reference to a bit array using a bit_pointer
93
   *
94
   * @param storage bit_pointer to the storage
95
   * @param extent Number of bits
96
   */
97
  constexpr array_ref(bit_pointer<word_type> storage, size_type extent)
788,308✔
98
    requires(N == std::dynamic_extent)
99
      : base(extent), m_storage(storage) {
1,576,616✔
100
  }
1,576,616✔
101
  constexpr array_ref(bit_pointer<word_type> storage)
42✔
102
    requires(N != std::dynamic_extent)
103
      : base(), m_storage(storage) {
84✔
104
  }
84✔
105

106
  /**
107
   * @brief Constructs a non-owning reference to a bit array from a bit_sized_range
108
   *
109
   * @param other bit_sized_range
110
   */
111
  constexpr array_ref(bit_range auto& other, size_type extent)
2✔
112
    requires(N == std::dynamic_extent)
113
      : base(extent), m_storage(&(*other.begin())) {
4✔
114
    assert(extent <= static_cast<size_type>(other.end() - other.begin()));
4!
115
  }
4✔
116
  constexpr array_ref(bit_range auto& other)
117
    requires(N != std::dynamic_extent)
118
      : base(), m_storage(&(*other.begin())) {
119
    assert(N <= static_cast<size_type>(other.end() - other.begin()));
120
  }
121

122
  /**
123
   * @brief Constructs a non-owning reference to a bit array from a bit_sized_range
124
   *
125
   * @param other bit_sized_range
126
   */
127
  constexpr array_ref(const bit_range auto& other, size_type extent)
128
    requires((N == std::dynamic_extent) && std::is_const_v<W>)
129
      : base(extent), m_storage(&(*other.begin())) {
130
    assert(extent <= (other.end() - other.begin()));
131
  }
132
  constexpr array_ref(const bit_range auto& other)
133
    requires((N != std::dynamic_extent) && std::is_const_v<W>)
134
      : base(), m_storage(&(*other.begin())) {
135
    assert(N <= (other.end() - other.begin()));
136
  }
137

138
  /**
139
   * @brief Copy constructor
140
   */
141
  constexpr array_ref(const array_ref& other) = default;
142

143
  /**
144
   * @brief Move constructor
145
   */
146
  constexpr array_ref(array_ref&& other) = default;
147

148
  /**
149
   * @brief Range Assignment operator - copies content but doesn't rebind
150
   */
151
  constexpr array_ref& operator=(const bit_sized_range auto& other) {
1,824✔
152
    if (size() != other.size()) {
1,824!
153
      throw std::invalid_argument("Cannot assign from array_ref of different size");
2✔
154
    }
1✔
155
    ::bit::copy(other.begin(), other.end(), this->begin());
1,822✔
156
    return *this;
2,733✔
157
  }
912✔
158

159
  /**
160
   * @brief Copy Assignment operator - copies content but doesn't rebind
161
   */
162
  constexpr array_ref& operator=(const array_ref& other) {
6✔
163
    if (this != &other) {
6!
164
      if (size() != other.size()) {
6✔
165
        throw std::invalid_argument("Cannot assign from array_ref of different size");
2✔
166
      }
1✔
167
      ::bit::copy(other.begin(), other.end(), this->begin());
4✔
168
    }
2✔
169
    return *this;
6✔
170
  }
3✔
171

172
  /**
173
   * @brief Move assignment operator - copies content but doesn't rebind
174
   */
175
  constexpr array_ref& operator=(array_ref&& other) {
524,288✔
176
    if (this != &other) {
524,288!
177
      if (size() != other.size()) {
524,288!
UNCOV
178
        throw std::invalid_argument("Cannot assign from array_ref of different size");
×
179
      }
180
      ::bit::copy(other.begin(), other.end(), this->begin());
524,288✔
181
    }
262,144✔
182
    return *this;
786,432✔
183
  }
262,144✔
184

185
  /**
186
   * @brief No destructor needed as we don't own the memory
187
   */
188
  ~array_ref() = default;
189

190
  /*
191
   * Iterators
192
   */
193
  constexpr iterator begin() noexcept {
2,627,976✔
194
    return iterator(m_storage);
2,627,976✔
195
  }
1,313,988✔
196

197
  constexpr const_iterator begin() const noexcept {
38✔
198
    return const_iterator(m_storage);
38✔
199
  }
19✔
200

201
  /*
202
   * Operations
203
   */
204
  constexpr void swap(array_ref& other) {
4✔
205
    if (size() != other.size()) {
4✔
206
      throw std::invalid_argument("Cannot swap array_ref of different sizes");
2✔
207
    }
1✔
208
    swap_ranges(begin(), end(), other.begin());
2✔
209
  }
2✔
210
};
211

212
static_assert(bit_range<array_ref<>>, "array_ref<> does not satisfy bit_range concept!");
213
static_assert(bit_sized_range<array_ref<>>, "array_ref<> does not satisfy bit_sized_range concept!");
214
#ifdef CONTIGUOUS_RANGE
215
static_assert(bit_contiguous_range<array_ref<>>, "array_ref<> does not satisfy bit_contiguous_range concept!");
216
static_assert(bit_contiguous_sized_range<array_ref<>>, "array_ref<> does not satisfy bit_contiguous_sized_range concept!");
217
#endif
218

219
// ========================================================================== //
220
}  // namespace bit
221

222
#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