From e42486b92eb699e1c91727fd89f0ed6c85a3a013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20Bystr=C3=B6m=20Ericsson?= Date: Tue, 17 Oct 2023 21:32:12 +0200 Subject: [PATCH] [NBKCoreKit] SuccinctInt. Comparisons. --- .../NBKStrictSignedInteger+Comparisons.swift | 8 +- ...NBKStrictUnsignedInteger+Comparisons.swift | 10 +- .../NBKCoreKit/Private/NBKSuccinctInt.swift | 165 +++++++++++------- .../Private/NBKTupleInteger+Division.swift | 8 +- .../Private/NBKSuccintInt.swift | 2 +- .../NBKStrictBinaryInteger+Complements.swift | 4 +- .../NBKStrictSignedInteger+Comparisons.swift | 17 +- ...NBKStrictUnsignedInteger+Comparisons.swift | 17 +- .../Private/NBKSuccinctInt.swift | 69 ++++++-- 9 files changed, 197 insertions(+), 103 deletions(-) diff --git a/Sources/NBKCoreKit/Private/NBKStrictSignedInteger+Comparisons.swift b/Sources/NBKCoreKit/Private/NBKStrictSignedInteger+Comparisons.swift index f1a80c9b..13803c3a 100644 --- a/Sources/NBKCoreKit/Private/NBKStrictSignedInteger+Comparisons.swift +++ b/Sources/NBKCoreKit/Private/NBKStrictSignedInteger+Comparisons.swift @@ -26,7 +26,7 @@ extension NBK.StrictSignedInteger { /// /// Specializing this it where `T == UInt` makes it faster. /// - @inlinable public static func compare(_ lhs: Base, to rhs: Base) -> Int where Base == UnsafeBufferPointer { + @inlinable public static func compare(_ lhs: Base, to rhs: Base) -> Int { let lhs = NBK.SuccinctInt(fromStrictSignedIntegerSubSequence: lhs)! let rhs = NBK.SuccinctInt(fromStrictSignedIntegerSubSequence: rhs)! return lhs.compared(to: rhs) as Int @@ -38,14 +38,14 @@ extension NBK.StrictSignedInteger { /// /// Specializing this it where `T == UInt` makes it faster. /// - @inlinable public static func compare(_ lhs: Base, to rhs: Base, at index: Int) -> Int where Base == UnsafeBufferPointer { + @inlinable public static func compare(_ lhs: Base, to rhs: Base, at index: Base.Index) -> Int { let lhs = NBK.SuccinctInt(fromStrictSignedIntegerSubSequence: lhs)! let rhs = NBK.SuccinctInt(fromStrictSignedIntegerSubSequence: rhs)! let partition = Swift.min(index, lhs.body.endIndex) - let suffix = Base(rebasing: lhs.body.suffix(from: partition)) + let suffix = lhs.body.suffix(from: partition) let comparison = NBK.SuccinctInt(unchecked: suffix, sign: lhs.sign).compared(to: rhs) if !comparison.isZero { return comparison } - let prefix = Base(rebasing: lhs.body.prefix(upTo: partition)) + let prefix = lhs.body.prefix(upTo: partition) return Int(bit: partition == index ? !prefix.allSatisfy({ $0.isZero }) : lhs.sign) } } diff --git a/Sources/NBKCoreKit/Private/NBKStrictUnsignedInteger+Comparisons.swift b/Sources/NBKCoreKit/Private/NBKStrictUnsignedInteger+Comparisons.swift index 7e50941c..1894a389 100644 --- a/Sources/NBKCoreKit/Private/NBKStrictUnsignedInteger+Comparisons.swift +++ b/Sources/NBKCoreKit/Private/NBKStrictUnsignedInteger+Comparisons.swift @@ -24,7 +24,7 @@ extension NBK.StrictUnsignedInteger.SubSequence { /// /// - Note: This operation interprets empty collections as zero. /// - @inlinable public static func compare(_ lhs: Base, to rhs: Base) -> Int where Base == UnsafeBufferPointer { + @inlinable public static func compare(_ lhs: Base, to rhs: Base) -> Int { let lhs = NBK.SuccinctInt(fromStrictUnsignedIntegerSubSequence: lhs) let rhs = NBK.SuccinctInt(fromStrictUnsignedIntegerSubSequence: rhs) return lhs.compared(toSameSign: rhs) as Int @@ -34,12 +34,12 @@ extension NBK.StrictUnsignedInteger.SubSequence { /// /// - Note: This operation interprets empty collections as zero. /// - @inlinable public static func compare(_ lhs: Base, to rhs: Base, at index: Int) -> Int where Base == UnsafeBufferPointer { + @inlinable public static func compare(_ lhs: Base, to rhs: Base, at index: Base.Index) -> Int { let partition = Swift.min(index, lhs.endIndex) - let suffix = Base(rebasing: lhs.suffix(from: partition)) - let comparison = self.compare(suffix, to: rhs) as Int + let suffix = lhs.suffix(from: partition) + let comparison = NBK.SUISS.compare(suffix, to: rhs[...]) if !comparison.isZero { return comparison } - let prefix = Base(rebasing: lhs.prefix(upTo: partition)) + let prefix = lhs.prefix(upTo: partition) return Int(bit: !prefix.allSatisfy({ $0.isZero })) } } diff --git a/Sources/NBKCoreKit/Private/NBKSuccinctInt.swift b/Sources/NBKCoreKit/Private/NBKSuccinctInt.swift index 8bd996b4..0679c9b5 100644 --- a/Sources/NBKCoreKit/Private/NBKSuccinctInt.swift +++ b/Sources/NBKCoreKit/Private/NBKSuccinctInt.swift @@ -29,13 +29,13 @@ extension NBK { //=--------------------------------------------------------------------= @inlinable public init(_ body: Base, sign: Bool) { - precondition(Self.isValid(body, sign: sign)) + precondition(Self.validate(body, sign: sign)) self.body = body self.sign = sign } @inlinable public init(unchecked body: Base, sign: Bool) { - Swift.assert(Self.isValid(body, sign: sign)) + Swift.assert(Self.validate(body, sign: sign)) self.body = body self.sign = sign } @@ -44,12 +44,94 @@ extension NBK { // MARK: Utilities //=--------------------------------------------------------------------= - @inlinable public static func isValid(_ body: Base, sign: Bool) -> Bool { + @inlinable public static func validate(_ body: Base, sign: Bool) -> Bool { body.last != Base.Element(repeating: sign) } } } +//=----------------------------------------------------------------------------= +// MARK: + Strict Binary Integer +//=----------------------------------------------------------------------------= + +extension NBK.SuccinctInt { + + //=------------------------------------------------------------------------= + // MARK: Initializers + //=------------------------------------------------------------------------= + + /// Creates a new instance from a strict signed integer subsequence. + /// + /// ``` + /// ┌─────────────── → ───────────────┬───────┐ + /// │ source │ body │ sign │ + /// ├─────────────── → ───────────────┼───────┤ + /// │ 0, 0, 0, 0 │ │ false │ + /// │ 1, 2, 0, 0 │ 1, 2 │ false │ + /// │ ~1, ~2, ~0, ~0 │ ~1, ~2 │ true │ + /// │ ~0, ~0, ~0, ~0 │ │ true │ + /// ├─────────────── → ───────────────┼───────┤ + /// │ │ │ nil │ + /// └─────────────── → ───────────────┴───────┘ + /// ``` + /// + @inlinable public init?(fromStrictSignedIntegerSubSequence source: T) + where T: RandomAccessCollection, Base == T.SubSequence { + //=--------------------------------------= + guard let sign = source.last?.mostSignificantBit else { return nil } + //=--------------------------------------= + let bits = UInt(repeating: sign) + let body = NBK.dropLast(from: source, while:{ $0 == bits }) + self.init(unchecked: body, sign: sign) + } + + /// Creates a new instance from a strict unsigned integer subsequence. + /// + /// ``` + /// ┌─────────────── → ───────────────┬───────┐ + /// │ source │ body │ sign │ + /// ├─────────────── → ───────────────┼───────┤ + /// │ 0, 0, 0, 0 │ │ false │ + /// │ 1, 2, 0, 0 │ 1, 2 │ false │ + /// │ ~1, ~2, ~0, ~0 │ ~1, ~2, ~0, ~0 │ false │ + /// │ ~0, ~0, ~0, ~0 │ ~0, ~0, ~0, ~0 │ false │ + /// ├─────────────── → ───────────────┼───────┤ + /// │ │ │ false │ + /// └─────────────── → ───────────────┴───────┘ + /// ``` + /// + /// ### Development + /// + /// `@inline(always)` is required for `NBKFlexibleWidth` performance reasons. + /// + @inline(__always) @inlinable public init(fromStrictUnsignedIntegerSubSequence source: T) + where T: RandomAccessCollection, Base == T.SubSequence { + let body = NBK.dropLast(from: source, while:{ $0.isZero }) + self.init(unchecked: body, sign: false) + } +} + +//=----------------------------------------------------------------------------= +// MARK: + where Base is Unsafe Buffer Pointer +//=----------------------------------------------------------------------------= + +extension NBK.SuccinctInt { + + //=------------------------------------------------------------------------= + // MARK: Initializers + //=------------------------------------------------------------------------= + + /// Creates an instance using the memory as the given sub sequence. + @inlinable public init(rebasing other: NBK.SuccinctInt) where Base == UnsafeBufferPointer { + self.init(unchecked: Base(rebasing: other.body), sign: other.sign) + } + + /// Creates an instance using the memory as the given sub sequence. + @inlinable public init(rebasing other: NBK.SuccinctInt) where Base == UnsafeMutableBufferPointer { + self.init(unchecked: Base(rebasing: other.body), sign: other.sign) + } +} + //=----------------------------------------------------------------------------= // MARK: + Comparisons //=----------------------------------------------------------------------------= @@ -94,10 +176,19 @@ extension NBK.SuccinctInt { //=--------------------------------------= // Word By Word, Back To Front //=--------------------------------------= - for index in self.body.indices.reversed() { - let lhsWord = self .body[index] as Base.Element - let rhsWord = other.body[index] as Base.Element - if lhsWord != rhsWord { return lhsWord < rhsWord ? -1 : 1 } + var lhsIndex = self .body.endIndex + var rhsIndex = other.body.endIndex + + backwards: while lhsIndex > self.body.startIndex { + self .body.formIndex(before: &lhsIndex) + other.body.formIndex(before: &rhsIndex) + + let lhsWord = self .body[lhsIndex] as Base.Element + let rhsWord = other.body[rhsIndex] as Base.Element + + if lhsWord != rhsWord { + return lhsWord < rhsWord ? -1 : 1 + } } //=--------------------------------------= // Same @@ -105,63 +196,3 @@ extension NBK.SuccinctInt { return 0 as Int as Int as Int as Int as Int } } - -//=----------------------------------------------------------------------------= -// MARK: + where Base is Unsafe Buffer Pointer -//=----------------------------------------------------------------------------= - -extension NBK.SuccinctInt { - - //=------------------------------------------------------------------------= - // MARK: Initializers - //=------------------------------------------------------------------------= - - /// Creates a new instance from a strict signed integer subsequence. - /// - /// ``` - /// ┌─────────────── → ───────────────┬───────┐ - /// │ source │ body │ sign │ - /// ├─────────────── → ───────────────┼───────┤ - /// │ 0, 0, 0, 0 │ │ false │ - /// │ 1, 2, 0, 0 │ 1, 2 │ false │ - /// │ ~1, ~2, ~0, ~0 │ ~1, ~2 │ true │ - /// │ ~0, ~0, ~0, ~0 │ │ true │ - /// ├─────────────── → ───────────────┼───────┤ - /// │ │ │ nil │ - /// └─────────────── → ───────────────┴───────┘ - /// ``` - /// - /// ### Development - /// - /// `@inline(always)` is required for `NBKFlexibleWidth` performance reasons. - /// - @inline(__always) @inlinable public init?(fromStrictSignedIntegerSubSequence source: Base) where Base == UnsafeBufferPointer { - guard let sign = source.last?.mostSignificantBit else { return nil } - let bits = UInt(repeating: sign) - let body = Base(rebasing: NBK.dropLast(from: source, while:{ $0 == bits })) - self.init(unchecked: body, sign: sign) - } - - /// Creates a new instance from a strict unsigned integer subsequence. - /// - /// ``` - /// ┌─────────────── → ───────────────┬───────┐ - /// │ source │ body │ sign │ - /// ├─────────────── → ───────────────┼───────┤ - /// │ 0, 0, 0, 0 │ │ false │ - /// │ 1, 2, 0, 0 │ 1, 2 │ false │ - /// │ ~1, ~2, ~0, ~0 │ ~1, ~2, ~0, ~0 │ false │ - /// │ ~0, ~0, ~0, ~0 │ ~0, ~0, ~0, ~0 │ false │ - /// ├─────────────── → ───────────────┼───────┤ - /// │ │ │ false │ - /// └─────────────── → ───────────────┴───────┘ - /// ``` - /// - /// ### Development - /// - /// `@inline(always)` is required for `NBKFlexibleWidth` performance reasons. - /// - @inline(__always) @inlinable public init(fromStrictUnsignedIntegerSubSequence source: Base) where Base == UnsafeBufferPointer { - self.init(unchecked: Base(rebasing: NBK.dropLast(from: source, while:{ $0.isZero })), sign: false) - } -} diff --git a/Sources/NBKCoreKit/Private/NBKTupleInteger+Division.swift b/Sources/NBKCoreKit/Private/NBKTupleInteger+Division.swift index ec1698f6..c62465da 100644 --- a/Sources/NBKCoreKit/Private/NBKTupleInteger+Division.swift +++ b/Sources/NBKCoreKit/Private/NBKTupleInteger+Division.swift @@ -22,15 +22,15 @@ extension NBK.TupleInteger where High: NBKUnsignedInteger { /// Divides 3 halves by 2 normalized halves, assuming the quotient fits in 1 half. /// + /// - Returns: The `quotient` is returned and the `remainder` replaces the dividend. + /// /// ### Development 1 /// - /// Skipping the comparison does not make it faster. + /// The profiler says comparing is faster than overflow checking. /// /// ### Development 2 /// - /// The approximation needs at most two adjustments, but the while loop is faster. - /// - /// - Returns: The `quotient` is returned and the `remainder` replaces the dividend. + /// The approximation needs at most two adjustments, but a loop is faster. /// @_transparent public static func divide3212MSBUnchecked(_ lhs: inout Wide3, by rhs: Wide2) -> High { assert(rhs.high.mostSignificantBit, "divisor must be normalized") diff --git a/Tests/NBKCoreKitBenchmarks/Private/NBKSuccintInt.swift b/Tests/NBKCoreKitBenchmarks/Private/NBKSuccintInt.swift index 6b83189f..181dc79f 100644 --- a/Tests/NBKCoreKitBenchmarks/Private/NBKSuccintInt.swift +++ b/Tests/NBKCoreKitBenchmarks/Private/NBKSuccintInt.swift @@ -22,7 +22,7 @@ private typealias Y = [UInt32] final class NBKSuccinctIntBenchmarks: XCTestCase { - typealias T = NBK.SuccinctInt> + typealias T = NBK.SuccinctInt //=------------------------------------------------------------------------= // MARK: Tests diff --git a/Tests/NBKCoreKitTests/Private/NBKStrictBinaryInteger+Complements.swift b/Tests/NBKCoreKitTests/Private/NBKStrictBinaryInteger+Complements.swift index 0263a2cd..5939b320 100644 --- a/Tests/NBKCoreKitTests/Private/NBKStrictBinaryInteger+Complements.swift +++ b/Tests/NBKCoreKitTests/Private/NBKStrictBinaryInteger+Complements.swift @@ -49,7 +49,7 @@ private func NBKAssertOnesComplement( _ operand: [UInt], _ result: [UInt], file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias SBI = NBK.StrictBinaryInteger<[UInt]>.SubSequence + typealias SBI = NBK.SBISS //=------------------------------------------= brr: do { var operand = operand @@ -62,7 +62,7 @@ private func NBKAssertTwosComplement( _ operand: [UInt], _ result: [UInt], file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias SBI = NBK.StrictBinaryInteger<[UInt]>.SubSequence + typealias SBI = NBK.SBISS //=------------------------------------------= brr: do { var operand = operand diff --git a/Tests/NBKCoreKitTests/Private/NBKStrictSignedInteger+Comparisons.swift b/Tests/NBKCoreKitTests/Private/NBKStrictSignedInteger+Comparisons.swift index 69adf51e..d5470505 100644 --- a/Tests/NBKCoreKitTests/Private/NBKStrictSignedInteger+Comparisons.swift +++ b/Tests/NBKCoreKitTests/Private/NBKStrictSignedInteger+Comparisons.swift @@ -116,8 +116,13 @@ private func NBKAssertComparison( _ lhs: [UInt], _ rhs: [UInt], _ signum: Int, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias T = NBK.StrictSignedInteger> + typealias T = NBK.StrictSignedInteger //=------------------------------------------= + brr: do { + XCTAssertEqual(T.compare(lhs, to: rhs), signum, file: file, line: line) + XCTAssertEqual(T.compare(rhs, to: lhs), -signum, file: file, line: line) + } + lhs.withUnsafeBufferPointer { lhs in rhs.withUnsafeBufferPointer { rhs in XCTAssertEqual(T.compare(lhs, to: rhs), signum, file: file, line: line) @@ -129,14 +134,18 @@ private func NBKAssertComparisonAtIndex( _ lhs: [UInt], _ rhs: [UInt], _ index: Int, _ signum: Int, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias T = NBK.StrictSignedInteger> + typealias T = NBK.StrictSignedInteger + //=------------------------------------------= + NBKAssertComparison(lhs, [UInt](repeating: 0, count: index) + rhs, signum, file: file, line: line) //=------------------------------------------= + brr: do { + XCTAssertEqual(T.compare(lhs, to: rhs, at: index), signum, file: file, line: line) + } + lhs.withUnsafeBufferPointer { lhs in rhs.withUnsafeBufferPointer { rhs in XCTAssertEqual(T.compare(lhs, to: rhs, at: index), signum, file: file, line: line) }} - //=------------------------------------------= - NBKAssertComparison(lhs, Array(repeating: 0 as UInt, count: index) + rhs, signum, file: file, line: line) } #endif diff --git a/Tests/NBKCoreKitTests/Private/NBKStrictUnsignedInteger+Comparisons.swift b/Tests/NBKCoreKitTests/Private/NBKStrictUnsignedInteger+Comparisons.swift index 87125d1f..629ff9a0 100644 --- a/Tests/NBKCoreKitTests/Private/NBKStrictUnsignedInteger+Comparisons.swift +++ b/Tests/NBKCoreKitTests/Private/NBKStrictUnsignedInteger+Comparisons.swift @@ -128,8 +128,13 @@ private func NBKAssertSubSequenceComparison( _ lhs: [UInt], _ rhs: [UInt], _ signum: Int, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias T = NBK.StrictUnsignedInteger>.SubSequence + typealias T = NBK.SUISS //=------------------------------------------= + brr: do { + XCTAssertEqual(T.compare(lhs, to: rhs), signum, file: file, line: line) + XCTAssertEqual(T.compare(rhs, to: lhs), -signum, file: file, line: line) + } + lhs.withUnsafeBufferPointer { lhs in rhs.withUnsafeBufferPointer { rhs in XCTAssertEqual(T.compare(lhs, to: rhs), signum, file: file, line: line) @@ -141,14 +146,18 @@ private func NBKAssertSubSequenceComparisonAtIndex( _ lhs: [UInt], _ rhs: [UInt], _ index: Int, _ signum: Int, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias T = NBK.StrictUnsignedInteger>.SubSequence + typealias T = NBK.SUISS + //=------------------------------------------= + NBKAssertSubSequenceComparison(lhs, [UInt](repeating: 0, count: index) + rhs, signum, file: file, line: line) //=------------------------------------------= + brr: do { + XCTAssertEqual(T.compare(lhs, to: rhs, at: index), signum, file: file, line: line) + } + lhs.withUnsafeBufferPointer { lhs in rhs.withUnsafeBufferPointer { rhs in XCTAssertEqual(T.compare(lhs, to: rhs, at: index), signum, file: file, line: line) }} - //=------------------------------------------= - NBKAssertSubSequenceComparison(lhs, Array(repeating: 0 as UInt, count: index) + rhs, signum, file: file, line: line) } #endif diff --git a/Tests/NBKCoreKitTests/Private/NBKSuccinctInt.swift b/Tests/NBKCoreKitTests/Private/NBKSuccinctInt.swift index 9c6ac33f..26007587 100644 --- a/Tests/NBKCoreKitTests/Private/NBKSuccinctInt.swift +++ b/Tests/NBKCoreKitTests/Private/NBKSuccinctInt.swift @@ -89,14 +89,14 @@ final class NBKSuccinctIntTests: XCTestCase { //*============================================================================* private func NBKAssertIsValid( -_ body: [UInt], _ sign: Bool, _ isValid: Bool, +_ body: [UInt], _ sign: Bool, _ success: Bool, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias T = NBK.SuccinctInt<[UInt]> + typealias T = NBK.SuccinctInt //=------------------------------------------= - XCTAssertEqual(T.isValid(body, sign: sign), isValid, file: file, line: line) + XCTAssertEqual(T.validate(body, sign: sign), success, file: file, line: line) //=------------------------------------------= - if isValid { + if success { XCTAssertNotNil(T( body, sign: sign), file: file, line: line) XCTAssertNotNil(T(unchecked: body, sign: sign), file: file, line: line) } @@ -106,11 +106,33 @@ private func NBKAssertFromStrictSignedIntegerSubSequence( _ source: [UInt], _ body: [UInt]?, _ sign: Bool?, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias T = NBK.SuccinctInt> + typealias T = NBK.SuccinctInt + //=------------------------------------------= + var source = source //=------------------------------------------= - source.withUnsafeBufferPointer { - XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: $0).map({ $0.sign }), sign, file: file, line: line) - XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: $0).map({ Array($0.body) }), body, file: file, line: line) + brr: do { + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map({ $0.sign }), sign, file: file, line: line) + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map({ Array($0.body) }), body, file: file, line: line) + } + + source.withUnsafeBufferPointer { source in + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map({ $0.sign }), sign, file: file, line: line) + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map({ Array($0.body) }), body, file: file, line: line) + } + + source.withUnsafeBufferPointer { source in + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map(T.init(rebasing:)).map({ $0.sign }), sign, file: file, line: line) + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map(T.init(rebasing:)).map({ Array($0.body) }), body, file: file, line: line) + } + + source.withUnsafeMutableBufferPointer { source in + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map({ $0.sign }), sign, file: file, line: line) + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map({ Array($0.body) }), body, file: file, line: line) + } + + source.withUnsafeMutableBufferPointer { source in + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map(T.init(rebasing:)).map({ $0.sign }), sign, file: file, line: line) + XCTAssertEqual(T(fromStrictSignedIntegerSubSequence: source).map(T.init(rebasing:)).map({ Array($0.body) }), body, file: file, line: line) } } @@ -118,12 +140,35 @@ private func NBKAssertFromStrictUnsignedIntegerSubSequence( _ source: [UInt], _ body: [UInt], _ sign: Bool, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------= - typealias T = NBK.SuccinctInt> + typealias T = NBK.SuccinctInt + //=------------------------------------------= + var source = source //=------------------------------------------= XCTAssertEqual(sign, false, file: file, line: line) - source.withUnsafeBufferPointer { - XCTAssertEqual( T(fromStrictUnsignedIntegerSubSequence: $0).sign, sign, file: file, line: line) - XCTAssertEqual(Array(T(fromStrictUnsignedIntegerSubSequence: $0).body), body, file: file, line: line) + + brr: do { + XCTAssertEqual( T(fromStrictUnsignedIntegerSubSequence: source).sign, sign, file: file, line: line) + XCTAssertEqual(Array(T(fromStrictUnsignedIntegerSubSequence: source).body), body, file: file, line: line) + } + + source.withUnsafeBufferPointer { source in + XCTAssertEqual( T(fromStrictUnsignedIntegerSubSequence: source).sign, sign, file: file, line: line) + XCTAssertEqual(Array(T(fromStrictUnsignedIntegerSubSequence: source).body), body, file: file, line: line) + } + + source.withUnsafeBufferPointer { source in + XCTAssertEqual( T(rebasing: T(fromStrictUnsignedIntegerSubSequence: source)).sign, sign, file: file, line: line) + XCTAssertEqual(Array(T(rebasing: T(fromStrictUnsignedIntegerSubSequence: source)).body), body, file: file, line: line) + } + + source.withUnsafeMutableBufferPointer { source in + XCTAssertEqual( T(fromStrictUnsignedIntegerSubSequence: source).sign, sign, file: file, line: line) + XCTAssertEqual(Array(T(fromStrictUnsignedIntegerSubSequence: source).body), body, file: file, line: line) + } + + source.withUnsafeMutableBufferPointer { source in + XCTAssertEqual( T(rebasing: T(fromStrictUnsignedIntegerSubSequence: source)).sign, sign, file: file, line: line) + XCTAssertEqual(Array(T(rebasing: T(fromStrictUnsignedIntegerSubSequence: source)).body), body, file: file, line: line) } }