@@ -61,14 +61,16 @@ internal class __SwiftNativeNSArrayWithContiguousStorage
61
61
}
62
62
}
63
63
64
+ private let NSNotFound : Int = . max
65
+
64
66
// Implement the APIs required by NSArray
65
67
extension __SwiftNativeNSArrayWithContiguousStorage : _NSArrayCore {
66
68
@objc internal var count : Int {
67
69
return withUnsafeBufferOfObjects { $0. count }
68
70
}
69
71
70
- @objc ( objectAtIndex : )
71
- internal func objectAt ( _ index: Int ) -> AnyObject {
72
+ @inline ( __always )
73
+ @ nonobjc private func _objectAt ( _ index: Int ) -> AnyObject {
72
74
return withUnsafeBufferOfObjects {
73
75
objects in
74
76
_precondition (
@@ -77,6 +79,16 @@ extension __SwiftNativeNSArrayWithContiguousStorage: _NSArrayCore {
77
79
return objects [ index]
78
80
}
79
81
}
82
+
83
+ @objc ( objectAtIndexedSubscript: )
84
+ dynamic internal func objectAtSubscript( _ index: Int ) -> AnyObject {
85
+ return _objectAt ( index)
86
+ }
87
+
88
+ @objc ( objectAtIndex: )
89
+ dynamic internal func objectAt( _ index: Int ) -> AnyObject {
90
+ return _objectAt ( index)
91
+ }
80
92
81
93
@objc internal func getObjects(
82
94
_ aBuffer: UnsafeMutablePointer < AnyObject > , range: _SwiftNSRange
@@ -131,6 +143,172 @@ extension __SwiftNativeNSArrayWithContiguousStorage: _NSArrayCore {
131
143
}
132
144
}
133
145
146
+ @_fixed_layout
147
+ @usableFromInline
148
+ @objc internal final class _SwiftNSMutableArray :
149
+ _SwiftNativeNSMutableArray , _NSArrayCore
150
+ {
151
+ internal var contents : [ AnyObject ]
152
+
153
+ internal init ( _ array: [ AnyObject ] ) {
154
+ contents = array
155
+ super. init ( )
156
+ }
157
+
158
+ @objc internal var count : Int {
159
+ return contents. count
160
+ }
161
+
162
+ @objc ( objectAtIndexedSubscript: )
163
+ dynamic internal func objectAtSubscript( _ index: Int ) -> AnyObject {
164
+ //TODO: exception instead of precondition, once that's possible
165
+ return contents [ index]
166
+ }
167
+
168
+ @objc ( objectAtIndex: )
169
+ dynamic internal func objectAt( _ index: Int ) -> AnyObject {
170
+ //TODO: exception instead of precondition, once that's possible
171
+ return contents [ index]
172
+ }
173
+
174
+ @objc internal func getObjects(
175
+ _ aBuffer: UnsafeMutablePointer < AnyObject > , range: _SwiftNSRange
176
+ ) {
177
+ return contents. withContiguousStorageIfAvailable { objects in
178
+ //TODO: exceptions instead of preconditions, once that's possible
179
+
180
+ _precondition (
181
+ _isValidArrayIndex ( range. location, count: objects. count) ,
182
+ " Array index out of range " )
183
+
184
+ _precondition (
185
+ _isValidArrayIndex (
186
+ range. location + range. length, count: objects. count) ,
187
+ " Array index out of range " )
188
+
189
+ if objects. isEmpty { return }
190
+
191
+ // These objects are "returned" at +0, so treat them as pointer values to
192
+ // avoid retains. Copy bytes via a raw pointer to circumvent reference
193
+ // counting while correctly aliasing with all other pointer types.
194
+ UnsafeMutableRawPointer ( aBuffer) . copyMemory (
195
+ from: objects. baseAddress! + range. location,
196
+ byteCount: range. length * MemoryLayout< AnyObject> . stride)
197
+ } !
198
+ }
199
+
200
+ @objc ( countByEnumeratingWithState: objects: count: )
201
+ internal func countByEnumerating(
202
+ with state: UnsafeMutablePointer < _SwiftNSFastEnumerationState > ,
203
+ objects: UnsafeMutablePointer < AnyObject > ? , count: Int
204
+ ) -> Int {
205
+ var enumerationState = state. pointee
206
+
207
+ if enumerationState. state != 0 {
208
+ return 0
209
+ }
210
+
211
+ return contents. withContiguousStorageIfAvailable {
212
+ objects in
213
+ enumerationState. mutationsPtr = _fastEnumerationStorageMutationsPtr
214
+ enumerationState. itemsPtr =
215
+ AutoreleasingUnsafeMutablePointer ( objects. baseAddress)
216
+ enumerationState. state = 1
217
+ state. pointee = enumerationState
218
+ return objects. count
219
+ } !
220
+ }
221
+
222
+ @objc ( copyWithZone: )
223
+ dynamic internal func copy( with _: _SwiftNSZone ? ) -> AnyObject {
224
+ return contents. _bridgeToObjectiveCImpl ( )
225
+ }
226
+
227
+ @objc ( insertObject: atIndex: )
228
+ dynamic internal func insert( _ anObject: AnyObject , at index: Int ) {
229
+ contents. insert ( anObject, at: index)
230
+ }
231
+
232
+ @objc ( removeObjectAtIndex: )
233
+ dynamic internal func removeObject( at index: Int ) {
234
+ contents. remove ( at: index)
235
+ }
236
+
237
+ @objc ( addObject: )
238
+ dynamic internal func add( _ anObject: AnyObject ) {
239
+ contents. append ( anObject)
240
+ }
241
+
242
+ @objc ( removeLastObject)
243
+ dynamic internal func removeLastObject( ) {
244
+ contents. removeLast ( )
245
+ }
246
+
247
+ @objc ( replaceObjectAtIndex: withObject: )
248
+ dynamic internal func replaceObject( at index: Int , with anObject: AnyObject ) {
249
+ //enforces bounds, unlike set equivalent, which can append
250
+ contents [ index] = anObject
251
+ }
252
+
253
+ //Non-core methods overridden for performance
254
+
255
+ @objc ( exchangeObjectAtIndex: withObjectAtIndex: )
256
+ dynamic internal func exchange( at index: Int , with index2: Int ) {
257
+ swap ( & contents[ index] , & contents[ index2] )
258
+ }
259
+
260
+ @objc ( replaceObjectsInRange: withObjects: count: )
261
+ dynamic internal func replaceObjects( in range: _SwiftNSRange ,
262
+ with objects: UnsafePointer < AnyObject > ,
263
+ count: Int ) {
264
+ let range = range. location ..< range. location + range. length
265
+ let buf = UnsafeBufferPointer ( start: objects, count: count)
266
+ contents. replaceSubrange ( range, with: buf)
267
+ }
268
+
269
+ @objc ( insertObjects: count: atIndex: )
270
+ dynamic internal func insertObjects( _ objects: UnsafePointer < AnyObject > ,
271
+ count: Int ,
272
+ at index: Int ) {
273
+ let buf = UnsafeBufferPointer ( start: objects, count: count)
274
+ contents. insert ( contentsOf: buf, at: index)
275
+ }
276
+
277
+ @objc ( indexOfObjectIdenticalTo: )
278
+ dynamic internal func index( ofObjectIdenticalTo object: AnyObject ) -> Int {
279
+ return contents. firstIndex { $0 === object } ?? NSNotFound
280
+ }
281
+
282
+ @objc ( removeObjectsInRange: )
283
+ dynamic internal func removeObjects( in range: _SwiftNSRange ) {
284
+ let range = range. location ..< range. location + range. length
285
+ contents. replaceSubrange ( range, with: [ ] )
286
+ }
287
+
288
+ @objc ( removeAllObjects)
289
+ dynamic internal func removeAllObjects( ) {
290
+ contents = [ ]
291
+ }
292
+
293
+ @objc ( setObject: atIndex: )
294
+ dynamic internal func setObject( _ anObject: AnyObject , at index: Int ) {
295
+ if index == contents. count {
296
+ contents. append ( anObject)
297
+ } else {
298
+ contents [ index] = anObject
299
+ }
300
+ }
301
+
302
+ @objc ( setObject: atIndexedSubscript: ) dynamic
303
+ internal func setObjectSubscript( _ anObject: AnyObject , at index: Int ) {
304
+ if index == contents. count {
305
+ contents. append ( anObject)
306
+ } else {
307
+ contents [ index] = anObject
308
+ }
309
+ }
310
+ }
311
+
134
312
/// An `NSArray` whose contiguous storage is created and filled, upon
135
313
/// first access, by bridging the elements of a Swift `Array`.
136
314
///
@@ -292,6 +470,18 @@ internal class __ContiguousArrayStorageBase
292
470
_internalInvariantFailure (
293
471
" Concrete subclasses must implement _getNonVerbatimBridgingBuffer " )
294
472
}
473
+
474
+ @objc ( mutableCopyWithZone: )
475
+ dynamic internal func mutableCopy( with _: _SwiftNSZone ? ) -> AnyObject {
476
+ let arr = Array < AnyObject > ( _ContiguousArrayBuffer ( self ) )
477
+ return _SwiftNSMutableArray ( arr)
478
+ }
479
+
480
+ @objc ( indexOfObjectIdenticalTo: )
481
+ dynamic internal func index( ofObjectIdenticalTo object: AnyObject ) -> Int {
482
+ let arr = Array < AnyObject > ( _ContiguousArrayBuffer ( self ) )
483
+ return arr. firstIndex { $0 === object } ?? NSNotFound
484
+ }
295
485
#endif
296
486
297
487
@inlinable
@@ -306,7 +496,7 @@ internal class __ContiguousArrayStorageBase
306
496
_internalInvariantFailure (
307
497
" Concrete subclasses must implement staticElementType " )
308
498
}
309
-
499
+
310
500
@inlinable
311
501
deinit {
312
502
_internalInvariant (
0 commit comments