Merge remote-tracking branch 'origin/development'

This commit is contained in:
John Wellbelove 2018-05-20 10:29:28 +01:00
parent 54d04ce1d8
commit eb36baedc7
3 changed files with 236 additions and 0 deletions

View File

@ -569,6 +569,76 @@ namespace etl
};
#endif
//***************************************************************************
/// Merges two values according to a mask.
/// Ones in the mask select bits from 'first', zeros select bits from second.
/// Mask is a function parameter.
//***************************************************************************
template <typename T>
T binary_merge(const T first, const T second, const T mask)
{
return second ^ ((second ^ first) & mask);
}
//***************************************************************************
/// Merges two values according to a mask.
/// Ones in the mask select bits from 'first', zeros select bits from second.
/// Mask is a template parameter.
//***************************************************************************
template <typename T, const T MASK>
T binary_merge(const T first, const T second)
{
return second ^ ((second ^ first) & MASK);
}
//***************************************************************************
/// Binary interleave
//***************************************************************************
#if ETL_8BIT_SUPPORT
uint16_t binary_interleave(uint8_t first, uint8_t second);
inline int16_t binary_interleave(int8_t first, int8_t second) { return int16_t(binary_interleave(uint8_t(first), uint8_t(second))); }
#endif
uint32_t binary_interleave(uint16_t first, uint16_t second);
inline int32_t binary_interleave(int16_t first, int16_t second) { return int32_t(binary_interleave(uint16_t(first), uint16_t(second))); }
uint64_t binary_interleave(uint32_t first, uint32_t second);
inline int64_t binary_interleave(int32_t first, int32_t second) { return int64_t(binary_interleave(uint16_t(first), uint16_t(second))); }
//***************************************************************************
/// Checks if odd.
//***************************************************************************
bool is_odd(const unsigned char value);
inline bool is_odd(const char value) { return is_odd((unsigned char)value); }
bool is_odd(const unsigned short value);
inline bool is_odd(const short value) { return is_odd((unsigned short)value); }
bool is_odd(const unsigned int value);
inline bool is_odd(const int value) { return is_odd((unsigned int)value); }
bool is_odd(const unsigned long value);
inline bool is_odd(const long value) { return is_odd((unsigned long)value); }
bool is_odd(const unsigned long long value);
inline bool is_odd(const long long value) { return is_odd((unsigned long long)value); }
//***************************************************************************
/// Checks if even.
//***************************************************************************
bool is_even(const unsigned char value);
inline bool is_even(const char value) { return is_even((unsigned char)value); }
bool is_even(const unsigned short value);
inline bool is_even(const short value) { return is_even((unsigned short)value); }
bool is_even(const unsigned int value);
inline bool is_even(const int value) { return is_even((unsigned int)value); }
bool is_even(const unsigned long value);
inline bool is_even(const long value) { return is_even((unsigned long)value); }
bool is_even(const unsigned long long value);
inline bool is_even(const long long value) { return is_even((unsigned long long)value); }
//***************************************************************************
/// 8 bit binary constants.
//***************************************************************************

View File

