Perform OR operation to all elements in array

0

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?

swift
asked on Stack Overflow Jan 20, 2019 by sabi • edited Jan 20, 2019 by Sulthan

1 Answer

3

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.

answered on Stack Overflow Jan 20, 2019 by Sulthan • edited Jan 20, 2019 by Sulthan

User contributions licensed under CC BY-SA 3.0