@@ -1242,8 +1242,28 @@ extension NSSet {
1242
1242
/// receiver.
1243
1243
@nonobjc
1244
1244
public convenience init ( set anSet: NSSet ) {
1245
- // FIXME: This is a bit weird. Maybe there's a better way?
1246
- self . init ( set: anSet as Set < NSObject > as Set < AnyHashable > )
1245
+ // FIXME(performance)(compiler limitation): we actually want to do just
1246
+ // `self = anSet.copy()`, but Swift does not have factory
1247
+ // initializers right now.
1248
+ let numElems = anSet. count
1249
+ let stride = MemoryLayout< Optional< UnsafeRawPointer>>. stride
1250
+ let alignment = MemoryLayout< Optional< UnsafeRawPointer>>. alignment
1251
+ let bufferSize = stride * numElems
1252
+ assert ( stride == MemoryLayout< AnyObject> . stride)
1253
+ assert ( alignment == MemoryLayout< AnyObject> . alignment)
1254
+
1255
+ let rawBuffer = UnsafeMutableRawPointer . allocate (
1256
+ bytes: bufferSize, alignedTo: alignment)
1257
+ defer {
1258
+ rawBuffer. deallocate ( bytes: bufferSize, alignedTo: alignment)
1259
+ _fixLifetime ( anSet)
1260
+ }
1261
+ let valueBuffer = rawBuffer. bindMemory (
1262
+ to: Optional< UnsafeRawPointer> . self , capacity: numElems)
1263
+
1264
+ CFSetGetValues ( anSet, valueBuffer)
1265
+ let valueBufferForInit = rawBuffer. assumingMemoryBound ( to: AnyObject . self)
1266
+ self . init ( objects: valueBufferForInit, count: numElems)
1247
1267
}
1248
1268
}
1249
1269
@@ -1256,12 +1276,47 @@ extension NSDictionary {
1256
1276
/// found in `otherDictionary`.
1257
1277
@objc ( _swiftInitWithDictionary_NSDictionary: )
1258
1278
public convenience init ( dictionary otherDictionary: NSDictionary ) {
1259
- // FIXME: This is a bit weird. Maybe there's a better way?
1260
- self . init ( dictionary: otherDictionary as [ NSObject : AnyObject ]
1261
- as [ AnyHashable : Any ] )
1279
+ // FIXME(performance)(compiler limitation): we actually want to do just
1280
+ // `self = otherDictionary.copy()`, but Swift does not have factory
1281
+ // initializers right now.
1282
+ let numElems = otherDictionary. count
1283
+ let stride = MemoryLayout< AnyObject> . stride
1284
+ let alignment = MemoryLayout< AnyObject> . alignment
1285
+ let singleSize = stride * numElems
1286
+ let totalSize = singleSize * 2
1287
+ _sanityCheck ( stride == MemoryLayout< NSCopying> . stride)
1288
+ _sanityCheck ( alignment == MemoryLayout< NSCopying> . alignment)
1289
+
1290
+ // Allocate a buffer containing both the keys and values.
1291
+ let buffer = UnsafeMutableRawPointer . allocate (
1292
+ bytes: totalSize, alignedTo: alignment)
1293
+ defer {
1294
+ buffer. deallocate ( bytes: totalSize, alignedTo: alignment)
1295
+ _fixLifetime ( otherDictionary)
1296
+ }
1297
+
1298
+ let valueBuffer = buffer. bindMemory ( to: AnyObject . self, capacity: numElems)
1299
+ let buffer2 = buffer + singleSize
1300
+ let keyBuffer = buffer2. bindMemory ( to: AnyObject . self, capacity: numElems)
1301
+
1302
+ _stdlib_NSDictionary_getObjects (
1303
+ nsDictionary: otherDictionary,
1304
+ objects: valueBuffer,
1305
+ andKeys: keyBuffer)
1306
+
1307
+ let keyBufferCopying = buffer2. assumingMemoryBound ( to: NSCopying . self)
1308
+ self . init ( objects: valueBuffer, forKeys: keyBufferCopying, count: numElems)
1262
1309
}
1263
1310
}
1264
1311
1312
+ @_silgen_name ( " __NSDictionaryGetObjects " )
1313
+ func _stdlib_NSDictionary_getObjects(
1314
+ nsDictionary: NSDictionary ,
1315
+ objects: UnsafeMutablePointer < AnyObject > ? ,
1316
+ andKeys keys: UnsafeMutablePointer < AnyObject > ?
1317
+ )
1318
+
1319
+
1265
1320
//===----------------------------------------------------------------------===//
1266
1321
// NSUndoManager
1267
1322
//===----------------------------------------------------------------------===//
0 commit comments