mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
342 lines
11 KiB
Swift
342 lines
11 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
public struct _Count {}
|
|
internal func _count<Args>(a: Args) -> (_Count, Args) {
|
|
return (_Count(), a)
|
|
}
|
|
|
|
// Default implementation of count for Collections
|
|
// Do not use this operator directly; call count(x) instead
|
|
public func ~> <T: _CollectionType>(x:T, _:(_Count,()))
|
|
-> T.Index.Distance
|
|
{
|
|
return distance(x.startIndex, x.endIndex)
|
|
}
|
|
|
|
/// Return the number of elements in x.
|
|
///
|
|
/// O(1) if T.Index is RandomAccessIndexType; O(N) otherwise.
|
|
public func count <T: _CollectionType>(x: T) -> T.Index.Distance {
|
|
return x~>_count()
|
|
}
|
|
|
|
@availability(*, unavailable, renamed="count")
|
|
public func countElements <T: _CollectionType>(x: T) -> T.Index.Distance {
|
|
return count(x)
|
|
}
|
|
|
|
/// This protocol is an implementation detail of `CollectionType`; do
|
|
/// not use it directly.
|
|
///
|
|
/// Its requirements are inherited by `CollectionType` and thus must
|
|
/// be satisfied by types conforming to that protocol.
|
|
public protocol _CollectionType : _SequenceType {
|
|
/// A type that represents a valid position in the collection.
|
|
///
|
|
/// Valid indices consist of the position of every element and a
|
|
/// "past the end" position that's not valid for use as a subscript.
|
|
typealias Index : ForwardIndexType
|
|
|
|
/// The position of the first element in a non-empty collection.
|
|
///
|
|
/// Identical to `endIndex` in an empty collection.
|
|
var startIndex: Index {get}
|
|
|
|
/// The collection's "past the end" position.
|
|
///
|
|
/// `endIndex` is not a valid argument to `subscript`, and is always
|
|
/// reachable from `startIndex` by zero or more applications of
|
|
/// `successor()`.
|
|
var endIndex: Index {get}
|
|
|
|
// The declaration of Element and _subscript here is a trick used to
|
|
// break a cyclic conformance/deduction that Swift can't handle. We
|
|
// need something other than a CollectionType.Generator.Element that can
|
|
// be used as IndexingGenerator<T>'s Element. Here we arrange for the
|
|
// CollectionType itself to have an Element type that's deducible from
|
|
// its subscript. Ideally we'd like to constrain this
|
|
// Element to be the same as CollectionType.Generator.Element (see
|
|
// below), but we have no way of expressing it today.
|
|
typealias _Element
|
|
subscript(_i: Index) -> _Element {get}
|
|
}
|
|
|
|
/// A multi-pass *sequence* with addressable positions.
|
|
///
|
|
/// Positions are represented by an associated `Index` type. Whereas
|
|
/// an arbitrary *sequence* may be consumed as it is traversed, a
|
|
/// *collection* is multi-pass: any element may be revisited merely by
|
|
/// saving its index.
|
|
///
|
|
/// The sequence view of the elements is identical to the collection
|
|
/// view. In other words, the following code binds the same series of
|
|
/// values to `x` as does `for x in self {}`::
|
|
///
|
|
/// for i in startIndex..<endIndex {
|
|
/// let x = self[i]
|
|
/// }
|
|
public protocol CollectionType : _CollectionType, SequenceType {
|
|
/// Access the element indicated by `position`.
|
|
///
|
|
/// Requires: `position` indicates a valid position in `self` and
|
|
/// `position != endIndex`.
|
|
subscript(position: Index) -> Generator.Element {get}
|
|
|
|
// Do not use this operator directly; call `count(x)` instead
|
|
func ~> (_:Self, _:(_Count, ())) -> Index.Distance
|
|
}
|
|
|
|
// Default implementation of underestimateCount for *collections*. Do not
|
|
// use this operator directly; call `underestimateCount(s)` instead
|
|
public func ~> <T: _CollectionType>(x:T,_:(_UnderestimateCount,())) -> Int {
|
|
return numericCast(x~>_count())
|
|
}
|
|
|
|
// Default implementation of `preprocessingPass` for *collections*. Do not
|
|
// use this operator directly; call `_preprocessingPass(s)` instead
|
|
public func ~> <T: _CollectionType, R>(
|
|
s: T, args: (_PreprocessingPass, ( (T)->R ))
|
|
) -> R? {
|
|
return args.1(s)
|
|
}
|
|
|
|
/// Returns `true` iff `x` is empty.
|
|
public func isEmpty<C: CollectionType>(x: C) -> Bool {
|
|
return x.startIndex == x.endIndex
|
|
}
|
|
|
|
/// Returns the first element of `x`, or `nil` if `x` is empty.
|
|
public func first<C: CollectionType>(x: C) -> C.Generator.Element? {
|
|
return isEmpty(x) ? nil : x[x.startIndex]
|
|
}
|
|
|
|
/// Returns the last element of `x`, or `nil` if `x` is empty.
|
|
public func last<C: CollectionType where C.Index: BidirectionalIndexType>(
|
|
x: C
|
|
) -> C.Generator.Element? {
|
|
return isEmpty(x) ? nil : x[x.endIndex.predecessor()]
|
|
}
|
|
|
|
/// A *collection* that supports subscript assignment.
|
|
///
|
|
/// For any instance `a` of a type conforming to
|
|
/// `MutableCollectionType`, ::
|
|
///
|
|
/// a[i] = x
|
|
/// let y = a[i]
|
|
///
|
|
/// is equivalent to ::
|
|
///
|
|
/// a[i] = x
|
|
/// let y = x
|
|
///
|
|
public protocol MutableCollectionType : CollectionType {
|
|
/// Access the element at `position`.
|
|
///
|
|
/// Requires: `position` indicates a valid position in `self` and
|
|
/// `position != endIndex`.
|
|
subscript(position: Index) -> Generator.Element {get set}
|
|
}
|
|
|
|
/// A *generator* for an arbitrary *collection*. Provided `C`
|
|
/// conforms to the other requirements of *CollectionType*,
|
|
/// `IndexingGenerator<C>` can be used as the result of `C`\ 's
|
|
/// `generate()` method. For example:
|
|
///
|
|
/// .. parsed-literal::
|
|
///
|
|
/// struct MyCollection : CollectionType {
|
|
/// struct Index : ForwardIndexType { *implementation hidden* }
|
|
/// subscript(i: Index) -> MyElement { *implementation hidden* }
|
|
/// func generate() -> **IndexingGenerator<MyCollection>** {
|
|
/// return IndexingGenerator(self)
|
|
/// }
|
|
/// }
|
|
public struct IndexingGenerator<
|
|
C: _CollectionType
|
|
> : GeneratorType, SequenceType {
|
|
// Because of <rdar://problem/14396120> we've had to factor
|
|
// _CollectionType out of CollectionType to make it useful.
|
|
|
|
/// Create a *generator* over the given collection
|
|
public init(_ seq: C) {
|
|
self._elements = seq
|
|
self._position = seq.startIndex
|
|
}
|
|
|
|
/// Return a *generator* over the elements of this *sequence*.
|
|
///
|
|
/// Complexity: O(1)
|
|
public func generate() -> IndexingGenerator {
|
|
return self
|
|
}
|
|
|
|
/// Advance to the next element and return it, or `nil` if no next
|
|
/// element exists.
|
|
///
|
|
/// Requires: no preceding call to `self.next()` has returned `nil`.
|
|
public mutating func next() -> C._Element? {
|
|
return _position == _elements.endIndex
|
|
? .None : .Some(_elements[_position++])
|
|
}
|
|
|
|
let _elements: C
|
|
var _position: C.Index
|
|
}
|
|
|
|
/// Return the range of `x` 's valid index values.
|
|
///
|
|
/// The result's `endIndex` is the same as that of `x`. Because
|
|
/// `Range` is half-open, iterating the values of the result produces
|
|
/// all valid subscript arguments for `x`, omitting its `endIndex`.
|
|
public func indices<
|
|
C : CollectionType>(x: C) -> Range<C.Index> {
|
|
return Range(start: x.startIndex, end: x.endIndex)
|
|
}
|
|
|
|
/// A *generator* that adapts a *collection* `C` and any *sequence* of
|
|
/// its `Index` type to present the collection's elements in a
|
|
/// permuted order.
|
|
public struct PermutationGenerator<
|
|
C: CollectionType, Indices: SequenceType
|
|
where C.Index == Indices.Generator.Element
|
|
> : GeneratorType, SequenceType {
|
|
var seq : C
|
|
var indices : Indices.Generator
|
|
|
|
/// The type of element returned by `next()`.
|
|
public typealias Element = C.Generator.Element
|
|
|
|
/// Advance to the next element and return it, or `nil` if no next
|
|
/// element exists.
|
|
///
|
|
/// Requires: no preceding call to `self.next()` has returned `nil`.
|
|
public mutating func next() -> Element? {
|
|
var result = indices.next()
|
|
return result != nil ? seq[result!] : .None
|
|
}
|
|
|
|
/// A type whose instances can produce the elements of this
|
|
/// sequence, in order.
|
|
public typealias Generator = PermutationGenerator
|
|
|
|
/// Return a *generator* over the elements of this *sequence*.
|
|
///
|
|
/// Complexity: O(1)
|
|
public func generate() -> Generator {
|
|
return self
|
|
}
|
|
|
|
/// Construct a *generator* over a permutation of `elements` given
|
|
/// by `indices`.
|
|
///
|
|
/// Requires: `elements[i]` is valid for every `i` in `indices`.
|
|
public init(elements: C, indices: Indices) {
|
|
self.seq = elements
|
|
self.indices = indices.generate()
|
|
}
|
|
}
|
|
|
|
/// This protocol is an implementation detail of `Sliceable`; do
|
|
/// not use it directly.
|
|
///
|
|
/// Its requirements are inherited by `Sliceable` and thus must
|
|
/// be satisfied by types conforming to that protocol.
|
|
public protocol _Sliceable : CollectionType {}
|
|
|
|
/// A *collection* from which a sub-range of elements (a "slice")
|
|
/// can be efficiently extracted.
|
|
public protocol Sliceable : _Sliceable {
|
|
// FIXME: Slice should also be Sliceable but we can't express
|
|
// that constraint (<rdar://problem/14375973> Include associated
|
|
// type information in protocol witness tables) Instead we constrain
|
|
// to _Sliceable; at least error messages will be more informative.
|
|
|
|
/// The *collection* type that represents a sub-range of elements.
|
|
///
|
|
/// Though it can't currently be enforced by the type system, the
|
|
/// `SubSlice` type in a concrete implementation of `Sliceable`
|
|
/// should also be `Sliceable`.
|
|
typealias SubSlice: _Sliceable
|
|
|
|
/// Access the elements delimited by the given half-open range of
|
|
/// indices.
|
|
///
|
|
/// Complexity: O(1) unless bridging from Objective-C requires an
|
|
/// O(N) conversion.
|
|
subscript(bounds: Range<Index>) -> SubSlice {get}
|
|
}
|
|
|
|
/// A *collection* with mutable slices.
|
|
///
|
|
/// For example,
|
|
///
|
|
/// .. parsed-literal:
|
|
///
|
|
/// x[i..<j] = *someExpression*
|
|
/// x[i..<j].\ *mutatingMethod*\ ()
|
|
public protocol MutableSliceable : Sliceable, MutableCollectionType {
|
|
subscript(_: Range<Index>) -> SubSlice {get set}
|
|
}
|
|
|
|
/// Return a slice containing all but the first element of `s`.
|
|
///
|
|
/// Requires: `s` is non-empty.
|
|
public func dropFirst<Seq : Sliceable>(s: Seq) -> Seq.SubSlice {
|
|
return s[s.startIndex.successor()..<s.endIndex]
|
|
}
|
|
|
|
/// Return a slice containing all but the last element of `s`.
|
|
///
|
|
/// Requires: `s` is non-empty.
|
|
public func dropLast<
|
|
S: Sliceable
|
|
where S.Index: BidirectionalIndexType
|
|
>(s: S) -> S.SubSlice {
|
|
return s[s.startIndex..<s.endIndex.predecessor()]
|
|
}
|
|
|
|
/// Return a slice, up to `maxLength` in length, containing the
|
|
/// initial elements of `s`.
|
|
///
|
|
/// If `maxLength` exceeds `count(s)`, the result contains all
|
|
/// the elements of `s`.
|
|
///
|
|
/// Complexity: O(1)+K when `S.Index` conforms to
|
|
/// `RandomAccessIndexType` and O(N)+K otherwise, where K is the cost
|
|
/// of slicing `s`.
|
|
public func prefix<S: Sliceable>(s: S, maxLength: Int) -> S.SubSlice {
|
|
return s[
|
|
s.startIndex..<advance(
|
|
s.startIndex, max(0, numericCast(maxLength)), s.endIndex)
|
|
]
|
|
}
|
|
|
|
/// Return a slice, up to `maxLength` in length, containing the
|
|
/// final elements of `s`.
|
|
///
|
|
/// If `maxLength` exceeds `count(s)`, the result contains all
|
|
/// the elements of `s`.
|
|
///
|
|
/// Complexity: O(1)+K when `S.Index` conforms to
|
|
/// `RandomAccessIndexType` and O(N)+K otherwise, where K is the cost
|
|
/// of slicing `s`.
|
|
public func suffix<
|
|
S: Sliceable where S.Index: BidirectionalIndexType
|
|
>(s: S, maxLength: Int) -> S.SubSlice {
|
|
return s[
|
|
advance(
|
|
s.endIndex, -max(0, numericCast(maxLength)), s.startIndex)..<s.endIndex
|
|
]
|
|
}
|