I want to extend Arrays of Enums: Numeric with a function OR() that ORs all element in the array.
This is what I came up:
extension Array where Element: RawRepresentable, Element.RawValue: Numeric {
func OR(_: Array) -> Element.RawValue {
return self.map{ $0.rawValue }.reduce(0x00000000){ $0|$1 }
}
}
and this is the error thrown by the compiler:
Cannot invoke 'reduce' with an argument list of type '(Int, (_, _) -> _)'
I want use it in situation like:
enum RendererFlags: CUnsignedInt {
case software = 0x00000001 // The renderer is a software fallback
case accelerated = 0x00000002 // The renderer uses hardware acceleration
case presentVSync = 0x00000004 // Present is synchronized with the refresh rate
case targetTexture = 0x00000008 // The renderer supports rendering to texture
}
or enums with other numeric rawValues, and then
let flags = [.software, .accelerated]OR()
Where is my error? Why the compiler is not happy with this?
Numeric
is not enough for your needs, you need BinaryInteger
:
extension Array where Element: RawRepresentable, Element.RawValue: BinaryInteger {
func OR() -> Element.RawValue {
return self.map{ $0.rawValue }.reduce(0) { $0 | $1 }
}
}
Also OR
should be without parameters and you need to specify the type somewhere:
let flags = ([.software, .accelerated] as [RendererFlags]).OR()
However, this can be implemented easier using OptionSet
:
struct RendererFlags: OptionSet {
let rawValue: CUnsignedInt
static let software = RendererFlags(rawValue: 1 << 0)
static let accelerated = RendererFlags(rawValue: 1 << 1)
static let presentVSync = RendererFlags(rawValue: 1 << 2)
static let targetTexture = RendererFlags(rawValue: 1 << 3)
}
let flags: RendererFlags = [.software, .accelerated]
The OR
operation is already implemented for you and the options behave like an array therefore you don't have to worry about mask operations.
User contributions licensed under CC BY-SA 3.0