@@ -22,7 +22,7 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
2222 internal var _values : ContiguousArray < _Element >
2323 /// A dictionary where each value is located.
2424 @usableFromInline
25- internal var positions : [ Key : DuplicateDictionaryPositions ]
25+ internal var positions : [ Key : Positions ]
2626
2727 public typealias Index = Int
2828 public typealias Element = ( key: Key , value: Value )
@@ -46,12 +46,14 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
4646
4747 /// Result value from a key lookup.
4848 public struct Entries {
49- private let positions : DuplicateDictionaryPositions
50- private let owner : DuplicateDictionary
49+ @usableFromInline
50+ let positions : Positions
51+ @usableFromInline
52+ let owner : DuplicateDictionary
5153
5254 @inline ( __always)
5355 fileprivate init (
54- positions: DuplicateDictionaryPositions ,
56+ positions: Positions ,
5557 owner: DuplicateDictionary
5658 ) {
5759 self . positions = positions
@@ -71,14 +73,73 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
7173 }
7274 }
7375
76+ /// Where the element is location in the `values` array.
77+ public enum Positions : Sendable , Equatable , Sequence {
78+ public typealias Index = Int
79+ public typealias Element = Int
80+
81+ /// Nowhere
82+ case empty
83+ /// Just a single location
84+ case single( Int )
85+ /// In many spots
86+ case many( [ Int ] )
87+
88+ /// How many spots it exists
89+ @inline ( __always)
90+ @inlinable
91+ var count : Int {
92+ return switch self {
93+ case . empty: 0
94+ case . single: 1
95+ case . many( let i) : i. count
96+ }
97+ }
98+
99+ /// Adds the index to the positions
100+ @inline ( __always)
101+ mutating func adding( _ index: Int ) {
102+ switch self {
103+ case . empty:
104+ self = . single( index)
105+ case . single( let existing) :
106+ self = . many( [ existing, index] )
107+ case . many( var existing) :
108+ existing. append ( index)
109+ self = . many( existing)
110+ }
111+ }
112+
113+ public func makeIterator( ) -> Iterator {
114+ Iterator ( positions: self )
115+ }
116+
117+ public struct Iterator : IteratorProtocol {
118+ let positions : Positions
119+ var currentIndex = 0
120+
121+ public mutating func next( ) -> Element ? {
122+ switch positions {
123+ case . empty:
124+ return nil
125+ case . single( let index) :
126+ return currentIndex == 0 ? index : nil
127+ case . many( let indices) :
128+ guard currentIndex < indices. count else { return nil }
129+ return indices [ currentIndex]
130+ }
131+ }
132+ }
133+ }
134+
74135 public init ( ) {
75136 self . _values = [ ]
76137 self . positions = [ : ]
77138 }
78139
79140 private init (
80141 values: ContiguousArray < _Element > ,
81- positions: [ Key : DuplicateDictionaryPositions ]
142+ positions: [ Key : Positions ]
82143 ) {
83144 self . _values = values
84145 self . positions = positions
@@ -92,6 +153,15 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
92153 positions [ key, default: . empty] . adding ( index)
93154 }
94155
156+ @inline ( __always)
157+ public mutating func append< S: Sequence > (
158+ contentsOf collection: S
159+ ) where S. Element == Element {
160+ for (key, value) in collection {
161+ append ( value, for: key)
162+ }
163+ }
164+
95165 /// Gets the values for the given key
96166 @inline ( __always)
97167 public subscript( key: Key ) -> Entries {
@@ -107,6 +177,11 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
107177 positions. reserveCapacity ( minimumCapacity)
108178 }
109179
180+ public func contains( key: Key ) -> Bool {
181+ guard let p = positions [ key] else { return false }
182+ return p != . empty
183+ }
184+
110185 /// Map over the values and transform them into a new dictionary
111186 /// with the same keys but with the transformed values.
112187 public func mapValues< T> (
@@ -116,7 +191,13 @@ public struct DuplicateDictionary<Key: Hashable, Value> {
116191 values: ContiguousArray ( _values. map {
117192 DuplicateDictionary < Key , T > . _Element ( $0. key, try transform ( $0. value) )
118193 } ) ,
119- positions: positions
194+ positions: positions. reduce ( into: [ : ] ) { r, p in
195+ r [ p. key] = switch p. value {
196+ case . empty: . empty
197+ case . single( let i) : . single( i)
198+ case . many( let i) : . many( i)
199+ }
200+ }
120201 )
121202 }
122203}
@@ -174,40 +255,39 @@ extension DuplicateDictionary: Collection {
174255 }
175256}
176257
177- extension DuplicateDictionary . Entries : Sequence {
258+ extension DuplicateDictionary . Entries : Collection {
178259 public typealias Element = Value
260+ public typealias Index = Int
179261
180262 @inline ( __always)
263+ @inlinable
264+ public subscript( index: Index ) -> Element {
265+ switch positions {
266+ case . empty:
267+ preconditionFailure ( " Index out of bounds " )
268+ case . single( let i) :
269+ guard index == 0 else { preconditionFailure ( " Index out of bounds " ) }
270+ return owner. _values [ i] . value
271+ case . many( let i) :
272+ return owner. _values [ i [ index] ] . value
273+ }
274+ }
275+
276+ @inline ( __always)
277+ @inlinable
181278 public var count : Int { positions. count }
182279
183280 @inline ( __always)
184- public func makeIterator( ) -> Iterator {
185- Iterator ( element: self )
186- }
281+ @inlinable
282+ public var startIndex : Int { 0 }
187283
188- public struct Iterator : IteratorProtocol {
189- private let element : DuplicateDictionary . Entries
190- private var currentIndex = 0
191-
192- init ( element: DuplicateDictionary . Entries ) {
193- self . element = element
194- }
195-
196- @inline ( __always)
197- public mutating func next( ) -> Value ? {
198- defer { currentIndex += 1 }
199-
200- switch element. positions {
201- case . empty:
202- return nil
203- case . single( let index) :
204- return currentIndex == 0 ? element. owner. _values [ index] . value : nil
205- case . many( let indices) :
206- guard currentIndex < indices. count else { return nil }
207- return element. owner. _values [ currentIndex] . value
208- }
209- }
210- }
284+ @inline ( __always)
285+ @inlinable
286+ public var endIndex : Int { positions. count }
287+
288+ @inline ( __always)
289+ @inlinable
290+ public func index( after i: Index ) -> Index { i + 1 }
211291}
212292
213293extension DuplicateDictionary {
@@ -216,33 +296,36 @@ extension DuplicateDictionary {
216296 Values ( dictionary: self )
217297 }
218298
219- public struct Values : Sequence {
299+ public struct Values : Collection {
220300 public typealias Element = Value
221301
302+ @usableFromInline
222303 let dictionary : DuplicateDictionary
223304
224305 init ( dictionary: DuplicateDictionary ) {
225306 self . dictionary = dictionary
226307 }
227308
228- public func makeIterator ( ) -> Iterator {
229- return Iterator ( dictionary : dictionary )
230- }
309+ @ inline ( __always )
310+ @ inlinable
311+ public subscript ( index : Index ) -> Element { dictionary . _values [ index ] . value }
231312
232- public struct Iterator : IteratorProtocol {
233- private let dictionary : DuplicateDictionary
234- private var index = 0
235-
236- @usableFromInline
237- init ( dictionary: DuplicateDictionary ) {
238- self . dictionary = dictionary
239- }
240-
241- public mutating func next( ) -> Element ? {
242- guard index < dictionary. _values. count else { return nil }
243- defer { index += 1 }
244- return dictionary. _values [ index] . value
245- }
313+ @inline ( __always)
314+ @inlinable
315+ public var count : Int { dictionary. _values. count }
316+
317+ @inline ( __always)
318+ @inlinable
319+ public var startIndex : Int { dictionary. _values. startIndex }
320+
321+ @inline ( __always)
322+ @inlinable
323+ public var endIndex : Int { dictionary. _values. endIndex }
324+
325+ @inline ( __always)
326+ @inlinable
327+ public func index( after i: Index ) -> Index {
328+ dictionary. _values. index ( after: i)
246329 }
247330 }
248331}
@@ -251,65 +334,3 @@ extension DuplicateDictionary: Sendable where Key: Sendable, Value: Sendable {}
251334extension DuplicateDictionary . _Element : Sendable where Key: Sendable , Value: Sendable { }
252335extension DuplicateDictionary . _Element : Equatable where Key: Equatable , Value: Equatable { }
253336extension DuplicateDictionary : Equatable where Key: Equatable , Value: Equatable { }
254-
255- /// Where the element is location in the `values` array.
256- ///
257- /// This cannot be nested in the `DuplicateDictionary` struct
258- /// due to the `mapValues` since `DuplicateDictionary<T, V>.Positions`
259- /// is not equal too `DuplicateDictionary<T, NewValue>.Positions`
260- public enum DuplicateDictionaryPositions : Sendable , Equatable , Sequence {
261- public typealias Index = Int
262- public typealias Element = Int
263-
264- /// Nowhere
265- case empty
266- /// Just a single location
267- case single( Int )
268- /// In many spots
269- case many( [ Int ] )
270-
271- /// How many spots it exists
272- @inline ( __always)
273- var count : Int {
274- return switch self {
275- case . empty: 0
276- case . single: 1
277- case . many( let i) : i. count
278- }
279- }
280-
281- /// Adds the index to the positions
282- @inline ( __always)
283- mutating func adding( _ index: Int ) {
284- switch self {
285- case . empty:
286- self = . single( index)
287- case . single( let existing) :
288- self = . many( [ existing, index] )
289- case . many( var existing) :
290- existing. append ( index)
291- self = . many( existing)
292- }
293- }
294-
295- public func makeIterator( ) -> Iterator {
296- Iterator ( positions: self )
297- }
298-
299- public struct Iterator : IteratorProtocol {
300- let positions : DuplicateDictionaryPositions
301- var currentIndex = 0
302-
303- public mutating func next( ) -> Element ? {
304- switch positions {
305- case . empty:
306- return nil
307- case . single( let index) :
308- return currentIndex == 0 ? index : nil
309- case . many( let indices) :
310- guard currentIndex < indices. count else { return nil }
311- return indices [ currentIndex]
312- }
313- }
314- }
315- }
0 commit comments