Skip to content

[stdlib] Convert existential collection === operator to method #3617

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

Merged
merged 3 commits into from
Jul 25, 2016
Merged
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
54 changes: 26 additions & 28 deletions stdlib/public/core/ExistentialCollection.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -715,30 +715,11 @@ public func < (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
//===--- Collections ------------------------------------------------------===//
//===----------------------------------------------------------------------===//

/// A protocol for `AnyCollection<Element>`,
/// `AnyBidirectionalCollection<Element>`, and
/// `AnyRandomAccessCollection<Element>`.
///
/// This protocol can be considered an implementation detail of the
/// `===` and `!==` implementations for these types.
public protocol AnyCollectionProtocol : Collection {
public // @testable
protocol _AnyCollectionProtocol : Collection {
/// Identifies the underlying collection stored by `self`. Instances
/// copied from one another have the same `_underlyingCollectionID`.
var _underlyingCollectionID: ObjectIdentifier { get }
}

/// Returns `true` iff `lhs` and `rhs` store the same underlying collection.
public func === <
L : AnyCollectionProtocol, R : AnyCollectionProtocol
>(lhs: L, rhs: R) -> Bool {
return lhs._underlyingCollectionID == rhs._underlyingCollectionID
}

/// Returns `false` iff `lhs` and `rhs` store the same underlying collection.
public func !== <
L : AnyCollectionProtocol, R : AnyCollectionProtocol
>(lhs: L, rhs: R) -> Bool {
return lhs._underlyingCollectionID != rhs._underlyingCollectionID
/// copied or upgraded/downgraded from one another have the same `_boxID`.
var _boxID: ObjectIdentifier { get }
}

% for (ti, Traversal) in enumerate(TRAVERSALS):
Expand All @@ -753,7 +734,7 @@ public func !== <
///
/// - SeeAlso: ${', '.join('`Any%sCollection`' % t for t in (2 * TRAVERSALS)[ti + 1 : ti + 3]) }
public struct ${Self}<Element>
: AnyCollectionProtocol, ${SelfProtocol} {
: _AnyCollectionProtocol, ${SelfProtocol} {

internal init(_box: _${Self}Box<Element>) {
self._box = _box
Expand Down Expand Up @@ -950,7 +931,7 @@ public struct ${Self}<Element>

/// Uniquely identifies the stored underlying collection.
public // Due to language limitations only
var _underlyingCollectionID: ObjectIdentifier {
var _boxID: ObjectIdentifier {
return ObjectIdentifier(_box)
}

Expand Down Expand Up @@ -978,10 +959,13 @@ extension Any${Kind} {
}
%end

@available(*, unavailable, renamed: "AnyCollectionProtocol")
public typealias AnyCollectionType = AnyCollectionProtocol
@available(*, unavailable, renamed: "_AnyCollectionProtocol")
public typealias AnyCollectionType = _AnyCollectionProtocol

@available(*, unavailable, renamed: "_AnyCollectionProtocol")
public typealias AnyCollectionProtocol = _AnyCollectionProtocol

extension AnyCollectionProtocol {
extension _AnyCollectionProtocol {
@available(*, unavailable, renamed: "makeIterator()")
public func generate() -> AnyIterator<Iterator.Element> {
Builtin.unreachable()
Expand All @@ -1003,3 +987,17 @@ public func anyGenerator<G : IteratorProtocol>(_ base: G) -> AnyIterator<G.Eleme
public func anyGenerator<Element>(_ body: () -> Element?) -> AnyIterator<Element> {
Builtin.unreachable()
}

@available(*, unavailable)
public func === <
L : _AnyCollectionProtocol, R : _AnyCollectionProtocol
>(lhs: L, rhs: R) -> Bool {
Builtin.unreachable()
}

@available(*, unavailable)
public func !== <
L : _AnyCollectionProtocol, R : _AnyCollectionProtocol
>(lhs: L, rhs: R) -> Bool {
Builtin.unreachable()
}
4 changes: 2 additions & 2 deletions test/1_stdlib/Renames.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func _ErrorType() {

func _ExistentialCollection<T>(i: AnyIterator<T>) {
func fn1<T>(_: AnyGenerator<T>) {} // expected-error {{'AnyGenerator' has been renamed to 'AnyIterator'}} {{18-30=AnyIterator}} {{none}}
func fn2<T : AnyCollectionType>(_: T) {} // expected-error {{'AnyCollectionType' has been renamed to 'AnyCollectionProtocol'}} {{16-33=AnyCollectionProtocol}} {{none}}
func fn2<T : AnyCollectionType>(_: T) {} // expected-error {{'AnyCollectionType' has been renamed to '_AnyCollectionProtocol'}} {{16-33=_AnyCollectionProtocol}} {{none}}
func fn3(_: AnyForwardIndex) {} // expected-error {{'AnyForwardIndex' has been renamed to 'AnyIndex'}} {{15-30=AnyIndex}} {{none}}
func fn4(_: AnyBidirectionalIndex) {} // expected-error {{'AnyBidirectionalIndex' has been renamed to 'AnyIndex'}} {{15-36=AnyIndex}} {{none}}
func fn5(_: AnyRandomAccessIndex) {} // expected-error {{'AnyRandomAccessIndex' has been renamed to 'AnyIndex'}} {{15-35=AnyIndex}} {{none}}
Expand All @@ -128,7 +128,7 @@ func _ExistentialCollection<T>(c: AnyBidirectionalCollection<T>) {
func _ExistentialCollection<T>(c: AnyRandomAccessCollection<T>) {
_ = c.underestimateCount() // expected-error {{'underestimateCount()' is unavailable: Please use underestimatedCount property instead.}} {{none}}
}
func _ExistentialCollection<C : AnyCollectionProtocol>(c: C) {
func _ExistentialCollection<C : _AnyCollectionProtocol>(c: C) {
_ = c.generate() // expected-error {{'generate()' has been renamed to 'makeIterator()'}} {{9-17=makeIterator}} {{none}}
}

Expand Down
20 changes: 13 additions & 7 deletions validation-test/stdlib/ExistentialCollection.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ extension AnyRandomAccessCollection where Element : TestProtocol1 {
}
}

func storesSameUnderlyingCollection<
L: _AnyCollectionProtocol, R: _AnyCollectionProtocol
>(_ lhs: L, _ rhs: R) -> Bool {
return lhs._boxID == rhs._boxID
}

var tests = TestSuite("ExistentialCollection")

tests.test("AnyIterator") {
Expand Down Expand Up @@ -357,13 +363,13 @@ tests.test("BidirectionalCollection") {
let bc0_ = AnyBidirectionalCollection(fc0) // upgrade!
expectNotEmpty(bc0_)
let bc0 = bc0_!
expectTrue(fc0 === bc0)
expectTrue(storesSameUnderlyingCollection(fc0, bc0))

let fc1 = AnyCollection(a0.lazy.reversed()) // new collection
expectFalse(fc1 === fc0)
expectFalse(storesSameUnderlyingCollection(fc1, fc0))

let fc2 = AnyCollection(bc0) // downgrade
expectTrue(fc2 === bc0)
expectTrue(storesSameUnderlyingCollection(fc2, bc0))

let a1 = ContiguousArray(bc0.lazy.reversed())
expectEqual(a0, a1)
Expand All @@ -381,7 +387,7 @@ tests.test("BidirectionalCollection") {
let s0 = "Hello, Woyld".characters
let bc1 = AnyBidirectionalCollection(s0)
let fc3 = AnyCollection(bc1)
expectTrue(fc3 === bc1)
expectTrue(storesSameUnderlyingCollection(fc3, bc1))
expectEmpty(AnyRandomAccessCollection(bc1))
expectEmpty(AnyRandomAccessCollection(fc3))
}
Expand All @@ -392,13 +398,13 @@ tests.test("RandomAccessCollection") {
let rc0_ = AnyRandomAccessCollection(fc0) // upgrade!
expectNotEmpty(rc0_)
let rc0 = rc0_!
expectTrue(rc0 === fc0)
expectTrue(storesSameUnderlyingCollection(rc0, fc0))

let bc1 = AnyBidirectionalCollection(rc0) // downgrade
expectTrue(bc1 === rc0)
expectTrue(storesSameUnderlyingCollection(bc1, rc0))

let fc1 = AnyBidirectionalCollection(rc0) // downgrade
expectTrue(fc1 === rc0)
expectTrue(storesSameUnderlyingCollection(fc1, rc0))

let a1 = ContiguousArray(rc0.lazy.reversed())
expectEqual(a0, a1)
Expand Down