Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// integerWithBytes.swift
// as seen in http://natecook.com/blog/2015/03/a-sanatorium-for-swift-generics/
//
// (c) 2015 Nate Cook, licensed under the MIT license
protocol BitshiftOperationsType {
func <<(lhs: Self, rhs: Self) -> Self
func >>(lhs: Self, rhs: Self) -> Self
func <<=(inout lhs: Self, rhs: Self)
func >>=(inout lhs: Self, rhs: Self)
}
protocol ByteConvertible {
init(_ value: UInt8)
init(truncatingBitPattern: UInt64)
}
extension Int : BitshiftOperationsType, ByteConvertible { }
extension Int8 : BitshiftOperationsType, ByteConvertible { }
extension Int16 : BitshiftOperationsType, ByteConvertible { }
extension Int32 : BitshiftOperationsType, ByteConvertible { }
extension Int64 : BitshiftOperationsType, ByteConvertible {
init(truncatingBitPattern value: UInt64) {
self = Int64(bitPattern: value)
}
}
extension UInt : BitshiftOperationsType, ByteConvertible { }
extension UInt8 : BitshiftOperationsType, ByteConvertible { }
extension UInt16 : BitshiftOperationsType, ByteConvertible { }
extension UInt32 : BitshiftOperationsType, ByteConvertible { }
extension UInt64 : BitshiftOperationsType, ByteConvertible {
init(truncatingBitPattern value: UInt64) {
self = value
}
}
func integerWithBytes<T: IntegerType where T: ByteConvertible, T: BitshiftOperationsType>
(bytes: [UInt8]) -> T?
{
if bytes.count != sizeof(T) {
return nil
}
if sizeof(T) == 1 {
return T(truncatingBitPattern: UInt64(bytes[0]))
}
var result: T = 0
for byte in bytes.reverse() {
result = result << 8 | T(byte)
}
return result
}
let bytes: [UInt8] = [0xFF, 0xFF, 0xFF, 0xFF]
let unsignedInteger: UInt32? = integerWithBytes(bytes)
let signedInteger: Int32? = integerWithBytes(bytes)
let shouldBeNil: UInt32? = integerWithBytes([1])
let shouldBeOne: UInt32? = integerWithBytes([1, 0, 0, 0])
let test1: UInt8? = integerWithBytes([1])
let test2: UInt8? = integerWithBytes([0xFF])
let test3: Int8? = integerWithBytes([1])
let test4: Int8? = integerWithBytes([0xFF])
let maxInt: Int? = integerWithBytes([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F])
Int.max == maxInt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.