//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2021 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 // //===----------------------------------------------------------------------===// // Loosely adapted from https://github.com/apple/swift/tree/main/stdlib/private/StdlibCollectionUnittest public enum UnderestimatedCountBehavior { /// Return the actual number of elements. case precise /// Return the actual number of elements divided by 2. case half /// Return an overestimated count. Useful to test how algorithms reserve /// memory. case overestimate /// Return the provided value. case value(Int) func value(forCount count: Int) -> Int { switch self { case .precise: return count case .half: return count / 2 case .overestimate: return count * 3 + 5 case .value(let count): return count } } } /// A Sequence that implements the protocol contract in the most /// narrow way possible. /// /// This sequence is consumed when its iterator is advanced. public struct MinimalSequence: Sequence, CustomDebugStringConvertible { public let timesMakeIteratorCalled = ResettableValue(0) internal let _sharedState: _MinimalIteratorSharedState internal let _isContiguous: Bool public init( elements: S, underestimatedCount: UnderestimatedCountBehavior = .value(0), isContiguous: Bool = false ) where S.Element == T { let data = Array(elements) self._sharedState = _MinimalIteratorSharedState(data) self._isContiguous = isContiguous switch underestimatedCount { case .precise: self._sharedState.underestimatedCount = data.count case .half: self._sharedState.underestimatedCount = data.count / 2 case .overestimate: self._sharedState.underestimatedCount = data.count * 3 + 5 case .value(let count): self._sharedState.underestimatedCount = count } } public func makeIterator() -> MinimalIterator { timesMakeIteratorCalled.value += 1 return MinimalIterator(_sharedState) } public var underestimatedCount: Int { return Swift.max(0, self._sharedState.underestimatedCount - self._sharedState.i) } public var debugDescription: String { return "MinimalSequence(\(_sharedState.data[_sharedState.i...]))" } public func withContiguousStorageIfAvailable( _ body: (UnsafeBufferPointer) throws -> R ) rethrows -> R? { guard _isContiguous else { return nil } return try _sharedState.data[_sharedState.i...] .withContiguousStorageIfAvailable(body) } }