Quick actions

cmd+k|ctrl+k

Navigation

Languages

mask_downshift

Snippet info

Language

Cpp

Visibility

public

Author

evine

Created

2017-08-17T00:36:31Z

Updated

2017-08-17T00:42:20Z

#include <stdio.h>
#include <assert.h>

enum struct Mask_Downshift_State{
    Begin,
    Bits,
    After,
};

constexpr
size_t get_shift_verify_mask(size_t mask)
{
    size_t shift_length = 0;
    size_t mask_check = mask;
    
    Mask_Downshift_State state = Mask_Downshift_State::Begin;
    
    for(size_t i = 0; i < sizeof(size_t) * 8; ++i)
    {
        size_t current_bit_value = mask_check & 1;
        
        if(state == Mask_Downshift_State::Begin && current_bit_value == 1)
        {
            shift_length = i;
            state = Mask_Downshift_State::Bits;
        }
        else if(state == Mask_Downshift_State::Bits && current_bit_value == 0)
        {
            state = Mask_Downshift_State::After;
        }
        else if(state == Mask_Downshift_State::After && current_bit_value == 1)
        {
            assert(false && "Bit mask is not contiguous");
        }
        
        mask_check >>= 1;
    }

    return shift_length;
}

template<size_t mask> constexpr
size_t mask_downshift(size_t value)
{
    assert(mask && "Mask can't be 0");
    constexpr size_t shift_length = get_shift_verify_mask(mask);
    size_t result = (value & mask) >> shift_length;
    return result;
}

int main(void) {
    volatile size_t value        = 0x0FF0123400FFF000;
    size_t result = mask_downshift<0x0000FFFF00000000>(value);
    printf("%lx\n", result);
    
    return 0;
}
INFO