I am aware of the OptionSet protocol, that is used to represent a "mathematical bit set". But I found it too be a bit "too much" for a simple bitmap. So I created my own, called RawBits. This is the first protocol I've written in Swift, so I'd be interested in any constructive criticism anyone might have.
Thanks! extension String { public func pad(with padding: Character, toLength length: Int) -> String { let paddingWidth = length - self.count guard 0 < paddingWidth else { return self } return String(repeating: padding, count: paddingWidth) + self } } extension Bool: ExpressibleByIntegerLiteral { public init(integerLiteral value: Int) { self = value != 0 } } public enum Bit: Bool { case off = 0 case on = 1 } public protocol RawBits: RawRepresentable, CustomStringConvertible { associatedtype Element = Self init(rawValue: RawValue) } extension RawBits { public init(_ rawValue: RawValue) { self.init(rawValue: rawValue) } } extension RawBits where RawValue: FixedWidthInteger, RawValue: UnsignedInteger { public init() { self.init(rawValue: 0) } public func asRadix(_ radix: Int) -> String { let s = String(self.rawValue, radix: radix, uppercase: true) var x: Int switch radix { case 16: x = 4 case 2: x = 1 default: x = 0 } return x == 0 ? s : s.pad(with: "0", toLength: rawValue.bitWidth / x) } public var asBinary: String { return asRadix(2) } public var asDecimal: String { return asRadix(10) } public var asHex: String { return asRadix(16) } public var description: String { return asBinary } public var bitWidth: Int { return rawValue.bitWidth } private func rangeCheck(_ bit: UInt) { guard bit < rawValue.bitWidth else { fatalError("Index out of range") } } public func get(bit: UInt) -> Bool { rangeCheck(bit) return (rawValue >> bit) & 1 == 1 } public func setOn(bit: UInt) -> RawValue { rangeCheck(bit) return rawValue | 1 << bit } public func setOff(bit: UInt) -> RawValue { rangeCheck(bit) return rawValue & ~(1 << bit) } public subscript(x: UInt) -> Bit { get { return Bit(rawValue: get(bit: x))! } set { self = Self(newValue == .on ? setOn(bit: x) : setOff(bit: x)) } } } struct RawBits64: RawBits { let rawValue: UInt64 } var bitmap = RawBits64(0xF33AC401A8E08062) print(bitmap.bitWidth) print(bitmap) print(bitmap.asHex) print(bitmap.asDecimal) bitmap[0] = Bit.on print(bitmap[0]) print(bitmap) print(bitmap.asHex) bitmap[0] = Bit.off print(bitmap[0]) print(bitmap) bitmap[7] = .on print(bitmap[7]) print(bitmap) bitmap[7] = .off print(bitmap[7]) print(bitmap) bitmap[63] = .off print(bitmap) #if OOR print(bitmap[64]) // fatal error, out of range #endif
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users