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