Skip to content

Commit ec0d53f

Browse files
Cbieniakairspeedswift
authored andcommitted
[stdlib] [SR-4005] Allow heterogenous comparisons in elementsEqual (#8045)
* [SR-4005] Allow heterogenous comparisons in elementsEqual When a user is supplying a predicate to compare the type equivalence isn’t required * elementsEqualWithPredicate tests Compares a string of a number with an integer value by using the elementsEqualPredicate closure * Update test expectations to use new sequence element types * Update hardcoded test to reference sequence
1 parent 6c4ed9c commit ec0d53f

File tree

4 files changed

+58
-3
lines changed

4 files changed

+58
-3
lines changed

stdlib/private/StdlibCollectionUnittest/CheckSequenceType.swift

+51
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,33 @@ public struct ElementsEqualTest {
7878
}
7979
}
8080

81+
public struct ElementsEqualWithPredicateTest {
82+
public let expected: Bool
83+
public let sequence: [Int]
84+
public let other: [String]
85+
public let predicate: (Int, String) -> Bool
86+
public let expectedLeftoverSequence: [Int]
87+
public let expectedLeftoverOther: [String]
88+
public let loc: SourceLoc
89+
90+
public init(
91+
_ expected: Bool, _ sequence: [Int], _ other: [String],
92+
_ predicate: @escaping (Int, String) -> Bool,
93+
_ expectedLeftoverSequence: [Int],
94+
_ expectedLeftoverOther: [String],
95+
file: String = #file, line: UInt = #line,
96+
comment: String = ""
97+
) {
98+
self.expected = expected
99+
self.sequence = sequence
100+
self.other = other
101+
self.predicate = predicate
102+
self.expectedLeftoverSequence = expectedLeftoverSequence
103+
self.expectedLeftoverOther = expectedLeftoverOther
104+
self.loc = SourceLoc(file, line, comment: "test data" + comment)
105+
}
106+
}
107+
81108
public struct EnumerateTest {
82109
public let expected: [(Int, Int)]
83110
public let sequence: [Int]
@@ -450,6 +477,30 @@ public let elementsEqualTests: [ElementsEqualTest] = [
450477
ElementsEqualTest(false, [ 1, 2 ], [ 1, 2, 3, 4 ], [], [ 4 ]),
451478
].flatMap { [ $0, $0.flip() ] }
452479

480+
func elementsEqualPredicate(_ x: Int, y: String) -> Bool {
481+
if let intVal = Int(y) {
482+
return x == intVal
483+
} else {
484+
return false
485+
}
486+
}
487+
488+
public let elementsEqualWithPredicateTests: [ElementsEqualWithPredicateTest] = [
489+
ElementsEqualWithPredicateTest(true, [], [], elementsEqualPredicate, [], []),
490+
491+
ElementsEqualWithPredicateTest(false, [ 1 ], [], elementsEqualPredicate, [ 1 ], []),
492+
ElementsEqualWithPredicateTest(false, [], [ "1" ], elementsEqualPredicate, [], [ "1" ]),
493+
494+
ElementsEqualWithPredicateTest(false, [ 1, 2 ], [], elementsEqualPredicate, [ 1, 2 ], []),
495+
ElementsEqualWithPredicateTest(false, [], [ "1", "2" ], elementsEqualPredicate, [], [ "1", "2" ]),
496+
497+
ElementsEqualWithPredicateTest(false, [ 1, 2, 3, 4 ], [ "1", "2" ], elementsEqualPredicate, [ 3, 4 ], []),
498+
ElementsEqualWithPredicateTest(false, [ 1, 2 ], [ "1", "2", "3", "4" ], elementsEqualPredicate, [], [ "3", "4" ]),
499+
500+
ElementsEqualWithPredicateTest(true, [ 1, 2, 3, 4 ], [ "1", "2", "3", "4" ], elementsEqualPredicate, [], []),
501+
ElementsEqualWithPredicateTest(true, [ 1, 2 ], [ "1", "2" ], elementsEqualPredicate, [], []),
502+
]
503+
453504
public let enumerateTests = [
454505
EnumerateTest([], []),
455506
EnumerateTest([ (0, 10) ], [ 10 ]),

stdlib/public/core/SequenceAlgorithms.swift.gyb

+4-2
Original file line numberDiff line numberDiff line change
@@ -338,12 +338,14 @@ ${equivalenceExplanation}
338338
public func elementsEqual<OtherSequence>(
339339
_ other: OtherSequence${"," if preds else ""}
340340
% if preds:
341-
by areEquivalent: (Element, Element) throws -> Bool
341+
by areEquivalent: (Element, OtherSequence.Element) throws -> Bool
342342
% end
343343
) ${rethrows_}-> Bool
344344
where
345-
OtherSequence: Sequence,
345+
OtherSequence: Sequence${" {" if preds else ","}
346+
% if not preds:
346347
OtherSequence.Element == Element {
348+
% end
347349
348350
var iter1 = self.makeIterator()
349351
var iter2 = other.makeIterator()

test/IDE/complete_from_stdlib.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ func testArchetypeReplacement3 (_ a : [Int]) {
170170
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceVar]/Super: first[#Int?#]
171171
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: map({#(transform): (Int) throws -> T##(Int) throws -> T#})[' rethrows'][#[T]#]
172172
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: dropLast({#(n): Int#})[#ArraySlice<Int>#]
173-
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: elementsEqual({#(other): Sequence#}, {#by: (Int, Int) throws -> Bool##(Int, Int) throws -> Bool#})[' rethrows'][#Bool#]
173+
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: elementsEqual({#(other): Sequence#}, {#by: (Int, Sequence.Element) throws -> Bool##(Int, Sequence.Element) throws -> Bool#})[' rethrows'][#Bool#]; name=elementsEqual(other: Sequence, by: (Int, Sequence.Element) throws -> Bool) rethrows
174+
// PRIVATE_NOMINAL_MEMBERS_7-DAG: Decl[InstanceMethod]/Super: elementsEqual({#(other): Sequence#})[#Bool#]; name=elementsEqual(other: Sequence)
174175

175176

176177
protocol P2 {

test/api-digester/source-stability.swift.expected

+1
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ Func ReversedRandomAccessCollection.index(_:offsetBy:) has return type change fr
328328
Func ReversedRandomAccessCollection.index(_:offsetBy:limitedBy:) has return type change from ReversedRandomAccessIndex<Base>? to ReversedRandomAccessCollection.Index?
329329
Func ReversedRandomAccessCollection.index(after:) has return type change from ReversedRandomAccessIndex<Base> to ReversedRandomAccessCollection.Index
330330
Func ReversedRandomAccessCollection.index(before:) has return type change from ReversedRandomAccessIndex<Base> to ReversedRandomAccessCollection.Index
331+
Func Sequence.elementsEqual(_:by:) has parameter 1 type change from (Self.Iterator.Element, Self.Iterator.Element) throws -> Bool to (Self.Element, OtherSequence.Element) throws -> Bool
331332
Func Set.formSymmetricDifference(_:) has parameter 0 type change from Set<Element> to Set<Set.Element>
332333
Func Set.index(after:) has return type change from SetIndex<Element> to Set<Element>.Index
333334
Func Set.index(of:) has return type change from SetIndex<Element>? to Set<Element>.Index?

0 commit comments

Comments
 (0)