Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3.0 OptionSet Bit Test

With the following OptionSet:

struct StatusOptions : OptionSet {
    let rawValue: Int
    static let CountdownDuration0 = StatusOptions(rawValue: 1 << 0)
    static let CountdownDuration1 = StatusOptions(rawValue: 1 << 1)
    static let CountdownDuration2 = StatusOptions(rawValue: 1 << 2)
    static let CountdownDuration3 = StatusOptions(rawValue: 1 << 3)
    static let CountdownDuration4 = StatusOptions(rawValue: 1 << 4)
    static let CountdownDuration5 = StatusOptions(rawValue: 1 << 5)
    static let HomeMode = StatusOptions(rawValue: 1 << 6)
    static let AwayMode = StatusOptions(rawValue: 1 << 7)

    static let Disarmed: StatusOptions = []
    static let ArmedHome: StatusOptions = .HomeMode
    static let ArmedAway: StatusOptions = .AwayMode
    static let ArmedBoth: StatusOptions = [.HomeMode, .AwayMode]
    static let ArmingCountdown: StatusOptions = [.CountdownDuration0, .CountdownDuration1, .CountdownDuration2, .CountdownDuration3, .CountdownDuration4, .CountdownDuration5]
}

How do I compare a byte

var statusFlags: UInt8 = 0b00000000

To the Options?

The following is what I'd think would work, but causes a playground error:

if (statusFlags & .Disarmed) {
    print("Disarmed")
}

Thanks

like image 438
Brandt Avatar asked Sep 30 '16 22:09

Brandt


People also ask

What is OptionSet in Swift?

An OptionSet in Swift is a very lightweight object that can be used to represent a fairly large number of boolean values. While you can initialize it with an array literal, it's actually much more like a Set than an array.

What is OptionSet?

A type that presents a mathematical set interface to a bit set.


1 Answers

Since .Disarmed is zero, you say:

if statusFlags == .Disarmed

or even more simply:

if statusFlags.isEmpty

For other values, you say, e.g.:

if statusFlags.contains(.CountdownDuration3)

That is the whole point of an OptionSet. You use set operations, not arithmetic bit operations.

But for this to work, so that you can take advantage of OptionSet's yummy goodness, statusFlags needs to be a StatusOptions. You can do that by way of the StatusOptions rawValue: initializer:

let statusFlags = StatusOptions(rawValue:0b00000000)
statusFlags.isEmpty // true

(Note that in Swift 3, a zero bitmask like .Disarmed probably wouldn't even be used. Zero is just an empty set.)

like image 50
matt Avatar answered Sep 22 '22 14:09

matt