mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
stdlib: change underestimateCount() into a method
rdar://19895265 Swift SVN r27346
This commit is contained in:
@@ -2187,17 +2187,15 @@ public struct MinimalSequence<T> : SequenceType {
|
||||
return MinimalGenerator(_sharedState)
|
||||
}
|
||||
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return underestimatedCount
|
||||
}
|
||||
|
||||
public var underestimatedCount: Int
|
||||
|
||||
internal let _sharedState: _MinimalGeneratorSharedState<T>
|
||||
}
|
||||
|
||||
public func ~> <T> (
|
||||
s: MinimalSequence<T>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return s.underestimatedCount
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MinimalForwardIndex
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -2359,17 +2357,15 @@ public struct ${Self}<T> : CollectionType {
|
||||
return _elements[i.position]
|
||||
}
|
||||
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return underestimatedCount
|
||||
}
|
||||
|
||||
public var underestimatedCount: Int
|
||||
|
||||
internal let _elements: [T]
|
||||
}
|
||||
|
||||
public func ~> <T> (
|
||||
c: ${Self}<T>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return c.underestimatedCount
|
||||
}
|
||||
|
||||
%end
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -2411,6 +2407,10 @@ public struct ${Self}<T> : RangeReplaceableCollectionType {
|
||||
return MinimalGenerator(elements)
|
||||
}
|
||||
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return underestimatedCount
|
||||
}
|
||||
|
||||
public var startIndex: ${Index} {
|
||||
return ${Index}(
|
||||
position: 0,
|
||||
@@ -2485,12 +2485,6 @@ public struct ${Self}<T> : RangeReplaceableCollectionType {
|
||||
public var elements: [T]
|
||||
}
|
||||
|
||||
public func ~> <T> (
|
||||
c: ${Self}<T>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return c.underestimatedCount
|
||||
}
|
||||
|
||||
%end
|
||||
|
||||
// ${'Local Variables'}:
|
||||
|
||||
@@ -66,10 +66,17 @@ public protocol _CollectionType : _SequenceType {
|
||||
subscript(_i: Index) -> _Element {get}
|
||||
}
|
||||
|
||||
public protocol _CollectionDefaultsType : _CollectionType {
|
||||
}
|
||||
public protocol _CollectionDefaultsType
|
||||
: _CollectionType, _SequenceElementInvariantDefaultsType {}
|
||||
|
||||
extension _CollectionDefaultsType {
|
||||
/// Return a value less than or equal to the number of elements in
|
||||
/// `self`, **nondestructively**.
|
||||
///
|
||||
/// Complexity: O(N)
|
||||
final public func _prext_underestimateCount() -> Int {
|
||||
return numericCast(count(self))
|
||||
}
|
||||
}
|
||||
|
||||
/// A multi-pass *sequence* with addressable positions.
|
||||
@@ -99,12 +106,6 @@ public protocol CollectionType
|
||||
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())
|
||||
}
|
||||
|
||||
// A fast implementation for when you are backed by a contiguous array.
|
||||
public func ~> <T : protocol<_Sequence_Type, _ArrayType>>(
|
||||
source: T, ptr: (_InitializeTo, UnsafeMutablePointer<T.Generator.Element>)) {
|
||||
|
||||
@@ -61,24 +61,6 @@ public protocol GeneratorType {
|
||||
public protocol _SequenceType {
|
||||
}
|
||||
|
||||
/// This protocol is an implementation detail of `SequenceType`; do
|
||||
/// not use it directly.
|
||||
///
|
||||
/// Its requirements are inherited by `SequenceType` and thus must
|
||||
/// be satisfied by types conforming to that protocol.
|
||||
public protocol _Sequence_Type : _SequenceType, _SequenceDefaultsType {
|
||||
/// A type whose instances can produce the elements of this
|
||||
/// sequence, in order.
|
||||
typealias Generator : GeneratorType
|
||||
|
||||
/// Return a *generator* over the elements of this *sequence*. The
|
||||
/// *generator*\ 's next element is the first element of the
|
||||
/// sequence.
|
||||
///
|
||||
/// Complexity: O(1)
|
||||
func generate() -> Generator
|
||||
}
|
||||
|
||||
public protocol _SequenceDefaultsType {
|
||||
/// A type that provides the *sequence*\ 's iteration interface and
|
||||
/// encapsulates its iteration state.
|
||||
@@ -95,7 +77,45 @@ public protocol _SequenceDefaultsType {
|
||||
extension _SequenceDefaultsType {
|
||||
}
|
||||
|
||||
extension _SequenceDefaultsType {
|
||||
public protocol _SequenceElementInvariantDefaultsType {
|
||||
// This protocol is an anchor point for default implementations for
|
||||
// SequenceType that don't depend on sequence contents.
|
||||
}
|
||||
|
||||
extension _SequenceElementInvariantDefaultsType {
|
||||
/// Return a value less than or equal to the number of elements in
|
||||
/// `self`, **nondestructively**.
|
||||
///
|
||||
/// Complexity: O(N)
|
||||
final public func _prext_underestimateCount() -> Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
/// This protocol is an implementation detail of `SequenceType`; do
|
||||
/// not use it directly.
|
||||
///
|
||||
/// Its requirements are inherited by `SequenceType` and thus must
|
||||
/// be satisfied by types conforming to that protocol.
|
||||
public protocol _Sequence_Type
|
||||
: _SequenceType, _SequenceDefaultsType, _SequenceElementInvariantDefaultsType {
|
||||
|
||||
/// A type whose instances can produce the elements of this
|
||||
/// sequence, in order.
|
||||
typealias Generator : GeneratorType
|
||||
|
||||
/// Return a *generator* over the elements of this *sequence*. The
|
||||
/// *generator*\ 's next element is the first element of the
|
||||
/// sequence.
|
||||
///
|
||||
/// Complexity: O(1)
|
||||
func generate() -> Generator
|
||||
|
||||
/// Return a value less than or equal to the number of elements in
|
||||
/// `self`, **nondestructively**.
|
||||
///
|
||||
/// Complexity: O(N)
|
||||
func _prext_underestimateCount() -> Int
|
||||
}
|
||||
|
||||
/// A type that can be iterated with a `for`\ ...\ `in` loop.
|
||||
@@ -114,12 +134,6 @@ public protocol SequenceType : _Sequence_Type {
|
||||
/// Complexity: O(1)
|
||||
func generate() -> Generator
|
||||
|
||||
/// Return a value less than or equal to the number of elements in
|
||||
/// self, **nondestructively**.
|
||||
///
|
||||
/// Complexity: O(N)
|
||||
func ~> (_:Self,_:(_UnderestimateCount,())) -> Int
|
||||
|
||||
/// If `self` is multi-pass (i.e., a `CollectionType`), invoke the function
|
||||
/// on `self` and return its result. Otherwise, return `nil`.
|
||||
func ~> <R>(_: Self, _: (_PreprocessingPass, ((Self)->R))) -> R?
|
||||
@@ -141,26 +155,12 @@ public func _copyToNativeArrayBuffer<Args>(args: Args)
|
||||
return (_CopyToNativeArrayBuffer(), args)
|
||||
}
|
||||
|
||||
// Operation tags for underestimateCount. See Index.swift for an
|
||||
// explanation of operation tags.
|
||||
public struct _UnderestimateCount {}
|
||||
internal func _underestimateCount<Args>(args: Args)
|
||||
-> (_UnderestimateCount, Args)
|
||||
{
|
||||
return (_UnderestimateCount(), args)
|
||||
}
|
||||
|
||||
// Default implementation of underestimateCount for Sequences. Do not
|
||||
// use this operator directly; call underestimateCount(s) instead
|
||||
public func ~> <T : _SequenceType>(s: T,_:(_UnderestimateCount, ())) -> Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
/// Return an underestimate of the number of elements in the given
|
||||
/// sequence, without consuming the sequence. For Sequences that are
|
||||
/// actually Collections, this will return count(x)
|
||||
public func underestimateCount<T : SequenceType>(x: T) -> Int {
|
||||
return x~>_underestimateCount()
|
||||
// FIXME(prext): remove this function when protocol extensions land.
|
||||
return x._prext_underestimateCount()
|
||||
}
|
||||
|
||||
public struct _InitializeTo {}
|
||||
|
||||
@@ -533,7 +533,7 @@ public func ~> <
|
||||
source: S, _: (_CopyToNativeArrayBuffer,())
|
||||
) -> _ContiguousArrayBuffer<S.Generator.Element>
|
||||
{
|
||||
let initialCapacity = source~>_underestimateCount()
|
||||
let initialCapacity = source._prext_underestimateCount()
|
||||
var result = _ContiguousArrayBuffer<S.Generator.Element>(
|
||||
count: 0, minimumCapacity: initialCapacity)
|
||||
|
||||
|
||||
@@ -214,10 +214,10 @@ public struct AnySequence<T> : SequenceType {
|
||||
}
|
||||
|
||||
% for Kind in ['Sequence'] + [t + 'Collection' for t in traversals]:
|
||||
public func ~> <Element>(
|
||||
source: Any${Kind}<Element>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return source._box._underestimateCount()
|
||||
extension Any${Kind} {
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return _box._underestimateCount()
|
||||
}
|
||||
}
|
||||
|
||||
public func ~> <Element>(
|
||||
|
||||
@@ -80,13 +80,11 @@ public struct ${Self}<S : CollectionType ${whereClause}> : CollectionType {
|
||||
return Array(_base)
|
||||
}
|
||||
|
||||
var _base: S
|
||||
}
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return underestimateCount(_base)
|
||||
}
|
||||
|
||||
public func ~> <S : CollectionType ${whereClause}> (
|
||||
s: ${Self}<S>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return underestimateCount(s._base)
|
||||
var _base: S
|
||||
}
|
||||
|
||||
/// Augment `s` with lazy methods such as `map`, `filter`, etc.
|
||||
|
||||
@@ -32,13 +32,11 @@ public struct LazySequence<S : SequenceType> : SequenceType {
|
||||
return Array(_base)
|
||||
}
|
||||
|
||||
var _base: S
|
||||
}
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return underestimateCount(_base)
|
||||
}
|
||||
|
||||
public func ~> <S : SequenceType> (
|
||||
s: LazySequence<S>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return underestimateCount(s._base)
|
||||
var _base: S
|
||||
}
|
||||
|
||||
/// Augment `s` with lazy methods such as `map`, `filter`, etc.
|
||||
|
||||
@@ -55,16 +55,14 @@ public struct MapSequenceView<Base : SequenceType, T> : SequenceType {
|
||||
_base: _base.generate(), _transform: _transform)
|
||||
}
|
||||
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return underestimateCount(_base)
|
||||
}
|
||||
|
||||
var _base: Base
|
||||
var _transform: (Base.Generator.Element)->T
|
||||
}
|
||||
|
||||
public func ~> <Base : SequenceType, T> (
|
||||
s: MapSequenceView<Base, T>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return underestimateCount(s._base)
|
||||
}
|
||||
|
||||
/// Return an `Array` containing the results of mapping `transform`
|
||||
/// over `source`.
|
||||
public func map<S : SequenceType, T>(
|
||||
@@ -121,16 +119,14 @@ public struct MapCollectionView<Base : CollectionType, T> : CollectionType {
|
||||
return MapSequenceGenerator(_base: _base.generate(), _transform: _transform)
|
||||
}
|
||||
|
||||
public func _prext_underestimateCount() -> Int {
|
||||
return underestimateCount(_base)
|
||||
}
|
||||
|
||||
var _base: Base
|
||||
var _transform: (Base.Generator.Element)->T
|
||||
}
|
||||
|
||||
public func ~> <Base: CollectionType, T> (
|
||||
s: MapCollectionView<Base, T>, _: (_UnderestimateCount, ())
|
||||
) -> Int {
|
||||
return underestimateCount(s._base)
|
||||
}
|
||||
|
||||
/// Return an `Array` containing the results of mapping `transform`
|
||||
/// over `source`.
|
||||
public func map<C : CollectionType, T>(
|
||||
|
||||
@@ -598,7 +598,7 @@ extension _StringCore : ExtensibleCollectionType {
|
||||
}
|
||||
}
|
||||
|
||||
let growth = s~>_underestimateCount()
|
||||
let growth = s._prext_underestimateCount()
|
||||
var g = s.generate()
|
||||
|
||||
if _fastPath(growth > 0) {
|
||||
|
||||
@@ -356,7 +356,7 @@ Algorithm.test("map/CollectionType") {
|
||||
expectType([Int16].self, &result)
|
||||
expectEqual([], result)
|
||||
expectLE(c.underestimatedCount, result.capacity)
|
||||
expectGE(2 * result.count, result.capacity) {
|
||||
expectGE(result.count + 3, result.capacity) {
|
||||
"map() should use the precise element count"
|
||||
}
|
||||
}
|
||||
@@ -365,16 +365,7 @@ Algorithm.test("map/CollectionType") {
|
||||
[ 0, 30, 10, 90 ], underestimatedCount: .Value(0))
|
||||
let result = map(c) { $0 + 1 }
|
||||
expectEqual([ 1, 31, 11, 91 ], result)
|
||||
expectGE(2 * result.count, result.capacity) {
|
||||
"map() should use the precise element count"
|
||||
}
|
||||
}
|
||||
if true {
|
||||
let c = MinimalForwardCollection(
|
||||
[ 0, 30, 10, 90 ], underestimatedCount: .Overestimate)
|
||||
let result = map(c) { $0 + 1 }
|
||||
expectEqual([ 1, 31, 11, 91 ], result)
|
||||
expectGE(2 * result.count, result.capacity) {
|
||||
expectGE(result.count + 3, result.capacity) {
|
||||
"map() should use the precise element count"
|
||||
}
|
||||
}
|
||||
@@ -1817,7 +1808,7 @@ SequenceTypeAlgorithms.test("map/CollectionType") {
|
||||
expectEqual(0, LifetimeTracked.instances)
|
||||
for test in mapTests {
|
||||
for underestimateCountBehavior in [
|
||||
UnderestimateCountBehavior.Overestimate,
|
||||
UnderestimateCountBehavior.Precise,
|
||||
UnderestimateCountBehavior.Value(0)
|
||||
] {
|
||||
let s = MinimalForwardCollection<OpaqueValue<Int>>(
|
||||
@@ -1840,7 +1831,7 @@ SequenceTypeAlgorithms.test("map/CollectionType") {
|
||||
expectEqual(test.sequence.count, timesClosureWasCalled) {
|
||||
"map() should be eager and should only call its predicate once per element"
|
||||
}
|
||||
expectGE(2 * result.count, result.capacity) {
|
||||
expectGE(result.count + 3, result.capacity) {
|
||||
"map() should use the precise element count"
|
||||
}
|
||||
}
|
||||
@@ -2119,6 +2110,143 @@ SequenceTypeAlgorithms.test("zip") {
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// underestimateCount()
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
func callGenericUnderestimatedCount<S : SequenceType>(s: S) -> Int {
|
||||
return s._prext_underestimateCount()
|
||||
}
|
||||
|
||||
struct SequenceWithDefaultUnderestimateCount : SequenceType {
|
||||
init() {}
|
||||
|
||||
func generate() -> MinimalSequence<OpaqueValue<Int>>.Generator {
|
||||
expectUnreachable()
|
||||
return MinimalSequence(
|
||||
[ 1, 2, 3 ]._prext_map { OpaqueValue($0) }
|
||||
).generate()
|
||||
}
|
||||
}
|
||||
|
||||
SequenceTypeAlgorithms.test("underestimateCount/SequenceType/DefaultImplementation") {
|
||||
let s = SequenceWithDefaultUnderestimateCount()
|
||||
expectEqual(0, callGenericUnderestimatedCount(s))
|
||||
}
|
||||
|
||||
struct SequenceWithCustomUnderestimateCount : SequenceType {
|
||||
init(underestimatedCount: Int) {
|
||||
self._underestimatedCount = underestimatedCount
|
||||
}
|
||||
|
||||
func generate() -> MinimalSequence<OpaqueValue<Int>>.Generator {
|
||||
expectUnreachable()
|
||||
return MinimalSequence(
|
||||
[ 0xffff, 0xffff, 0xffff ]._prext_map { OpaqueValue($0) }
|
||||
).generate()
|
||||
}
|
||||
|
||||
func _prext_underestimateCount() -> Int {
|
||||
return _underestimatedCount
|
||||
}
|
||||
|
||||
let _underestimatedCount: Int
|
||||
}
|
||||
|
||||
SequenceTypeAlgorithms.test("underestimateCount/SequenceType/CustomImplementation") {
|
||||
if true {
|
||||
let s = SequenceWithCustomUnderestimateCount(underestimatedCount: 5)
|
||||
expectEqual(5, callGenericUnderestimatedCount(s))
|
||||
}
|
||||
if true {
|
||||
let s = SequenceWithCustomUnderestimateCount(underestimatedCount: 42)
|
||||
expectEqual(42, callGenericUnderestimatedCount(s))
|
||||
}
|
||||
}
|
||||
|
||||
struct CollectionWithDefaultUnderestimateCount : CollectionType {
|
||||
init(count: Int) {
|
||||
self._count = count
|
||||
}
|
||||
|
||||
func generate() -> MinimalGenerator<OpaqueValue<Int>> {
|
||||
expectUnreachable()
|
||||
return MinimalGenerator([])
|
||||
}
|
||||
|
||||
var startIndex: MinimalForwardIndex {
|
||||
return MinimalForwardIndex(position: 0, startIndex: 0, endIndex: _count)
|
||||
}
|
||||
|
||||
var endIndex: MinimalForwardIndex {
|
||||
return MinimalForwardIndex(
|
||||
position: _count, startIndex: 0, endIndex: _count)
|
||||
}
|
||||
|
||||
subscript(i: MinimalForwardIndex) -> OpaqueValue<Int> {
|
||||
expectUnreachable()
|
||||
return OpaqueValue(0xffff)
|
||||
}
|
||||
|
||||
var _count: Int
|
||||
}
|
||||
|
||||
SequenceTypeAlgorithms.test("underestimateCount/CollectionType/DefaultImplementation") {
|
||||
if true {
|
||||
let s = CollectionWithDefaultUnderestimateCount(count: 0)
|
||||
expectEqual(0, callGenericUnderestimatedCount(s))
|
||||
}
|
||||
if true {
|
||||
let s = CollectionWithDefaultUnderestimateCount(count: 5)
|
||||
expectEqual(5, callGenericUnderestimatedCount(s))
|
||||
}
|
||||
}
|
||||
|
||||
struct CollectionWithCustomUnderestimateCount : CollectionType {
|
||||
init(underestimatedCount: Int) {
|
||||
self._underestimatedCount = underestimatedCount
|
||||
}
|
||||
|
||||
func generate() -> MinimalGenerator<OpaqueValue<Int>> {
|
||||
expectUnreachable()
|
||||
return MinimalGenerator([])
|
||||
}
|
||||
|
||||
var startIndex: MinimalForwardIndex {
|
||||
expectUnreachable()
|
||||
return MinimalForwardIndex(position: 0, startIndex: 0, endIndex: 0xffff)
|
||||
}
|
||||
|
||||
var endIndex: MinimalForwardIndex {
|
||||
expectUnreachable()
|
||||
return MinimalForwardIndex(
|
||||
position: 0xffff, startIndex: 0, endIndex: 0xffff)
|
||||
}
|
||||
|
||||
subscript(i: MinimalForwardIndex) -> OpaqueValue<Int> {
|
||||
expectUnreachable()
|
||||
return OpaqueValue(0xffff)
|
||||
}
|
||||
|
||||
func _prext_underestimateCount() -> Int {
|
||||
return _underestimatedCount
|
||||
}
|
||||
|
||||
let _underestimatedCount: Int
|
||||
}
|
||||
|
||||
SequenceTypeAlgorithms.test("underestimateCount/CollectionType/CustomImplementation") {
|
||||
if true {
|
||||
let s = CollectionWithCustomUnderestimateCount(underestimatedCount: 0)
|
||||
expectEqual(0, callGenericUnderestimatedCount(s))
|
||||
}
|
||||
if true {
|
||||
let s = CollectionWithCustomUnderestimateCount(underestimatedCount: 5)
|
||||
expectEqual(5, callGenericUnderestimatedCount(s))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// isEmpty
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user