Skip to content

Commit 264747a

Browse files
committed
[stdlib] add span property to CollectionOfOne
1 parent a5e04e0 commit 264747a

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

stdlib/public/core/CollectionOfOne.swift

Lines changed: 16 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
@@ -22,6 +22,7 @@
2222
/// let b = a + CollectionOfOne(toAdd)
2323
/// // b == [1, 2, 3, 4, 100]
2424
@frozen // trivial-implementation
25+
@_addressableForDependencies
2526
public struct CollectionOfOne<Element> {
2627
@usableFromInline // trivial-implementation
2728
internal var _element: Element
@@ -158,6 +159,20 @@ extension CollectionOfOne: RandomAccessCollection, MutableCollection {
158159
}
159160
}
160161

162+
extension CollectionOfOne {
163+
164+
@available(SwiftStdlib 6.2, *)
165+
public var span: Span<Element> {
166+
@lifetime(borrow self)
167+
@_alwaysEmitIntoClient
168+
get {
169+
let pointer = UnsafePointer<Element>(Builtin.addressOfBorrow(self))
170+
let span = Span(_unsafeStart: pointer, count: 1)
171+
return _overrideLifetime(span, borrowing: self)
172+
}
173+
}
174+
}
175+
161176
@_unavailableInEmbedded
162177
extension CollectionOfOne: CustomDebugStringConvertible {
163178
/// A textual representation of the collection, suitable for debugging.

stdlib/public/core/Span/RawSpan.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ extension RawSpan {
316316
let pointer = span._pointer
317317
let rawSpan = unsafe RawSpan(
318318
_unchecked: pointer,
319-
byteCount: span.count &* MemoryLayout<Element>.stride
319+
byteCount: span.count == 1 ? MemoryLayout<Element>.size
320+
: span.count &* MemoryLayout<Element>.stride
320321
)
321322
self = unsafe _overrideLifetime(rawSpan, copying: span)
322323
}

test/stdlib/Span/InlineStorage.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===--- InlineStorage.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
14+
15+
// REQUIRES: executable_test
16+
17+
import StdlibUnittest
18+
19+
var suite = TestSuite("InlineTypesStorageProperty")
20+
defer { runAllTests() }
21+
22+
suite.test("CollectionOfOne.span property")
23+
.skip(.custom(
24+
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
25+
reason: "Requires Swift 6.2's standard library"
26+
))
27+
.code {
28+
guard #available(SwiftStdlib 6.2, *) else { return }
29+
30+
var s = "A long string that is absolutely not smol at all."
31+
let u = Array(s.utf8)
32+
let c = CollectionOfOne(consume s)
33+
s = ""
34+
let span = c.span
35+
expectEqual(span.count, 1)
36+
let v = Array(span[0].utf8)
37+
expectEqual(u, v)
38+
}
39+
40+
suite.test("CollectionOfOne.span property (simple)")
41+
.skip(.custom(
42+
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
43+
reason: "Requires Swift 6.2's standard library"
44+
))
45+
.code {
46+
guard #available(SwiftStdlib 6.2, *) else { return }
47+
48+
let c = CollectionOfOne(Int.random(in: 0..<100000))
49+
let span = c.span
50+
expectEqual(span.count, c.indices.count)
51+
expectEqual(span[0], c[0])
52+
}
53+
54+
struct Padded: BitwiseCopyable {
55+
var storage: (Int64, Int8)
56+
}
57+
58+
suite.test("CollectionOfOne.span stride test")
59+
.skip(.custom(
60+
{ if #available(SwiftStdlib 6.2, *) { false } else { true } },
61+
reason: "Requires Swift 6.2's standard library"
62+
))
63+
.code {
64+
guard #available(SwiftStdlib 6.2, *) else { return }
65+
66+
let c = CollectionOfOne(Padded(storage: (-1, 1)))
67+
let span = c.span
68+
let bytes = span.bytes
69+
expectEqual(bytes.byteCount, MemoryLayout.size(ofValue: c))
70+
}

0 commit comments

Comments
 (0)