Files
swift-mirror/stdlib/internal/SwiftExperimental/ExistentialCollection.swift.gyb
Dave Abrahams 93ff088535 [stdlib] AnyGenerator is a Sequence
Swift SVN r26427
2015-03-23 03:20:07 +00:00

426 lines
13 KiB
Plaintext

//===--- ExistentialCollection.swift.gyb ----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//===--- Definitions needed only while experimental -----------------------===//
internal typealias _ContiguousArrayStorageBase = AnyObject
extension _InitializeTo { init() {} }
extension _CopyToNativeArrayBuffer { init() {} }
extension _Count { init() {} }
extension _ContiguousArrayBuffer {
var _storage: _ContiguousArrayStorageBase { return owner }
init(_ owner: _ContiguousArrayStorageBase) {
self = unsafeBitCast(owner, _ContiguousArrayBuffer.self)
}
}
//===----------------------------------------------------------------------===//
% traversals = ['Forward', 'Bidirectional', 'RandomAccess']
@noreturn @inline(never)
internal func _abstract(file: StaticString = __FILE__, line: UWord = __LINE__) {
fatalError("Method must be overridden", file: file, line: line)
}
//===--- Generator --------------------------------------------------------===//
//===----------------------------------------------------------------------===//
public class _AnyGeneratorBase {}
public class AnyGenerator<T> : _AnyGeneratorBase, GeneratorType, SequenceType {
public func next() -> T? {_abstract()}
public func generate() -> AnyGenerator { return self }
}
internal final class _GeneratorBox<
Base: GeneratorType
> : AnyGenerator<Base.Element> {
init(_ base: Base) { self.base = base }
override func next() -> Base.Element? { return base.next() }
var base: Base
}
internal func _typeID(instance: AnyObject) -> ObjectIdentifier {
return ObjectIdentifier(instance.dynamicType)
}
//===--- Sequence ---------------------------------------------------------===//
//===----------------------------------------------------------------------===//
internal class _AnySequenceBox {
// FIXME: can't make _AnySequenceBox generic and return
// _AnyGenerator<T> here due to <rdar://20211022>
func generate() -> _AnyGeneratorBase {_abstract()}
func _underestimateCount() -> Int {_abstract()}
// FIXME: can't traffic in UnsafeMutablePointer<T> and
// _ContiguousArrayBuffer<T> here due to <rdar://20164041>
func _initializeTo(ptr: UnsafeMutablePointer<Void>) {_abstract()}
func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase {_abstract()}
}
internal class _AnyCollectionBoxBase : _AnySequenceBox {
init(startIndex: _ForwardIndexBoxType, endIndex: _ForwardIndexBoxType) {
self.startIndex = startIndex
self.endIndex = endIndex
}
let startIndex: _ForwardIndexBoxType
let endIndex: _ForwardIndexBoxType
}
% for Kind in ['Sequence', 'Collection']:
// FIXME: can't make this a protocol due to <rdar://20209031>
internal class _${Kind}Box<S: ${Kind}Type>
: _Any${Kind}Box${'<S.Generator.Element>'if Kind == 'Collection' else ''} {
typealias Element = S.Generator.Element
override func generate() -> _AnyGeneratorBase {
return _GeneratorBox(_base.generate())
}
override func _underestimateCount() -> Int {
return Swift.underestimateCount(_base)
}
override func _initializeTo(ptr: UnsafeMutablePointer<Void>) {
_base~>(_InitializeTo(), UnsafeMutablePointer(ptr))
}
override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase {
return (_base~>(_CopyToNativeArrayBuffer(), ()))._storage
}
% if Kind == 'Collection':
override func _count() -> IntMax {
return numericCast(_base~>(_Count(), ()))
}
override subscript(position: _ForwardIndexBoxType) -> Element {
if let i? = position._unbox() as S.Index? {
return _base[i]
}
fatalError("Index type mismatch!")
}
init(
_ base: S,
startIndex: _ForwardIndexBoxType,
endIndex: _ForwardIndexBoxType
) {
self._base = base
super.init(startIndex: startIndex, endIndex: endIndex)
}
% else:
init(_ base: S) {
self._base = base
}
% end
internal var _base: S
}
% end
public struct AnySequence<T> : SequenceType {
typealias Element = T
public init<S: SequenceType where S.Generator.Element == T>(_ base: S) {
_box = _SequenceBox(base)
}
public func generate() -> AnyGenerator<Element> {
return unsafeDowncast(_box.generate())
}
internal let _box: _AnySequenceBox
}
% for Kind in ['Sequence'] + [t + 'Collection' for t in traversals]:
public func ~> <Element>(
source: Any${Kind}<Element>, _: (_UnderestimateCount, ())
) -> Int {
return source._box._underestimateCount()
}
public func ~> <Element>(
source: Any${Kind}<Element>,
ptr: (_InitializeTo, UnsafeMutablePointer<Element>)
) {
source._box._initializeTo(UnsafeMutablePointer(ptr.1))
}
public func ~> <Element>(
source: Any${Kind}<Element>, _: (_CopyToNativeArrayBuffer,())
) -> _ContiguousArrayBuffer<Element> {
return _ContiguousArrayBuffer(source._box._copyToNativeArrayBuffer())
}
% if Kind != 'Sequence':
public func ~> <Element>(
source: Any${Kind}<Element>, _: (_Count,())
) -> IntMax {
return source._box._count()
}
% end
% end
//===--- ForwardIndex -----------------------------------------------------===//
//===----------------------------------------------------------------------===//
internal protocol _ForwardIndexBoxType : class {
var typeID: ObjectIdentifier {get}
func successor() -> _ForwardIndexBoxType
func equals(other: _ForwardIndexBoxType) -> Bool
func _unbox<T: ForwardIndexType>() -> T?
func _distanceTo(other: _ForwardIndexBoxType) -> AnyForwardIndex.Distance
// FIXME: Can't return Self from _advancedBy pending <rdar://20181253>
func _advancedBy(distance: AnyForwardIndex.Distance) -> _ForwardIndexBoxType
func _advancedBy(
distance: AnyForwardIndex.Distance,
_ limit: _ForwardIndexBoxType
) -> _ForwardIndexBoxType
}
internal class _ForwardIndexBox<
BaseIndex: ForwardIndexType
> : _ForwardIndexBoxType {
required init(_ base: BaseIndex) {
self.base = base
}
func successor() -> _ForwardIndexBoxType {
return self.dynamicType(self.base.successor())
}
func unsafeUnbox(other: _ForwardIndexBoxType) -> BaseIndex {
return (unsafeDowncast(other) as _ForwardIndexBox).base
}
func equals(other: _ForwardIndexBoxType) -> Bool {
return base == unsafeUnbox(other)
}
func _distanceTo(other: _ForwardIndexBoxType) -> AnyForwardIndex.Distance {
return numericCast(distance(base, unsafeUnbox(other)))
}
func _advancedBy(n: AnyForwardIndex.Distance) -> _ForwardIndexBoxType {
return self.dynamicType(advance(base, numericCast(n)))
}
func _advancedBy(
n: AnyForwardIndex.Distance,
_ limit: _ForwardIndexBoxType
) -> _ForwardIndexBoxType {
return self.dynamicType(advance(base, numericCast(n), unsafeUnbox(limit)))
}
func _unbox<T: ForwardIndexType>() -> T? {
if T.self is BaseIndex.Type {
_sanityCheck(BaseIndex.self is T.Type)
// This bit cast is really nothing as we have proven they are
// the same type.
return unsafeBitCast(base, T.self)
}
return nil
}
var typeID: ObjectIdentifier { return _typeID(self) }
internal // private
let base: BaseIndex
}
//===--- BidirectionalIndex -----------------------------------------------===//
//===----------------------------------------------------------------------===//
internal protocol _BidirectionalIndexBoxType : _ForwardIndexBoxType {
func predecessor() -> _BidirectionalIndexBoxType
}
internal class _BidirectionalIndexBox<
BaseIndex: BidirectionalIndexType
> : _ForwardIndexBox<BaseIndex>, _BidirectionalIndexBoxType {
required init(_ base: BaseIndex) {
super.init(base)
}
override func successor() -> _ForwardIndexBoxType {
return self.dynamicType(self.base.successor())
}
func predecessor() -> _BidirectionalIndexBoxType {
return self.dynamicType(self.base.predecessor())
}
}
//===--- RandomAccessIndex -----------------------------------------------===//
//===----------------------------------------------------------------------===//
internal protocol _RandomAccessIndexBoxType : _BidirectionalIndexBoxType {}
internal final class _RandomAccessIndexBox<
BaseIndex: RandomAccessIndexType
> : _BidirectionalIndexBox<BaseIndex>, _RandomAccessIndexBoxType {
required init(_ base: BaseIndex) {
super.init(base)
}
}
//===--- All Index Protocols ----------------------------------------------===//
//===----------------------------------------------------------------------===//
% for Traversal in traversals:
% Self = 'Any%sIndex' % Traversal
public struct ${Self} : ${Traversal}IndexType {
public typealias Distance = IntMax
public init<BaseIndex: ${Traversal}IndexType>(_ base: BaseIndex) {
_box = _${Traversal}IndexBox(base)
}
public func successor() -> ${Self} {
return ${Self}(_box.successor())
}
% if Traversal != 'Forward':
public func predecessor() -> ${Self} {
return ${Self}(_box.predecessor())
}
% end
% if Traversal == 'RandomAccess':
public func distanceTo(other: ${Self}) -> Distance {
return _box._distanceTo(other._box)
}
public func advancedBy(amount: Distance) -> ${Self} {
return ${Self}(_box._advancedBy(amount))
}
% end
//===--- private --------------------------------------------------------===//
internal var _typeID: ObjectIdentifier {
return _box.typeID
}
internal init(_ box: _ForwardIndexBoxType) {
self._box = box${
'' if Traversal == 'Forward' else ' as! _%sIndexBoxType' % Traversal}
}
internal let _box: _${Traversal}IndexBoxType
}
public func ~> (
start: ${Self}, other : (_Distance, ${Self})
) -> ${Self}.Distance {
precondition(
start._typeID == other.1._typeID,
"distance: base index types differ.")
return start._box._distanceTo(other.1._box)
}
public func ~> (
start: ${Self}, distance : (_Advance, ${Self}.Distance)
) -> ${Self} {
return ${Self}(start._box._advancedBy(distance.1))
}
public func ~> (
start: ${Self},
args: (_Advance, (${Self}.Distance, ${Self}))
) -> ${Self} {
precondition(
start._typeID == args.1.1._typeID, "advance: base index types differ.")
return ${Self}(start._box._advancedBy(args.1.0, args.1.1._box))
}
public func == (lhs: ${Self}, rhs: ${Self}) -> Bool {
precondition(lhs._typeID == rhs._typeID, "base index types differ.")
return lhs._box.equals(rhs._box)
}
% end
//===--- Collections ------------------------------------------------------===//
//===----------------------------------------------------------------------===//
class _AnyCollectionBox<Element> : _AnyCollectionBoxBase {
subscript(_ForwardIndexBoxType) -> Element {_abstract()}
func _count() -> IntMax {_abstract()}
// FIXME: should be inherited, but a known bug prevents it since
// this class is generic.
override init(
startIndex: _ForwardIndexBoxType,
endIndex: _ForwardIndexBoxType
) {
super.init(startIndex: startIndex, endIndex: endIndex)
}
}
public protocol _AnyCollectionType : CollectionType {
var _boxID: ObjectIdentifier {get}
}
public func === <L: _AnyCollectionType, R: _AnyCollectionType>(lhs: L, rhs: R) -> Bool {
return lhs._boxID == rhs._boxID
}
public func !== <L: _AnyCollectionType, R: _AnyCollectionType>(lhs: L, rhs: R) -> Bool {
return lhs._boxID != rhs._boxID
}
% for (ti, Traversal) in enumerate(traversals):
public struct Any${Traversal}Collection<Element> : _AnyCollectionType {
typealias Box = _AnyCollectionBox<Element>
% for SubTraversal in traversals[ti:]:
public init<
C: CollectionType
where C.Index: ${SubTraversal}IndexType, C.Generator.Element == Element
>(_ base: C) {
self._box = _CollectionBox<C>(
base,
startIndex: _${SubTraversal}IndexBox(base.startIndex),
endIndex: _${SubTraversal}IndexBox(base.endIndex))
}
public init(_ other: Any${SubTraversal}Collection<Element>) {
self._box = other._box
}
% end
% for SuperTraversal in traversals[:ti]:
public init?(_ other: Any${SuperTraversal}Collection<Element>) {
if !(other._box.startIndex is _${Traversal}IndexBoxType) {
return nil
}
_sanityCheck(other._box.endIndex is _${Traversal}IndexBoxType)
self._box = other._box
}
% end
public func generate() -> AnyGenerator<Element> {
return unsafeDowncast(_box.generate())
}
public var startIndex: Any${Traversal}Index {
return Any${Traversal}Index(_box.startIndex)
}
public var endIndex: Any${Traversal}Index {
return Any${Traversal}Index(_box.endIndex)
}
public subscript(position: Any${Traversal}Index) -> Element {
return _box[position._box]
}
public var _boxID: ObjectIdentifier {
return ObjectIdentifier(_box)
}
internal let _box: Box
}
% end