Swift Bitmasks - Things nobody needs

Whoever wrote an iOS App in Objective-C knows bitmasks very well. Even just configuring a simple UIButton one is confronted with a UIControlState and things like UIControlStateHighlighted|UIControlStateDisabled. Before autolayout one had to fight with UIViewAutoresizing. But bitmasks aren’t a common concept in Swift and creating them isn’t trivial.

To get a better understanding of bitmasks, generics and bitshifting in swift I wrote an extension fo UInt8 which is an eight bit bitmask. Bigger bitmasks aren’t difficult either.

typealias Bitmask = UInt8
typealias BitName = UInt8

extension Bitmask {
    func setBit<T: RawRepresentable>(at index: T, newValue: Bool) -> Bitmask where T.RawValue == BitName {
        let rawValue = index.rawValue
        let currentState: Bool = getBit(at: index)
        if currentState != newValue {
            return self ^ (1 << rawValue)
        }
        return self
    }
    
    func getBit<T: RawRepresentable>(at index: T) -> Bool where T.RawValue == BitName {
        let rawValue = index.rawValue
        return self & (1 << rawValue) > 0
    }
    
    var description: String {
        return "[\((self>>7)%2),\((self>>6)%2),\((self>>5)%2),\((self>>4)%2),\((self>>3)%2),\((self>>2)%2),\((self>>1)%2),\(self%2)]"
    }
}

With a simple usage.

enum RoomBitNames: BitName {
    case Livingroom = 0
    case Kitchen = 1
    case Bedroom = 2
    // there can be 5 more bits
}


let a: Bitmask = 0
let b = a.setBit(at: RoomBitNames.Livingroom, newValue: true)
let c = b.setBit(at: RoomBitNames.Kitchen, newValue: true)
let hasLivingroom = c.getBit(at: RoomBitNames.Livingroom)
let hasKitchen = c.getBit(at: RoomBitNames.Kitchen)
let hasBedroom = c.getBit(at: RoomBitNames.Bedroom)
print(a.description)
print(b.description)
print(c.description)