@@ -80,27 +80,39 @@ public protocol CxxSequence: Sequence {
80
80
mutating func __endUnsafe( ) -> RawIterator
81
81
}
82
82
83
- public class CxxIterator < T> : IteratorProtocol where T: CxxSequence {
84
- // Declared as a class instead of a struct to avoid copies of this object,
85
- // which would result in dangling pointers for some C++ sequence types.
83
+ /// Prevents a C++ sequence from being copied or moved implicitly. Makes sure
84
+ /// that raw C++ iterators pointing into the sequence are not invalidated.
85
+ @usableFromInline
86
+ internal final class CxxSequenceBox < T> where T: CxxSequence {
87
+ @usableFromInline
88
+ internal var sequence : T
89
+
90
+ @usableFromInline
91
+ internal init ( _ sequence: __shared T) {
92
+ self . sequence = sequence
93
+ }
94
+ }
86
95
96
+ @frozen
97
+ public struct CxxIterator < T> : IteratorProtocol where T: CxxSequence {
87
98
public typealias Element = T . RawIterator . Pointee
88
99
89
100
@usableFromInline
90
- internal var sequence : T
101
+ internal let sequence : CxxSequenceBox < T >
91
102
@usableFromInline
92
103
internal var rawIterator : T . RawIterator
93
104
@usableFromInline
94
105
internal let endIterator : T . RawIterator
95
106
96
- public init ( sequence: T ) {
97
- self . sequence = sequence
98
- self . rawIterator = self . sequence. __beginUnsafe ( )
99
- self . endIterator = self . sequence. __endUnsafe ( )
107
+ @inlinable
108
+ public init ( sequence: __shared T) {
109
+ self . sequence = CxxSequenceBox < T > ( sequence)
110
+ self . rawIterator = self . sequence. sequence. __beginUnsafe ( )
111
+ self . endIterator = self . sequence. sequence. __endUnsafe ( )
100
112
}
101
113
102
114
@inlinable
103
- public func next( ) -> Element ? {
115
+ public mutating func next( ) -> Element ? {
104
116
if self . rawIterator == self . endIterator {
105
117
return nil
106
118
}
0 commit comments