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

PeterCDMcLean / BitLib / 15658406666

15 Jun 2025 02:12AM UTC coverage: 96.002% (+42.5%) from 53.519%
15658406666

Pull #17

github

web-flow
Merge 5e911f3b7 into 0f0b787a1
Pull Request #17: Truncation policy

122 of 148 new or added lines in 9 files covered. (82.43%)

4 existing lines in 3 files now uncovered.

1561 of 1626 relevant lines covered (96.0%)

20765048.89 hits per line

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

86.67
/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) {
25
  using word_type = typename bit_iterator<RandomAccessIt>::word_type;
26
  using size_type = typename bit_iterator<RandomAccessIt>::size_type;
27
  constexpr size_type digits = bitsof<word_type>();
4✔
28

29

30
  size_type total_bits_to_op = distance(first, last);
4✔
31
  bool keep_going = true;;
4✔
32
  if constexpr (initial_sub_word) {
33
    size_type sub_digits;
34
    if constexpr (forward) {
35
      sub_digits = std::min(digits - first.position(), total_bits_to_op);
4✔
36
      if (sub_digits != 0) {
4✔
37
        acc = binary_op_subword(std::move(acc), get_word<word_type>(first, sub_digits), sub_digits);
4✔
38
        advance(first, digits - first.position());
4✔
39
      }
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;
4✔
48
  }
49

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

53
  for (size_t i = 0; i < whole_words_to_op; i ++) {
4✔
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
    }
61
  }
62
  if (remaining_bits_to_op > 0) {
4✔
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
    }
69
  }
70

71
  return acc;
8✔
72
}
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) {
81
  using word_type = typename bit_iterator<RandomAccessIt>::word_type;
82
  using size_type = typename bit_iterator<RandomAccessIt>::size_type;
83
  using difference_type = typename bit_iterator<RandomAccessIt>::difference_type;
84
  constexpr size_type digits = bitsof<word_type>();
4✔
85

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

89
  bool keep_going = true;;
4✔
90
  if constexpr (initial_sub_word) {
91
    if (whole_words_to_op > 1) {
4✔
92
      size_type sub_digits;
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 {
100
        sub_digits = std::min(last.position(), total_bits_to_op);
1✔
101
        if (sub_digits != 0) {
1✔
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);
×
104
        }
105
      }
106
      total_bits_to_op -= sub_digits;
1✔
107
      if (!keep_going) {
1✔
NEW
108
        return acc; // Stop early if the operation indicates to stop
×
109
      }
110
    }
111
  }
112

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

116
  for (size_type i = 0; i < whole_words_to_op; i ++) {
6✔
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 {
121
      advance(last, -digits);
4✔
122
      std::tie(keep_going, acc) = binary_op(std::move(acc), get_word<word_type>(last));
4✔
123
    }
124
    if (!keep_going) {
4✔
125
      return acc; // Stop early if the operation indicates to stop
2✔
126
    }
127
  }
128
  if (remaining_bits_to_op > 0) {
2✔
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 {
132
      advance(last, -remaining_bits_to_op);
1✔
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);
1✔
134
    }
135
  }
136

137
  return acc;
2✔
138
}
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) {
147
  return accumulate<true, true>(first, last, acc, binary_op, binary_op);
8✔
148
}
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) {
197
  return accumulate_while<false, true>(first, last, acc, binary_op, binary_op_subword);
8✔
198
}
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