Utility function to get a vector of set bits

Template function to return a vector with the positions of all set bits in a variable.
This commit is contained in:
Erik Fröjdh 2020-08-05 13:42:57 +02:00 committed by GitHub
parent 6db5954d21
commit aa0c36713c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 8 deletions

View File

@ -1,4 +1,5 @@
#include "CmdProxy.h"
#include "bit_utils.h"
#include "TimeHelper.h"
#include "ToString.h"
#include "container_utils.h"
@ -1810,14 +1811,7 @@ std::string CmdProxy::Counters(int action) {
WrongNumberOfParameters(0);
}
auto mask = det->getCounterMask({det_id}).squash(-1);
// scan counter enable mask to get vector
std::vector<int> result;
for (size_t i = 0; i < 32; ++i) {
if (mask & (1 << i)) {
result.push_back(static_cast<int>(i));
}
}
os << sls::ToString(result) << '\n';
os << sls::ToString(getSetBits(mask)) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.empty()) {
WrongNumberOfParameters(1);

View File

@ -40,6 +40,7 @@ if(SLS_DEVEL_HEADERS)
include/UdpRxSocket.h
include/versionAPI.h
include/ZmqSocket.h
include/bit_utils.h
)
endif()

View File

@ -0,0 +1,19 @@
#pragma once
#include <vector>
#include <bitset>
namespace sls {
template <typename T> std::vector<int> getSetBits(T val) {
constexpr size_t bitsPerByte = 8;
constexpr size_t numBits = sizeof(T)*bitsPerByte;
std::bitset<numBits> bs(val);
std::vector<int> set_bits;
set_bits.reserve(bs.count());
for (size_t i = 0; i < bs.size(); ++i) {
if (bs[i]) {
set_bits.push_back(static_cast<int>(i));
}
}
return set_bits;
}
} // namespace sls

View File

@ -1,4 +1,5 @@
target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-bit_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-container_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-network_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-string_utils.cpp

View File

@ -0,0 +1,39 @@
#include "catch.hpp"
#include <vector>
#include "bit_utils.h"
TEST_CASE("Get set bits from 0"){
auto vec = sls::getSetBits(0);
REQUIRE(vec.empty());
}
TEST_CASE("Get set bits from 1"){
auto vec = sls::getSetBits(1);
REQUIRE(vec.size() == 1);
REQUIRE(vec[0] == 0);
}
TEST_CASE("Get set bits from 2"){
auto vec = sls::getSetBits(2ul);
REQUIRE(vec.size() == 1);
REQUIRE(vec[0] == 1);
}
TEST_CASE("Get set bits from 3"){
auto vec = sls::getSetBits(3u);
REQUIRE(vec.size() == 2);
REQUIRE(vec[0] == 0);
REQUIRE(vec[1] == 1);
}
TEST_CASE("All bits set"){
uint8_t val = -1;
auto vec = sls::getSetBits(val);
REQUIRE(vec == std::vector<int>{0,1,2,3,4,5,6,7});
}
TEST_CASE("Get set bits from 523"){
//0b1000001011 == 523
auto vec = sls::getSetBits(523);
REQUIRE(vec == std::vector<int>{0,1,3,9});
}