mirror of https://github.com/openXC7/prjxray.git
lib: bit manipulation functions
Functions for hiding all the masking and shifting required for accessing bit ranges within an integer type. Signed-off-by: Rick Altherr <kc8apf@kc8apf.net> Signed-off-by: Tim 'mithro' Ansell <mithro@mithis.com>
This commit is contained in:
parent
4d556f9112
commit
f65ee46f7c
|
|
@ -6,6 +6,11 @@ target_include_directories(libprjxray PUBLIC "include")
|
|||
target_link_libraries(libprjxray absl::strings)
|
||||
|
||||
if (PRJXRAY_BUILD_TESTING)
|
||||
add_executable(bit_ops_test bit_ops_test.cc)
|
||||
target_link_libraries(bit_ops_test libprjxray gtest_main)
|
||||
add_test(NAME bit_ops_test
|
||||
COMMAND bit_ops_test)
|
||||
|
||||
add_executable(memory_mapped_file_test memory_mapped_file_test.cc)
|
||||
target_link_libraries(memory_mapped_file_test libprjxray gtest_main)
|
||||
add_test(NAME memory_mapped_file_test
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
#include <prjxray/bit_ops.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(BitMaskTest, Bit0) {
|
||||
uint32_t expected = prjxray::bit_mask<uint32_t>(0);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0x1), expected);
|
||||
}
|
||||
|
||||
TEST(BitMaskTest, Bit3) {
|
||||
uint32_t expected = prjxray::bit_mask<uint32_t>(3);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0x8), expected);
|
||||
}
|
||||
|
||||
TEST(BitMaskRange, SingleBit) {
|
||||
uint32_t expected = prjxray::bit_mask_range<uint32_t>(23, 23);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0x800000), expected);
|
||||
}
|
||||
|
||||
TEST(BitMaskRange, DownToZero) {
|
||||
uint32_t expected = prjxray::bit_mask_range<uint32_t>(7, 0);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0xFF), expected);
|
||||
}
|
||||
|
||||
TEST(BitMaskRange, MiddleBits) {
|
||||
uint32_t expected = prjxray::bit_mask_range<uint32_t>(18, 8);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0x7FF00), expected);
|
||||
}
|
||||
|
||||
TEST(BitFieldGetTest, OneSelectedBit) {
|
||||
uint32_t expected = prjxray::bit_field_get(0xFFFFFFFF, 23, 23);
|
||||
EXPECT_EQ(static_cast<uint32_t>(1), expected);
|
||||
}
|
||||
|
||||
TEST(BitFieldGetTest, SelectDownToZero) {
|
||||
uint32_t expected = prjxray::bit_field_get(0xFFCCBBAA, 7, 0);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0xAA), expected);
|
||||
}
|
||||
|
||||
TEST(BitFieldGetTest, SelectMidway) {
|
||||
uint32_t expected = prjxray::bit_field_get(0xFFCCBBAA, 18, 8);
|
||||
EXPECT_EQ(static_cast<uint32_t>(0x4BB), expected);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef PRJXRAY_LIB_BIT_OPS_H
|
||||
#define PRJXRAY_LIB_BIT_OPS_H
|
||||
|
||||
namespace prjxray {
|
||||
|
||||
template<typename UInt>
|
||||
constexpr UInt bit_mask(int bit) {
|
||||
return (static_cast<UInt>(1) << bit);
|
||||
}
|
||||
|
||||
template<typename UInt>
|
||||
constexpr UInt bit_sizeof() {
|
||||
return sizeof(UInt) * 8;
|
||||
}
|
||||
|
||||
template<typename UInt>
|
||||
constexpr UInt bit_all_ones() {
|
||||
return ~static_cast<UInt>(0);
|
||||
}
|
||||
|
||||
template<typename UInt>
|
||||
constexpr UInt bit_mask_range(int top_bit, int bottom_bit) {
|
||||
return ((bit_all_ones<UInt>() >> (bit_sizeof<UInt>() - 1 - top_bit)) &
|
||||
(bit_all_ones<UInt>() - bit_mask<UInt>(bottom_bit) +
|
||||
static_cast<UInt>(1)));
|
||||
}
|
||||
|
||||
|
||||
template<typename UInt>
|
||||
constexpr UInt bit_field_get(UInt value, int top_bit, int bottom_bit) {
|
||||
return (value & bit_mask_range<UInt>(top_bit, bottom_bit)) >> bottom_bit;
|
||||
}
|
||||
|
||||
} // namespace prjxray
|
||||
|
||||
#endif // PRJXRAY_LIB_BIT_OPS_H
|
||||
Loading…
Reference in New Issue