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

Reply via email to