[swift-users] my first protocol
Frank Swarbrick
fswarbrick at gmail.com
Sat Dec 9 22:41:23 CST 2017
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20171209/4200639e/attachment.html>
More information about the swift-users
mailing list