diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index a4d2d266c..aae4e5f3d 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -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 result; - for (size_t i = 0; i < 32; ++i) { - if (mask & (1 << i)) { - result.push_back(static_cast(i)); - } - } - os << sls::ToString(result) << '\n'; + os << sls::ToString(getSetBits(mask)) << '\n'; } else if (action == defs::PUT_ACTION) { if (args.empty()) { WrongNumberOfParameters(1); diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index c595d317e..c447dd773 100755 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -40,6 +40,7 @@ if(SLS_DEVEL_HEADERS) include/UdpRxSocket.h include/versionAPI.h include/ZmqSocket.h + include/bit_utils.h ) endif() diff --git a/slsSupportLib/include/bit_utils.h b/slsSupportLib/include/bit_utils.h new file mode 100644 index 000000000..8043c3dad --- /dev/null +++ b/slsSupportLib/include/bit_utils.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +namespace sls { +template std::vector getSetBits(T val) { + constexpr size_t bitsPerByte = 8; + constexpr size_t numBits = sizeof(T)*bitsPerByte; + std::bitset bs(val); + std::vector 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(i)); + } + } + return set_bits; +} +} // namespace sls diff --git a/slsSupportLib/tests/CMakeLists.txt b/slsSupportLib/tests/CMakeLists.txt index 4dd33e64d..8265c7159 100755 --- a/slsSupportLib/tests/CMakeLists.txt +++ b/slsSupportLib/tests/CMakeLists.txt @@ -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 diff --git a/slsSupportLib/tests/test-bit_stuff.cpp b/slsSupportLib/tests/test-bit_stuff.cpp new file mode 100644 index 000000000..adf3768d7 --- /dev/null +++ b/slsSupportLib/tests/test-bit_stuff.cpp @@ -0,0 +1,39 @@ +#include "catch.hpp" +#include +#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{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{0,1,3,9}); +}