Skip to content

Commit 7d79179

Browse files
committed
SIL: add the IterableSet utility
It is a set which supports iterating over its elements.
1 parent 2c5d823 commit 7d79179

File tree

1 file changed

+63
-0
lines changed
  • SwiftCompilerSources/Sources/SIL/DataStructures

1 file changed

+63
-0
lines changed

SwiftCompilerSources/Sources/SIL/DataStructures/Set.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,66 @@ extension IntrusiveSet {
287287
insert(contentsOf: source)
288288
}
289289
}
290+
291+
/// A set which supports iterating over its elements.
292+
/// The iteration order is deterministic. All set operations are O(1).
293+
public struct IterableSet<Set: IntrusiveSet> : CollectionLikeSequence {
294+
public typealias Element = Set.Element
295+
296+
private var set: Set
297+
298+
// Erased elements do not get removed from `list`, because this would be O(n).
299+
private var list: Stack<Element>
300+
301+
// Elements which are in `list. This is different from `set` if elements get erased.
302+
private var inList: Set
303+
304+
public init(_ context: some Context) {
305+
self.set = Set(context)
306+
self.list = Stack(context)
307+
self.inList = Set(context)
308+
}
309+
310+
public mutating func deinitialize() {
311+
inList.deinitialize()
312+
list.deinitialize()
313+
set.deinitialize()
314+
}
315+
316+
public func contains(_ element: Element) -> Bool {
317+
set.contains(element)
318+
}
319+
320+
/// Returns true if `element` was not contained in the set before inserting.
321+
@discardableResult
322+
public mutating func insert(_ element: Element) -> Bool {
323+
if inList.insert(element) {
324+
list.append(element)
325+
}
326+
return set.insert(element)
327+
}
328+
329+
public mutating func erase(_ element: Element) {
330+
set.erase(element)
331+
}
332+
333+
public func makeIterator() -> Iterator { Iterator(base: list.makeIterator(), set: set) }
334+
335+
public struct Iterator: IteratorProtocol {
336+
var base: Stack<Element>.Iterator
337+
let set: Set
338+
339+
public mutating func next() -> Element? {
340+
while let n = base.next() {
341+
if set.contains(n) {
342+
return n
343+
}
344+
}
345+
return nil
346+
}
347+
}
348+
}
349+
350+
public typealias IterableInstructionSet = IterableSet<InstructionSet>
351+
public typealias SpecificIterableInstructionSet<InstType: Instruction> = IterableSet<SpecificInstructionSet<InstType>>
352+
public typealias IterableBasicBlockSet = IterableSet<BasicBlockSet>

0 commit comments

Comments
 (0)