From d4fab1a5d1e1a31a4aae6274c274504991c534e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20Bystr=C3=B6m=20Ericsson?= Date: Tue, 18 Apr 2023 07:20:36 +0200 Subject: [PATCH] custom smart bitshifts (#60) (#76) --- .../ANKFullWidthKit/ANKFullWidth+Shifts.swift | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/Sources/ANKFullWidthKit/ANKFullWidth+Shifts.swift b/Sources/ANKFullWidthKit/ANKFullWidth+Shifts.swift index fcc0db35..c280ea69 100644 --- a/Sources/ANKFullWidthKit/ANKFullWidth+Shifts.swift +++ b/Sources/ANKFullWidthKit/ANKFullWidth+Shifts.swift @@ -19,6 +19,18 @@ extension ANKFullWidth { // MARK: Transformations //=------------------------------------------------------------------------= + @inlinable public static func <<=(lhs: inout Self, rhs: some BinaryInteger) { + lhs._bitshiftLeftSmart(by: Int(clamping: rhs)) + } + + @_transparent public static func <<(lhs: Self, rhs: some BinaryInteger) -> Self { + var lhs = lhs; lhs <<= rhs; return lhs + } + + //=------------------------------------------------------------------------= + // MARK: Transformations + //=------------------------------------------------------------------------= + @inlinable public static func &<<=(lhs: inout Self, rhs: Self) { lhs._bitshiftLeft(by: rhs._moduloBitWidth) } @@ -31,6 +43,26 @@ extension ANKFullWidth { // MARK: Transformations x Int //=------------------------------------------------------------------------= + /// - Parameters: + /// - amount: `Int.min <= amount <= Int.max` + /// + @inlinable mutating func _bitshiftLeftSmart(by amount: Int) { + let amountAbsoluteValue: Int = abs(amount) + switch (amount >= 0, amountAbsoluteValue < Self.bitWidth) { + case (true, true ): self._bitshiftLeft(by: amountAbsoluteValue) + case (true, false): self = Self(repeating: false) + case (false, true ): self._bitshiftRight(by: amountAbsoluteValue) + case (false, false): self = Self(repeating: self.isLessThanZero) + } + } + + /// - Parameters: + /// - amount: `Int.min <= amount <= Int.max` + /// + @_transparent @usableFromInline func _bitshiftedLeftSmart(by amount: Int) -> Self { + var x = self; x._bitshiftLeftSmart(by: amount); return x + } + /// - Parameters: /// - amount: `0 <= amount < Self.bitWidth` /// @@ -95,6 +127,18 @@ extension ANKFullWidth { // MARK: Transformations //=------------------------------------------------------------------------= + @inlinable public static func >>=(lhs: inout Self, rhs: some BinaryInteger) { + lhs._bitshiftRightSmart(by: Int(clamping: rhs)) + } + + @_transparent public static func >>(lhs: Self, rhs: some BinaryInteger) -> Self { + var lhs = lhs; lhs >>= rhs; return lhs + } + + //=------------------------------------------------------------------------= + // MARK: Transformations + //=------------------------------------------------------------------------= + @inlinable public static func &>>=(lhs: inout Self, rhs: Self) { lhs._bitshiftRight(by: rhs._moduloBitWidth) } @@ -107,6 +151,26 @@ extension ANKFullWidth { // MARK: Transformations x Int //=------------------------------------------------------------------------= + /// - Parameters: + /// - amount: `Int.min <= amount <= Int.max` + /// + @inlinable mutating func _bitshiftRightSmart(by amount: Int) { + let amountAbsoluteValue: Int = abs(amount) + switch (amount >= 0, amountAbsoluteValue < Self.bitWidth) { + case (true, true ): self._bitshiftRight(by: amountAbsoluteValue) + case (true, false): self = Self(repeating: self.isLessThanZero) + case (false, true ): self._bitshiftLeft(by: amountAbsoluteValue) + case (false, false): self = Self(repeating: false) + } + } + + /// - Parameters: + /// - amount: `Int.min <= amount <= Int.max` + /// + @_transparent @usableFromInline func _bitshiftedRightSmart(by amount: Int) -> Self { + var x = self; x._bitshiftRightSmart(by: amount); return x + } + /// - Parameters: /// - amount: `0 <= amount < Self.bitWidth` ///