Skip to content

Commit 56b7e5f

Browse files
committed
Merge pull request swiftlang#1540 from shawnce/swift-3-indexing-model
[stdlib] - WIP moved aspects of ForwardIndex and BidirectionalIndex i…
2 parents 38726d0 + fe42606 commit 56b7e5f

14 files changed

+410
-549
lines changed

stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,12 +1837,14 @@ internal func _checkIncrementalAdvance<
18371837
${TRACE}
18381838
) {
18391839
for i in instances {
1840-
let d = sign > 0 ? i.distance(to: limit) : -limit.distance(to: i)
1840+
// TODO: swift-3-indexing-model - Review what we need to do here, unittest is focusing on wrong class now
1841+
let d: Instances.Iterator.Element.Distance = 0 //sign > 0 ? i.distance(to: limit) : -limit.distance(to: i)
18411842

18421843
var offset: Instances.Iterator.Element.Distance = 0
18431844
for _ in 0...(d * sign).toIntMax() {
1844-
let j = i.advanced(by: offset)
1845-
let k = i.advanced(by: offset + sign, limit: limit)
1845+
// TODO: swift-3-indexing-model - Review what we need to do here, unittest is focusing on wrong class now
1846+
let j = i//.advanced(by: offset)
1847+
let k = i//.advanced(by: offset + sign, limit: limit)
18461848
let jAtLimit = offset == d
18471849
if jAtLimit {
18481850
expectEqual(limit, j, ${trace})
@@ -2292,7 +2294,7 @@ public func checkSliceableWithBidirectionalIndex<
22922294
% end
22932295

22942296
public func nthIndex<C: Collection>(x: C, _ n: Int) -> C.Index {
2295-
return x.startIndex.advanced(by: numericCast(n))
2297+
return x.advance(x.startIndex, by: numericCast(n))
22962298
}
22972299

22982300
public func nth<C: Collection>(x: C, _ n: Int) -> C.Iterator.Element {

stdlib/private/SwiftPrivate/SwiftPrivate.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ public func scatter<T>(a: [T], _ idx: [Int]) -> [T] {
7575
public func withArrayOfCStrings<R>(
7676
args: [String], _ body: ([UnsafeMutablePointer<CChar>]) -> R
7777
) -> R {
78-
78+
// TODO: swift-3-indexing-model - last doesn't yet show up on arrays
79+
fatalError("FIXME: swift-3-indexing-model")
80+
81+
/*
7982
let argsCounts = Array(args.map { $0.utf8.count + 1 })
8083
let argsOffsets = [ 0 ] + scan(argsCounts, 0, +)
8184
let argsBufferSize = argsOffsets.last!
@@ -94,5 +97,6 @@ public func withArrayOfCStrings<R>(
9497
cStrings[cStrings.count - 1] = nil
9598
return body(cStrings)
9699
}
100+
*/
97101
}
98102

stdlib/public/core/BidirectionalCollection.swift

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,14 @@ public protocol BidirectionalCollection : Collection {
2323
@warn_unused_result
2424
func previous(i: Index) -> Index
2525

26-
// TODO: swift-3-indexing-model - replaces functionality in BidirectionalIndex
2726
func _previousInPlace(inout i: Index)
2827
}
2928

3029
/// Default implementation for bidirectional collections.
3130
extension BidirectionalCollection {
3231
// TODO: swift-3-indexing-model - stub to allow things to compile, remove when we have real implementations
3332
public func previous(i: Index) -> Index {
34-
fatalError("collections need to implement, this is a temp stub to make things compile")
33+
fatalError("FIXME: swift-3-indexing-model")
3534
}
3635

3736
@inline(__always)
@@ -45,7 +44,7 @@ extension BidirectionalCollection {
4544
return _advanceForward(i, by: n)
4645
}
4746
var i = i
48-
for var offset: IndexDistance = n; offset != 0; offset = offset + 1 {
47+
for _ in 0..<(-n) {
4948
_previousInPlace(&i)
5049
}
5150
return i
@@ -57,9 +56,11 @@ extension BidirectionalCollection {
5756
return _advanceForward(i, by: n, limit: limit)
5857
}
5958
var i = i
60-
for var offset: IndexDistance = n; offset != 0 && i != limit;
61-
offset = offset + 1 {
62-
_previousInPlace(&i)
59+
for _ in 0..<(-n) {
60+
if (limit == i) {
61+
break;
62+
}
63+
_previousInPlace(&i)
6364
}
6465
return i
6566
}
@@ -85,4 +86,74 @@ extension BidirectionalCollection {
8586
//
8687
// return count
8788
// }
88-
}
89+
}
90+
91+
extension BidirectionalCollection where SubSequence == Self {
92+
/// If `!self.isEmpty`, remove the last element and return it, otherwise
93+
/// return `nil`.
94+
///
95+
/// - Complexity: O(1)
96+
@warn_unused_result
97+
public mutating func popLast() -> Iterator.Element? {
98+
guard !isEmpty else { return nil }
99+
let element = last!
100+
self = self[startIndex..<previous(endIndex)]
101+
return element
102+
}
103+
104+
/// Remove an element from the end.
105+
///
106+
/// - Complexity: O(1)
107+
/// - Precondition: `!self.isEmpty`
108+
public mutating func removeLast() -> Iterator.Element {
109+
let element = last!
110+
self = self[startIndex..<previous(endIndex)]
111+
return element
112+
}
113+
114+
/// Remove the last `n` elements.
115+
///
116+
/// - Complexity:
117+
/// - O(1) if `Index` conforms to `RandomAccessIndex`
118+
/// - O(n) otherwise
119+
/// - Precondition: `n >= 0 && self.count >= n`.
120+
public mutating func removeLast(n: Int) {
121+
if n == 0 { return }
122+
_precondition(n >= 0, "number of elements to remove should be non-negative")
123+
_precondition(count >= numericCast(n),
124+
"can't remove more items from a collection than it contains")
125+
self = self[startIndex..<advance(endIndex, by: numericCast(-n))]
126+
}
127+
}
128+
129+
extension BidirectionalCollection {
130+
/// Returns a subsequence containing all but the last `n` elements.
131+
///
132+
/// - Precondition: `n >= 0`
133+
/// - Complexity: O(`n`)
134+
@warn_unused_result
135+
public func dropLast(n: Int) -> SubSequence {
136+
_precondition(
137+
n >= 0, "Can't drop a negative number of elements from a collection")
138+
let end = advance(endIndex, by: numericCast(-n), limit: startIndex)
139+
return self[startIndex..<end]
140+
}
141+
142+
/// Returns a slice, up to `maxLength` in length, containing the
143+
/// final elements of `self`.
144+
///
145+
/// If `maxLength` exceeds `s.count`, the result contains all
146+
/// the elements of `self`.
147+
///
148+
/// - Precondition: `maxLength >= 0`
149+
/// - Complexity: O(`maxLength`)
150+
@warn_unused_result
151+
public func suffix(maxLength: Int) -> SubSequence {
152+
_precondition(
153+
maxLength >= 0,
154+
"Can't take a suffix of negative length from a collection")
155+
let start = advance(endIndex, by: numericCast(-maxLength), limit: startIndex)
156+
return self[start..<endIndex]
157+
}
158+
}
159+

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ set(SWIFTLIB_ESSENTIAL
6868
Map.swift
6969
Mirrors.swift.gyb
7070
Misc.swift
71+
MutableCollection.swift
7172
ObjCMirrors.swift
7273
Optional.swift
7374
OptionSet.swift

0 commit comments

Comments
 (0)