swiftoptionsettypeoption-set

What is a convenient way to work with OptionSet?


I work on a project with many bitwise option sets and each of them contains many options with all option e.g:

struct MyOption: OptionSet {
    let rawValue: Int
    
    static let a = Self(rawValue: 1 << 0)
    static let b = Self(rawValue: 1 << 1)
    static let c = Self(rawValue: 1 << 2)
    ...
    static let last = Self(rawValue: 1 << N)
    
    static let all: Self = [.a, .b, .c, ..., .last]
}

It requires to maintain much of similar code so is it any way to eliminate hardcoded bitwise shift operations and the all option?


Solution

  • You can use next OptionSet's extension which implements all option and a convenient initializer:

    extension OptionSet where RawValue == Int {
        static var all: Self {
            Self.init(rawValue: Int.max)
        }
        
        init(_ shift: Int) {
            self.init(rawValue: 1 << shift)
        }
    }
    

    Then you can re-write your option set:

    struct Option: OptionSet {
        let rawValue: Int
        
        static let a = Self(0)
        static let b = Self(1)
        static let c = Self(2)
    }
    
    Option.a.rawValue // 1
    Option.b.rawValue // 2
    Option.c.rawValue // 4
    
    let options: Option = [.a, .b]
    Option.all.contains(options) // true