ios - How to create NS_OPTIONS-style bitmask enumerations in Swift? -


in apple's documentation interacting c apis, describe way ns_enum-marked c-style enumerations imported swift enumerations. makes sense, , since enumerations in swift readily provided enum value type it's easy see how create our own.

further down, says ns_options-marked c-style options:

swift imports options marked ns_options macro. whereas options behave imported enumerations, options can support bitwise operations, such &, |, , ~. in objective-c, represent empty option set constant 0 (0). in swift, use nil represent absence of options.

given there isn't options value type in swift, how can create c-style options variable work with?

swift 3.0

almost identical swift 2.0. optionsettype renamed optionset , enums written lower case convention.

struct myoptions : optionset {     let rawvalue: int      static let firstoption  = myoptions(rawvalue: 1 << 0)     static let secondoption = myoptions(rawvalue: 1 << 1)     static let thirdoption  = myoptions(rawvalue: 1 << 2) } 

instead of providing none option, swift 3 recommendation use empty array literal:

let nooptions: myoption = [] 

other usage:

let singleoption = myoptions.firstoption let multipleoptions: myoptions = [.firstoption, .secondoption] if multipleoptions.contains(.secondoption) {     print("multipleoptions has secondoption") } let alloptions = myoptions(rawvalue: 7) if alloptions.contains(.thirdoption) {     print("alloptions has thirdoption") } 

swift 2.0

in swift 2.0, protocol extensions take care of of boilerplate these, imported struct conforms optionsettype. (rawoptionsettype has disappeared of swift 2 beta 2.) declaration far simpler:

struct myoptions : optionsettype {     let rawvalue: int      static let none         = myoptions(rawvalue: 0)     static let firstoption  = myoptions(rawvalue: 1 << 0)     static let secondoption = myoptions(rawvalue: 1 << 1)     static let thirdoption  = myoptions(rawvalue: 1 << 2) } 

now can use set-based semantics myoptions:

let singleoption = myoptions.firstoption let multipleoptions: myoptions = [.firstoption, .secondoption] if multipleoptions.contains(.secondoption) {     print("multipleoptions has secondoption") } let alloptions = myoptions(rawvalue: 7) if alloptions.contains(.thirdoption) {     print("alloptions has thirdoption") } 

swift 1.2

looking @ objective-c options imported swift (uiviewautoresizing, example), can see options declared struct conforms protocol rawoptionsettype, in turn conforms _rawoptionsettype, equatable, rawrepresentable, bitwiseoperationstype, , nilliteralconvertible. can create our own this:

struct myoptions : rawoptionsettype {     typealias rawvalue = uint     private var value: uint = 0     init(_ value: uint) { self.value = value }     init(rawvalue value: uint) { self.value = value }     init(nilliteral: ()) { self.value = 0 }     static var allzeros: myoptions { return self(0) }     static func frommask(raw: uint) -> myoptions { return self(raw) }     var rawvalue: uint { return self.value }      static var none: myoptions { return self(0) }     static var firstoption: myoptions   { return self(1 << 0) }     static var secondoption: myoptions  { return self(1 << 1) }     static var thirdoption: myoptions   { return self(1 << 2) } } 

now can treat new option set, myoptions, described in apple's documentation: can use enum-like syntax:

let opt1 = myoptions.firstoption let opt2: myoptions = .secondoption let opt3 = myoptions(4) 

and behaves we'd expect options behave:

let singleoption = myoptions.firstoption let multipleoptions: myoptions = singleoption | .secondoption if multipleoptions & .secondoption != nil {     // see note     println("multipleoptions has secondoption") } let alloptions = myoptions.frommask(7)   // aka .frommask(0b111) if alloptions & .thirdoption != nil {     println("alloptions has thirdoption") } 

i've built generator create swift option set without find/replacing.

latest: modifications swift 1.1 beta 3.


Comments