Here are two problems being fixed. First, considering the example:
struct MyRawDataStruct { var size: UInt32 var signature: UInt32 var width: UInt32 var height: UInt32 } The type UInt32 doesn't tall us the endianness of the value. Also, if we read the value of it, the value is being byte-swapped when endianness is not matching with the system. This causes us have to manual convert the value from/to correct endianness. struct MyRawDataStruct { var size: BEInteger<UInt32> var signature: BEInteger<UInt32> var width: BEInteger<UInt32> var height: BEInteger<UInt32> } So, my proposal fix the problem. We can easily to get the value. let header: MyRawDataStruct = data.withUnsafePointer { $0.pointee } print(header.size) // print the representing value Second, it's misleading means of bigEndian and littleEndian from FixedWidthInteger if we do this let a = 1 print(a.bigEndian.bigEndian) It's just swap bytes twice but not converting value to big-endian My proposal solves the problem let b = a.bigEndian // BEInteger<Int> b.bigEndian // remain big-endian of a > Max Moiseev <mois...@apple.com> 於 2017年7月8日 上午1:48 寫道: > > Hi Susan, > > Was there any motivation for this proposal that I missed? If not then, can > you please provide it in a few sentences? Otherwise it’s not clear to me what > problem it is supposed to fix. > > Thanks, > Max > > >> On Jul 6, 2017, at 8:21 PM, Susan Cheng via swift-evolution >> <swift-evolution@swift.org> wrote: >> >> 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.addingReportingOverflow(rhs.representingValue) >> return (Self(representingValue: partialValue), overflow) >> } >> >> @_transparent >> public func subtractingReportingOverflow(_ rhs: Self) -> (partialValue: >> Self, overflow: ArithmeticOverflow) { >> let (partialValue, overflow) = >> representingValue.subtractingReportingOverflow(rhs.representingValue) >> return (Self(representingValue: partialValue), overflow) >> } >> >> @_transparent >> public func multipliedReportingOverflow(by rhs: Self) -> (partialValue: >> Self, overflow: ArithmeticOverflow) { >> let (partialValue, overflow) = >> representingValue.multipliedReportingOverflow(by: rhs.representingValue) >> return (Self(representingValue: partialValue), overflow) >> } >> >> @_transparent >> public func dividedReportingOverflow(by rhs: Self) -> (partialValue: >> Self, overflow: ArithmeticOverflow) { >> let (partialValue, overflow) = >> representingValue.dividedReportingOverflow(by: rhs.representingValue) >> return (Self(representingValue: partialValue), overflow) >> } >> >> @_transparent >> public func remainderReportingOverflow(dividingBy rhs: Self) -> >> (partialValue: Self, overflow: ArithmeticOverflow) { >> let (partialValue, overflow) = >> representingValue.remainderReportingOverflow(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 >> } >> } >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org >> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution