Skip to content

Commit 52259b7

Browse files
authored
Merge pull request #11193 from xwu/lossless-integers
[stdlib] Conform fixed-width integer types to LosslessStringConvertible
2 parents 3c7af4e + 7578822 commit 52259b7

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

stdlib/public/core/IntegerParsing.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ extension FixedWidthInteger {
102102
///
103103
/// The string passed as `text` may begin with a plus or minus sign character
104104
/// (`+` or `-`), followed by one or more numeric digits (`0-9`) or letters
105-
/// (`a-z` or `A-Z`). The string is case insensitive.
105+
/// (`a-z` or `A-Z`). Parsing of the string is case insensitive.
106106
///
107107
/// let x = Int("123")
108108
/// // x == 123
@@ -116,7 +116,7 @@ extension FixedWidthInteger {
116116
/// // z == 123
117117
///
118118
/// If `text` is in an invalid format or contains characters that are out of
119-
/// range for the given `radix`, or if the value it denotes in the given
119+
/// bounds for the given `radix`, or if the value it denotes in the given
120120
/// `radix` is not representable, the result is `nil`. For example, the
121121
/// following conversions result in `nil`:
122122
///
@@ -155,4 +155,28 @@ extension FixedWidthInteger {
155155
guard _fastPath(result != nil) else { return nil }
156156
self = result!
157157
}
158+
159+
/// Creates a new integer value from the given string.
160+
///
161+
/// The string passed as `description` may begin with a plus or minus sign
162+
/// character (`+` or `-`), followed by one or more numeric digits (`0-9`).
163+
///
164+
/// let x = Int("123")
165+
/// // x == 123
166+
///
167+
/// If `description` is in an invalid format, or if the value it denotes in
168+
/// base 10 is not representable, the result is `nil`. For example, the
169+
/// following conversions result in `nil`:
170+
///
171+
/// Int(" 100") // Includes whitespace
172+
/// Int("21-50") // Invalid format
173+
/// Int("ff6600") // Characters out of bounds
174+
/// Int("10000000000000000000000000") // Out of range
175+
///
176+
/// - Parameter description: The ASCII representation of a number.
177+
@_semantics("optimize.sil.specialize.generic.partial.never")
178+
@inline(__always)
179+
public init?(_ description: String) {
180+
self.init(description, radix: 10)
181+
}
158182
}

stdlib/public/core/Integers.swift.gyb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,8 @@ extension BinaryInteger {
19091909
/// customization points for arithmetic operations. When you provide just those
19101910
/// methods, the standard library provides default implementations for all
19111911
/// other arithmetic methods and operators.
1912-
public protocol FixedWidthInteger : BinaryInteger, _BitwiseOperations
1912+
public protocol FixedWidthInteger :
1913+
BinaryInteger, LosslessStringConvertible, _BitwiseOperations
19131914
where Magnitude : FixedWidthInteger
19141915
{
19151916
/// The number of bits used for the underlying binary representation of

test/stdlib/Integers.swift.gyb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,16 @@ tests.test("truncatingIfNeeded") {
364364
expectEqual(129, UInt8(truncatingIfNeeded: 129 + 1024 as UDWord))
365365
}
366366

367+
tests.test("Parsing/LosslessStringConvertible") {
368+
func _toArray<T: LosslessStringConvertible>(_ text: String) -> [T] {
369+
return text.split(separator: " ").map { T(String($0)) }.flatMap { $0 }
370+
}
371+
372+
expectEqualSequence([1, 2, 3], _toArray("1 2 3") as [Int])
373+
expectEqualSequence(
374+
[Int](), _toArray("21-50 ff6600 10000000000000000000000000") as [Int])
375+
}
376+
367377
tests.test("HeterogeneousEquality") {
368378
expectTrue(-1 as DWord != UDWord.max)
369379
expectTrue(DWord.max == UDWord.max / 2)

0 commit comments

Comments
 (0)