Skip to content

Commit f4d5a3d

Browse files
author
Dave Abrahams
committed
[stdlib/prototype] Fix uword() implementation
1 parent b76c0ab commit f4d5a3d

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

test/Prototypes/Integers.swift.gyb

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -535,14 +535,14 @@ extension FixedWidthIntegerType {
535535

536536
@_transparent
537537
public func uword(n: Word) -> UWord {
538-
var n = n
539538
_precondition(n >= 0, "Negative word index")
540-
var x = self
541-
while n > 0 {
542-
x &>>= Swift.min(Self(_truncatingBits: UWord(Self.bitWidth._storage)) &- 1, ${word_bits})
543-
n -= 1
539+
if _fastPath(n < countRepresentedWords) {
540+
let shift = UWord(n._storage) &* ${word_bits}
541+
let bitWidth = UWord(Self.bitWidth._storage)
542+
_sanityCheck(shift < bitWidth)
543+
return (self &>> Self(_truncatingBits: shift))._lowUWord
544544
}
545-
return x._lowUWord
545+
return self < 0 ? ~0 : 0
546546
}
547547

548548
public var countRepresentedWords: Word {
@@ -1302,6 +1302,20 @@ tests.test("Basics") {
13021302
expectEqual(32, Int32.bitWidth)
13031303
}
13041304

1305+
tests.test("uword") {
1306+
let x = UDWord(Word.max)
1307+
expectEqual(Word.max._lowUWord, x.uword(0))
1308+
expectEqual(0, x.uword(1))
1309+
1310+
let y = DWord(Word.min)
1311+
expectEqual(Word.min._lowUWord, y.uword(0))
1312+
expectEqual(~0, y.uword(1))
1313+
1314+
let z = UWord(~Word.min) + 1
1315+
expectEqual(Word.min._lowUWord, z.uword(0))
1316+
expectEqual(0, z.uword(1))
1317+
}
1318+
13051319
tests.test("Multiprecision/+/DWord") {
13061320
var x = DWord.max - 2
13071321
x += (1 as UInt8)

0 commit comments

Comments
 (0)