Still getting used to the use of OptionSetType
in Swift.
In good ol' C, if I had something like
typedef enum {
CHAR_PROP_BROADCAST =0x01,
CHAR_PROP_READ =0x02,
CHAR_PROP_WRITE_WITHOUT_RESP =0x04,
CHAR_PROP_WRITE =0x08,
CHAR_PROP_NOTIFY =0x10,
CHAR_PROP_INDICATE =0x20,
CHAR_PROP_SIGNED_WRITE =0x40,
CHAR_PROP_EXT =0x80
} 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])
or
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)
result:
"true"
"true"
"true"
"true"