Skip to content

Commit

Permalink
[NBKCoreKit] Cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Oct 27, 2023
1 parent a99f1b9 commit 4dd56ba
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 78 deletions.
19 changes: 12 additions & 7 deletions Sources/NBKCoreKit/Private/NBK+Collection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ extension NBK {
//=------------------------------------------------------------------------=

/// Drops elements that satisfy the predicate from the end of the given `collection`.
@_transparent public static func dropLast<T>(from collection: T, while predicate: (T.Element) -> Bool)
-> T.SubSequence where T: BidirectionalCollection {
@_transparent public static func dropLast<T: BidirectionalCollection>(
from collection: T, while predicate: (T.Element) -> Bool) -> T.SubSequence {
var newEndIndex = collection.endIndex

backwards: while newEndIndex > collection.startIndex {
Expand All @@ -36,15 +36,17 @@ extension NBK {
//=------------------------------------------------------------------------=

/// Removes `count` prefixing elements from the given `collection`.
@inlinable public static func removePrefix<T>(from collection: inout T, count: Int) -> T where T: RandomAccessCollection, T == T.SubSequence {
@inlinable public static func removePrefix<T: RandomAccessCollection>(
from collection: inout T, count: Int) -> T where T == T.SubSequence {
let index = collection.index(collection.startIndex, offsetBy: count)
let prefix = collection.prefix(upTo: index)
collection = collection.suffix(from: index)
return prefix as T
}

/// Removes `count` suffixing elements from the given `collection`.
@inlinable public static func removeSuffix<T>(from collection: inout T, count: Int) -> T where T: RandomAccessCollection, T == T.SubSequence {
@inlinable public static func removeSuffix<T: RandomAccessCollection>(
from collection: inout T, count: Int) -> T where T == T.SubSequence {
let index = collection.index(collection.endIndex, offsetBy: count.negated())
let suffix = collection.suffix(from: index)
collection = collection.prefix(upTo: index)
Expand All @@ -56,14 +58,16 @@ extension NBK {
//=------------------------------------------------------------------------=

/// Removes up to `maxLength` prefixing elements from the given `collection`.
@inlinable public static func removePrefix<T>(from collection: inout T, maxLength: Int) -> T where T: RandomAccessCollection, T == T.SubSequence {
@inlinable public static func removePrefix<T: RandomAccessCollection>(
from collection: inout T, maxLength: Int) -> T where T == T.SubSequence {
let prefix = collection.prefix(maxLength)
collection = collection.suffix(from: prefix.endIndex)
return prefix as T
}

/// Removes up to `maxLength` suffixing elements from the given `collection`.
@inlinable public static func removeSuffix<T>(from collection: inout T, maxLength: Int) -> T where T: RandomAccessCollection, T == T.SubSequence {
@inlinable public static func removeSuffix<T: RandomAccessCollection>(
from collection: inout T, maxLength: Int) -> T where T == T.SubSequence {
let suffix = collection.suffix(maxLength)
collection = collection.prefix(upTo: suffix.startIndex)
return suffix as T
Expand All @@ -74,7 +78,8 @@ extension NBK {
//=------------------------------------------------------------------------=

/// Returns the array-like result of `index(_:offsetBy:limitedBy:)`.
@inlinable public static func arrayIndex(_ index: Int, offsetBy distance: Int, limitedBy limit: Int) -> Int? {
@inlinable public static func arrayIndex(
_ index: Int, offsetBy distance: Int, limitedBy limit: Int) -> Int? {
let distanceLimit = limit - index

guard distance >= 0 as Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ extension NBK.IntegerDescription {
guard !digits.isEmpty else { return }
//=--------------------------------------=
var digits = digits.drop(while:{ $0 == 48 })
let split = NBK.dividing(NBK.ZeroOrMore(unchecked: digits.count), by: NBK.PowerOf2(unchecked: radix.exponent()))
let split = NBK.PBI.dividing(NBK.ZeroOrMore(unchecked: digits.count), by: NBK.PowerOf2(unchecked: radix.exponent()))
let count = split.quotient &+ Int(bit: split.remainder.isMoreThanZero)
//=--------------------------------------=
return Swift.withUnsafeTemporaryAllocation(of: UInt.self, capacity: count) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
//=----------------------------------------------------------------------------=

//*============================================================================*
// MARK: * NBK x Division
// MARK: * NBK x Proper Binary Integer x Division x Core Integer
//*============================================================================*

extension NBK {
extension NBK.ProperBinaryInteger where Integer: NBKCoreInteger {

//=------------------------------------------------------------------------=
// MARK: Transformation x where Divisor is Power of 2
// MARK: Transformation x Zero Or More By Power of 2
//=------------------------------------------------------------------------=

/// Returns the `quotient` and `remainder` of dividing the `dividend` by the `divisor`.
Expand All @@ -23,8 +23,9 @@ extension NBK {
///
/// Must use `init(bitPattern:)` for performance reasons (see Int256 division).
///
@inlinable public static func dividing<T: NBKCoreInteger>(
_ dividend: ZeroOrMore<T>, by divisor: PowerOf2<T>) -> QR<T, T> where T.Magnitude == UInt {
@inlinable public static func dividing(
_ dividend: NBK.ZeroOrMore<Integer>, by divisor: NBK.PowerOf2<Integer>)
-> QR<Integer, Integer> where Integer.Magnitude == UInt {
return QR(
quotient: self.quotient (dividing: dividend, by: divisor),
remainder: self.remainder(dividing: dividend, by: divisor))
Expand All @@ -36,43 +37,81 @@ extension NBK {
///
/// Must use `init(bitPattern:)` for performance reasons (see Int256 division).
///
@inlinable public static func quotient<T: NBKCoreInteger>(
dividing dividend: ZeroOrMore<T>, by divisor: PowerOf2<T>) -> T where T.Magnitude == UInt {
dividend.value &>> T(bitPattern: divisor.value.trailingZeroBitCount)
@inlinable public static func quotient(
dividing dividend: NBK.ZeroOrMore<Integer>, by divisor: NBK.PowerOf2<Integer>)
-> Integer where Integer.Magnitude == UInt {
dividend.value &>> Integer(bitPattern: divisor.value.trailingZeroBitCount)
}

/// Returns the `remainder` of dividing the `dividend` by the `divisor`.
@inlinable public static func remainder<T: NBKCoreInteger>(
dividing dividend: ZeroOrMore<T>, by divisor: PowerOf2<T>) -> T {
dividend.value & (divisor.value &- 1 as T)
@inlinable public static func remainder(
dividing dividend: NBK.ZeroOrMore<Integer>, by divisor: NBK.PowerOf2<Integer>) -> Integer {
dividend.value & (divisor.value &- 1 as Integer)
}
}

//*============================================================================*
// MARK: * NBK x Division x Least Positive Residue x Binary Integer By Word
// MARK: * NBK x Proper Binary Integer x Division x Binary Integer By Word
//*============================================================================*
//=----------------------------------------------------------------------------=
// NOTE: We still need to interact with Swift's generic protocol requirements.
//=----------------------------------------------------------------------------=
//=----------------------------------------------------------------------------=
// MARK: + Least Positive Residue
//=----------------------------------------------------------------------------=

extension NBK {
extension NBK.ProperBinaryInteger where Integer: NBKCoreInteger<UInt> {

//=------------------------------------------------------------------------=
// MARK: Transformations x Overflow
//=------------------------------------------------------------------------=

/// Returns the least positive `residue` of dividing the `dividend` by the `divisor`.
///
/// - Note: In the case of `overflow`, the result is the truncated `dividend`.
///
@inlinable public static func leastPositiveResidueReportingOverflow<T: BinaryInteger, U: NBKCoreInteger>(
dividing dividend: T, by divisor: U) -> PVO<U> where U.Magnitude == UInt {
NBK.bitCast(self.leastPositiveResidueReportingOverflow(dividing: dividend, by: divisor.magnitude))
@inlinable public static func leastPositiveResidueReportingOverflow(
dividing dividend: some BinaryInteger, by divisor: Integer) -> PVO<Integer> {
NBK.bitCast(NBK.PBI.leastPositiveResidueReportingOverflow(dividing: dividend, by: divisor.magnitude))
}

//=------------------------------------------------------------------------=
// MARK: Transformations x Dividing By Non Zero
//=------------------------------------------------------------------------=

/// Returns the least positive `residue` of dividing the `dividend` by the `divisor`.
@inlinable public static func leastPositiveResidue(
dividing dividend: some BinaryInteger, by divisor: NBK.NonZero<Integer>) -> Integer {
Integer(bitPattern: NBK.PBI.leastPositiveResidue(dividing: dividend, by: NBK.NonZero(unchecked: divisor.value.magnitude)))
}

//=------------------------------------------------------------------------=
// MARK: Transformations x Dividing By Power Of 2
//=------------------------------------------------------------------------=

/// Returns the least positive `residue` of dividing the `dividend` by the `divisor`.
@inlinable public static func leastPositiveResidue(
dividing dividend: some BinaryInteger, by divisor: NBK.PowerOf2<Integer>) -> Integer {
Integer(bitPattern: dividend._lowWord & UInt(bitPattern: divisor.value &- 1 as Integer))
}
}

//=----------------------------------------------------------------------------=
// MARK: + Least Positive Residue x Unsigned
//=----------------------------------------------------------------------------=

extension NBK.ProperBinaryInteger where Integer: NBKCoreInteger<UInt> & NBKUnsignedInteger {

//=------------------------------------------------------------------------=
// MARK: Transformations x Overflow
//=------------------------------------------------------------------------=

/// Returns the least positive `residue` of dividing the `dividend` by the `divisor`.
///
/// - Note: In the case of `overflow`, the result is the truncated `dividend`.
///
@inlinable public static func leastPositiveResidueReportingOverflow<T: BinaryInteger>(
dividing dividend: T, by divisor: UInt) -> PVO<UInt> {
@inlinable public static func leastPositiveResidueReportingOverflow(
dividing dividend: some BinaryInteger, by divisor: Integer) -> PVO<Integer> {
//=--------------------------------------=
guard let divisor = NBK.NonZero(exactly: divisor) else {
return PVO(dividend._lowWord, true)
Expand All @@ -82,36 +121,19 @@ extension NBK {
}

//=------------------------------------------------------------------------=
// MARK: Transformations x where Divisor is Non Zero
// MARK: Transformations x Dividing By Non Zero
//=------------------------------------------------------------------------=

/// Returns the least positive `residue` of dividing the `dividend` by the `divisor`.
@inlinable public static func leastPositiveResidue<T: BinaryInteger, U: NBKCoreInteger>(
dividing dividend: T, by divisor: NonZero<U>) -> U where U.Magnitude == UInt {
U(bitPattern: NBK.leastPositiveResidue(dividing: dividend, by: NBK.NonZero(unchecked: divisor.value.magnitude)))
}

/// Returns the least positive `residue` of dividing the `dividend` by the `divisor`.
@inlinable public static func leastPositiveResidue<T: BinaryInteger>(
dividing dividend: T, by divisor: NonZero<UInt>) -> UInt {
typealias SUI = StrictUnsignedInteger<T.Magnitude.Words>
dividing dividend: T, by divisor: NBK.NonZero<Integer>) -> Integer {
//=--------------------------------------=
if let divisor = PowerOf2(exactly: divisor.value) {
return self.leastPositiveResidue(dividing: dividend, by: divisor)
if let divisor = NBK.PowerOf2(exactly: divisor.value) {
return NBK.PBI.leastPositiveResidue(dividing: dividend, by: divisor)
}
//=--------------------------------------=
let minus = T.isSigned && dividend < T.zero
let remainder = SUI.SubSequence.remainder(dividing: dividend.magnitude.words, by: divisor)
let minus: Bool = T.isSigned && dividend < T.zero
let remainder = NBK.SUISS.remainder(dividing: dividend.magnitude.words, by: divisor)
return minus && !remainder.isZero ? divisor.value &- remainder : remainder
}

//=------------------------------------------------------------------------=
// MARK: Transformations x where Divisor is Power of 2
//=------------------------------------------------------------------------=

/// Returns the least positive `residue` of dividing the `dividend` by the `divisor`.
@inlinable public static func leastPositiveResidue<T: BinaryInteger, U: NBKCoreInteger>(
dividing dividend: T, by divisor: PowerOf2<U>) -> U where U.Magnitude == UInt {
U(bitPattern: dividend._lowWord & UInt(bitPattern: divisor.value &- 1 as U))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ extension NBK.ProperBinaryInteger where Integer: NBKUnsignedInteger {
if rhs.isZero { return lhs }
if lhs.isZero { return rhs }
//=--------------------------------------=
let lhsShift = lhs.trailingZeroBitCount as Int
let rhsShift = rhs.trailingZeroBitCount as Int
let lhs2sCount = lhs.trailingZeroBitCount // lhs == 2 ^ a * b
let rhs2sCount = rhs.trailingZeroBitCount // rhs == 2 ^ x * y
//=--------------------------------------=
var lhs: Integer = lhs >> lhsShift
var rhs: Integer = rhs >> rhsShift
var lhs: Integer = lhs >> lhs2sCount
var rhs: Integer = rhs >> rhs2sCount

while lhs != rhs {
if lhs < rhs {
Expand All @@ -65,7 +65,7 @@ extension NBK.ProperBinaryInteger where Integer: NBKUnsignedInteger {
}
}

lhs <<= Swift.min(lhsShift, rhsShift)
lhs <<= Swift.min(lhs2sCount, rhs2sCount) // the 2s in common
return lhs as Integer.Magnitude
}
}
10 changes: 5 additions & 5 deletions Sources/NBKDoubleWidthKit/NBKDoubleWidth+Division.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ extension NBKDoubleWidth where High == High.Magnitude {
//=--------------------------------------=
// normalization
//=--------------------------------------=
let major = NBK .quotient(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.remainder(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))
let major = NBK.PBI .quotient(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.PBI.remainder(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))

let top = shift.value.isZero ? High.zero : lhs.high &>> (High.bitWidth &- shift.value)
let lhs = lhs.bitShiftedLeft(major: major, minor: minor) as Self
let rhs = rhs.bitShiftedLeft(major: major, minor: minor) as Self
Expand Down Expand Up @@ -222,8 +222,8 @@ extension NBKDoubleWidth where High == High.Magnitude {
//=--------------------------------------=
// normalization
//=--------------------------------------=
let major = NBK .quotient(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.remainder(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))
let major = NBK.PBI .quotient(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.PBI.remainder(dividing: shift, by: NBK.PowerOf2(bitWidth: UInt.self))

let lhs = lhs.bitShiftedLeft(major: major, minor: minor) as NBKDoubleWidth<Self>
let rhs = rhs.bitShiftedLeft(major: major, minor: minor) as Self
Expand Down
12 changes: 6 additions & 6 deletions Sources/NBKDoubleWidthKit/NBKDoubleWidth+Shifts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extension NBKDoubleWidth {
}

@inlinable public static func &<<=(lhs: inout Self, rhs: some BinaryInteger) {
lhs.bitShiftLeft(by: NBK.leastPositiveResidue(dividing: rhs, by: NBK.NonZero(unchecked: Self.bitWidth)))
lhs.bitShiftLeft(by: NBK.PBI.leastPositiveResidue(dividing: rhs, by: NBK.NonZero(unchecked: Self.bitWidth)))
}

@inlinable public static func &<<(lhs: Self, rhs: some BinaryInteger) -> Self {
Expand Down Expand Up @@ -68,8 +68,8 @@ extension NBKDoubleWidth {
/// - distance: `0 <= distance < self.bitWidth`
///
@inlinable public mutating func bitShiftLeft(@NBK.ZeroOrMore by distance: Int) {
let major = NBK .quotient(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.remainder(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
let major = NBK.PBI .quotient(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.PBI.remainder(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
return self.bitShiftLeft(major: major, minor: minor)
}

Expand Down Expand Up @@ -148,7 +148,7 @@ extension NBKDoubleWidth {
}

@inlinable public static func &>>=(lhs: inout Self, rhs: some BinaryInteger) {
lhs.bitShiftRight(by: NBK.leastPositiveResidue(dividing: rhs, by: NBK.NonZero(unchecked: Self.bitWidth)))
lhs.bitShiftRight(by: NBK.PBI.leastPositiveResidue(dividing: rhs, by: NBK.NonZero(unchecked: Self.bitWidth)))
}

@inlinable public static func &>>(lhs: Self, rhs: some BinaryInteger) -> Self {
Expand Down Expand Up @@ -188,8 +188,8 @@ extension NBKDoubleWidth {
/// - distance: `0 <= distance < self.bitWidth`
///
@inlinable public mutating func bitShiftRight(@NBK.ZeroOrMore by distance: Int) {
let major = NBK .quotient(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.remainder(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
let major = NBK.PBI .quotient(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
let minor = NBK.PBI.remainder(dividing: $distance, by: NBK.PowerOf2(bitWidth: UInt.self))
return self.bitShiftRight(major: major, minor: minor)
}

Expand Down
Loading

0 comments on commit 4dd56ba

Please sign in to comment.