Skip to content

Commit 3015bf5

Browse files
committed
[stdlib] add storage property to String.UTF8View
1 parent c9b1ab8 commit 3015bf5

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

stdlib/public/core/StringUTF8View.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -89,6 +89,7 @@ extension String {
8989
/// print(String(s1.utf8.prefix(15))!)
9090
/// // Prints "They call me 'B"
9191
@frozen
92+
@_addressableForDependencies
9293
public struct UTF8View: Sendable {
9394
@usableFromInline
9495
internal var _guts: _StringGuts
@@ -317,6 +318,31 @@ extension String.UTF8View {
317318
}
318319
}
319320

321+
extension String.UTF8View {
322+
323+
@available(SwiftStdlib 6.2, *)
324+
public var span: Span<UTF8.CodeUnit> {
325+
@lifetime(borrow self)
326+
borrowing get {
327+
let count = _guts.count
328+
if _guts.isSmall {
329+
let a = Builtin.addressOfBorrow(self)
330+
let address = unsafe UnsafePointer<UTF8.CodeUnit>(a)
331+
let span = unsafe Span(_unsafeStart: address, count: count)
332+
return unsafe _overrideLifetime(span, borrowing: self)
333+
}
334+
else if _guts.isFastUTF8 {
335+
let buffer = unsafe _guts._object.fastUTF8
336+
_internalInvariant(count == buffer.count)
337+
let span = unsafe Span(_unsafeElements: buffer)
338+
return unsafe _overrideLifetime(span, borrowing: self)
339+
}
340+
// handle other Objective-C bridging cases here
341+
fatalError("Some bridged Strings are not supported at this time")
342+
}
343+
}
344+
}
345+
320346
// Index conversions
321347
extension String.UTF8View.Index {
322348
/// Creates an index in the given UTF-8 view that corresponds exactly to the
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===--- StringUTF8StorageProperty.swift ----------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// RUN: %target-run-stdlib-swift(-enable-experimental-feature LifetimeDependence -enable-experimental-feature Span -enable-experimental-feature AddressableTypes)
14+
15+
// REQUIRES: executable_test
16+
17+
import StdlibUnittest
18+
19+
var suite = TestSuite("StringUTF8StorageProperty")
20+
defer { runAllTests() }
21+
22+
suite.test("Span from Small String")
23+
.require(.stdlib_6_2).code {
24+
guard #available(SwiftStdlib 6.2, *) else { return }
25+
26+
let s = "A small string.".utf8
27+
let u = Array(s)
28+
let span = s.span
29+
30+
let count = span.count
31+
expectEqual(count, s.count)
32+
33+
for i in span.indices {
34+
expectEqual(span[i], u[i])
35+
}
36+
}
37+
38+
suite.test("Span from Large Native String")
39+
.require(.stdlib_6_2).code {
40+
guard #available(SwiftStdlib 6.2, *) else { return }
41+
42+
let s = "A long string that is altogether not smol.".utf8
43+
let u = Array(s)
44+
let span = s.span
45+
46+
let count = span.count
47+
expectEqual(count, s.count)
48+
49+
for i in span.indices {
50+
expectEqual(span[i], u[i])
51+
}
52+
}

0 commit comments

Comments
 (0)