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

PeterCDMcLean / BitLib / 15658468082

15 Jun 2025 02:19AM UTC coverage: 54.19% (+0.7%) from 53.519%
15658468082

Pull #17

github

web-flow
Merge 9f7c4d06e into 0f0b787a1
Pull Request #17: Truncation policy

10212 of 18780 branches covered (54.38%)

Branch coverage included in aggregate %.

179 of 225 new or added lines in 12 files covered. (79.56%)

214 existing lines in 11 files now uncovered.

6037 of 11205 relevant lines covered (53.88%)

7751643.37 hits per line

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

55.42
/include/bitlib/bit-algorithms/accumulate.hpp
1
// ================================= BIT_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
template <bool forward, bool initial_sub_word, typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
19
constexpr auto accumulate(
4✔
20
    bit_iterator<RandomAccessIt> first,
21
    bit_iterator<RandomAccessIt> last,
22
    T acc,
23
    BinaryOperation binary_op,
24
    BinaryOperationSubword binary_op_subword) {
4✔
25
  using word_type = typename bit_iterator<RandomAccessIt>::word_type;
4✔
26
  using size_type = typename bit_iterator<RandomAccessIt>::size_type;
4✔
27
  constexpr size_type digits = bitsof<word_type>();
8✔
28

29

30
  size_type total_bits_to_op = distance(first, last);
8✔
31
  bool keep_going = true;;
8✔
32
  if constexpr (initial_sub_word) {
4✔
33
    size_type sub_digits;
4✔
34
    if constexpr (forward) {
4✔
35
      sub_digits = std::min(digits - first.position(), total_bits_to_op);
8✔
36
      if (sub_digits != 0) {
8!
37
        acc = binary_op_subword(std::move(acc), get_word<word_type>(first, sub_digits), sub_digits);
8✔
38
        advance(first, digits - first.position());
8✔
39
      }
4✔
40
    } else {
41
      sub_digits = std::min(last.position(), total_bits_to_op);
42
      if (sub_digits != 0) {
43
        advance(last, -sub_digits);
44
        acc = binary_op_subword(std::move(acc), get_word<word_type>(last, sub_digits), sub_digits);
45
      }
46
    }
47
    total_bits_to_op -= sub_digits;
8✔
48
  }
4✔
49

50
  const size_type whole_words_to_op = total_bits_to_op / digits;
8✔
51
  const size_type remaining_bits_to_op = total_bits_to_op % digits;
8✔
52

53
  for (size_t i = 0; i < whole_words_to_op; i ++) {
8!
NEW
54
    if constexpr (forward) {
NEW
55
      acc = binary_op(std::move(acc), get_word<word_type>(first));
×
NEW
56
      advance(first, digits);
×
57
    } else {
58
      advance(last, -digits);
59
      acc = binary_op(std::move(acc), get_word<word_type>(last));
60
    }
NEW
61
  }
62
  if (remaining_bits_to_op > 0) {
8!
NEW
63
    if constexpr (forward) {
NEW
64
      acc = binary_op_subword(std::move(acc), get_word<word_type>(first, remaining_bits_to_op), remaining_bits_to_op);
×
65
    } else {
66
      advance(last, -remaining_bits_to_op);
67
      acc = binary_op_subword(std::move(acc), get_word<word_type>(last, remaining_bits_to_op), remaining_bits_to_op);
68
    }
NEW
69
  }
70

71
  return acc;
12✔
72
}
4✔
73

