Skip to content

Commit 04518af

Browse files
committed
[stdlib] Add conditional Hashable conformance for indices
1 parent 9dce40c commit 04518af

File tree

6 files changed

+86
-0
lines changed

6 files changed

+86
-0
lines changed

stdlib/public/core/ClosedRange.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ extension ClosedRangeIndex : Comparable {
8585
}
8686
}
8787

88+
extension ClosedRangeIndex : Hashable where Bound : Hashable {
89+
public var hashValue: Int {
90+
switch _value {
91+
case .inRange(let value):
92+
return value.hashValue
93+
case .pastEnd:
94+
return .max
95+
}
96+
}
97+
}
98+
8899
/// A closed range that forms a collection of consecutive values.
89100
///
90101
/// You create a `CountableClosedRange` instance by using the closed range

stdlib/public/core/DropWhile.swift.gyb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ public struct LazyDropWhileIndex<Base : Collection> : Comparable {
140140
}
141141
}
142142

143+
extension LazyDropWhileIndex : Hashable where Base.Index : Hashable {
144+
public var hashValue: Int {
145+
return base.hashValue
146+
}
147+
}
148+
143149
% for Traversal in ['Forward', 'Bidirectional']:
144150
% Collection = collectionForTraversal(Traversal)
145151
% Self = "LazyDropWhile" + Collection

stdlib/public/core/Flatten.swift.gyb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@ extension ${Index} : Comparable {
220220
}
221221
}
222222

223+
extension ${Index} : Hashable
224+
where BaseElements.Index : Hashable, BaseElements.Element.Index : Hashable
225+
{
226+
public var hashValue: Int {
227+
return _mixInt(_inner?.hashValue ?? 0) ^ _outer.hashValue
228+
}
229+
}
230+
223231
/// A flattened view of a base collection of collections.
224232
///
225233
/// The elements of this view are a concatenation of the elements of

stdlib/public/core/PrefixWhile.swift.gyb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ public struct LazyPrefixWhileIndex<Base : Collection> : Comparable {
161161
}
162162
}
163163

164+
extension LazyPrefixWhileIndex : Hashable where Base.Index : Hashable {
165+
public var hashValue: Int {
166+
switch _value {
167+
case .index(let value):
168+
return value.hashValue
169+
case .pastEnd:
170+
return .max
171+
}
172+
}
173+
}
174+
164175
% for Traversal in ['Forward', 'Bidirectional']:
165176
% Collection = collectionForTraversal(Traversal)
166177
% Self = "LazyPrefixWhile" + Collection

stdlib/public/core/Reverse.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ public struct ReversedIndex<Base : Collection> : Comparable {
149149
}
150150
}
151151

152+
extension ReversedIndex : Hashable where Base.Index : Hashable {
153+
public var hashValue: Int {
154+
return base.hashValue
155+
}
156+
}
157+
152158
/// A collection that presents the elements of its base collection
153159
/// in reverse order.
154160
///
@@ -349,6 +355,12 @@ public struct ReversedRandomAccessIndex<
349355
}
350356
}
351357

358+
extension ReversedRandomAccessIndex : Hashable where Base.Index : Hashable {
359+
public var hashValue: Int {
360+
return base.hashValue
361+
}
362+
}
363+
352364
/// A collection that presents the elements of its base collection
353365
/// in reverse order.
354366
///
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
4+
import StdlibUnittest
5+
6+
var HashTests = TestSuite("HashableIndices")
7+
8+
HashTests.test("ClosedRangeIndex") {
9+
let a = 1...10
10+
checkHashable(a.indices, equalityOracle: { $0 == $1 })
11+
}
12+
13+
HashTests.test("FlattenIndex") {
14+
let a = [1...10, 11...20, 21...30].joined()
15+
checkHashable(a.indices, equalityOracle: { $0 == $1 })
16+
}
17+
18+
HashTests.test("LazyDropWhileIndex") {
19+
let a = (1...10).lazy.drop(while: { $0 < 5 })
20+
checkHashable(a.indices, equalityOracle: { $0 == $1 })
21+
}
22+
23+
HashTests.test("LazyPrefixWhileIndex") {
24+
let a = (1...10).lazy.prefix(while: { $0 < 5 })
25+
checkHashable(a.indices, equalityOracle: { $0 == $1 })
26+
}
27+
28+
HashTests.test("ReversedIndex") {
29+
let a = (1...10).lazy.filter({ $0 > 3 }).reversed()
30+
checkHashable(a.indices, equalityOracle: { $0 == $1 })
31+
}
32+
33+
HashTests.test("ReversedRandomAccessIndex") {
34+
let a = (1...10).reversed()
35+
checkHashable(a.indices, equalityOracle: { $0 == $1 })
36+
}
37+
38+
runAllTests()

0 commit comments

Comments
 (0)