|
3 | 3 | /// Variable-length array, most likely stored on the stack. |
4 | 4 | /// |
5 | 5 | /// - Warning: May fall back to heap allocation if the compiler/runtime decides the allocation is too big for the stack. |
6 | | -public struct VLArray<Element>: ~Copyable, @unchecked Sendable { |
| 6 | +public struct VLArray<Element>: ~Copyable, @unchecked Sendable where Element: ~Copyable { |
7 | 7 | public typealias Index = Int |
8 | 8 |
|
9 | 9 | @usableFromInline |
@@ -96,6 +96,23 @@ public struct VLArray<Element>: ~Copyable, @unchecked Sendable { |
96 | 96 | _storage.index(before: i) |
97 | 97 | } |
98 | 98 |
|
| 99 | + /// Exchanges the values at the specified indices of the buffer. |
| 100 | + /// |
| 101 | + /// Both parameters must be valid indices of the buffer, and not |
| 102 | + /// equal to `endIndex`. Passing the same index as both `i` and `j` has no |
| 103 | + /// effect. |
| 104 | + /// |
| 105 | + /// - Parameters: |
| 106 | + /// - i: The index of the first value to swap. |
| 107 | + /// - j: The index of the second value to swap. |
| 108 | + @inlinable |
| 109 | + public mutating func swapAt(_ i: Index, _ j: Index) { |
| 110 | + _storage.swapAt(i, j) |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | +// MARK: Subscript |
| 115 | +extension VLArray { |
99 | 116 | /// Accesses the element at the specified position. |
100 | 117 | /// |
101 | 118 | /// The following example uses the buffer pointer's subscript to access and |
@@ -126,19 +143,37 @@ public struct VLArray<Element>: ~Copyable, @unchecked Sendable { |
126 | 143 | get { _storage[i] } |
127 | 144 | set { _storage[i] = newValue } |
128 | 145 | } |
129 | | - |
130 | | - /// Exchanges the values at the specified indices of the buffer. |
| 146 | +} |
| 147 | +extension VLArray where Element: ~Copyable { |
| 148 | + /// Accesses the element at the specified position. |
131 | 149 | /// |
132 | | - /// Both parameters must be valid indices of the buffer, and not |
133 | | - /// equal to `endIndex`. Passing the same index as both `i` and `j` has no |
134 | | - /// effect. |
| 150 | + /// The following example uses the buffer pointer's subscript to access and |
| 151 | + /// modify the elements of a mutable buffer pointing to the contiguous |
| 152 | + /// contents of an array: |
135 | 153 | /// |
136 | | - /// - Parameters: |
137 | | - /// - i: The index of the first value to swap. |
138 | | - /// - j: The index of the second value to swap. |
| 154 | + /// var numbers = [1, 2, 3, 4, 5] |
| 155 | + /// numbers.withUnsafeMutableBufferPointer { buffer in |
| 156 | + /// for i in stride(from: buffer.startIndex, to: buffer.endIndex - 1, by: 2) { |
| 157 | + /// let x = buffer[i] |
| 158 | + /// buffer[i + 1] = buffer[i] |
| 159 | + /// buffer[i] = x |
| 160 | + /// } |
| 161 | + /// } |
| 162 | + /// print(numbers) |
| 163 | + /// // Prints "[2, 1, 4, 3, 5]" |
| 164 | + /// |
| 165 | + /// Uninitialized memory cannot be initialized to a nontrivial type |
| 166 | + /// using this subscript. Instead, use an initializing method, such as |
| 167 | + /// `initializeElement(at:to:)` |
| 168 | + /// |
| 169 | + /// - Note: Bounds checks for `i` are performed only in debug mode. |
| 170 | + /// |
| 171 | + /// - Parameter i: The position of the element to access. `i` must be in the |
| 172 | + /// range `0..<count`. |
139 | 173 | @inlinable |
140 | | - public mutating func swapAt(_ i: Index, _ j: Index) { |
141 | | - _storage.swapAt(i, j) |
| 174 | + public subscript(i: Index) -> Element { |
| 175 | + _read { yield _storage[i] } |
| 176 | + _modify { yield &_storage[i] } |
142 | 177 | } |
143 | 178 | } |
144 | 179 |
|
|
0 commit comments