@@ -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