[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