mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-10 15:19:50 +08:00
Optimised bitset shift operations
This commit is contained in:
parent
0eefbc2a90
commit
f87dfd5b92
@ -543,7 +543,7 @@ namespace etl
|
|||||||
pdata[i] = ~pdata[i];
|
pdata[i] = ~pdata[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
pdata[Number_Of_Elements - 1U] &= Top_Mask;
|
adjust_top_bits();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -782,18 +782,14 @@ namespace etl
|
|||||||
}
|
}
|
||||||
else if (shift == Bits_Per_Element)
|
else if (shift == Bits_Per_Element)
|
||||||
{
|
{
|
||||||
for (size_t i = (Number_Of_Elements - 1U); i > 0U; --i)
|
etl::copy_backward(pdata, pdata + Number_Of_Elements - 1U, pdata + Number_Of_Elements);
|
||||||
{
|
|
||||||
pdata[i] = pdata[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
pdata[0] = 0;
|
pdata[0] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Where we are shifting from.
|
// Where we are shifting from.
|
||||||
int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U);
|
int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U);
|
||||||
size_t src_position = Bits_Per_Element - (shift % Bits_Per_Element);
|
const size_t src_position = Bits_Per_Element - (shift % Bits_Per_Element);
|
||||||
|
|
||||||
// Where we are shifting to.
|
// Where we are shifting to.
|
||||||
int dst_index = int(Number_Of_Elements - 1U);
|
int dst_index = int(Number_Of_Elements - 1U);
|
||||||
@ -814,9 +810,12 @@ namespace etl
|
|||||||
// Now do the shifting.
|
// Now do the shifting.
|
||||||
while (src_index >= 0)
|
while (src_index >= 0)
|
||||||
{
|
{
|
||||||
|
// Shift msb.
|
||||||
element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift);
|
element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift);
|
||||||
pdata[dst_index] = pdata[dst_index] | msb;
|
pdata[dst_index] = pdata[dst_index] | msb;
|
||||||
--dst_index;
|
--dst_index;
|
||||||
|
|
||||||
|
// Shift lsb.
|
||||||
element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift);
|
element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift);
|
||||||
pdata[dst_index] = lsb;
|
pdata[dst_index] = lsb;
|
||||||
--src_index;
|
--src_index;
|
||||||
@ -836,7 +835,7 @@ namespace etl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Truncate any bits shifted to the left.
|
// Truncate any bits shifted to the left.
|
||||||
pdata[Number_Of_Elements - 1U] &= Top_Mask;
|
adjust_top_bits();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -861,18 +860,14 @@ namespace etl
|
|||||||
// Shift is the size of an element?
|
// Shift is the size of an element?
|
||||||
else if (shift == Bits_Per_Element)
|
else if (shift == Bits_Per_Element)
|
||||||
{
|
{
|
||||||
for (size_t i = 0UL; i < (Number_Of_Elements - 1U); ++i)
|
etl::copy(pdata + 1, pdata + Number_Of_Elements, pdata);
|
||||||
{
|
|
||||||
pdata[i] = pdata[i + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
pdata[Number_Of_Elements - 1U] = 0;
|
pdata[Number_Of_Elements - 1U] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Where we are shifting from.
|
// Where we are shifting from.
|
||||||
int src_index = int(shift / Bits_Per_Element);
|
int src_index = int(shift / Bits_Per_Element);
|
||||||
size_t src_position = shift % Bits_Per_Element;
|
const size_t src_position = shift % Bits_Per_Element;
|
||||||
|
|
||||||
// Where we are shifting to.
|
// Where we are shifting to.
|
||||||
int dst_index = 0;
|
int dst_index = 0;
|
||||||
@ -891,8 +886,10 @@ namespace etl
|
|||||||
// Shift msb.
|
// Shift msb.
|
||||||
element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift);
|
element_t msb = element_t((pdata[src_index] & msb_mask) >> msb_shift);
|
||||||
++src_index;
|
++src_index;
|
||||||
|
|
||||||
// Shift lsb.
|
// Shift lsb.
|
||||||
element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift);
|
element_t lsb = element_t((pdata[src_index] & lsb_mask) << lsb_shift);
|
||||||
|
|
||||||
// Combine them.
|
// Combine them.
|
||||||
pdata[dst_index] = lsb | msb;
|
pdata[dst_index] = lsb | msb;
|
||||||
++dst_index;
|
++dst_index;
|
||||||
@ -969,10 +966,10 @@ namespace etl
|
|||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
const size_t SHIFT = (integral_limits<unsigned long long>::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element;
|
const size_t Shift = (integral_limits<unsigned long long>::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element;
|
||||||
|
|
||||||
// Can we do it in one hit?
|
// Can we do it in one hit?
|
||||||
if (SHIFT == 0)
|
if (Shift == 0)
|
||||||
{
|
{
|
||||||
pdata[0] = element_t(value);
|
pdata[0] = element_t(value);
|
||||||
}
|
}
|
||||||
@ -983,11 +980,11 @@ namespace etl
|
|||||||
while ((value != 0) && (i < Number_Of_Elements))
|
while ((value != 0) && (i < Number_Of_Elements))
|
||||||
{
|
{
|
||||||
pdata[i++] = value & ALL_SET;
|
pdata[i++] = value & ALL_SET;
|
||||||
value = value >> SHIFT;
|
value = value >> Shift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pdata[Number_Of_Elements - 1U] &= Top_Mask;
|
adjust_top_bits();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -1002,7 +999,7 @@ namespace etl
|
|||||||
pdata[i] = ~pdata[i];
|
pdata[i] = ~pdata[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
pdata[Number_Of_Elements - 1U] &= Top_Mask;
|
adjust_top_bits();
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
@ -1021,8 +1018,8 @@ namespace etl
|
|||||||
, Number_Of_Elements(size_)
|
, Number_Of_Elements(size_)
|
||||||
, pdata(pdata_)
|
, pdata(pdata_)
|
||||||
{
|
{
|
||||||
size_t allocated_bits = Number_Of_Elements * Bits_Per_Element;
|
const size_t allocated_bits = Number_Of_Elements * Bits_Per_Element;
|
||||||
size_t top_mask_shift = ((Bits_Per_Element - (allocated_bits - Total_Bits)) % Bits_Per_Element);
|
const size_t top_mask_shift = ((Bits_Per_Element - (allocated_bits - Total_Bits)) % Bits_Per_Element);
|
||||||
Top_Mask = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift));
|
Top_Mask = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,6 +1035,14 @@ namespace etl
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Correct the unused top bits after bit manipulation.
|
||||||
|
//*************************************************************************
|
||||||
|
void adjust_top_bits()
|
||||||
|
{
|
||||||
|
pdata[Number_Of_Elements - 1U] &= Top_Mask;
|
||||||
|
}
|
||||||
|
|
||||||
// Disable copy construction.
|
// Disable copy construction.
|
||||||
ibitset(const ibitset&);
|
ibitset(const ibitset&);
|
||||||
|
|
||||||
|
|||||||
@ -896,28 +896,34 @@ namespace
|
|||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_shift_left_operator_all_shifts_full_size)
|
TEST(test_shift_left_operator_all_shifts_full_size)
|
||||||
{
|
{
|
||||||
constexpr uint64_t value = 0x01233456789ABCDEULL;
|
constexpr uint64_t value = 0x0123456789ABCDEFULL;
|
||||||
|
|
||||||
for (int shift = 0; shift <= 64; ++shift)
|
for (int shift = 0; shift < 64; ++shift)
|
||||||
{
|
{
|
||||||
etl::bitset<64> data(value);
|
etl::bitset<64> data(value);
|
||||||
|
|
||||||
CHECK_EQUAL_HEX((value << shift), (data << shift).value<uint64_t>());
|
CHECK_EQUAL_HEX((value << shift), (data << shift).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etl::bitset<64> data(value);
|
||||||
|
CHECK_EQUAL_HEX(0, (data << 64).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_shift_left_operator_all_shifts_partial_size)
|
TEST(test_shift_left_operator_all_shifts_partial_size)
|
||||||
{
|
{
|
||||||
constexpr uint64_t value = 0x01233456789ABCDEULL;
|
constexpr uint64_t value = 0x0123456789ABCDEFULL;
|
||||||
constexpr uint64_t mask = 0x0FFFFFFFFFFFFFFFULL;
|
constexpr uint64_t mask = 0x0FFFFFFFFFFFFFFFULL;
|
||||||
|
|
||||||
for (int shift = 0; shift <= 64; ++shift)
|
for (int shift = 0; shift < 64; ++shift)
|
||||||
{
|
{
|
||||||
etl::bitset<60> data(value);
|
etl::bitset<60> data(value);
|
||||||
|
|
||||||
CHECK_EQUAL_HEX(((value << shift) & mask), (data << shift).value<uint64_t>());
|
CHECK_EQUAL_HEX(((value << shift) & mask), (data << shift).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etl::bitset<64> data(value);
|
||||||
|
CHECK_EQUAL_HEX(0, (data << 64).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
@ -945,28 +951,34 @@ namespace
|
|||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_shift_right_operator_all_shifts_full_size)
|
TEST(test_shift_right_operator_all_shifts_full_size)
|
||||||
{
|
{
|
||||||
constexpr uint64_t value = 0x01233456789ABCDEULL;
|
constexpr uint64_t value = 0x0123456789ABCDEFULL;
|
||||||
|
|
||||||
for (int shift = 0; shift <= 64; ++shift)
|
for (int shift = 0; shift < 64; ++shift)
|
||||||
{
|
{
|
||||||
etl::bitset<64> data(value);
|
etl::bitset<64> data(value);
|
||||||
|
|
||||||
CHECK_EQUAL_HEX((value >> shift), (data >> shift).value<uint64_t>());
|
CHECK_EQUAL_HEX((value >> shift), (data >> shift).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etl::bitset<64> data(value);
|
||||||
|
CHECK_EQUAL_HEX(0, (data >> 64).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_shift_right_operator_all_shifts_partial_size)
|
TEST(test_shift_right_operator_all_shifts_partial_size)
|
||||||
{
|
{
|
||||||
constexpr uint64_t value = 0x01233456789ABCDEULL;
|
constexpr uint64_t value = 0x0123456789ABCDEFULL;
|
||||||
constexpr uint64_t mask = 0x0FFFFFFFFFFFFFFFULL;
|
constexpr uint64_t mask = 0x0FFFFFFFFFFFFFFFULL;
|
||||||
|
|
||||||
for (int shift = 0; shift <= 64; ++shift)
|
for (int shift = 0; shift < 64; ++shift)
|
||||||
{
|
{
|
||||||
etl::bitset<60> data(value);
|
etl::bitset<60> data(value);
|
||||||
|
|
||||||
CHECK_EQUAL_HEX(((value >> shift) & mask), (data >> shift).value<uint64_t>());
|
CHECK_EQUAL_HEX(((value >> shift) & mask), (data >> shift).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etl::bitset<64> data(value);
|
||||||
|
CHECK_EQUAL_HEX(0, (data >> 64).value<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user