• 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

96.3
/include/bitlib/bit-containers/bit_array_base.hpp
1
// ================================= BIT_ARRAY_BASE =================================== //
2
// Project:     The Experimental Bit Algorithms Library
3
// \file        bit_array_base.hpp
4
// Description: Base implementation for bit_array variants
5
// Creator:     Vincent Reverdy
6
// Contributor: Peter McLean [2025]
7
// License:     BSD 3-Clause License
8
// ========================================================================== //
9
#ifndef _BIT_ARRAY_BASE_HPP_INCLUDED
10
#define _BIT_ARRAY_BASE_HPP_INCLUDED
11
// ========================================================================== //
12

13
// ================================ PREAMBLE ================================ //
14
// C++ standard library
15
#include <algorithm>
16
#include <bit>
17
#include <cmath>
18
#include <cstring>  // memcpy
19
#include <span>
20
#include <string>
21
#include <type_traits>
22
#include <vector>
23

24
// Project sources
25
#include "bitlib/bit-algorithms/bit_algorithm.hpp"
26
#include "bitlib/bit-containers/bit_bitsof.hpp"
27
#include "bitlib/bit-containers/bit_span.hpp"
28
#include "bitlib/bit-iterator/bit.hpp"
29

30
namespace bit {
31

32
template <typename T, typename W>
33
class bit_array_ref;
34
// ========================================================================== //
35

36
/**
37
 * @brief Base class template for bit_array implementations
38
 *
39
 * This is a CRTP (Curiously Recurring Template Pattern) base class that provides
40
 * common functionality for bit_array variants.
41
 *
42
 * @tparam Derived The derived class (CRTP pattern)
43
 * @tparam T The value type (typically bit_value)
44
 * @tparam W The word type used for storage
45
 * @tparam It The iterator type for the derived class
46
 * @tparam CIt The const_iterator type for the derived class
47
 */
48
template <typename Derived, typename T, typename W, typename It, typename CIt>
49
class bit_array_base {
50
 public:
51
  using word_type = W;
52
  using value_type = T;
53
  using size_type = std::size_t;
54
  using difference_type = std::ptrdiff_t;
55
  using reference = typename std::conditional<std::is_same_v<T, bit_value>, bit_reference<word_type>, T&>::type;
56
  using const_reference = typename std::conditional<std::is_same_v<T, bit_value>, const bit_reference<const word_type>, const T&>::type;
57
  using pointer = typename std::conditional<std::is_same_v<T, bit_value>, bit_pointer<word_type>, T&>::type;
58
  using const_pointer = const pointer;
59
  using iterator = It;
60
  using const_iterator = CIt;
61

62
  // Element access
63
  constexpr reference operator[](size_type pos) {
918✔
64
    return derived().begin()[pos];
1,834✔
65
  }
66

67
  constexpr const_reference operator[](size_type pos) const {
68
    return derived().begin()[pos];
69
  }
70

71
  constexpr reference at(size_type pos) {
6✔
72
    if (pos < derived().size()) {
6✔
73
      return derived().begin()[pos];
10✔
74
    } else {
75
      throw std::out_of_range("Position is out of range");
1✔
76
    }
77
  }
78

79
  constexpr const_reference at(size_type pos) const {
80
    if (pos < derived().size()) {
81
      return derived().begin()[pos];
82
    } else {
83
      throw std::out_of_range("Position is out of range");
84
    }
85
  }
86

87
  constexpr reference front() {
3✔
88
    return derived().begin()[0];
6✔
89
  }
90

91
  constexpr const_reference front() const {
92
    return derived().begin()[0];
93
  }
94

95
  constexpr reference back() {
3✔
96
    return derived().begin()[derived().size() - 1];
6✔
97
  }
98

99
  constexpr const_reference back() const {
100
    return derived().begin()[derived().size() - 1];
101
  }
102

103
  // Capacity
104
  constexpr bool empty() const noexcept {
4✔
105
    return 0 == derived().size();
4✔
106
  }
107

108
  constexpr size_type max_size() const noexcept {
1✔
109
    return derived().size();
1✔
110
  }
111

112
  // String representation
113
  constexpr std::string debug_string() const {
114
    return debug_string(derived().begin(), derived().end());
115
  }
116

117
  constexpr std::string debug_string(const_iterator first, const_iterator last) const {
118
    std::string ret = "";
119
    auto position = 0;
120
    for (auto it = first; it != last; ++it) {
121
      if (position % bitsof<word_type>() == 0 && position != 0) {
122
        ret += " ";
123
      } else if (position % 8 == 0 && position != 0) {
124
        ret += '.';
125
      }
126
      ret += *it == bit1 ? '1' : '0';
127
      ++position;
128
    }
129
    return ret;
130
  }
131

132
  // Comparison
133
  constexpr bool operator==(const Derived& other) const noexcept {
10✔
134
    if (derived().size() != other.size()) {
10✔
NEW
135
      return false;
×
136
    }
137
    return equal(derived().begin(), derived().end(), other.begin());
10✔
138
  }
139

140
  // Slice operations
141
  constexpr auto operator()(size_type offset, size_type right) const noexcept {
142
    return bit_array_ref<bit_value, const word_type>(&this->at(offset), right - offset);
143
  }
144

145
  constexpr auto operator()(size_type offset, size_type right) noexcept {
3✔
146
    return bit_array_ref<bit_value, word_type>(&this->at(offset), right - offset);
3✔
147
  }
148

149
  // Common operations
150
  constexpr void fill(value_type bit_val) noexcept {
33✔
151
    std::fill(derived().begin(), derived().end(), bit_val);
33✔
152
  }
33✔
153

154
  // Common integral conversion operator
155
  template <std::integral U>
156
  explicit constexpr operator U() const noexcept {
157
    U result{};
158
    // Calculate bytes to copy (minimum of integral type size or array's storage size)
159
    std::memcpy(&result, derived().data(), std::min(sizeof(U), ((derived().size() + bitsof<word_type>() - 1) / bitsof<word_type>()) * sizeof(word_type)));
160

161
    if constexpr (std::is_signed_v<U>) {
162
      if (derived().size() > 0 && derived().begin()[derived().size() - 1]) {
163
        for (size_type i = derived().size(); i < bitsof<U>(); ++i) {
164
          result |= (static_cast<U>(1) << i);
165
        }
166
      } else {
167
        for (size_type i = derived().size(); i < bitsof<U>(); ++i) {
168
          result &= ~(static_cast<U>(1) << i);
169
        }
170
      }
171
    }
172
    return result;
173
  }
174

175
 protected:
176
  constexpr Derived& derived() noexcept {
1,004✔
177
    return static_cast<Derived&>(*this);
1,004✔
178
  }
179

180
  constexpr const Derived& derived() const noexcept {
35✔
181
    return static_cast<const Derived&>(*this);
35✔
182
  }
183
};
184

185
}  // namespace bit
186

187
#endif  // _BIT_ARRAY_BASE_HPP_INCLUDED
188
        // ========================================================================== //
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