blob: 869afeb1335714f8ea4d53bc45cc3f10fa17afc2 [file] [log] [blame]
//===--- ExistentialCollection.swift.gyb ----------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
%{
from gyb_stdlib_support import (
TRAVERSALS,
collectionForTraversal
)
}%
// TODO: swift-3-indexing-model: perform type erasure on the associated
// `Indices` type.
import SwiftShims
@inline(never)
@usableFromInline
internal func _abstract(
file: StaticString = #file,
line: UInt = #line
) -> Never {
fatalError("Method must be overridden", file: file, line: line)
}
//===--- Iterator ---------------------------------------------------------===//
//===----------------------------------------------------------------------===//
/// A type-erased iterator of `Element`.
///
/// This iterator forwards its `next()` method to an arbitrary underlying
/// iterator having the same `Element` type, hiding the specifics of the
/// underlying `IteratorProtocol`.
@_fixed_layout
public struct AnyIterator<Element> {
@usableFromInline
internal let _box: _AnyIteratorBoxBase<Element>
/// Creates an iterator that wraps a base iterator but whose type depends
/// only on the base iterator's element type.
///
/// You can use `AnyIterator` to hide the type signature of a more complex
/// iterator. For example, the `digits()` function in the following example
/// creates an iterator over a collection that lazily maps the elements of a
/// `Range<Int>` instance to strings. Instead of returning an
/// iterator with a type that encapsulates the implementation of the
/// collection, the `digits()` function first wraps the iterator in an
/// `AnyIterator` instance.
///
/// func digits() -> AnyIterator<String> {
/// let lazyStrings = (0..<10).lazy.map { String($0) }
/// let iterator:
/// LazyMapIterator<IndexingIterator<Range<Int>>, String>
/// = lazyStrings.makeIterator()
///
/// return AnyIterator(iterator)
/// }
///
/// - Parameter base: An iterator to type-erase.
@inlinable
public init<I : IteratorProtocol>(_ base: I) where I.Element == Element {
self._box = _IteratorBox(base)
}
/// Creates an iterator that wraps the given closure in its `next()` method.
///
/// The following example creates an iterator that counts up from the initial
/// value of an integer `x` to 15:
///
/// var x = 7
/// let iterator: AnyIterator<Int> = AnyIterator {
/// defer { x += 1 }
/// return x < 15 ? x : nil
/// }
/// let a = Array(iterator)
/// // a == [7, 8, 9, 10, 11, 12, 13, 14]
///
/// - Parameter body: A closure that returns an optional element. `body` is
/// executed each time the `next()` method is called on the resulting
/// iterator.
@inlinable
public init(_ body: @escaping () -> Element?) {
self._box = _IteratorBox(_ClosureBasedIterator(body))
}
@inlinable
internal init(_box: _AnyIteratorBoxBase<Element>) {
self._box = _box
}
}
extension AnyIterator: IteratorProtocol {
/// Advances to the next element and returns it, or `nil` if no next element
/// exists.
///
/// Once `nil` has been returned, all subsequent calls return `nil`.
@inlinable
public func next() -> Element? {
return _box.next()
}
}
/// Every `IteratorProtocol` can also be a `Sequence`. Note that
/// traversing the sequence consumes the iterator.
extension AnyIterator: Sequence { }
@usableFromInline
@_fixed_layout
internal struct _ClosureBasedIterator<Element> : IteratorProtocol {
@inlinable
internal init(_ body: @escaping () -> Element?) {
self._body = body
}
@inlinable
internal func next() -> Element? { return _body() }
@usableFromInline
internal let _body: () -> Element?
}
@_fixed_layout
@usableFromInline
internal class _AnyIteratorBoxBase<Element> : IteratorProtocol {
@inlinable // FIXME(sil-serialize-all)
internal init() {}
@inlinable // FIXME(sil-serialize-all)
deinit {}
/// Advances to the next element and returns it, or `nil` if no next element
/// exists.
///
/// Once `nil` has been returned, all subsequent calls return `nil`.
///
/// - Note: Subclasses must override this method.
@inlinable // FIXME(sil-serialize-all)
internal func next() -> Element? { _abstract() }
}
@_fixed_layout
@usableFromInline
internal final class _IteratorBox<
Base : IteratorProtocol
> : _AnyIteratorBoxBase<Base.Element> {
@inlinable
internal init(_ base: Base) { self._base = base }
@inlinable // FIXME(sil-serialize-all)
deinit {}
@inlinable
internal override func next() -> Base.Element? { return _base.next() }
@usableFromInline
internal var _base: Base
}
//===--- Sequence ---------------------------------------------------------===//
//===----------------------------------------------------------------------===//
% for Kind in ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
@_fixed_layout
@usableFromInline
% if Kind == 'Sequence':
internal class _AnySequenceBox<Element>
% elif Kind == 'Collection':
internal class _AnyCollectionBox<Element> : _AnySequenceBox<Element>
% elif Kind == 'BidirectionalCollection':
internal class _AnyBidirectionalCollectionBox<Element>
: _AnyCollectionBox<Element>
% elif Kind == 'RandomAccessCollection':
internal class _AnyRandomAccessCollectionBox<Element>
: _AnyBidirectionalCollectionBox<Element>
% else:
% assert False, 'Unknown kind'
% end
{
% if Kind == 'Sequence':
@inlinable // FIXME(sil-serialize-all)
internal init() { }
@inlinable
internal func _makeIterator() -> AnyIterator<Element> { _abstract() }
@inlinable
internal var _underestimatedCount: Int { _abstract() }
@inlinable
internal func _map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {
_abstract()
}
@inlinable
internal func _filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
_abstract()
}
@inlinable
internal func _forEach(
_ body: (Element) throws -> Void
) rethrows {
_abstract()
}
@inlinable
internal func __customContainsEquatableElement(
_ element: Element
) -> Bool? {
_abstract()
}
@inlinable
internal func __preprocessingPass<R>(
_ preprocess: () throws -> R
) rethrows -> R? {
_abstract()
}
@inlinable
internal func __copyToContiguousArray() -> ContiguousArray<Element> {
_abstract()
}
@inlinable
internal func __copyContents(initializing buf: UnsafeMutableBufferPointer<Element>)
-> (AnyIterator<Element>,UnsafeMutableBufferPointer<Element>.Index) {
_abstract()
}
% end
% # This deinit has to be present on all the types
@inlinable // FIXME(sil-serialize-all)
deinit {}
% override = 'override' if Kind != 'Sequence' else ''
@inlinable
internal ${override} func _drop(
while predicate: (Element) throws -> Bool
) rethrows -> _Any${Kind}Box<Element> {
_abstract()
}
@inlinable
internal ${override} func _dropFirst(_ n: Int) -> _Any${Kind}Box<Element> {
_abstract()
}
@inlinable
internal ${override} func _dropLast(_ n: Int) -> _Any${Kind}Box<Element> {
_abstract()
}
@inlinable
internal ${override} func _prefix(_ maxLength: Int) -> _Any${Kind}Box<Element> {
_abstract()
}
@inlinable
internal ${override} func _prefix(
while predicate: (Element) throws -> Bool
) rethrows -> _Any${Kind}Box<Element> {
_abstract()
}
@inlinable
internal ${override} func _suffix(_ maxLength: Int) -> _Any${Kind}Box<Element> {
_abstract()
}
@inlinable
internal func _split(
maxSplits: Int, omittingEmptySubsequences: Bool,
whereSeparator isSeparator: (Element) throws -> Bool
) rethrows -> [Any${Kind}<Element>] {
_abstract()
}
% if Kind == 'Collection':
@inlinable
internal subscript(i: _AnyIndexBox) -> Element { _abstract() }
@inlinable
internal func _index(after i: _AnyIndexBox) -> _AnyIndexBox { _abstract() }
@inlinable
internal func _formIndex(after i: _AnyIndexBox) { _abstract() }
@inlinable
internal func _index(
_ i: _AnyIndexBox, offsetBy n: Int
) -> _AnyIndexBox {
_abstract()
}
@inlinable
internal func _index(
_ i: _AnyIndexBox, offsetBy n: Int, limitedBy limit: _AnyIndexBox
) -> _AnyIndexBox? {
_abstract()
}
@inlinable
internal func _formIndex(_ i: inout _AnyIndexBox, offsetBy n: Int) {
_abstract()
}
@inlinable
internal func _formIndex(
_ i: inout _AnyIndexBox, offsetBy n: Int, limitedBy limit: _AnyIndexBox
) -> Bool {
_abstract()
}
@inlinable
internal func _distance(
from start: _AnyIndexBox, to end: _AnyIndexBox
) -> Int {
_abstract()
}
// TODO: swift-3-indexing-model: forward the following methods.
/*
var _indices: Indices
func prefix(upTo end: Index) -> SubSequence
func suffix(from start: Index) -> SubSequence
func prefix(through position: Index) -> SubSequence
var isEmpty: Bool { get }
*/
@inlinable // FIXME(sil-serialize-all)
internal var _count: Int { _abstract() }
// TODO: swift-3-indexing-model: forward the following methods.
/*
func _customIndexOfEquatableElement(element: Element) -> Index??
func _customLastIndexOfEquatableElement(element: Element) -> Index??
*/
@inlinable // FIXME(sil-serialize-all)
internal var _first: Element? { _abstract() }
@inlinable
internal init(
_startIndex: _AnyIndexBox,
endIndex: _AnyIndexBox
) {
self._startIndex = _startIndex
self._endIndex = endIndex
}
@usableFromInline
internal let _startIndex: _AnyIndexBox
@usableFromInline
internal let _endIndex: _AnyIndexBox
% end
% if Kind in ['Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
% override = 'override' if Kind != 'Collection' else ''
@inlinable
internal ${override} subscript(
start start: _AnyIndexBox,
end end: _AnyIndexBox
) -> _Any${Kind}Box<Element> { _abstract() }
% end
% if Kind == 'BidirectionalCollection':
@inlinable
internal func _index(before i: _AnyIndexBox) -> _AnyIndexBox { _abstract() }
@inlinable
internal func _formIndex(before i: _AnyIndexBox) { _abstract() }
@inlinable
internal var _last: Element? { _abstract() }
% end
}
% end
% for Kind in ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
% if Kind == 'Sequence':
% EqualAndWeakerKinds = ['Sequence']
% elif Kind == 'Collection':
% EqualAndWeakerKinds = ['Sequence', 'Collection']
% elif Kind == 'BidirectionalCollection':
% EqualAndWeakerKinds = ['Sequence', 'Collection', 'BidirectionalCollection']
% elif Kind == 'RandomAccessCollection':
% EqualAndWeakerKinds = ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']
% else:
% assert False, 'Unknown kind'
% end
@_fixed_layout
@usableFromInline
internal final class _${Kind}Box<S : ${Kind}> : _Any${Kind}Box<S.Element>
{
@usableFromInline
internal typealias Element = S.Element
@inline(__always)
@inlinable
internal override func _makeIterator() -> AnyIterator<Element> {
return AnyIterator(_base.makeIterator())
}
@inlinable
internal override var _underestimatedCount: Int {
return _base.underestimatedCount
}
@inlinable
internal override func _map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {
return try _base.map(transform)
}
@inlinable
internal override func _filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
return try _base.filter(isIncluded)
}
@inlinable
internal override func _forEach(
_ body: (Element) throws -> Void
) rethrows {
return try _base.forEach(body)
}
@inlinable
internal override func __customContainsEquatableElement(
_ element: Element
) -> Bool? {
return _base._customContainsEquatableElement(element)
}
@inlinable
internal override func __preprocessingPass<R>(
_ preprocess: () throws -> R
) rethrows -> R? {
return try _base._preprocessingPass(preprocess)
}
@inlinable
internal override func __copyToContiguousArray() -> ContiguousArray<Element> {
return _base._copyToContiguousArray()
}
@inlinable
internal override func __copyContents(initializing buf: UnsafeMutableBufferPointer<Element>)
-> (AnyIterator<Element>,UnsafeMutableBufferPointer<Element>.Index) {
let (it,idx) = _base._copyContents(initializing: buf)
return (AnyIterator(it),idx)
}
@inlinable
internal override func _drop(
while predicate: (Element) throws -> Bool
) rethrows -> _Any${Kind}Box<Element> {
return try _${Kind}Box<S.SubSequence>(_base: _base.drop(while: predicate))
}
@inlinable
internal override func _dropFirst(_ n: Int) -> _Any${Kind}Box<Element> {
return _${Kind}Box<S.SubSequence>(_base: _base.dropFirst(n))
}
@inlinable
internal override func _dropLast(_ n: Int) -> _Any${Kind}Box<Element> {
return _${Kind}Box<S.SubSequence>(_base: _base.dropLast(n))
}
@inlinable
internal override func _prefix(
while predicate: (Element) throws -> Bool
) rethrows -> _Any${Kind}Box<Element> {
return try _${Kind}Box<S.SubSequence>(_base: _base.prefix(while: predicate))
}
@inlinable
internal override func _prefix(_ maxLength: Int) -> _Any${Kind}Box<Element> {
return _${Kind}Box<S.SubSequence>(_base: _base.prefix(maxLength))
}
@inlinable
internal override func _suffix(_ maxLength: Int) -> _Any${Kind}Box<Element> {
return _${Kind}Box<S.SubSequence>(_base: _base.suffix(maxLength))
}
% for ResultKind in EqualAndWeakerKinds:
@inlinable
internal override func _split(
maxSplits: Int, omittingEmptySubsequences: Bool,
whereSeparator isSeparator: (Element) throws -> Bool
) rethrows -> [Any${ResultKind}<Element>] {
return try _base.split(
maxSplits: maxSplits,
omittingEmptySubsequences: omittingEmptySubsequences,
whereSeparator: isSeparator)
.map {
Any${ResultKind}(_box: _${Kind}Box<S.SubSequence>(_base: $0))
}
}
% end
@inlinable // FIXME(sil-serialize-all)
deinit {}
% if Kind == 'Sequence':
@inlinable
internal init(_base: S) {
self._base = _base
}
% else:
@inlinable
internal init(_base: S) {
self._base = _base
super.init(
_startIndex: _IndexBox(_base: _base.startIndex),
endIndex: _IndexBox(_base: _base.endIndex))
}
@inlinable
internal func _unbox(
_ position: _AnyIndexBox, file: StaticString = #file, line: UInt = #line
) -> S.Index {
if let i = position._unbox() as S.Index? {
return i
}
fatalError("Index type mismatch!", file: file, line: line)
}
@inlinable
internal override subscript(position: _AnyIndexBox) -> Element {
return _base[_unbox(position)]
}
@inlinable
internal override subscript(start start: _AnyIndexBox, end end: _AnyIndexBox)
-> _Any${Kind}Box<Element>
{
return _${Kind}Box<S.SubSequence>(_base:
_base[_unbox(start)..<_unbox(end)]
)
}
@inlinable
internal override func _index(after position: _AnyIndexBox) -> _AnyIndexBox {
return _IndexBox(_base: _base.index(after: _unbox(position)))
}
@inlinable
internal override func _formIndex(after position: _AnyIndexBox) {
if let p = position as? _IndexBox<S.Index> {
return _base.formIndex(after: &p._base)
}
fatalError("Index type mismatch!")
}
@inlinable
internal override func _index(
_ i: _AnyIndexBox, offsetBy n: Int
) -> _AnyIndexBox {
return _IndexBox(_base: _base.index(_unbox(i), offsetBy: numericCast(n)))
}
@inlinable
internal override func _index(
_ i: _AnyIndexBox,
offsetBy n: Int,
limitedBy limit: _AnyIndexBox
) -> _AnyIndexBox? {
return _base.index(
_unbox(i),
offsetBy: numericCast(n),
limitedBy: _unbox(limit))
.map { _IndexBox(_base: $0) }
}
@inlinable
internal override func _formIndex(
_ i: inout _AnyIndexBox, offsetBy n: Int
) {
if let box = i as? _IndexBox<S.Index> {
return _base.formIndex(&box._base, offsetBy: numericCast(n))
}
fatalError("Index type mismatch!")
}
@inlinable
internal override func _formIndex(
_ i: inout _AnyIndexBox, offsetBy n: Int, limitedBy limit: _AnyIndexBox
) -> Bool {
if let box = i as? _IndexBox<S.Index> {
return _base.formIndex(
&box._base,
offsetBy: numericCast(n),
limitedBy: _unbox(limit))
}
fatalError("Index type mismatch!")
}
@inlinable
internal override func _distance(
from start: _AnyIndexBox,
to end: _AnyIndexBox
) -> Int {
return numericCast(_base.distance(from: _unbox(start), to: _unbox(end)))
}
@inlinable
internal override var _count: Int {
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 {
return _IndexBox(_base: _base.index(before: _unbox(position)))
}
@inlinable
internal override func _formIndex(before position: _AnyIndexBox) {
if let p = position as? _IndexBox<S.Index> {
return _base.formIndex(before: &p._base)
}
fatalError("Index type mismatch!")
}
@inlinable
internal override var _last: Element? {
return _base.last
}
% end
% end
@usableFromInline
internal var _base: S
}
% end
@usableFromInline
@_fixed_layout
internal struct _ClosureBasedSequence<Iterator : IteratorProtocol> {
@usableFromInline
internal var _makeUnderlyingIterator: () -> Iterator
@inlinable
internal init(_ makeUnderlyingIterator: @escaping () -> Iterator) {
self._makeUnderlyingIterator = makeUnderlyingIterator
}
}
extension _ClosureBasedSequence: Sequence {
@inlinable
internal func makeIterator() -> Iterator {
return _makeUnderlyingIterator()
}
}
/// A type-erased sequence.
///
/// An instance of `AnySequence` forwards its operations to an underlying base
/// sequence having the same `Element` type, hiding the specifics of the
/// underlying sequence.
//@usableFromInline
@_fixed_layout
public struct AnySequence<Element> {
@usableFromInline
internal let _box: _AnySequenceBox<Element>
/// Creates a sequence whose `makeIterator()` method forwards to
/// `makeUnderlyingIterator`.
@inlinable
public init<I : IteratorProtocol>(
_ makeUnderlyingIterator: @escaping () -> I
) where I.Element == Element {
self.init(_ClosureBasedSequence(makeUnderlyingIterator))
}
@inlinable
internal init(_box: _AnySequenceBox<Element>) {
self._box = _box
}
}
extension AnySequence: Sequence {
public typealias Iterator = AnyIterator<Element>
/// Creates a new sequence that wraps and forwards operations to `base`.
@inlinable
public init<S : Sequence>(_ base: S)
where
S.Element == Element {
self._box = _SequenceBox(_base: base)
}
}
% for Kind in ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
extension Any${Kind} {
% if Kind == 'Sequence':
/// Returns an iterator over the elements of this sequence.
% else:
/// Returns an iterator over the elements of this collection.
% end
@inline(__always)
@inlinable
public func makeIterator() -> Iterator {
return _box._makeIterator()
}
@inlinable
public var underestimatedCount: Int {
return _box._underestimatedCount
}
@inlinable
public func map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {
return try _box._map(transform)
}
@inlinable
public func filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
return try _box._filter(isIncluded)
}
@inlinable
public func forEach(
_ body: (Element) throws -> Void
) rethrows {
return try _box._forEach(body)
}
@inlinable
public func drop(
while predicate: (Element) throws -> Bool
) rethrows -> Any${Kind}<Element> {
return try Any${Kind}(_box: _box._drop(while: predicate))
}
@inlinable
public func dropFirst(_ n: Int) -> Any${Kind}<Element> {
return Any${Kind}(_box: _box._dropFirst(n))
}
@inlinable
public func dropLast(_ n: Int) -> Any${Kind}<Element> {
return Any${Kind}(_box: _box._dropLast(n))
}
@inlinable
public func prefix(
while predicate: (Element) throws -> Bool
) rethrows -> Any${Kind}<Element> {
return try Any${Kind}(_box: _box._prefix(while: predicate))
}
@inlinable
public func prefix(_ maxLength: Int) -> Any${Kind}<Element> {
return Any${Kind}(_box: _box._prefix(maxLength))
}
@inlinable
public func suffix(_ maxLength: Int) -> Any${Kind}<Element> {
return Any${Kind}(_box: _box._suffix(maxLength))
}
@inlinable
public func split(
maxSplits: Int = Int.max,
omittingEmptySubsequences: Bool = true,
whereSeparator isSeparator: (Element) throws -> Bool
) rethrows -> [Any${Kind}<Element>] {
return try _box._split(
maxSplits: maxSplits,
omittingEmptySubsequences: omittingEmptySubsequences,
whereSeparator: isSeparator)
}
@inlinable
public func _customContainsEquatableElement(
_ element: Element
) -> Bool? {
return _box.__customContainsEquatableElement(element)
}
@inlinable
public func _preprocessingPass<R>(
_ preprocess: () throws -> R
) rethrows -> R? {
return try _box.__preprocessingPass(preprocess)
}
@inlinable
public func _copyToContiguousArray() -> ContiguousArray<Element> {
return self._box.__copyToContiguousArray()
}
@inlinable
public func _copyContents(initializing buf: UnsafeMutableBufferPointer<Element>)
-> (AnyIterator<Element>,UnsafeMutableBufferPointer<Element>.Index) {
let (it,idx) = _box.__copyContents(initializing: buf)
return (AnyIterator(it),idx)
}
}
% end
//===--- Index ------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
@usableFromInline
internal protocol _AnyIndexBox : class {
var _typeID: ObjectIdentifier { get }
func _unbox<T : Comparable>() -> T?
func _isEqual(to rhs: _AnyIndexBox) -> Bool
func _isLess(than rhs: _AnyIndexBox) -> Bool
}
@_fixed_layout
@usableFromInline
internal final class _IndexBox<
BaseIndex : Comparable
> : _AnyIndexBox {
@usableFromInline
internal var _base: BaseIndex
@inlinable
internal init(_base: BaseIndex) {
self._base = _base
}
@inlinable
internal func _unsafeUnbox(_ other: _AnyIndexBox) -> BaseIndex {
return unsafeDowncast(other, to: _IndexBox.self)._base
}
@inlinable
internal var _typeID: ObjectIdentifier {
return ObjectIdentifier(type(of: self))
}
@inlinable
internal func _unbox<T : Comparable>() -> T? {
return (self as _AnyIndexBox as? _IndexBox<T>)?._base
}
@inlinable
internal func _isEqual(to rhs: _AnyIndexBox) -> Bool {
return _base == _unsafeUnbox(rhs)
}
@inlinable
internal func _isLess(than rhs: _AnyIndexBox) -> Bool {
return _base < _unsafeUnbox(rhs)
}
}
/// A wrapper over an underlying index that hides the specific underlying type.
@_fixed_layout
public struct AnyIndex {
@usableFromInline
internal var _box: _AnyIndexBox
/// Creates a new index wrapping `base`.
@inlinable
public init<BaseIndex : Comparable>(_ base: BaseIndex) {
self._box = _IndexBox(_base: base)
}
@inlinable
internal init(_box: _AnyIndexBox) {
self._box = _box
}
@inlinable
internal var _typeID: ObjectIdentifier {
return _box._typeID
}
}
extension AnyIndex : Comparable {
/// Returns a Boolean value indicating whether two indices wrap equal
/// underlying indices.
///
/// The types of the two underlying indices must be identical.
///
/// - Parameters:
/// - lhs: An index to compare.
/// - rhs: Another index to compare.
@inlinable
public static func == (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
_precondition(lhs._typeID == rhs._typeID, "Base index types differ")
return lhs._box._isEqual(to: rhs._box)
}
/// Returns a Boolean value indicating whether the first argument represents a
/// position before the second argument.
///
/// The types of the two underlying indices must be identical.
///
/// - Parameters:
/// - lhs: An index to compare.
/// - rhs: Another index to compare.
@inlinable
public static func < (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
_precondition(lhs._typeID == rhs._typeID, "Base index types differ")
return lhs._box._isLess(than: rhs._box)
}
}
//===--- Collections ------------------------------------------------------===//
//===----------------------------------------------------------------------===//
public // @testable
protocol _AnyCollectionProtocol : Collection {
/// Identifies the underlying collection stored by `self`. Instances
/// copied or upgraded/downgraded from one another have the same `_boxID`.
var _boxID: ObjectIdentifier { get }
}
% for (ti, Traversal) in enumerate(TRAVERSALS):
% SelfProtocol = collectionForTraversal(Traversal)
% Self = 'Any' + SelfProtocol
/// A type-erased wrapper over any collection with indices that
/// support ${Traversal.lower().replace('omacc', 'om acc')} traversal.
///
/// An `${Self}` instance forwards its operations to a base collection having the
/// same `Element` type, hiding the specifics of the underlying
/// collection.
@_fixed_layout
public struct ${Self}<Element> {
@usableFromInline
internal let _box: _${Self}Box<Element>
@inlinable
internal init(_box: _${Self}Box<Element>) {
self._box = _box
}
}
extension ${Self}: ${SelfProtocol} {
public typealias Indices = DefaultIndices<${Self}>
public typealias Iterator = AnyIterator<Element>
public typealias Index = AnyIndex
public typealias SubSequence = ${Self}<Element>
% for SubTraversal in TRAVERSALS[ti:]:
% SubProtocol = collectionForTraversal(SubTraversal)
/// Creates a type-erased collection that wraps the given collection.
///
/// - Parameter base: The collection to wrap.
///
/// - Complexity: O(1).
@inlinable
public init<C : ${SubProtocol}>(_ base: C) where C.Element == Element {
// Traversal: ${Traversal}
// SubTraversal: ${SubTraversal}
self._box = _${SubProtocol}Box<C>(
_base: base)
}
/// Creates an `${Self}` having the same underlying collection as `other`.
///
/// - Complexity: O(1)
@inlinable
public init(_ other: Any${SubProtocol}<Element>) {
self._box = other._box
}
% end
% for SuperTraversal in TRAVERSALS[:ti]:
/// Creates an `${Self}` having the same underlying collection as `other`.
///
/// If the underlying collection stored by `other` does not satisfy
/// `${SelfProtocol}`, the result is `nil`.
///
/// - Complexity: O(1)
@inlinable
public init?(_ other: Any${collectionForTraversal(SuperTraversal)}<Element>) {
guard let box =
other._box as? _${Self}Box<Element> else {
return nil
}
self._box = box
}
% end
/// The position of the first element in a non-empty collection.
///
/// In an empty collection, `startIndex == endIndex`.
@inlinable
public var startIndex: Index {
return AnyIndex(_box: _box._startIndex)
}
/// The collection's "past the end" position---that is, the position one
/// greater than the last valid subscript argument.
///
/// `endIndex` is always reachable from `startIndex` by zero or more
/// applications of `index(after:)`.
@inlinable
public var endIndex: Index {
return AnyIndex(_box: _box._endIndex)
}
/// Accesses the element indicated by `position`.
///
/// - Precondition: `position` indicates a valid position in `self` and
/// `position != endIndex`.
@inlinable
public subscript(position: Index) -> Element {
return _box[position._box]
}
@inlinable
public subscript(bounds: Range<Index>) -> SubSequence {
return ${Self}(_box:
_box[start: bounds.lowerBound._box, end: bounds.upperBound._box])
}
@inlinable
public func _failEarlyRangeCheck(_ index: Index, bounds: Range<Index>) {
// Do nothing. Doing a range check would involve unboxing indices,
// performing dynamic dispatch etc. This seems to be too costly for a fast
// range check for QoI purposes.
}
@inlinable
public func _failEarlyRangeCheck(_ range: Range<Index>, bounds: Range<Index>) {
// Do nothing. Doing a range check would involve unboxing indices,
// performing dynamic dispatch etc. This seems to be too costly for a fast
// range check for QoI purposes.
}
@inlinable
public func index(after i: Index) -> Index {
return AnyIndex(_box: _box._index(after: i._box))
}
@inlinable
public func formIndex(after i: inout Index) {
if _isUnique(&i._box) {
_box._formIndex(after: i._box)
}
else {
i = index(after: i)
}
}
@inlinable
public func index(_ i: Index, offsetBy n: Int) -> Index {
return AnyIndex(_box: _box._index(i._box, offsetBy: n))
}
@inlinable
public func index(
_ i: Index, offsetBy n: Int, limitedBy limit: Index
) -> Index? {
return _box._index(i._box, offsetBy: n, limitedBy: limit._box)
.map { AnyIndex(_box:$0) }
}
@inlinable
public func formIndex(_ i: inout Index, offsetBy n: Int) {
if _isUnique(&i._box) {
return _box._formIndex(&i._box, offsetBy: n)
} else {
i = index(i, offsetBy: n)
}
}
@inlinable
public func formIndex(
_ i: inout Index,
offsetBy n: Int,
limitedBy limit: Index
) -> Bool {
if _isUnique(&i._box) {
return _box._formIndex(&i._box, offsetBy: n, limitedBy: limit._box)
}
if let advanced = index(i, offsetBy: n, limitedBy: limit) {
i = advanced
return true
}
i = limit
return false
}
@inlinable
public func distance(from start: Index, to end: Index) -> Int {
return _box._distance(from: start._box, to: end._box)
}
/// The number of elements.
///
% if Traversal != 'RandomAccess':
/// To check whether a collection is empty, use its `isEmpty` property
/// instead of comparing `count` to zero. Calculating `count` can be an O(*n*)
/// operation.
///
% end
/// - Complexity: ${'O(1)' if Traversal == 'RandomAccess' else 'O(*n*)'}
@inlinable
public var count: Int {
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 {
return AnyIndex(_box: _box._index(before: i._box))
}
@inlinable
public func formIndex(before i: inout Index) {
if _isUnique(&i._box) {
_box._formIndex(before: i._box)
}
else {
i = index(before: i)
}
}
@inlinable
public var last: Element? {
return _box._last
}
% end
}
extension ${Self}: _AnyCollectionProtocol {
/// Uniquely identifies the stored underlying collection.
@inlinable
public // Due to language limitations only
var _boxID: ObjectIdentifier {
return ObjectIdentifier(_box)
}
}
% end
// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End: