Skip to content

[stdlib][DNM] Remove customization points from Sequence and Collection #19769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions stdlib/private/StdlibCollectionUnittest/LoggingWrappers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ public class SequenceLog {
// Sequence
public static var makeIterator = TypeIndexed(0)
public static var underestimatedCount = TypeIndexed(0)
public static var map = TypeIndexed(0)
public static var filter = TypeIndexed(0)
public static var forEach = TypeIndexed(0)
public static var dropFirst = TypeIndexed(0)
public static var dropLast = TypeIndexed(0)
public static var dropWhile = TypeIndexed(0)
Expand Down Expand Up @@ -107,14 +105,12 @@ public class SequenceLog {
public static var isEmpty = TypeIndexed(0)
public static var count = TypeIndexed(0)
public static var _customIndexOfEquatableElement = TypeIndexed(0)
public static var first = TypeIndexed(0)
public static var advance = TypeIndexed(0)
public static var advanceLimit = TypeIndexed(0)
public static var distance = TypeIndexed(0)
// BidirectionalCollection
public static var predecessor = TypeIndexed(0)
public static var formPredecessor = TypeIndexed(0)
public static var last = TypeIndexed(0)
// MutableCollection
public static var subscriptIndexSet = TypeIndexed(0)
public static var subscriptRangeSet = TypeIndexed(0)
Expand Down Expand Up @@ -222,25 +218,13 @@ extension LoggingSequence: Sequence {
return base.underestimatedCount
}

public func map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {
SequenceLog.map[selfType] += 1
return try base.map(transform)
}

public func filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
SequenceLog.filter[selfType] += 1
return try base.filter(isIncluded)
}

public func forEach(_ body: (Element) throws -> Void) rethrows {
SequenceLog.forEach[selfType] += 1
try base.forEach(body)
}

