@@ -40,6 +40,10 @@ public protocol CxxDictionary<Key, Value>: ExpressibleByDictionaryLiteral {
4040 @discardableResult
4141 mutating func erase( _ key: Key ) -> Size
4242
43+ /// Do not implement this function manually in Swift.
44+ @discardableResult
45+ mutating func __eraseUnsafe( _ iter: RawMutableIterator ) -> RawMutableIterator
46+
4347 /// Do not implement this function manually in Swift.
4448 func __beginUnsafe( ) -> RawIterator
4549
@@ -73,6 +77,25 @@ extension CxxDictionary {
7377 }
7478 }
7579
80+ @inlinable
81+ public init < S: Sequence > (
82+ grouping values: __owned S,
83+ by keyForValue: ( S . Element ) throws -> Key
84+ ) rethrows where Value: CxxVector < S . Element > {
85+ self . init ( )
86+ for value in values {
87+ let key = try keyForValue ( value)
88+ var iter = __findMutatingUnsafe ( key)
89+ if iter != __endMutatingUnsafe ( ) {
90+ iter. pointee. second. push_back ( value)
91+ } else {
92+ var vector = Value ( )
93+ vector. push_back ( value)
94+ self [ key] = vector
95+ }
96+ }
97+ }
98+
7699 @inlinable
77100 public subscript( key: Key ) -> Value ? {
78101 get {
@@ -98,7 +121,29 @@ extension CxxDictionary {
98121 }
99122 }
100123 }
101-
124+
125+ @inlinable
126+ public subscript(
127+ key: Key , default defaultValue: @autoclosure ( ) -> Value
128+ ) -> Value {
129+ get {
130+ let iter = __findUnsafe ( key)
131+ guard iter != __endUnsafe ( ) else {
132+ return defaultValue ( )
133+ }
134+ return iter. pointee. second
135+ }
136+ set ( newValue) {
137+ var iter = self . __findMutatingUnsafe ( key)
138+ if iter != self . __endMutatingUnsafe ( ) {
139+ iter. pointee. second = newValue
140+ } else {
141+ let keyValuePair = Element ( first: key, second: newValue)
142+ self . __insertUnsafe ( keyValuePair)
143+ }
144+ }
145+ }
146+
102147 public func filter( _ isIncluded: ( _ key: Key , _ value: Value ) throws -> Bool ) rethrows -> Self {
103148 var filteredDictionary = Self . init ( )
104149 var iterator = __beginUnsafe ( )
@@ -116,4 +161,95 @@ extension CxxDictionary {
116161
117162 return filteredDictionary
118163 }
164+
165+ @inlinable
166+ @discardableResult
167+ public mutating func removeValue( forKey key: Key ) -> Value ? {
168+ var iter = self . __findMutatingUnsafe ( key)
169+ guard iter != self . __endMutatingUnsafe ( ) else { return nil }
170+
171+ let value = iter. pointee. second
172+ self . __eraseUnsafe ( iter)
173+ return value
174+ }
175+
176+ @inlinable
177+ public mutating func merge< S: Sequence > (
178+ _ other: __owned S,
179+ uniquingKeysWith combine: ( Value , Value ) throws -> Value
180+ ) rethrows where S. Element == ( Key , Value ) {
181+ for (key, value) in other {
182+ var iter = self . __findMutatingUnsafe ( key)
183+ if iter != self . __endMutatingUnsafe ( ) {
184+ iter. pointee. second = try combine ( iter. pointee. second, value)
185+ } else {
186+ let keyValuePair = Element ( first: key, second: value)
187+ self . __insertUnsafe ( keyValuePair)
188+ }
189+ }
190+ }
191+
192+ @inlinable
193+ public mutating func merge(
194+ _ other: __owned Dictionary< Key , Value > ,
195+ uniquingKeysWith combine: ( Value , Value ) throws -> Value
196+ ) rethrows where Key: Hashable {
197+ for (key, value) in other {
198+ var iter = self . __findMutatingUnsafe ( key)
199+ if iter != self . __endMutatingUnsafe ( ) {
200+ iter. pointee. second = try combine ( iter. pointee. second, value)
201+ } else {
202+ let keyValuePair = Element ( first: key, second: value)
203+ self . __insertUnsafe ( keyValuePair)
204+ }
205+ }
206+ }
207+
208+ @inlinable
209+ public mutating func merge(
210+ _ other: __owned Self,
211+ uniquingKeysWith combine: ( Value , Value ) throws -> Value
212+ ) rethrows {
213+ var iterator = other. __beginUnsafe ( )
214+ while iterator != other. __endUnsafe ( ) {
215+ var iter = self . __findMutatingUnsafe ( iterator. pointee. first)
216+ if iter != self . __endMutatingUnsafe ( ) {
217+ iter. pointee. second = try combine ( iter. pointee. second, iterator. pointee. second)
218+ } else {
219+ let keyValuePair = Element ( first: iterator. pointee. first, second: iterator. pointee. second)
220+ self . __insertUnsafe ( keyValuePair)
221+ }
222+ iterator = iterator. successor ( )
223+ }
224+ }
225+
226+ @inlinable
227+ public __consuming func merging< S: Sequence > (
228+ _ other: __owned S,
229+ uniquingKeysWith combine: ( Value , Value ) throws -> Value
230+ ) rethrows -> Self where S. Element == ( Key , Value ) {
231+ var result = self
232+ try result. merge ( other, uniquingKeysWith: combine)
233+ return result
234+ }
235+
236+ @inlinable
237+ public __consuming func merging(
238+ _ other: __owned Dictionary< Key , Value > ,
239+ uniquingKeysWith combine: ( Value , Value ) throws -> Value
240+ ) rethrows -> Self where Key: Hashable {
241+ var result = self
242+ try result. merge ( other, uniquingKeysWith: combine)
243+ return result
244+ }
245+
246+ @inlinable
247+ public __consuming func merging(
248+ _ other: __owned Self,
249+ uniquingKeysWith combine: ( Value , Value ) throws -> Value
250+ ) rethrows -> Self {
251+ var result = self
252+ try result. merge ( other, uniquingKeysWith: combine)
253+ return result
254+ }
119255}
0 commit comments