#include "bit.h"
#include "testing.h"
[[gnu::const]] static size_t nulCheck(size_t x) {
size_t m = repeatBytes(0x7f);
return (x & m) + m | m;
}
[[gnu::const]] bool fza(size_t x) {
return ~(nulCheck(x) | x);
}
[[gnu::const]] bool isNulExist(size_t x) {
return ~nulCheck(x);
}
test (zero_byte_check) {
size_t x = 0x10'10'10'10'10'00'00'00;
expect(fza(x));
expect(isNulExist(x));
x = 0xde'ad'be'ef'de'ad'be'ef;
expect(!fza(x));
expect(!isNulExist(x));
x = 0x80'80'80'80'80'80'80'80;
expect(!fza(x));
expect(isNulExist(x));
}
[[gnu::const]] size_t repeatBytes(byte_t c) {
return -1UL / 0xff * (size_t)c;
}
test_table(
repeat_bytes, repeatBytes, (size_t, byte_t),
{
{0xff'ff'ff'ff'ff'ff'ff'ff, 0xff},
{0x12'12'12'12'12'12'12'12, 0x12},
{0x01'01'01'01'01'01'01'01, 0x01},
{0x00'00'00'00'00'00'00'00, 0x00},
}
)
/**
* @brief Align to multiples of size
* @param[in] base Pointer
* @param[in] size Size
* @return Aligned pointer
*/
[[gnu::const]] void *alignBackward(void const *base, size_t size) {
return (void *)((size_t)base & -size);
}
[[gnu::const]] void *alignForward(void const *base, size_t size) {
return alignBackward(base + size - 1, size);
}
test_table(
alignBack, alignBackward, (void *, void const *, size_t),
{
{(void *)8, (void *)9, 8},
{(void *)8, (void *)15, 8},
{(void *)8, (void *)8, 8},
}
)
test_table(
alignFor, alignForward, (void *, void const *, size_t),
{
{(void *)8, (void *)5, 8},
{(void *)8, (void *)1, 8},
{(void *)8, (void *)8, 8},
}
)