public func dropFirst(_ n: Int) -> SubSequence {
SequenceLog.dropFirst[selfType] += 1
return base.dropFirst(n)
Expand Down Expand Up @@ -406,11 +390,6 @@ extension LoggingCollection: Collection {
return base._customIndexOfEquatableElement(element)
}

public var first: Element? {
CollectionLog.first[selfType] += 1
return base.first
}

public func index(_ i: Index, offsetBy n: Int) -> Index {
CollectionLog.advance[selfType] += 1
return base.index(i, offsetBy: n)
Expand Down Expand Up @@ -443,11 +422,6 @@ extension LoggingBidirectionalCollection: BidirectionalCollection {
BidirectionalCollectionLog.formPredecessor[selfType] += 1
base.formIndex(before: &i)
}

public var last: Element? {
BidirectionalCollectionLog.last[selfType] += 1
return base.last
}
}

public typealias LoggingRandomAccessCollection<Base: RandomAccessCollection>
Expand Down
14 changes: 0 additions & 14 deletions stdlib/public/core/BidirectionalCollection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,6 @@ where SubSequence: BidirectionalCollection, Indices: BidirectionalCollection {
/// // c == MyFancyCollection([2, 4, 6, 8, 10])
override var indices: Indices { get }

// TODO: swift-3-indexing-model: tests.
/// The last element of the collection.
///
/// If the collection is empty, the value of this property is `nil`.
///
/// let numbers = [10, 20, 30, 40, 50]
/// if let lastNumber = numbers.last {
/// print(lastNumber)
/// }
/// // Prints "50"
///
/// - Complexity: O(1)
var last: Element? { get }

/// Accesses a contiguous subrange of the collection's elements.
///
/// The accessed slice uses the same indices for the same elements as the
Expand Down
19 changes: 1 addition & 18 deletions stdlib/public/core/Collection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -632,22 +632,6 @@ public protocol Collection: Sequence where SubSequence: Collection {
/// - Complexity: Hopefully less than O(`count`).
func _customLastIndexOfEquatableElement(_ element: Element) -> Index??

// FIXME(move-only types): `first` might not be implementable by collections
// with move-only elements, since they would need to be able to somehow form
// a temporary `Optional<Element>` value from a nonoptional Element without
// modifying the collection.

/// The first element of the collection.
///
/// If the collection is empty, the value of this property is `nil`.
///
/// let numbers = [10, 20, 30, 40, 50]
/// if let firstNumber = numbers.first {
/// print(firstNumber)
/// }
/// // Prints "10"
var first: Element? { get }

/// Returns an index that is the specified distance from the given index.
///
/// The following example obtains an index advanced four positions from a
Expand Down Expand Up @@ -1346,8 +1330,7 @@ extension Collection {
@inlinable
public __consuming func dropFirst(_ k: Int) -> SubSequence {
_precondition(k >= 0, "Can't drop a negative number of elements from a collection")
let start = index(startIndex,
offsetBy: k, limitedBy: endIndex) ?? endIndex
let start = index(startIndex, offsetBy: k, limitedBy: endIndex) ?? endIndex
return self[start..<endIndex]
}

Expand Down
13 changes: 0 additions & 13 deletions stdlib/public/core/Dictionary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -728,19 +728,6 @@ extension Dictionary: Collection {
public var isEmpty: Bool {
return count == 0
}

/// The first element of the dictionary.
///
/// The first element of the dictionary is not necessarily the first element
/// added to the dictionary. Don't expect any particular ordering of
/// dictionary elements.
///
/// If the dictionary is empty, the value of this property is `nil`.
@inlinable
public var first: Element? {
var it = makeIterator()
return it.next()
}
}

extension Dictionary {
Expand Down
24 changes: 0 additions & 24 deletions stdlib/public/core/ExistentialCollection.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,6 @@ internal class _AnyRandomAccessCollectionBox<Element>
func _customLastIndexOfEquatableElement(element: Element) -> Index??
*/

@inlinable // FIXME(sil-serialize-all)
internal var _first: Element? { _abstract() }

@inlinable
internal init(
_startIndex: _AnyIndexBox,
Expand Down Expand Up @@ -385,8 +382,6 @@ internal class _AnyRandomAccessCollectionBox<Element>
internal func _index(before i: _AnyIndexBox) -> _AnyIndexBox { _abstract() }
@inlinable
internal func _formIndex(before i: _AnyIndexBox) { _abstract() }
@inlinable
internal var _last: Element? { _abstract() }
% end
}

Expand Down Expand Up @@ -617,11 +612,6 @@ internal final class _${Kind}Box<S : ${Kind}> : _Any${Kind}Box<S.Element>
return numericCast(_base.count)
}

@inlinable
internal override var _first: Element? {
return _base.first
}

% if Kind in ['BidirectionalCollection', 'RandomAccessCollection']:
@inlinable
internal override func _index(before position: _AnyIndexBox) -> _AnyIndexBox {
Expand All @@ -636,10 +626,6 @@ internal final class _${Kind}Box<S : ${Kind}> : _Any${Kind}Box<S.Element>
fatalError("Index type mismatch!")
}

@inlinable
internal override var _last: Element? {
return _base.last
}
% end

% end
Expand Down Expand Up @@ -1118,11 +1104,6 @@ extension ${Self}: ${SelfProtocol} {
return _box._count
}

@inlinable
public var first: Element? {
return _box._first
}

% if Traversal == 'Bidirectional' or Traversal == 'RandomAccess':
@inlinable
public func index(before i: Index) -> Index {
Expand All @@ -1138,11 +1119,6 @@ extension ${Self}: ${SelfProtocol} {
i = index(before: i)
}
}

@inlinable
public var last: Element? {
return _box._last
}
% end
}

Expand Down
11 changes: 0 additions & 11 deletions stdlib/public/core/LazyCollection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,6 @@ extension LazyCollection : Collection {
return _base._customLastIndexOfEquatableElement(element)
}

/// Returns the first element of `self`, or `nil` if `self` is empty.
@inlinable
public var first: Element? {
return _base.first
}

// TODO: swift-3-indexing-model - add docs
@inlinable
public func index(_ i: Index, offsetBy n: Int) -> Index {
Expand Down Expand Up @@ -235,11 +229,6 @@ extension LazyCollection : BidirectionalCollection
public func index(before i: Index) -> Index {
return _base.index(before: i)
}

@inlinable
public var last: Element? {
return _base.last
}
}

extension LazyCollection : RandomAccessCollection
Expand Down
6 changes: 0 additions & 6 deletions stdlib/public/core/Map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,6 @@ extension LazyMapCollection: LazyCollectionProtocol {
return _base.count
}

@inlinable
public var first: Element? { return _base.first.map(_transform) }

@inlinable
public func index(_ i: Index, offsetBy n: Int) -> Index {
return _base.index(i, offsetBy: n)
Expand Down Expand Up @@ -223,9 +220,6 @@ extension LazyMapCollection : BidirectionalCollection
public func formIndex(before i: inout Index) {
_base.formIndex(before: &i)
}

@inlinable
public var last: Element? { return _base.last.map(_transform) }
}

extension LazyMapCollection : RandomAccessCollection
Expand Down
54 changes: 0 additions & 54 deletions stdlib/public/core/Sequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,29 +348,6 @@ public protocol Sequence {
/// In this case, see the documentation of `Collection.underestimatedCount`.
var underestimatedCount: Int { get }

/// Returns an array containing the results of mapping the given closure
/// over the sequence's elements.
///
/// In this example, `map` is used first to convert the names in the array
/// to lowercase strings and then to count their characters.
///
/// let cast = ["Vivien", "Marlon", "Kim", "Karl"]
/// let lowercaseNames = cast.map { $0.lowercased() }
/// // 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
/// let letterCounts = cast.map { $0.count }
/// // 'letterCounts' == [6, 6, 3, 4]
///
/// - Parameter transform: A mapping closure. `transform` accepts an
/// element of this sequence as its parameter and returns a transformed
/// value of the same or of a different type.
/// - Returns: An array containing the transformed elements of this
/// sequence.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
func map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T]

/// Returns an array containing, in order, the elements of the sequence
/// that satisfy the given predicate.
///
Expand All @@ -392,37 +369,6 @@ public protocol Sequence {
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element]

/// Calls the given closure on each element in the sequence in the same order
/// as a `for`-`in` loop.
///
/// The two loops in the following example produce the same output:
///
/// let numberWords = ["one", "two", "three"]
/// for word in numberWords {
/// print(word)
/// }
/// // Prints "one"
/// // Prints "two"
/// // Prints "three"
///
/// numberWords.forEach { word in
/// print(word)
/// }
/// // Same as above
///
/// Using the `forEach` method is distinct from a `for`-`in` loop in two
/// important ways:
///
/// 1. You cannot use a `break` or `continue` statement to exit the current
/// call of the `body` closure or skip subsequent calls.
/// 2. Using the `return` statement in the `body` closure will exit only from
/// the current call to `body`, not from any outer scope, and won't skip
/// subsequent calls.
///
/// - Parameter body: A closure that takes an element of the sequence as a
/// parameter.
func forEach(_ body: (Element) throws -> Void) rethrows

// Note: The complexity of Sequence.dropFirst(_:) requirement
// is documented as O(n) because Collection.dropFirst(_:) is
// implemented in O(n), even though the default
Expand Down
12 changes: 0 additions & 12 deletions stdlib/public/core/Set.swift
Original file line number Diff line number Diff line change
Expand Up @@ -391,18 +391,6 @@ extension Set: Collection {
public var isEmpty: Bool {
return count == 0
}

/// The first element of the set.
///
/// The first element of the set is not necessarily the first element added
/// to the set. Don't expect any particular ordering of set elements.
///
/// If the set is empty, the value of this property is `nil`.
@inlinable
public var first: Element? {
var iterator = makeIterator()
return iterator.next()
}
}

// FIXME: rdar://problem/23549059 (Optimize == for Set)
Expand Down
21 changes: 21 additions & 0 deletions test/api-digester/Outputs/stability-stdlib-abi.swift.expected
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,33 @@ Struct _PrefixSequence has generic signature change from <τ_0_0 where τ_0_0 :
/* Removed Decls */
Constructor _DropFirstSequence.init(_iterator:limit:dropped:) has been removed
Constructor _PrefixSequence.init(_iterator:maxLength:taken:) has been removed
Func Sequence.forEach(_:) has been removed
Func Sequence.map(_:) has been removed
Func _DropFirstSequence.next() has been removed
Func _PrefixSequence.next() has been removed
Var AnyBidirectionalCollection.first has been removed
Var AnyBidirectionalCollection.last has been removed
Var AnyCollection.first has been removed
Var AnyRandomAccessCollection.first has been removed
Var AnyRandomAccessCollection.last has been removed
Var BidirectionalCollection.last has been removed
Var Dictionary.first has been removed
Var LazyCollection.first has been removed
Var LazyCollection.last has been removed
Var LazyMapCollection.first has been removed
Var LazyMapCollection.last has been removed
Var Set.first has been removed
Var _AnyBidirectionalCollectionBox._last has been removed
Var _AnyCollectionBox._first has been removed
Var _BidirectionalCollectionBox._first has been removed
Var _BidirectionalCollectionBox._last has been removed
Var _CollectionBox._first has been removed
Var _DropFirstSequence._dropped has been removed
Var _DropFirstSequence._iterator has been removed
Var _PrefixSequence._iterator has been removed
Var _PrefixSequence._taken has been removed
Var _RandomAccessCollectionBox._first has been removed
Var _RandomAccessCollectionBox._last has been removed

/* Moved Decls */
Struct _DropFirstSequence has been renamed to Struct DropFirstSequence
Expand Down
Loading