0

Is it possible (if so, how) to convert a struct of integers into a bitmask. One bit for each integer (0 if the int is 0, otherwise 1). For example

struct Int_List_t
{  
    uint64_t int1;
    uint64_t int2;
    uint64_t int3;
    uint64_t int4;
} int_list={10,0,5,0};



char int_mask = somefunction(int_list); 
//Would contain 1010
                ||||
                |||+-- int4 is 0
                ||+--- int3 is not 0
                |+---- int2 is 0
                +----- int1 is not 0
Barry
  • 286,269
  • 29
  • 621
  • 977

1 Answers1

2

You could just do it explicitly:

char mask(const Int_List_t& vals)
{
    return (vals.int1 ? 0x8 : 0x0) |
           (vals.int2 ? 0x4 : 0x0) |
           (vals.int3 ? 0x2 : 0x0) |
           (vals.int4 ? 0x1 : 0x0);
}

If you passed in an array instead of a struct, you could write a loop:

template <size_t N>
uint64_t mask(uint64_t (&vals)[N])
{
    uint64_t result = 0;
    uint64_t mask = 1 << (N - 1); 
    for (size_t i = 0; i < N; ++i, mask >>= 1) {
        result |= (vals[i] ? mask : 0); 
    }   
    return result;
}

If you're open to completely bypassing any type safety whatsoever, you could even implement the above by just reinterpreting your object to be a pointer, although I wouldn't necessarily recommend it:

template <typename T>
uint64_t mask(const T& obj)
{
    const uint64_t* p = reinterpret_cast<const uint64_t*>(&obj);
    const uint64_t N = sizeof(T)/8;

    uint64_t result = 0;
    uint64_t mask = 1 << (N - 1); 
    for (size_t i = 0; i < N; ++i, ++p, mask >>= 1) {
        result |= (*p ? mask : 0); 
    }   
    return result;
}
Barry
  • 286,269
  • 29
  • 621
  • 977
  • I was hoping for a builtin way, because I am expanding this to 16 or maybe even 32 bit integers. – Nigel Armstrong Jan 20 '15 at 16:28
  • @NigelArmstrong Gave you some more options. – Barry Jan 20 '15 at 16:48
  • @Barry Apologies. What I should have said is that code exhibits the dreadful bad practice of using the comma operator in a `for(;;)` declaration that only serves to confuse readers! ;) – Persixty Jan 20 '15 at 17:09
  • 1
    @DanAllen If you need to change more than one thing in the iteration step, that is the way to do it... – Barry Jan 20 '15 at 17:16