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

PeterCDMcLean / BitLib / 15668442123

15 Jun 2025 11:21PM UTC coverage: 54.204% (+0.7%) from 53.519%
15668442123

Pull #17

github

web-flow
Merge 91a9e717f into 0f0b787a1
Pull Request #17: Truncation policy

10212 of 18774 branches covered (54.39%)

Branch coverage included in aggregate %.

177 of 216 new or added lines in 12 files covered. (81.94%)

214 existing lines in 11 files now uncovered.

6035 of 11200 relevant lines covered (53.88%)

7755103.91 hits per line

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

87.18
/include/bitlib/bit-algorithms/count.hpp
1
// ================================= COUNT ================================== //
2
// Project: The Experimental Bit Algorithms Library
3
// Description: bit_iterator overloads for std::count, std::count_if
4
// License: BSD 3-Clause License
5
// ========================================================================== //
6
#ifndef _COUNT_HPP_INCLUDED
7
#define _COUNT_HPP_INCLUDED
8
// ========================================================================== //
9

10
// ============================== PREAMBLE ================================== //
11
// C++ standard library
12
#include <iterator>
13
#include <numeric>
14
// Project sources
15
#include "bitlib/bit-algorithms/accumulate.hpp"
16
#include "bitlib/bit-algorithms/libpopcnt.h"
17
#include "bitlib/bit-iterator/bit.hpp"
18
// Third-party libraries
19
#ifdef BITLIB_HWY
20
#include "hwy/highway.h"
21
HWY_BEFORE_NAMESPACE();
22
#endif
23
// Miscellaneous
24

25
#define is_aligned(POINTER, BYTE_COUNT) \
26
    (((uintptr_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)
27

28
namespace bit {
29

30
#ifdef BITLIB_HWY
31
namespace hn = hwy::HWY_NAMESPACE;
32
#endif
33
// ========================================================================== //
34

35
template<class RandomAccessIt>
36
constexpr typename bit_iterator<RandomAccessIt>::difference_type
37
count(
30,464✔
38
    bit_iterator <RandomAccessIt> first,
39
    bit_iterator <RandomAccessIt> last,
40
    bit_value value
41
) {
30,464✔
42
    // Assertions
43
    _assert_range_viability(first, last);
60,928✔
44

45
    // Types and constants
46
    using word_type = typename bit_iterator<RandomAccessIt>::word_type;
30,464✔
47
    using difference_type = typename bit_iterator<RandomAccessIt>::difference_type;
30,464✔
48
    using iterator_type = typename bit_iterator<RandomAccessIt>::iterator_type;
30,464✔
49
    constexpr difference_type digits = binary_digits<word_type>::value;
60,928✔
50

51
    // Initialization
52
    difference_type result = 0;
60,928✔
53

54
    // Computation when bits belong to several underlying words
55
    if (first.base() != last.base()) {
60,928✔
56
      iterator_type it = first.base();
45,824✔
57

58
      if (first.position() != 0) {
45,824!
59
        word_type first_value = lsr(*first.base(), first.position());
45,824✔
60
        result = _popcnt(first_value);
45,824✔
61
        ++it;
45,824✔
62
      }
22,848✔
63
// The SIMD implementation here is actually slower than the standard
64
//#ifdef BITLIB_HWY
65
        //// ReduceSum not implemented for unsigned char
66
        //if constexpr (digits > 8)
67
        //{
68
            //// Align to boundary
69
            //for (; it != last.base() && !is_aligned(&(*it), 64); ++it) {
70
                //result += _popcnt(*it);
71
            //}
72

73
            //// SIMD
74
            //hn::ScalableTag<word_type> d;
75
            //for (; std::distance(it, last.base()) >= hn::Lanes(d); it += hn::Lanes(d))
76
            //{
77
                //const auto popcntV = hn::PopulationCount(hn::Load(d, &*it));
78
                //result += hn::ReduceSum(d, popcntV);
79
            //}
80

81
            //// Remaining
82
            //for (; it != last.base(); ++it) {
83
                //result += _popcnt(*it);
84
            //}
85
        //} else
86
//#endif
87
        {
22,848✔
88
            // std:: version
89
            //result += std::transform_reduce(
90
                    //it,
91
                    //last.base(),
92
                    //0,
93
                    //std::plus{},
94
                    //[](word_type word) {return _popcnt(word); }
95
            //);
96

97
            // libpopcnt
98
            result += popcnt(&*it, (digits / 8) * std::distance(it, last.base()));
68,800✔
99
        }
22,848✔
100
        if (last.position() != 0) {
45,824✔
101
            word_type last_value = *last.base() << (digits - last.position());
44,288✔
102
            result += _popcnt(last_value);
44,288✔
103
        }
22,080✔
104
    // Computation when bits belong to the same underlying word
105
    } else {
22,848✔
106
        result = _popcnt(
17,120✔
107
            _bextr<word_type>(*first.base(), first.position(), last.position()
30,080✔
108
              - first.position())
15,104✔
109
        );
7,616✔
110
    }
7,616✔
111

112
    // Negates when the number of zero bits is requested
113
    if (!static_cast<bool>(value)) {
60,928✔
114
        result = std::distance(first, last) - result;
45,696✔
115
    }
15,232✔
116

117
    // Finalization
118
    return result;
91,392✔
119
}
30,464✔
120

121
template <class RandomAccessIt>
122
constexpr int count_msb(
4✔
123
    bit_iterator<RandomAccessIt> first,
124
    bit_iterator<RandomAccessIt> last,
125
    bit_value value) {
4✔
126
  if (value) {
8!
NEW
127
    return bit::accumulate_backward_while(
×
NEW
128
        first, last, 0,
×
NEW
129
        [](int acc, auto word) { return std::make_pair((word == 0), acc + std::countl_one(word)); },
×
NEW
130
        [](int acc, auto word, auto bits) { return std::make_pair((word == 0), acc + std::countl_one(word) - (bit::bitsof(word) - bits)); });
×
131
  } else {
4✔
132
    return bit::accumulate_backward_while(
8✔
133
        first, last, 0,
12✔
134
        [](int acc, auto word) { return std::make_pair((word == 0), acc + std::countl_zero(word)); },
12✔
135
        [](int acc, auto word, auto bits) { return std::make_pair((word == 0), acc + std::countl_zero(word) - (bit::bitsof(word) - bits)); });
10✔
136
  }
4✔
137
}
4✔
138

139
} // namespace bit
140
#ifdef BITLIB_HWY
141
HWY_AFTER_NAMESPACE();
142
#endif
143

144
// ========================================================================== //
145
#endif // _COUNT_HPP_INCLUDED
146
// ========================================================================== //
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