Skip to content

Commit 510eef9

Browse files
committed
[stdlib] add storage property to Substring.UTF8View
1 parent 6d21292 commit 510eef9

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

stdlib/public/core/Span/Properties/StringFamilyExtensions.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,31 @@ extension String.UTF8View {
3535
}
3636
}
3737
}
38+
39+
extension Substring.UTF8View {
40+
41+
@available(SwiftStdlib 6.1, *)
42+
public var storage: Span<UTF8.CodeUnit> {
43+
@_alwaysEmitIntoClient
44+
@lifetime(borrow self)
45+
borrowing get {
46+
let start = _slice._startIndex._encodedOffset
47+
let end = _slice._endIndex._encodedOffset
48+
if _wholeGuts.isSmall {
49+
let a = Builtin.addressOfBorrow(self)
50+
let offset = start &+ (MemoryLayout<String.Index>.stride &<< 1)
51+
let address = UnsafePointer<UTF8.CodeUnit>(a).advanced(by: offset)
52+
let span = Span(_unsafeStart: address, count: end &- start)
53+
return _overrideLifetime(span, borrowing: self)
54+
}
55+
else if _wholeGuts.isFastUTF8 {
56+
let buffer = _wholeGuts._object.fastUTF8.extracting(start..<end)
57+
let count = end &- start
58+
_internalInvariant(count == buffer.count)
59+
let span = Span(_unsafeElements: buffer)
60+
return _overrideLifetime(span, borrowing: self)
61+
}
62+
fatalError()
63+
}
64+
}
65+
}

test/stdlib/Span/StringUTF8StorageProperty.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,45 @@ suite.test("Span from Large Native String")
5858
expectEqual(span[i], u[i])
5959
}
6060
}
61+
62+
suite.test("Span from Small String's Substring")
63+
.skip(.custom(
64+
{ if #available(SwiftStdlib 6.1, *) { false } else { true } },
65+
reason: "Requires Swift 6.1's standard library"
66+
))
67+
.code {
68+
guard #available(SwiftStdlib 6.1, *) else { return }
69+
70+
let s = "A small string.".dropFirst(8).utf8
71+
let u = Array("string.".utf8)
72+
let span = s.storage
73+
74+
let count = span.count
75+
expectEqual(count, s.count)
76+
77+
for i in span.indices {
78+
expectEqual(span[i], u[i])
79+
}
80+
}
81+
82+
suite.test("Span from Large Native String's Substring")
83+
.skip(.custom(
84+
{ if #available(SwiftStdlib 6.1, *) { false } else { true } },
85+
reason: "Requires Swift 6.1's standard library"
86+
))
87+
.code {
88+
guard #available(SwiftStdlib 6.1, *) else { return }
89+
90+
let t = "A long string that is altogether not smol."
91+
let s = t.dropFirst(22).prefix(10).utf8
92+
let u = Array("altogether".utf8)
93+
let span = s.storage
94+
95+
let count = span.count
96+
expectEqual(count, s.count)
97+
98+
for i in span.indices {
99+
expectEqual(span[i], u[i])
100+
}
101+
}
102+

0 commit comments

Comments
 (0)