#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
typedef enum{
MASK_DOWNSHIFT__BEGIN,
MASK_DOWNSHIFT__BITS,
MASK_DOWNSHIFT__AFTER,
}Mask_Downshift_State;
size_t mask_downshift(size_t value, size_t mask)
{
assert(mask && "Mask can't be 0");
size_t result_masked = value & mask;
size_t shift_length = 0;
size_t mask_check = mask;
Mask_Downshift_State state = MASK_DOWNSHIFT__BEGIN;
for(size_t i = 0; i < sizeof(size_t) * 8; ++i)
{
size_t current_bit_value = mask_check & 1;
if(state == MASK_DOWNSHIFT__BEGIN && current_bit_value == 1)
{
shift_length = i;
state = MASK_DOWNSHIFT__BITS;
}
else if(state == MASK_DOWNSHIFT__BITS && current_bit_value == 0)
{
state = MASK_DOWNSHIFT__AFTER;
}
else if(state == MASK_DOWNSHIFT__AFTER && current_bit_value == 1)
{
assert(false && "Bit mask is not contiguous");
}
mask_check >>= 1;
}
size_t result = result_masked >> shift_length;
return result;
}
int main(void) {
volatile size_t value = 0x0FF0123400FFF000;
size_t result = mask_downshift(value, 0x0000FFFF00000000);
printf("%lx\n", result);
return 0;
}