[swift-evolution] [Proposal] Introduces endianness specific type
Susan Cheng
susan.doggie at gmail.com
Thu Jul 6 22:20:58 CDT 2017
IMO, it has unclear representation when FixedWidthInteger working with
endianness specific type.
so I want to introduce the endianness specific wrapper:
public struct BEInteger<Base : FixedWidthInteger> : FixedWidthInteger {
public var bigEndian: BEInteger { get }
public var littleEndian: LEInteger<Base> { get }
}
public struct LEInteger<Base : FixedWidthInteger> : FixedWidthInteger {
public var bigEndian: BEInteger<Base> { get }
public var littleEndian: LEInteger { get }
}
also, we should change the FixedWidthInteger as follow:
public protocol FixedWidthInteger : BinaryInteger {
/// deprecated, we should use value.bigEndian instead
init(bigEndian value: Self)
/// deprecated, we should use value.littleEndian instead
init(littleEndian value: Self)
associatedtype EndianRepresentingValue : FixedWidthInteger
var bigEndian: BEInteger<EndianRepresentingValue> { get }
var littleEndian: LEInteger<EndianRepresentingValue> { get }
}
=============================
this is my working alternative implementation:
@_versioned
protocol EndianInteger : FixedWidthInteger {
associatedtype BitPattern : FixedWidthInteger
associatedtype RepresentingValue : FixedWidthInteger
var bitPattern: BitPattern { get }
init(bitPattern: BitPattern)
var representingValue : RepresentingValue { get set }
init(representingValue: RepresentingValue)
}
extension EndianInteger {
@_transparent
public init(integerLiteral value: RepresentingValue.IntegerLiteralType)
{
self.init(representingValue: RepresentingValue(integerLiteral:
value))
}
@_transparent
public init?<T>(exactly source: T) where T : BinaryInteger {
guard let value = RepresentingValue(exactly: source) else { return
nil }
self.init(representingValue: value)
}
@_transparent
public init?<T>(exactly source: T) where T : FloatingPoint {
guard let value = RepresentingValue(exactly: source) else { return
nil }
self.init(representingValue: value)
}
@_transparent
public init(_ value: RepresentingValue) {
self.init(representingValue: value)
}
@_transparent
public init<T>(_ source: T) where T : FloatingPoint {
self.init(representingValue: RepresentingValue(source))
}
@_transparent
public init<T>(_ source: T) where T : BinaryInteger {
self.init(representingValue: RepresentingValue(source))
}
@_transparent
public init<T>(extendingOrTruncating source: T) where T : BinaryInteger
{
self.init(representingValue: RepresentingValue(extendingOrTruncating:
source))
}
@_transparent
public init<T>(clamping source: T) where T : BinaryInteger {
self.init(representingValue: RepresentingValue(clamping: source))
}
@_transparent
public init(_truncatingBits bits: UInt) {
self.init(representingValue: RepresentingValue(_truncatingBits:
bits))
}
}
extension EndianInteger {
@_transparent
public static var isSigned: Bool {
return RepresentingValue.isSigned
}
@_transparent
public static var bitWidth: Int {
return RepresentingValue.bitWidth
}
@_transparent
public static var max: Self {
return Self(representingValue: RepresentingValue.max)
}
@_transparent
public static var min: Self {
return Self(representingValue: RepresentingValue.min)
}
}
extension EndianInteger {
@_transparent
public var hashValue: Int {
return representingValue.hashValue
}
@_transparent
public var description: String {
return representingValue.description
}
@_transparent
public var bitWidth: Int {
return representingValue.bitWidth
}
@_transparent
public var magnitude: RepresentingValue.Magnitude {
return representingValue.magnitude
}
@_transparent
public var trailingZeroBitCount: Int {
return representingValue.trailingZeroBitCount
}
@_transparent
public var nonzeroBitCount: Int {
return representingValue.nonzeroBitCount
}
@_transparent
public var leadingZeroBitCount: Int {
return representingValue.leadingZeroBitCount
}
@_transparent
public var byteSwapped: Self {
return Self(representingValue: representingValue.byteSwapped)
}
}
extension EndianInteger {
@_transparent
public func _word(at n: Int) -> UInt {
return representingValue._word(at: n)
}
@_transparent
public func distance(to other: Self) -> RepresentingValue.Stride {
return self.representingValue.distance(to: other.representingValue)
}
@_transparent
public func advanced(by n: RepresentingValue.Stride) -> Self {
return Self(representingValue: self.representingValue.advanced(by:
n))
}
@_transparent
public func addingReportingOverflow(_ rhs: Self) -> (partialValue: Self,
overflow: ArithmeticOverflow) {
let (partialValue, overflow) = representingValue.addingReport
ingOverflow(rhs.representingValue)
return (Self(representingValue: partialValue), overflow)
}
@_transparent
public func subtractingReportingOverflow(_ rhs: Self) -> (partialValue:
Self, overflow: ArithmeticOverflow) {
let (partialValue, overflow) = representingValue.subtractingR
eportingOverflow(rhs.representingValue)
return (Self(representingValue: partialValue), overflow)
}
@_transparent
public func multipliedReportingOverflow(by rhs: Self) -> (partialValue:
Self, overflow: ArithmeticOverflow) {
let (partialValue, overflow) = representingValue.multipliedRe
portingOverflow(by: rhs.representingValue)
return (Self(representingValue: partialValue), overflow)
}
@_transparent
public func dividedReportingOverflow(by rhs: Self) -> (partialValue:
Self, overflow: ArithmeticOverflow) {
let (partialValue, overflow) = representingValue.dividedRepor
tingOverflow(by: rhs.representingValue)
return (Self(representingValue: partialValue), overflow)
}
@_transparent
public func remainderReportingOverflow(dividingBy rhs: Self) ->
(partialValue: Self, overflow: ArithmeticOverflow) {
let (partialValue, overflow) = representingValue.remainderRep
ortingOverflow(dividingBy: rhs.representingValue)
return (Self(representingValue: partialValue), overflow)
}
@_transparent
public func multipliedFullWidth(by other: Self) -> (high: Self, low:
RepresentingValue.Magnitude) {
let (high, low) = representingValue.multipliedFullWidth(by: other.
representingValue)
return (Self(representingValue: high), low)
}
@_transparent
public func dividingFullWidth(_ dividend: (high: Self, low:
RepresentingValue.Magnitude)) -> (quotient: Self, remainder: Self) {
let (quotient, remainder) = representingValue.dividingFullWidth
((dividend.high.representingValue, dividend.low))
return (Self(representingValue: quotient), Self(representingValue:
remainder))
}
}
extension EndianInteger {
@_transparent
public static prefix func +(x: Self) -> Self {
return x
}
@_transparent
public static func +(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue + rhs.
representingValue)
}
@_transparent
public static func +=(lhs: inout Self, rhs: Self) {
lhs.representingValue += rhs.representingValue
}
@_transparent
public static func -(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue - rhs.
representingValue)
}
@_transparent
public static func -=(lhs: inout Self, rhs: Self) {
lhs.representingValue -= rhs.representingValue
}
@_transparent
public static func *(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue * rhs.
representingValue)
}
@_transparent
public static func *=(lhs: inout Self, rhs: Self) {
lhs.representingValue *= rhs.representingValue
}
@_transparent
public static func /(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue / rhs.
representingValue)
}
@_transparent
public static func /=(lhs: inout Self, rhs: Self) {
lhs.representingValue /= rhs.representingValue
}
@_transparent
public static func %(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue % rhs.
representingValue)
}
@_transparent
public static func %=(lhs: inout Self, rhs: Self) {
lhs.representingValue %= rhs.representingValue
}
@_transparent
public static func &(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue & rhs.
representingValue)
}
@_transparent
public static func &=(lhs: inout Self, rhs: Self) {
lhs.representingValue &= rhs.representingValue
}
@_transparent
public static func |(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue | rhs.
representingValue)
}
@_transparent
public static func |=(lhs: inout Self, rhs: Self) {
lhs.representingValue |= rhs.representingValue
}
@_transparent
public static func ^(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue ^ rhs.
representingValue)
}
@_transparent
public static func ^=(lhs: inout Self, rhs: Self) {
lhs.representingValue ^= rhs.representingValue
}
@_transparent
prefix public static func ~(x: Self) -> Self {
return Self(representingValue: ~x.representingValue)
}
@_transparent
public static func &>>(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue &>> rhs.
representingValue)
}
@_transparent
public static func &<<(lhs: Self, rhs: Self) -> Self {
return Self(representingValue: lhs.representingValue &<< rhs.
representingValue)
}
@_transparent
public static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.bitPattern == rhs.bitPattern
}
@_transparent
public static func !=(lhs: Self, rhs: Self) -> Bool {
return lhs.bitPattern != rhs.bitPattern
}
@_transparent
public static func >(lhs: Self, rhs: Self) -> Bool {
return lhs.representingValue > rhs.representingValue
}
@_transparent
public static func <(lhs: Self, rhs: Self) -> Bool {
return lhs.representingValue < rhs.representingValue
}
@_transparent
public static func >=(lhs: Self, rhs: Self) -> Bool {
return lhs.representingValue >= rhs.representingValue
}
@_transparent
public static func <=(lhs: Self, rhs: Self) -> Bool {
return lhs.representingValue <= rhs.representingValue
}
}
public struct BEInteger<Base : FixedWidthInteger> : FixedWidthInteger,
EndianInteger {
public var bitPattern: Base
@_transparent
public init(bitPattern: Base) {
self.bitPattern = bitPattern
}
@_versioned
@_transparent
init(representingValue: Base) {
self.bitPattern = representingValue.bigEndian
}
@_versioned
@_transparent
var representingValue: Base {
get {
return Base(bigEndian: bitPattern)
}
set {
bitPattern = newValue.bigEndian
}
}
@_transparent
public init(bigEndian value: BEInteger) {
self.bitPattern = value.bitPattern
}
@_transparent
public init(littleEndian value: BEInteger) {
self.bitPattern = value.bitPattern.byteSwapped
}
@_transparent
public var bigEndian: BEInteger {
return self
}
@_transparent
public var littleEndian: BEInteger {
return BEInteger(littleEndian: self)
}
}
public struct LEInteger<Base : FixedWidthInteger> : FixedWidthInteger,
EndianInteger {
public var bitPattern: Base
@_transparent
public init(bitPattern: Base) {
self.bitPattern = bitPattern
}
@_versioned
@_transparent
init(representingValue: Base) {
self.bitPattern = representingValue.littleEndian
}
@_versioned
@_transparent
var representingValue: Base {
get {
return Base(littleEndian: bitPattern)
}
set {
bitPattern = newValue.littleEndian
}
}
@_transparent
public init(bigEndian value: LEInteger) {
self.bitPattern = value.bitPattern.byteSwapped
}
@_transparent
public init(littleEndian value: LEInteger) {
self.bitPattern = value.bitPattern
}
@_transparent
public var bigEndian: LEInteger {
return LEInteger(bigEndian: self)
}
@_transparent
public var littleEndian: LEInteger {
return self
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170707/9e3df849/attachment.html>
More information about the swift-evolution
mailing list