@@ -192,7 +192,7 @@ func ==(_ lhs: BoundVersion, _ rhs: BoundVersion) -> Bool {
192
192
// `PackageContainerConstraint`s. That won't work if we decide this should
193
193
// eventually map based on the `Container` rather than the `Identifier`, though,
194
194
// so they are separate for now.
195
- struct PackageContainerConstraintSet < C: PackageContainer > {
195
+ struct PackageContainerConstraintSet < C: PackageContainer > : Collection {
196
196
typealias Container = C
197
197
typealias Identifier = Container . Identifier
198
198
@@ -244,18 +244,37 @@ struct PackageContainerConstraintSet<C: PackageContainer> {
244
244
///
245
245
/// - Returns: False if the merger has made the set unsatisfiable; i.e. true
246
246
/// when the resulting set is satisfiable, if it was already so.
247
- mutating func merge( _ rhs : PackageContainerConstraintSet < Container > ) -> Bool {
247
+ mutating func merge( _ constraints : PackageContainerConstraintSet < Container > ) -> Bool {
248
248
var satisfiable = true
249
- for (key, versionRequirement) in rhs . constraints {
249
+ for (key, versionRequirement) in constraints {
250
250
if !merge( versionRequirement: versionRequirement, for: key) {
251
251
satisfiable = false
252
252
}
253
253
}
254
254
return satisfiable
255
255
}
256
+
257
+ // MARK: Collection Conformance
258
+
259
+ var startIndex : Index {
260
+ return constraints. startIndex
261
+ }
262
+
263
+ var endIndex : Index {
264
+ return constraints. endIndex
265
+ }
266
+
267
+ func index( after i: Index ) -> Index {
268
+ return constraints. index ( after: i)
269
+ }
270
+
271
+ subscript( position: Index ) -> Element {
272
+ return constraints [ position]
273
+ }
256
274
}
257
275
258
- /// A container for version assignments for a set of packages.
276
+ /// A container for version assignments for a set of packages, exposed as a
277
+ /// sequence of `Container` to `BoundVersion` bindings.
259
278
///
260
279
/// This is intended to be an efficient data structure for accumulating a set of
261
280
/// version assignments along with efficient access to the derived information
@@ -267,7 +286,7 @@ struct PackageContainerConstraintSet<C: PackageContainer> {
267
286
/// `constraints`, but this invariant is not explicitly enforced.
268
287
//
269
288
// FIXME: Actually make efficient.
270
- struct VersionAssignmentSet < C: PackageContainer > {
289
+ struct VersionAssignmentSet < C: PackageContainer > : Sequence {
271
290
typealias Container = C
272
291
typealias Identifier = Container . Identifier
273
292
@@ -320,15 +339,15 @@ struct VersionAssignmentSet<C: PackageContainer> {
320
339
// The induced constraints are satisfiable, so we *can* union the
321
340
// assignments without breaking our internal invariant on
322
341
// satisfiability.
323
- for entry in assignment. assignments . values {
324
- if let existing = self [ entry . container] {
325
- if existing != entry . binding {
342
+ for (container , binding ) in assignment {
343
+ if let existing = self [ container] {
344
+ if existing != binding {
326
345
// NOTE: We are returning here with the data structure
327
346
// partially updated, which feels wrong. See FIXME above.
328
347
return false
329
348
}
330
349
} else {
331
- self [ entry . container] = entry . binding
350
+ self [ container] = binding
332
351
}
333
352
}
334
353
@@ -410,6 +429,24 @@ struct VersionAssignmentSet<C: PackageContainer> {
410
429
411
430
return true
412
431
}
432
+
433
+ // MARK: Sequence Conformance
434
+
435
+ // FIXME: This should really be a collection, but that takes significantly
436
+ // more work given our current backing collection.
437
+
438
+ typealias Iterator = AnyIterator < ( Container , BoundVersion ) >
439
+
440
+ func makeIterator( ) -> Iterator {
441
+ var it = assignments. values. makeIterator ( )
442
+ return AnyIterator {
443
+ if let next = it. next ( ) {
444
+ return ( next. container, next. binding)
445
+ } else {
446
+ return nil
447
+ }
448
+ }
449
+ }
413
450
}
414
451
415
452
/// A general purpose package dependency resolver.
0 commit comments