swift2 - How do you enumerate OptionSetType in Swift? -
i have custom optionsettype struct in swift. how can enumerate values of instance?
this optionsettype:
struct weekdayset: optionsettype { let rawvalue: uint8 init(rawvalue: uint8) { self.rawvalue = rawvalue } static let sunday = weekdayset(rawvalue: 1 << 0) static let monday = weekdayset(rawvalue: 1 << 1) static let tuesday = weekdayset(rawvalue: 1 << 2) static let wednesday = weekdayset(rawvalue: 1 << 3) static let thursday = weekdayset(rawvalue: 1 << 4) static let friday = weekdayset(rawvalue: 1 << 5) static let saturday = weekdayset(rawvalue: 1 << 6) }
i this:
let weekdays: weekdayset = [.monday, .tuesday] weekday in weekdays { // weekday }
as of swift 4, there no methods in standard library enumerate elements of optionsettype
(swift 2) resp. optionset
(swift 3, 4).
here possible implementation checks each bit of underlying raw value, , each bit set, corresponding element returned. "overflow multiplication" &* 2
used left-shift because <<
defined concrete integer types, not integertype
protocol.
swift 2.2:
public extension optionsettype rawvalue : integertype { func elements() -> anysequence<self> { var remainingbits = self.rawvalue var bitmask: rawvalue = 1 return anysequence { return anygenerator { while remainingbits != 0 { defer { bitmask = bitmask &* 2 } if remainingbits & bitmask != 0 { remainingbits = remainingbits & ~bitmask return self(rawvalue: bitmask) } } return nil } } } }
example usage:
let weekdays: weekdayset = [.monday, .tuesday] weekday in weekdays.elements() { print(weekday) } // output: // weekdayset(rawvalue: 2) // weekdayset(rawvalue: 4)
swift 3:
public extension optionset rawvalue : integer { func elements() -> anysequence<self> { var remainingbits = rawvalue var bitmask: rawvalue = 1 return anysequence { return anyiterator { while remainingbits != 0 { defer { bitmask = bitmask &* 2 } if remainingbits & bitmask != 0 { remainingbits = remainingbits & ~bitmask return self(rawvalue: bitmask) } } return nil } } } }
swift 4:
public extension optionset rawvalue: fixedwidthinteger { func elements() -> anysequence<self> { var remainingbits = rawvalue var bitmask: rawvalue = 1 return anysequence { return anyiterator { while remainingbits != 0 { defer { bitmask = bitmask &* 2 } if remainingbits & bitmask != 0 { remainingbits = remainingbits & ~bitmask return self(rawvalue: bitmask) } } return nil } } } }
Comments
Post a Comment