@ -467,4 +467,132 @@ namespace etl
return count;
}
#if ETL_8BIT_SUPPORT
//*****************************************************************************
/// Binary interleave
//*****************************************************************************
uint16_t binary_interleave(uint8_t first, uint8_t second)
{
static const uint16_t mask[] = { 0x5555, 0x3333, 0x0F0F };
uint16_t f = first;
uint16_t s = second;
f = (f | (f << 4)) & mask[2];
f = (f | (f << 2)) & mask[1];
f = (f | (f << 1)) & mask[0];
s = (s | (s << 4)) & mask[2];
s = (s | (s << 2)) & mask[1];
s = (s | (s << 1)) & mask[0];
return (f | (s << 1));
}
#endif
//*****************************************************************************
/// Binary interleave
//*****************************************************************************
uint32_t binary_interleave(uint16_t first, uint16_t second)
{
static const uint32_t mask[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF };
uint32_t f = first;
uint32_t s = second;
f = (f | (f << 8)) & mask[3];
f = (f | (f << 4)) & mask[2];
f = (f | (f << 2)) & mask[1];
f = (f | (f << 1)) & mask[0];
s = (s | (s << 8)) & mask[3];
s = (s | (s << 4)) & mask[2];
s = (s | (s << 2)) & mask[1];
s = (s | (s << 1)) & mask[0];
return (f | (s << 1));
}
//*****************************************************************************
/// Binary interleave
//*****************************************************************************
uint64_t binary_interleave(uint32_t first, uint32_t second)
{
static const uint64_t mask[] = { 0x5555555555555555, 0x3333333333333333, 0x0F0F0F0F0F0F0F0F, 0x00FF00FF00FF00FF, 0x0000FFFF0000FFFF };
uint64_t f = first;
uint64_t s = second;
f = (f | (f << 16)) & mask[4];
f = (f | (f << 8)) & mask[3];
f = (f | (f << 4)) & mask[2];
f = (f | (f << 2)) & mask[1];
f = (f | (f << 1)) & mask[0];
s = (s | (s << 16)) & mask[4];
s = (s | (s << 8)) & mask[3];
s = (s | (s << 4)) & mask[2];
s = (s | (s << 2)) & mask[1];
s = (s | (s << 1)) & mask[0];
return (f | (s << 1));
}
//***************************************************************************
/// Checks if odd.
//***************************************************************************
bool is_odd(const unsigned char value)
{
return ((value & 1U) != 0U);
}
bool is_odd(const unsigned short value)
{
return ((value & 1U) != 0U);
}
bool is_odd(const unsigned int value)
{
return ((value & 1U) != 0U);
}
bool is_odd(const unsigned long value)
{
return ((value & 1U) != 0U);
}
bool is_odd(const unsigned long long value)
{
return ((value & 1U) != 0U);
}
//***************************************************************************
/// Checks if even.
//***************************************************************************
bool is_even(const unsigned char value)
{
return ((value & 1U) == 0U);
}
bool is_even(const unsigned short value)
{
return ((value & 1U) == 0U);
}
bool is_even(const unsigned int value)
{
return ((value & 1U) == 0U);
}
bool is_even(const unsigned long value)
{
return ((value & 1U) == 0U);
}
bool is_even(const unsigned long long value)
{
return ((value & 1U) == 0U);
}
}

View File

@ -1480,6 +1480,44 @@ namespace
CHECK(!(etl::has_byte_n<>::test(int64_t(0x0123456789ABCDEF), 0x12)));
CHECK((etl::has_byte_n<>::test(int64_t(0x0123456789ABCDEF), 0xAB)));
}
//*************************************************************************
TEST(test_binary_merge)
{
CHECK_EQUAL((etl::binary_merge(uint8_t(0x12), uint8_t(0x34), uint8_t(0xF0))), uint8_t(0x14));
CHECK_EQUAL((etl::binary_merge<uint8_t, 0xF0>(uint8_t(0x12), uint8_t(0x34))), uint8_t(0x14));
CHECK_EQUAL((etl::binary_merge(uint16_t(0x1234), uint16_t(0x3456), uint16_t(0xF0F0))), uint16_t(0x1436));
CHECK_EQUAL((etl::binary_merge<uint16_t, 0xF0F0>(uint16_t(0x1234), uint16_t(0x3456))), uint16_t(0x1436));
CHECK_EQUAL((etl::binary_merge(uint32_t(0x12345678), uint32_t(0x3456789A), uint32_t(0xF0F0F0F0))), uint32_t(0x1436587A));
CHECK_EQUAL((etl::binary_merge<uint32_t, 0xF0F0F0F0>(uint32_t(0x12345678), uint32_t(0x3456789A))), uint32_t(0x1436587A));
CHECK_EQUAL((etl::binary_merge(uint64_t(0x123456789ABCDEF0), uint64_t(0x3456789ABCDEF012), uint64_t(0xF0F0F0F0F0F0F0F0))), uint64_t(0x1436587A9CBED0F2));
CHECK_EQUAL((etl::binary_merge<uint64_t, 0xF0F0F0F0F0F0F0F0>(uint64_t(0x123456789ABCDEF0), uint64_t(0x3456789ABCDEF012))), uint64_t(0x1436587A9CBED0F2));
}
//*************************************************************************
TEST(test_binary_interleave)
{
CHECK_EQUAL((etl::binary_interleave(uint8_t(0x5A), uint8_t(0xA5))), uint16_t(0x9966));
CHECK_EQUAL((etl::binary_interleave(uint16_t(0x5A5A), uint16_t(0xA5A5))), uint32_t(0x99669966));
CHECK_EQUAL((etl::binary_interleave(uint32_t(0x5A5A5A5A), uint32_t(0xA5A5A5A5))), uint64_t(0x9966996699669966));
}
//*************************************************************************
TEST(test_is_odd)
{
CHECK(etl::is_odd(1));
CHECK(!etl::is_odd(2));
}
//*************************************************************************
TEST(test_is_even)
{
CHECK(!etl::is_even(1));
CHECK(etl::is_even(2));
}
};
}