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

PeterCDMcLean / BitLib / 16830501887

08 Aug 2025 12:32PM UTC coverage: 76.436% (-0.4%) from 76.797%
16830501887

Pull #29

github

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

3353 of 5056 branches covered (66.32%)

Branch coverage included in aggregate %.

197 of 202 new or added lines in 16 files covered. (97.52%)

17 existing lines in 3 files now uncovered.

2570 of 2693 relevant lines covered (95.43%)

29289657.02 hits per line

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

35.65
/include/bitlib/bit-algorithms/accumulate.hpp
1
// ================================= array_REF =================================== //
2
// Project:     The Experimental Bit Algorithms Library
3
// \file        accumulate.hpp
4
// Description: Implementation of accumulate
5
// Creator:     Vincent Reverdy
6
// Contributor: Peter McLean [2025]
7
// License:     BSD 3-Clause License
8
// ========================================================================== //
9

10
#ifndef _BIT_ACCUMULATE_HPP_INCLUDED
11
#define _BIT_ACCUMULATE_HPP_INCLUDED
12

13
#include "bitlib/bit-iterator/bit_iterator.hpp"
14
#include "bitlib/bit-iterator/bit_details.hpp"
15

16
namespace bit {
17

18
namespace policy {
19
struct AccumulateInitialSubword {
20
  static constexpr bool initial_sub_word = true;
21
};
22

23
struct AccumulateNoInitialSubword {
24
  static constexpr bool initial_sub_word = false;
25
};
26
}  // namespace policy
27

28
template <bool forward, bool initial_sub_word, typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
29
constexpr auto accumulate(
30
    bit_iterator<RandomAccessIt> first,
31
    bit_iterator<RandomAccessIt> last,
32
    T acc,
33
    BinaryOperation binary_op,
34
    BinaryOperationSubword binary_op_subword) {
35
  using word_type = typename bit_iterator<RandomAccessIt>::word_type;
36
  using size_type = typename bit_iterator<RandomAccessIt>::size_type;
37
  constexpr size_type digits = bitsof<word_type>();
38

39
  size_type total_bits_to_op = distance(first, last);
40
  if constexpr (initial_sub_word) {
41
    size_type sub_digits;
42
    if constexpr (forward) {
43
      sub_digits = std::min(digits - first.position(), total_bits_to_op);
44
      if (sub_digits != 0) {
45
        acc = binary_op_subword(std::move(acc), get_masked_word<word_type>(first, sub_digits), sub_digits);
46
        advance(first, digits - first.position());
47
      }
48
    } else {
49
      sub_digits = std::min(last.position(), total_bits_to_op);
50
      if (sub_digits != 0) {
51
        reverse(last, sub_digits);
52
        acc = binary_op_subword(std::move(acc), get_masked_word<word_type>(last, sub_digits), sub_digits);
53
      }
54
    }
55
    total_bits_to_op -= sub_digits;
56
  }
57

58
  const size_type whole_words_to_op = total_bits_to_op / digits;
59
  const size_type remaining_bits_to_op = total_bits_to_op % digits;
60

61
  for (size_t i = 0; i < whole_words_to_op; i ++) {
62
    if constexpr (forward) {
63
      acc = binary_op(std::move(acc), get_word<word_type>(first));
64
      advance(first, digits);
65
    } else {
66
      reverse(last, digits);
67
      acc = binary_op(std::move(acc), get_word<word_type>(last));
68
    }
69
  }
70
  if (remaining_bits_to_op > 0) {
71
    if constexpr (forward) {
72
      acc = binary_op_subword(std::move(acc), get_masked_word<word_type>(first, remaining_bits_to_op), remaining_bits_to_op);
73
    } else {
74
      reverse(last, remaining_bits_to_op);
75
      acc = binary_op_subword(std::move(acc), get_masked_word<word_type>(last, remaining_bits_to_op), remaining_bits_to_op);
76
    }
77
  }
78

79
  return acc;
80
}
81

82
template <bool forward, bool initial_sub_word, typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
83
constexpr auto accumulate_while(
270✔
84
    bit_iterator<RandomAccessIt> first,
85
    bit_iterator<RandomAccessIt> last,
86
    T acc,
87
    BinaryOperation binary_op,
88
    BinaryOperationSubword binary_op_subword) {
270✔
89
  using word_type = typename bit_iterator<RandomAccessIt>::word_type;
270✔
90
  using size_type = typename bit_iterator<RandomAccessIt>::size_type;
270✔
91
  constexpr size_type digits = bitsof<word_type>();
540✔
92

93
  size_type total_bits_to_op = distance(first, last);
540✔
94
  size_type whole_words_to_op = total_bits_to_op / digits;
540✔
95

96
  bool keep_going = true;;
540✔
97
  if constexpr (initial_sub_word) {
270✔
98
    if (whole_words_to_op > 1) {
20!
99
      size_type sub_digits;
2✔
100
      if constexpr (forward) {
101
        sub_digits = std::min(digits - first.position(), total_bits_to_op);
102
        if (sub_digits != 0) {
103
          std::tie(keep_going, acc) = binary_op_subword(std::move(acc), get_masked_word<word_type>(first, sub_digits), sub_digits);
104
          advance(first, digits - first.position());
105
        }
106
      } else {
1✔
107
        sub_digits = std::min(last.position(), total_bits_to_op);
2✔
108
        if (sub_digits != 0) {
2!
NEW
109
          reverse(last, sub_digits);
×
110
          std::tie(keep_going, acc) = binary_op_subword(std::move(acc), get_masked_word<word_type>(first, sub_digits), sub_digits);
×
111
        }
112
      }
1✔
113
      total_bits_to_op -= sub_digits;
2✔
114
      if (!keep_going) {
2!
115
        return acc; // Stop early if the operation indicates to stop
×
116
      }
117
    }
1✔
118
  }
10✔
119

120
  whole_words_to_op = total_bits_to_op / digits;
280✔
121
  const size_type remaining_bits_to_op = total_bits_to_op % digits;
540✔
122

123
  for (size_type i = 0; i < whole_words_to_op; i ++) {
2,392!
124
    if constexpr (forward) {
935✔
125
      std::tie(keep_going, acc) = binary_op(std::move(acc), get_word<word_type>(first));
1,862✔
126
      advance(first, digits);
1,862✔
127
    } else {
931✔
128
      reverse(last, digits);
8✔
129
      std::tie(keep_going, acc) = binary_op(std::move(acc), get_word<word_type>(last));
8✔
130
    }
4✔
131
    if (!keep_going) {
1,870!
132
      return acc; // Stop early if the operation indicates to stop
18✔
133
    }
9✔
134
  }
935✔
135
  if (remaining_bits_to_op > 0) {
522!
136
    if constexpr (forward) {
260✔
137
      std::tie(std::ignore, acc) = binary_op_subword(std::move(acc), get_masked_word<word_type>(first, remaining_bits_to_op), remaining_bits_to_op);
506✔
138
    } else {
253✔
139
      reverse(last, remaining_bits_to_op);
14✔
140
      std::tie(std::ignore, acc) = binary_op_subword(std::move(acc), get_masked_word<word_type>(last, remaining_bits_to_op), remaining_bits_to_op);
14✔
141
    }
7✔
142
  }
260✔
143

144
  return acc;
522✔
145
}
270✔
146

147
// Requires BinaryOperation to have a third but defaulted argument
148
template <typename RandomAccessIt, typename T, typename BinaryOperation>
149
constexpr auto accumulate(
150
    const bit_iterator<RandomAccessIt>& first,
151
    const bit_iterator<RandomAccessIt>& last,
152
    const T& acc,
153
    BinaryOperation binary_op) {
154
  return accumulate<true, true>(first, last, acc, binary_op, binary_op);
155
}
156

157
template <typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
158
constexpr auto accumulate(
159
    const bit_iterator<RandomAccessIt>& first,
160
    const bit_iterator<RandomAccessIt>& last,
161
    const T& acc,
162
    BinaryOperation binary_op,
163
    BinaryOperationSubword binary_op_subword) {
164
  return accumulate<true, true>(first, last, acc, binary_op, binary_op_subword);
165
}
166

167
// Requires BinaryOperation to have a third but defaulted argument
168
template <typename RandomAccessIt, typename T, typename BinaryOperation>
169
constexpr auto accumulate_while(
170
    const bit_iterator<RandomAccessIt>& first,
171
    const bit_iterator<RandomAccessIt>& last,
172
    const T& acc,
173
    BinaryOperation binary_op) {
174
  return accumulate_while<true, true>(first, last, acc, binary_op, binary_op);
175
}
176

177
template <typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
178
constexpr auto accumulate_while(
179
    const bit_iterator<RandomAccessIt>& first,
180
    const bit_iterator<RandomAccessIt>& last,
181
    const T& acc,
182
    BinaryOperation binary_op,
183
    BinaryOperationSubword binary_op_subword) {
184
  return accumulate_while<true, true>(first, last, acc, binary_op, binary_op_subword);
185
}
186

187
// Requires BinaryOperation to have a third but defaulted argument
188
template <typename RandomAccessIt, typename T, typename BinaryOperation>
189
constexpr auto accumulate_backward_while(
190
    const bit_iterator<RandomAccessIt>& first,
191
    const bit_iterator<RandomAccessIt>& last,
192
    const T& acc,
193
    BinaryOperation binary_op) {
194
  return accumulate_while<false, true>(first, last, acc, binary_op, binary_op);
195
}
196

197
template <typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
198
constexpr auto accumulate_backward_while(
10✔
199
    const bit_iterator<RandomAccessIt>& first,
200
    const bit_iterator<RandomAccessIt>& last,
201
    const T& acc,
202
    BinaryOperation binary_op,
203
    BinaryOperationSubword binary_op_subword) {
10✔
204
  return accumulate_while<false, true>(first, last, acc, binary_op, binary_op_subword);
30✔
205
}
10✔
206

207
// Requires BinaryOperation to have a third but defaulted argument
208
template <typename Policy, typename RandomAccessIt, typename T, typename BinaryOperation>
209
constexpr auto accumulate(
210
    Policy,
211
    const bit_iterator<RandomAccessIt>& first,
212
    const bit_iterator<RandomAccessIt>& last,
213
    const T& acc,
214
    BinaryOperation binary_op) {
215
  return accumulate<true, Policy::initial_sub_word>(first, last, acc, binary_op, binary_op);
216
}
217

218
template <typename Policy, typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
219
constexpr auto accumulate(
220
    Policy,
221
    const bit_iterator<RandomAccessIt>& first,
222
    const bit_iterator<RandomAccessIt>& last,
223
    const T& acc,
224
    BinaryOperation binary_op,
225
    BinaryOperationSubword binary_op_subword) {
226
  return accumulate<true, Policy::initial_sub_word>(first, last, acc, binary_op, binary_op_subword);
227
}
228

229
// Requires BinaryOperation to have a third but defaulted argument
230
template <typename Policy, typename RandomAccessIt, typename T, typename BinaryOperation>
231
constexpr auto accumulate_while(
260✔
232
    Policy,
233
    const bit_iterator<RandomAccessIt>& first,
234
    const bit_iterator<RandomAccessIt>& last,
235
    const T& acc,
236
    BinaryOperation binary_op) {
260✔
237
  return accumulate_while<true, Policy::initial_sub_word>(first, last, acc, binary_op, binary_op);
1,040✔
238
}
260✔
239

240
template <typename Policy, typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
241
constexpr auto accumulate_while(
242
    Policy,
243
    const bit_iterator<RandomAccessIt>& first,
244
    const bit_iterator<RandomAccessIt>& last,
245
    const T& acc,
246
    BinaryOperation binary_op,
247
    BinaryOperationSubword binary_op_subword) {
248
  return accumulate_while<true, Policy::initial_sub_word>(first, last, acc, binary_op, binary_op_subword);
249
}
250

251
// Requires BinaryOperation to have a third but defaulted argument
252
template <typename Policy, typename RandomAccessIt, typename T, typename BinaryOperation>
253
constexpr auto accumulate_backward_while(
254
    Policy,
255
    const bit_iterator<RandomAccessIt>& first,
256
    const bit_iterator<RandomAccessIt>& last,
257
    const T& acc,
258
    BinaryOperation binary_op) {
259
  return accumulate_while<false, Policy::initial_sub_word>(first, last, acc, binary_op, binary_op);
260
}
261

262
template <typename Policy, typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
263
constexpr auto accumulate_backward_while(
264
    Policy,
265
    const bit_iterator<RandomAccessIt>& first,
266
    const bit_iterator<RandomAccessIt>& last,
267
    const T& acc,
268
    BinaryOperation binary_op,
269
    BinaryOperationSubword binary_op_subword) {
270
  return accumulate_while<false, Policy::initial_sub_word>(first, last, acc, binary_op, binary_op_subword);
271
}
272

273
} // namespace bit
274

275
#endif  // _BIT_ACCUMULATE_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

© 2026 Coveralls, Inc