Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use bit field with Swift to store values with more than 1 bit

In C I can do something like this:

struct byte_nibbles {
    unsigned char b1: 4;
    unsigned char b2: 4;
    unsigned char b3: 4;
    unsigned char b4: 4;
    unsigned char b5: 4;
    unsigned char b6: 4;
    unsigned char b7: 4;
    unsigned char b8: 4;
};

union {
    unsigned long var;
    struct byte_nibbles b;
}
u;

int main(void)
{
    u.b.b1=0x01; u.b.b2=0x02; u.b.b3=0x03; u.b.b4=0x04;
    u.b.b5=0x05; u.b.b6=0x06; u.b.b7=0x07; u.b.b8=0x08;
    return 0;
}

So I can access specific parts of the byte_nibbles. Obviously this is just one example. It is possible to create bit fields of any size that fits in the basic types.

Despite my efforts and a lot of research I could not figure out how to do this in Swift. I can use bitwise to have the same result, but this is not as readable and elegant.

Any idea?

like image 537
Cesar Gimenes Avatar asked Sep 28 '22 23:09

Cesar Gimenes


1 Answers

Swift simply does not support bit fields, so you can only

  • use the next larger integer type instead (in your case Int8) and accept that the variables need more memory, or
  • use bit operations to access the different parts of the integer.

For the second case you could define custom computed properties to ease the access. As an example:

extension UInt8 {
    var lowNibble : UInt8 {
        get {
            return self & 0x0F
        }
        set(newValue) {
            self = (self & 0xF0) | (newValue & 0x0F)
        }
    }

    var highNibble : UInt8 {
        get {
            return (self & 0xF0) >> 4
        }
        set(newValue) {
            self = (self & 0x0F) | ((newValue & 0x0F) << 4)
        }
    }
}


var byte : UInt8 = 0
byte.lowNibble = 0x01
byte.highNibble = 0x02
print(byte.lowNibble)
print(byte.highNibble)
like image 186
Martin R Avatar answered Nov 01 '22 15:11

Martin R