You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* [se0447] edit regarding _read accessor
* [se0447] remove an aside
* [se0447] small api update
- remove `isWithin`
- rename `indicesWithin()` to `indices(of:)`, and reverse polarity.
* [se0447] update some doc-comments
* [se0447] remove index validation utilities
- plan to introduce an API on Range instead
* [se0447] explicitly give `Span` an `Index`
* [se0447] wordsmith around `unsafeLoad`
* [se0447] add the `byteOffsets` property to `RawSpan`
Note that we use a `_read` accessor for the subscript, a requirement in order to `yield` a borrowed non-copyable `Element` (see ["Coroutines"](#Coroutines).) This will be updated to a final syntax at a later time, understanding that we intend the replacement to be source-compatible.
130
+
Note that we use a `_read` accessor for the subscript, a requirement in order to `yield` a borrowed non-copyable `Element` (see ["Coroutines"](#Coroutines).) This yields an element whose lifetime is scoped around this particular access, as opposed to matching the lifetime dependency of the `Span` itself. This is a language limitation we expect to resolve with a followup proposal introducing a new accessor model. The subscript will then be updated to use the new accessor semantics. We expect the updated accessor to be source-compatible, as it will provide a borrowed element with a wider lifetime than a `_read` accessor can provide.
118
131
119
132
##### Unchecked access to elements:
120
133
121
134
The `subscript` mentioned above has always-on bounds checking of its parameter, in order to prevent out-of-bounds accesses. We also want to provide unchecked variants as an alternative for cases where bounds-checking is proving costly, such as in tight loops:
122
135
123
136
```swift
124
137
extensionSpanwhereElement:~Copyable {
125
-
// Unchecked subscripting and extraction
126
138
127
139
/// Accesses the element at the specified `position`.
128
140
///
129
141
/// This subscript does not validate `position`; this is an unsafe operation.
130
142
///
131
143
/// - Parameter position: The offset of the element to access. `position`
132
144
/// must be greater or equal to zero, and less than `count`.
Every time `Span` uses a position parameter, it checks for its validity, unless the parameter is marked with the word "unchecked". The validation is performed with these functions:
140
-
141
-
```swift
142
-
extensionSpanwhereElement:~Copyable {
143
-
/// Return true if `index` is a valid offset into this `Span`
144
-
///
145
-
/// - Parameters:
146
-
/// - index: an index to validate
147
-
/// - Returns: true if `index` is a valid index
148
-
publicfuncboundsContain(_index: Int) ->Bool
149
-
150
-
/// Return true if `indices` is a valid range of offsets into this `Span`
151
-
///
152
-
/// - Parameters:
153
-
/// - indices: a range of indices to validate
154
-
/// - Returns: true if `indices` is a valid range of indices
When using the unchecked subscript, the index must be known to be valid. While we are not proposing explicit index validation API on `Span` itself, its `indices` property can be use to validate a single index, in the form of the function `Range<Int>.contains(_: Int) -> Bool`. We expect that `Range` will also add efficient containment checking of a subrange's endpoints, which should be generally useful for index range validation in this and other contexts.
167
150
168
151
##### Identifying whether a `Span` is a subrange of another:
169
152
@@ -174,21 +157,13 @@ extension Span where Element: ~Copyable {
174
157
/// Returns true if the other span represents exactly the same memory
@@ -256,7 +231,7 @@ Initializers, required for library adoption, will be proposed alongside [lifetim
256
231
257
232
##### <aname="Load"></a>Accessing the memory of a `RawSpan`:
258
233
259
-
`RawSpan` has basic operations to access the contents of its memory: `unsafeLoad(as:)` and `unsafeLoadUnaligned(as:)`. These operations are not type-safe, in that the loaded value returned by the operation can be invalid. Some types have a property that makes this operation safe, but there we don't have a way to [formally identify](#SurjectiveBitPattern) such types at this time.
234
+
`RawSpan` has basic operations to access the contents of its memory: `unsafeLoad(as:)` and `unsafeLoadUnaligned(as:)`:
260
235
261
236
```swift
262
237
extensionRawSpan {
@@ -302,7 +277,10 @@ extension RawSpan {
302
277
) -> T
303
278
```
304
279
305
-
These functions have counterparts which omit bounds-checking for cases where redundant checks affect performance:
280
+
These operations are not type-safe, in that the loaded value returned by the operation can be invalid, and violate type invariants. Some types have a property that makes the `unsafeLoad(as:)` function safe, but we don't have a way to [formally identify](#SurjectiveBitPattern) such types at this time.
281
+
282
+
The `unsafeLoad` functions have counterparts which omit bounds-checking for cases where redundant checks affect performance:
283
+
306
284
```swift
307
285
/// Returns a new instance of the given type, constructed from the raw memory
308
286
/// at the specified offset.
@@ -382,20 +360,9 @@ extension RawSpan {
382
360
383
361
/// A Boolean value indicating whether the span is empty.
384
362
publicvar isEmpty: Bool { get }
385
-
}
386
-
```
387
-
388
-
##### `RawSpan` bounds checking:
389
-
```swift
390
-
extensionRawSpan {
391
-
/// Return true if `offset` is a valid byte offset into this `RawSpan`
392
-
publicfuncboundsContain(_offset: Int) ->Bool
393
-
394
-
/// Return true if `offsets` is a valid range of offsets into this `RawSpan`
@@ -501,6 +466,10 @@ extension Array where Element: BitwiseCopyable {
501
466
502
467
Of these, the closure-taking functions can be implemented now, but it is unclear whether they are desirable. The lifetime-dependent computed properties require lifetime annotations, as initializers do. We are deferring proposing these extensions until the lifetime annotations are proposed.
503
468
469
+
#### Index Validation Utilities
470
+
471
+
This proposal originally included index validation utilities for `Span`. such as `boundsContain(_: Index) ->Bool` and `boundsContain(_: Range<Index>) ->Bool`. After review feedback, we believe that the utilities proposed would also be useful for index validation on `UnsafeBufferPointer`, `Array`, and other similar `RandomAccessCollection` types. `Range` already a single-element `contains(_: Bound) ->Bool` function which can be made even more efficient. We should add an additional function that identifies whether a `Range` contains the _endpoints_ of another `Range`. Note that this is not the same as the existing `contains(_: some Collection<Bound>) ->Bool`, which is about the _elements_ of the collection. This semantic difference can lead to different results when examing empty `Range` instances.
An earlier version of this proposal proposed a `ContiguousStorage` protocol by which a type could indicate that it can provide a `Span`. `ContiguousStorage` would form a bridge between generically-typed interfaces and a performant concrete implementation. It would supersede the rejected [SE-0256](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0256-contiguous-collection.md).
0 commit comments