Travis Griggs Travis Griggs - 7 months ago 42
Swift Question

more idiomatic swift test for optionset?

Still getting used to the use of

in Swift.

In good ol' C, if I had something like

typedef enum {
} CharacteristicProperty;

I could test a set of flags with something simple like:

if ((propertiesMask & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) != 0) ...

The Swift alternative might look like

let properties:CBCharacteristicProperties = [.Write, .Read, .Indicate]
!properties.intersect([.Indicate, .Notify]).isEmpty

Is there a more idiomatic way to do this test? Not a fan of the ! out front. But otherwise, seems straightforward enough, except I'm really interested in when there IS an intersection. This led me to want to add my own.

extension OptionSetType {
func hasIntersection(other:Self) -> Bool {
return !self.intersect(other).isEmpty

Which then allows me to write

properties.hasIntersection([.Indicate, .Notify])

Is there a better/more idiomatic way to do this? Did I roll my own and miss something?


There's this method from the protocol SetAlgebraType which OptionSetType implements:

isDisjointWith(_: Self) -> Bool

Returns true iff self.intersect(other).isEmpty.

So you could shorten your test to:

!properties.isDisjointWith([.Indicate, .Notify])


properties.isDisjointWith([.Indicate, .Notify]) == false

You can also compare the raw values with bitwise operators, just as you would do in C:

(properties.rawValue & (CharacteristicProperties.Notify.rawValue | CharacteristicProperties.Indicate.rawValue)) != 0

Full example code (in a playground):

struct CBCharacteristicProperties : OptionSetType {
  let rawValue: UInt
  init(rawValue: UInt) { self.rawValue = rawValue }

  static let Broadcast          = CBCharacteristicProperties(rawValue:0x01)
  static let Read               = CBCharacteristicProperties(rawValue:0x02)
  static let WriteWithoutResp   = CBCharacteristicProperties(rawValue:0x04)
  static let Write              = CBCharacteristicProperties(rawValue:0x08)
  static let Notify             = CBCharacteristicProperties(rawValue:0x10)
  static let Indicate           = CBCharacteristicProperties(rawValue:0x20)
  static let SignedWrite        = CBCharacteristicProperties(rawValue:0x40)
  static let Ext                = CBCharacteristicProperties(rawValue:0x80)

let properties = CBCharacteristicProperties([.Write, .Read, .Indicate])
print(!properties.intersect([.Indicate, .Notify]).isEmpty)
print(!properties.isDisjointWith([.Indicate, .Notify]))
print(properties.isDisjointWith([.Indicate, .Notify]) == false)
print((properties.rawValue & (CBCharacteristicProperties.Notify.rawValue | CBCharacteristicProperties.Indicate.rawValue)) != 0)