74
template <bool forward, bool initial_sub_word, typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
75
constexpr auto accumulate_while(
4✔
76
    bit_iterator<RandomAccessIt> first,
77
    bit_iterator<RandomAccessIt> last,
78
    T acc,
79
    BinaryOperation binary_op,
80
    BinaryOperationSubword binary_op_subword) {
4✔
81
  using word_type = typename bit_iterator<RandomAccessIt>::word_type;
4✔
82
  using size_type = typename bit_iterator<RandomAccessIt>::size_type;
4✔
83
  using difference_type = typename bit_iterator<RandomAccessIt>::difference_type;
4✔
84
  constexpr size_type digits = bitsof<word_type>();
8✔
85

86
  size_type total_bits_to_op = distance(first, last);
8✔
87
  size_type whole_words_to_op = total_bits_to_op / digits;
8✔
88

89
  bool keep_going = true;;
8✔
90
  if constexpr (initial_sub_word) {
4✔
91
    if (whole_words_to_op > 1) {
8!
92
      size_type sub_digits;
1✔
93
      if constexpr (forward) {
94
        sub_digits = std::min(digits - first.position(), total_bits_to_op);
95
        if (sub_digits != 0) {
96
          std::tie(keep_going, acc) = binary_op_subword(std::move(acc), get_word<word_type>(first, sub_digits), sub_digits);
97
          advance(first, digits - first.position());
98
        }
99
      } else {
1✔
100
        sub_digits = std::min(last.position(), total_bits_to_op);
2✔
101
        if (sub_digits != 0) {
2!
NEW
102
          advance(last, -sub_digits);
×
NEW
103
          std::tie(keep_going, acc) = binary_op_subword(std::move(acc), get_word<word_type>(first, sub_digits), sub_digits);
×
NEW
104
        }
105
      }
1✔
106
      total_bits_to_op -= sub_digits;
2✔
107
      if (!keep_going) {
2!
NEW
108
        return acc; // Stop early if the operation indicates to stop
×
NEW
109
      }
110
    }
1✔
111
  }
4✔
112

113
  whole_words_to_op = total_bits_to_op / digits;
8✔
114
  const size_type remaining_bits_to_op = total_bits_to_op % digits;
8✔
115

116
  for (size_type i = 0; i < whole_words_to_op; i ++) {
12!
117
    if constexpr (forward) {
118
      std::tie(keep_going, acc) = binary_op(std::move(acc), get_word<word_type>(first));
119
      advance(first, digits);
120
    } else {
4✔
121
      advance(last, -digits);
8✔
122
      std::tie(keep_going, acc) = binary_op(std::move(acc), get_word<word_type>(last));
8✔
123
    }
4✔
124
    if (!keep_going) {
8!
125
      return acc; // Stop early if the operation indicates to stop
4✔
126
    }
2✔
127
  }
4✔
128
  if (remaining_bits_to_op > 0) {
4!
129
    if constexpr (forward) {
130
      std::tie(std::ignore, acc) = binary_op_subword(std::move(acc), get_word<word_type>(first, remaining_bits_to_op), remaining_bits_to_op);
131
    } else {
1✔
132
      advance(last, -remaining_bits_to_op);
2✔
133
      std::tie(std::ignore, acc) = binary_op_subword(std::move(acc), get_word<word_type>(last, remaining_bits_to_op), remaining_bits_to_op);
2✔
134
    }
1✔
135
  }
1✔
136

137
  return acc;
4✔
138
}
4✔
139

140
// Requires BinaryOperation to have a third but defaulted argument
141
template <typename RandomAccessIt, typename T, typename BinaryOperation>
142
constexpr auto accumulate(
4✔
143
    const bit_iterator<RandomAccessIt>& first,
144
    const bit_iterator<RandomAccessIt>& last,
145
    const T& acc,
146
    BinaryOperation binary_op) {
4✔
147
  return accumulate<true, true>(first, last, acc, binary_op, binary_op);
12✔
148
}
4✔
149

150
template <typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
151
constexpr auto accumulate(
152
    const bit_iterator<RandomAccessIt>& first,
153
    const bit_iterator<RandomAccessIt>& last,
154
    const T& acc,
155
    BinaryOperation binary_op,
156
    BinaryOperationSubword binary_op_subword) {
157
  return accumulate<true, true>(first, last, acc, binary_op, binary_op_subword);
158
}
159

160
// Requires BinaryOperation to have a third but defaulted argument
161
template <typename RandomAccessIt, typename T, typename BinaryOperation>
162
constexpr auto accumulate_while(
163
    const bit_iterator<RandomAccessIt>& first,
164
    const bit_iterator<RandomAccessIt>& last,
165
    const T& acc,
166
    BinaryOperation binary_op) {
167
  return accumulate_while<true, true>(first, last, acc, binary_op, binary_op);
168
}
169

170
template <typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
171
constexpr auto accumulate_while(
172
    const bit_iterator<RandomAccessIt>& first,
173
    const bit_iterator<RandomAccessIt>& last,
174
    const T& acc,
175
    BinaryOperation binary_op,
176
    BinaryOperationSubword binary_op_subword) {
177
  return accumulate_while<true, true>(first, last, acc, binary_op, binary_op_subword);
178
}
179

180
// Requires BinaryOperation to have a third but defaulted argument
181
template <typename RandomAccessIt, typename T, typename BinaryOperation>
182
constexpr auto accumulate_backward_while(
183
    const bit_iterator<RandomAccessIt>& first,
184
    const bit_iterator<RandomAccessIt>& last,
185
    const T& acc,
186
    BinaryOperation binary_op) {
187
  return accumulate_while<false, true>(first, last, acc, binary_op, binary_op);
188
}
189

190
template <typename RandomAccessIt, typename T, typename BinaryOperation, typename BinaryOperationSubword>
191
constexpr auto accumulate_backward_while(
4✔
192
    const bit_iterator<RandomAccessIt>& first,
193
    const bit_iterator<RandomAccessIt>& last,
194
    const T& acc,
195
    BinaryOperation binary_op,
196
    BinaryOperationSubword binary_op_subword) {
4✔
197
  return accumulate_while<false, true>(first, last, acc, binary_op, binary_op_subword);
12✔
198
}
4✔
199

200
} // namespace bit
201

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