@@ -3749,12 +3749,9 @@ final internal class _SwiftDeferredNS${Self}<${TypeParametersDecl}> { }
3749
3749
#endif
3750
3750
3751
3751
#if _runtime(_ObjC)
3752
-
3753
- // FIXME: this should really be a struct but can't because of the lazy allKeys.
3754
- // (but it might be removed with eager bridging, so this is "fine" for now)
3755
3752
@_versioned
3756
3753
@_fixed_layout
3757
- internal final class _Cocoa${Self}Buffer : _HashBuffer {
3754
+ internal struct _Cocoa${Self}Buffer : _HashBuffer {
3758
3755
@_versioned
3759
3756
internal var cocoa${Self}: _NS${Self}
3760
3757
@@ -3765,31 +3762,22 @@ internal final class _Cocoa${Self}Buffer : _HashBuffer {
3765
3762
internal typealias Key = AnyObject
3766
3763
internal typealias Value = AnyObject
3767
3764
3768
- internal lazy var allKeys : _Box<_HeapBuffer<Int, AnyObject>> = {
3769
- return _Box(_stdlib_NS${Self}_all${'Objects' if Self == 'Set' else 'Keys'}(self.cocoa${Self}))
3770
- }()
3771
-
3772
3765
internal var startIndex: Index {
3773
- return Index(value: 0 )
3766
+ return Index(cocoa${Self}, startIndex: () )
3774
3767
}
3775
3768
3776
3769
internal var endIndex: Index {
3777
- return Index(value: allKeys._value.value )
3770
+ return Index(cocoa${Self}, endIndex: () )
3778
3771
}
3779
3772
3780
- // Assumption: we rely on NS${Self}.getObjects when being
3781
- // repeatedly called on the same NS${Self}, returning items in the same
3782
- // order every time.
3783
3773
@_versioned
3784
3774
internal func index(after i: Index) -> Index {
3785
- _precondition(
3786
- i.currentKeyIndex < allKeys._value.value, "cannot increment endIndex")
3787
- return _Cocoa${Self}Index(value: i.currentKeyIndex + 1)
3775
+ return i.successor()
3788
3776
}
3789
3777
3790
- @_versioned
3791
3778
internal func formIndex(after i: inout Index) {
3792
- i = index(after: i)
3779
+ // FIXME: swift-3-indexing-model: optimize if possible.
3780
+ i = i.successor()
3793
3781
}
3794
3782
3795
3783
@_versioned
@@ -3802,26 +3790,31 @@ internal final class _Cocoa${Self}Buffer : _HashBuffer {
3802
3790
return nil
3803
3791
}
3804
3792
3793
+ %if Self == 'Set':
3794
+ let allKeys = _stdlib_NSSet_allObjects(cocoaSet)
3795
+ %elif Self == 'Dictionary':
3796
+ let allKeys = _stdlib_NSDictionary_allKeys(cocoaDictionary)
3797
+ %end
3805
3798
var keyIndex = -1
3806
- for i in 0..<allKeys._value. value {
3807
- if _stdlib_NSObject_isEqual(key, allKeys._value [i]) {
3799
+ for i in 0..<allKeys.value {
3800
+ if _stdlib_NSObject_isEqual(key, allKeys[i]) {
3808
3801
keyIndex = i
3809
3802
break
3810
3803
}
3811
3804
}
3812
3805
_sanityCheck(keyIndex >= 0,
3813
3806
"key was found in fast path, but not found later?")
3814
- return Index(value: keyIndex)
3807
+ return Index(cocoa${Self}, allKeys, keyIndex)
3815
3808
}
3816
3809
3817
3810
internal func assertingGet(_ i: Index) -> SequenceElement {
3818
3811
%if Self == 'Set':
3819
- let value: Value? = allKeys._value [i.currentKeyIndex]
3812
+ let value: Value? = i.allKeys [i.currentKeyIndex]
3820
3813
_sanityCheck(value != nil, "item not found in underlying NS${Self}")
3821
3814
return value!
3822
3815
%elif Self == 'Dictionary':
3823
- let key: Key = allKeys._value [i.currentKeyIndex]
3824
- let value: Value = cocoaDictionary.objectFor(key)!
3816
+ let key: Key = i.allKeys [i.currentKeyIndex]
3817
+ let value: Value = i. cocoaDictionary.objectFor(key)!
3825
3818
return (key, value)
3826
3819
%end
3827
3820
@@ -3850,33 +3843,29 @@ internal final class _Cocoa${Self}Buffer : _HashBuffer {
3850
3843
3851
3844
}
3852
3845
3853
- internal init(cocoa${Self}: _NS${Self}) {
3854
- self.cocoa${Self} = cocoa${Self}
3855
- }
3856
-
3857
3846
@discardableResult
3858
- internal func updateValue(_ value: Value, forKey key: Key) -> Value? {
3847
+ internal mutating func updateValue(_ value: Value, forKey key: Key) -> Value? {
3859
3848
_sanityCheckFailure("cannot mutate NS${Self}")
3860
3849
}
3861
3850
3862
3851
@discardableResult
3863
- internal func insert(
3852
+ internal mutating func insert(
3864
3853
_ value: Value, forKey key: Key
3865
3854
) -> (inserted: Bool, memberAfterInsert: Value) {
3866
3855
_sanityCheckFailure("cannot mutate NS${Self}")
3867
3856
}
3868
3857
3869
3858
@discardableResult
3870
- internal func remove(at index: Index) -> SequenceElement {
3859
+ internal mutating func remove(at index: Index) -> SequenceElement {
3871
3860
_sanityCheckFailure("cannot mutate NS${Self}")
3872
3861
}
3873
3862
3874
3863
@discardableResult
3875
- internal func removeValue(forKey key: Key) -> Value? {
3864
+ internal mutating func removeValue(forKey key: Key) -> Value? {
3876
3865
_sanityCheckFailure("cannot mutate NS${Self}")
3877
3866
}
3878
3867
3879
- internal func removeAll(keepingCapacity keepCapacity: Bool) {
3868
+ internal mutating func removeAll(keepingCapacity keepCapacity: Bool) {
3880
3869
_sanityCheckFailure("cannot mutate NS${Self}")
3881
3870
}
3882
3871
@@ -4465,9 +4454,8 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
4465
4454
//
4466
4455
// FIXME(performance): fuse data migration and element deletion into one
4467
4456
// operation.
4468
- let cocoaIndex = index._cocoaIndex
4469
- let anyObjectKey: AnyObject =
4470
- cocoaBuffer.allKeys._value[cocoaIndex.currentKeyIndex]
4457
+ let index = index._cocoaIndex
4458
+ let anyObjectKey: AnyObject = index.allKeys[index.currentKeyIndex]
4471
4459
migrateDataToNativeBuffer(cocoaBuffer)
4472
4460
let key = _forceBridgeFromObjectiveC(anyObjectKey, Key.self)
4473
4461
let value = nativeRemoveObject(forKey: key)
@@ -4628,11 +4616,61 @@ extension _Native${Self}Index {
4628
4616
#if _runtime(_ObjC)
4629
4617
@_versioned
4630
4618
internal struct _Cocoa${Self}Index : Comparable {
4631
- /// Index into `allKeys` on the CocoaSelfBuffer
4619
+ // Assumption: we rely on NSDictionary.getObjects when being
4620
+ // repeatedly called on the same NSDictionary, returning items in the same
4621
+ // order every time.
4622
+ // Similarly, the same assumption holds for NSSet.allObjects.
4623
+
4624
+ /// A reference to the NS${Self}, which owns members in `allObjects`,
4625
+ /// or `allKeys`, for NSSet and NSDictionary respectively.
4626
+ internal let cocoa${Self}: _NS${Self}
4627
+ // FIXME: swift-3-indexing-model: try to remove the cocoa reference, but make
4628
+ // sure that we have a safety check for accessing `allKeys`. Maybe move both
4629
+ // into the dictionary/set itself.
4630
+
4631
+ /// An unowned array of keys.
4632
+ internal var allKeys: _HeapBuffer<Int, AnyObject>
4633
+
4634
+ /// Index into `allKeys`
4632
4635
internal var currentKeyIndex: Int
4633
4636
4634
- internal init(value: Int) {
4635
- currentKeyIndex = value
4637
+ internal init(_ cocoa${Self}: _NS${Self}, startIndex: ()) {
4638
+ self.cocoa${Self} = cocoa${Self}
4639
+ %if Self == 'Set':
4640
+ self.allKeys = _stdlib_NSSet_allObjects(cocoaSet)
4641
+ %elif Self == 'Dictionary':
4642
+ self.allKeys = _stdlib_NSDictionary_allKeys(cocoaDictionary)
4643
+ %end
4644
+ self.currentKeyIndex = 0
4645
+ }
4646
+
4647
+ internal init(_ cocoa${Self}: _NS${Self}, endIndex: ()) {
4648
+ self.cocoa${Self} = cocoa${Self}
4649
+ %if Self == 'Set':
4650
+ self.allKeys = _stdlib_NS${Self}_allObjects(cocoa${Self})
4651
+ %elif Self == 'Dictionary':
4652
+ self.allKeys = _stdlib_NS${Self}_allKeys(cocoa${Self})
4653
+ %end
4654
+ self.currentKeyIndex = allKeys.value
4655
+ }
4656
+
4657
+ internal init(_ cocoa${Self}: _NS${Self},
4658
+ _ allKeys: _HeapBuffer<Int, AnyObject>,
4659
+ _ currentKeyIndex: Int
4660
+ ) {
4661
+ self.cocoa${Self} = cocoa${Self}
4662
+ self.allKeys = allKeys
4663
+ self.currentKeyIndex = currentKeyIndex
4664
+ }
4665
+
4666
+ /// Returns the next consecutive value after `self`.
4667
+ ///
4668
+ /// - Precondition: The next value is representable.
4669
+ internal func successor() -> _Cocoa${Self}Index {
4670
+ // FIXME: swift-3-indexing-model: remove this method.
4671
+ _precondition(
4672
+ currentKeyIndex < allKeys.value, "cannot increment endIndex")
4673
+ return _Cocoa${Self}Index(cocoa${Self}, allKeys, currentKeyIndex + 1)
4636
4674
}
4637
4675
}
4638
4676
0 commit comments