@@ -23,15 +23,14 @@ public protocol BidirectionalCollection : Collection {
23
23
@warn_unused_result
24
24
func previous( i: Index ) -> Index
25
25
26
- // TODO: swift-3-indexing-model - replaces functionality in BidirectionalIndex
27
26
func _previousInPlace( inout i: Index )
28
27
}
29
28
30
29
/// Default implementation for bidirectional collections.
31
30
extension BidirectionalCollection {
32
31
// TODO: swift-3-indexing-model - stub to allow things to compile, remove when we have real implementations
33
32
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 " )
35
34
}
36
35
37
36
@inline ( __always)
@@ -45,7 +44,7 @@ extension BidirectionalCollection {
45
44
return _advanceForward ( i, by: n)
46
45
}
47
46
var i = i
48
- for var offset : IndexDistance = n; offset != 0 ; offset = offset + 1 {
47
+ for _ in 0 ..< ( - n ) {
49
48
_previousInPlace ( & i)
50
49
}
51
50
return i
@@ -57,9 +56,11 @@ extension BidirectionalCollection {
57
56
return _advanceForward ( i, by: n, limit: limit)
58
57
}
59
58
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)
63
64
}
64
65
return i
65
66
}
@@ -85,4 +86,74 @@ extension BidirectionalCollection {
85
86
//
86
87
// return count
87
88
// }
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
+
0 commit comments